// Copyright 2015-2020 Parity Technologies (UK) Ltd.
// This file is part of OpenEthereum.
// OpenEthereum is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// OpenEthereum is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with OpenEthereum. If not, see .
//! Types used in Confirmations queue (Trusted Signer)
use ansi_term::Colour;
use bytes::ToPretty;
use serde::{Serialize, Serializer};
use std::fmt;
use ethereum_types::{H160, H256, H520, U256};
use ethkey::Password;
use v1::{
helpers,
types::{Bytes, Origin, RichRawTransaction, TransactionCondition, TransactionRequest},
};
/// Confirmation waiting in a queue
#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct ConfirmationRequest {
/// Id of this confirmation
pub id: U256,
/// Payload
pub payload: ConfirmationPayload,
/// Request origin
pub origin: Origin,
}
impl From for ConfirmationRequest {
fn from(c: helpers::ConfirmationRequest) -> Self {
ConfirmationRequest {
id: c.id,
payload: c.payload.into(),
origin: c.origin,
}
}
}
impl fmt::Display for ConfirmationRequest {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"#{}: {} coming from {}",
self.id, self.payload, self.origin
)
}
}
impl fmt::Display for ConfirmationPayload {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
ConfirmationPayload::SendTransaction(ref transaction) => write!(f, "{}", transaction),
ConfirmationPayload::SignTransaction(ref transaction) => {
write!(f, "(Sign only) {}", transaction)
}
ConfirmationPayload::EthSignMessage(ref sign) => write!(f, "{}", sign),
ConfirmationPayload::EIP191SignMessage(ref sign) => write!(f, "{}", sign),
ConfirmationPayload::Decrypt(ref decrypt) => write!(f, "{}", decrypt),
}
}
}
/// Ethereum-prefixed Sign request
#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct EthSignRequest {
/// Address
pub address: H160,
/// Hash to sign
pub data: Bytes,
}
/// EIP191 Sign request
#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct EIP191SignRequest {
/// Address
pub address: H160,
/// Hash to sign
pub data: H256,
}
impl From<(H160, H256)> for EIP191SignRequest {
fn from(tuple: (H160, H256)) -> Self {
EIP191SignRequest {
address: tuple.0,
data: tuple.1,
}
}
}
impl fmt::Display for EIP191SignRequest {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"sign 0x{} with {}",
self.data.0.pretty(),
Colour::White.bold().paint(format!("0x{:?}", self.address)),
)
}
}
impl From<(H160, Bytes)> for EthSignRequest {
fn from(tuple: (H160, Bytes)) -> Self {
EthSignRequest {
address: tuple.0,
data: tuple.1,
}
}
}
impl fmt::Display for EthSignRequest {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"sign 0x{} with {}",
self.data.0.pretty(),
Colour::White.bold().paint(format!("0x{:?}", self.address)),
)
}
}
/// Decrypt request
#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct DecryptRequest {
/// Address
pub address: H160,
/// Message to decrypt
pub msg: Bytes,
}
impl From<(H160, Bytes)> for DecryptRequest {
fn from(tuple: (H160, Bytes)) -> Self {
DecryptRequest {
address: tuple.0,
msg: tuple.1,
}
}
}
impl fmt::Display for DecryptRequest {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"decrypt data with {}",
Colour::White.bold().paint(format!("0x{:?}", self.address)),
)
}
}
/// Confirmation response for particular payload
#[derive(Debug, Clone, PartialEq)]
pub enum ConfirmationResponse {
/// Transaction Hash
SendTransaction(H256),
/// Transaction RLP
SignTransaction(RichRawTransaction),
/// Signature (encoded as VRS)
Signature(H520),
/// Decrypted data
Decrypt(Bytes),
}
impl Serialize for ConfirmationResponse {
fn serialize(&self, serializer: S) -> Result
where
S: Serializer,
{
match *self {
ConfirmationResponse::SendTransaction(ref hash) => hash.serialize(serializer),
ConfirmationResponse::SignTransaction(ref rlp) => rlp.serialize(serializer),
ConfirmationResponse::Signature(ref signature) => signature.serialize(serializer),
ConfirmationResponse::Decrypt(ref data) => data.serialize(serializer),
}
}
}
/// Confirmation response with additional token for further requests
#[derive(Clone, PartialEq, Serialize)]
pub struct ConfirmationResponseWithToken {
/// Actual response
pub result: ConfirmationResponse,
/// New token
pub token: Password,
}
/// Confirmation payload, i.e. the thing to be confirmed
#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
#[serde(rename_all = "camelCase")]
pub enum ConfirmationPayload {
/// Send Transaction
SendTransaction(TransactionRequest),
/// Sign Transaction
SignTransaction(TransactionRequest),
/// Signature
#[serde(rename = "sign")]
EthSignMessage(EthSignRequest),
/// signature without prefix
EIP191SignMessage(EIP191SignRequest),
/// Decryption
Decrypt(DecryptRequest),
}
impl From for ConfirmationPayload {
fn from(c: helpers::ConfirmationPayload) -> Self {
match c {
helpers::ConfirmationPayload::SendTransaction(t) => {
ConfirmationPayload::SendTransaction(t.into())
}
helpers::ConfirmationPayload::SignTransaction(t) => {
ConfirmationPayload::SignTransaction(t.into())
}
helpers::ConfirmationPayload::EthSignMessage(address, data) => {
ConfirmationPayload::EthSignMessage(EthSignRequest {
address,
data: data.into(),
})
}
helpers::ConfirmationPayload::SignMessage(address, data) => {
ConfirmationPayload::EIP191SignMessage(EIP191SignRequest { address, data })
}
helpers::ConfirmationPayload::Decrypt(address, msg) => {
ConfirmationPayload::Decrypt(DecryptRequest {
address,
msg: msg.into(),
})
}
}
}
}
/// Possible modifications to the confirmed transaction sent by `Trusted Signer`
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
#[serde(rename_all = "camelCase")]
pub struct TransactionModification {
/// Modified transaction sender
pub sender: Option,
/// Modified gas price
pub gas_price: Option,
/// Modified gas
pub gas: Option,
/// Modified transaction condition.
pub condition: Option