diff --git a/crates/ethcore/types/src/encoded.rs b/crates/ethcore/types/src/encoded.rs index 1a13e2668..daf15eba0 100644 --- a/crates/ethcore/types/src/encoded.rs +++ b/crates/ethcore/types/src/encoded.rs @@ -210,7 +210,7 @@ impl Body { } /// A view over each transaction in the block. - pub fn transaction_views(&self) -> Vec { + pub fn transaction_views(&self) -> Vec { self.view().transaction_views() } @@ -405,7 +405,7 @@ impl Block { } /// A view over each transaction in the block. - pub fn transaction_views(&self) -> Vec { + pub fn transaction_views(&self) -> Vec { self.view().transaction_views() } diff --git a/crates/ethcore/types/src/transaction/transaction.rs b/crates/ethcore/types/src/transaction/transaction.rs index af225dcac..bf760eb77 100644 --- a/crates/ethcore/types/src/transaction/transaction.rs +++ b/crates/ethcore/types/src/transaction/transaction.rs @@ -267,7 +267,7 @@ impl AccessListTx { &mut self.transaction } - // decode bytes by this payload spec: rlp([3, [chainId, nonce, gasPrice, gasLimit, to, value, data, access_list, senderV, senderR, senderS]]) + // decode bytes by this payload spec: rlp([1, [chainId, nonce, gasPrice, gasLimit, to, value, data, access_list, senderV, senderR, senderS]]) pub fn decode(tx: &[u8]) -> Result { let tx_rlp = &Rlp::new(tx); diff --git a/crates/ethcore/types/src/views/block.rs b/crates/ethcore/types/src/views/block.rs index 237cf8694..e540d0a38 100644 --- a/crates/ethcore/types/src/views/block.rs +++ b/crates/ethcore/types/src/views/block.rs @@ -22,7 +22,7 @@ use ethereum_types::H256; use hash::keccak; use header::Header; use transaction::{LocalizedTransaction, TypedTransaction, UnverifiedTransaction}; -use views::{HeaderView, TransactionView}; +use views::{HeaderView, TypedTransactionView}; /// View onto block rlp. pub struct BlockView<'a> { @@ -114,10 +114,10 @@ impl<'a> BlockView<'a> { } /// Return List of transactions in given block. - pub fn transaction_views(&self) -> Vec> { + pub fn transaction_views(&self) -> Vec> { self.transactions_rlp() .iter() - .map(TransactionView::new) + .map(TypedTransactionView::new) .collect() } diff --git a/crates/ethcore/types/src/views/body.rs b/crates/ethcore/types/src/views/body.rs index 0fcc8eb38..055a54f5e 100644 --- a/crates/ethcore/types/src/views/body.rs +++ b/crates/ethcore/types/src/views/body.rs @@ -22,7 +22,7 @@ use ethereum_types::H256; use hash::keccak; use header::Header; use transaction::{LocalizedTransaction, TypedTransaction, UnverifiedTransaction}; -use views::{HeaderView, TransactionView}; +use views::{HeaderView, TypedTransactionView}; use BlockNumber; /// View onto block rlp. @@ -95,10 +95,10 @@ impl<'a> BodyView<'a> { self.transactions_rlp().item_count() } /// Return List of transactions in given block. - pub fn transaction_views(&self) -> Vec> { + pub fn transaction_views(&self) -> Vec> { self.transactions_rlp() .iter() - .map(TransactionView::new) + .map(TypedTransactionView::new) .collect() } diff --git a/crates/ethcore/types/src/views/mod.rs b/crates/ethcore/types/src/views/mod.rs index 312e5ecc1..bb0574c5a 100644 --- a/crates/ethcore/types/src/views/mod.rs +++ b/crates/ethcore/types/src/views/mod.rs @@ -21,10 +21,10 @@ mod view_rlp; mod block; mod body; mod header; -mod transaction; +mod typed_transaction; pub use self::{ - block::BlockView, body::BodyView, header::HeaderView, transaction::TransactionView, + block::BlockView, body::BodyView, header::HeaderView, typed_transaction::TypedTransactionView, view_rlp::ViewRlp, }; diff --git a/crates/ethcore/types/src/views/transaction.rs b/crates/ethcore/types/src/views/transaction.rs deleted file mode 100644 index d20115cbb..000000000 --- a/crates/ethcore/types/src/views/transaction.rs +++ /dev/null @@ -1,131 +0,0 @@ -// 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 . - -//! View onto transaction rlp -use super::ViewRlp; -use bytes::Bytes; -use ethereum_types::{H256, U256}; -use hash::keccak; - -/// View onto transaction rlp. -pub struct TransactionView<'a> { - rlp: ViewRlp<'a>, -} - -impl<'a> TransactionView<'a> { - /// Creates new view onto valid transaction rlp. - /// Use the `view!` macro to create this view in order to capture debugging info. - /// - /// # Example - /// - /// ``` - /// #[macro_use] - /// extern crate common_types as types; - /// - /// use types::views::{TransactionView}; - /// - /// fn main() { - /// let bytes : &[u8] = &[]; - /// let tx_view = view!(TransactionView, bytes); - /// } - /// ``` - pub fn new(rlp: ViewRlp<'a>) -> TransactionView<'a> { - TransactionView { rlp: rlp } - } - - /// Return reference to underlaying rlp. - pub fn rlp(&self) -> &ViewRlp<'a> { - &self.rlp - } - - /// Returns transaction hash. - pub fn hash(&self) -> H256 { - keccak(self.rlp.as_raw()) - } - - /// Get the nonce field of the transaction. - pub fn nonce(&self) -> U256 { - self.rlp.val_at(0) - } - - /// Get the gas_price field of the transaction. - pub fn gas_price(&self) -> U256 { - self.rlp.val_at(1) - } - - /// Get the gas field of the transaction. - pub fn gas(&self) -> U256 { - self.rlp.val_at(2) - } - - /// Get the value field of the transaction. - pub fn value(&self) -> U256 { - self.rlp.val_at(4) - } - - /// Get the data field of the transaction. - pub fn data(&self) -> Bytes { - self.rlp.val_at(5) - } - - /// Get the v field of the transaction. - pub fn v(&self) -> u8 { - let r: u16 = self.rlp.val_at(6); - r as u8 - } - - /// Get the r field of the transaction. - pub fn r(&self) -> U256 { - self.rlp.val_at(7) - } - - /// Get the s field of the transaction. - pub fn s(&self) -> U256 { - self.rlp.val_at(8) - } -} - -#[cfg(test)] -mod tests { - use super::TransactionView; - use rustc_hex::FromHex; - - #[test] - fn test_transaction_view() { - let rlp = "f87c80018261a894095e7baea6a6c7c4c2dfeb977efac326af552d870a9d00000000000000000000000000000000000000000000000000000000001ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804".from_hex().unwrap(); - - let view = view!(TransactionView, &rlp); - assert_eq!(view.nonce(), 0.into()); - assert_eq!(view.gas_price(), 1.into()); - assert_eq!(view.gas(), 0x61a8.into()); - assert_eq!(view.value(), 0xa.into()); - assert_eq!( - view.data(), - "0000000000000000000000000000000000000000000000000000000000" - .from_hex() - .unwrap() - ); - assert_eq!( - view.r(), - "48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353".into() - ); - assert_eq!( - view.s(), - "efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804".into() - ); - assert_eq!(view.v(), 0x1b); - } -} diff --git a/crates/ethcore/types/src/views/typed_transaction.rs b/crates/ethcore/types/src/views/typed_transaction.rs new file mode 100644 index 000000000..3a504c117 --- /dev/null +++ b/crates/ethcore/types/src/views/typed_transaction.rs @@ -0,0 +1,252 @@ +// 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 . + +//! View onto transaction rlp +use std::convert::TryInto; + +use crate::transaction::{signature, TypedTxId}; + +use super::ViewRlp; +use bytes::Bytes; +use ethereum_types::{H256, U256}; +use hash::keccak; +use rlp::Rlp; + +/// View onto transaction rlp. Assumption is this is part of block. +/// Typed Transaction View. It handles raw bytes to search for particular field. +/// Access tx: +/// 1 | [chainId, nonce, gasPrice, gasLimit, to, value, data, access_list, senderV, senderR, senderS] +/// Legacy tx: +/// [nonce, gasPrice, gasLimit, to, value, data, senderV, senderR, senderS] +pub struct TypedTransactionView<'a> { + rlp: ViewRlp<'a>, + transaction_type: TypedTxId, +} +impl<'a> TypedTransactionView<'a> { + /// Creates new view onto valid transaction rlp. + /// Use the `view!` macro to create this view in order to capture debugging info. + /// + /// # Example + /// + /// ``` + /// #[macro_use] + /// extern crate common_types as types; + /// + /// use types::views::{TransactionView}; + /// + /// fn main() { + /// let bytes : &[u8] = &[]; + /// let tx_view = view!(TransactionView, bytes); + /// } + /// ``` + pub fn new(rlp: ViewRlp<'a>) -> TypedTransactionView<'a> { + let transaction_type = Self::extract_transaction_type(&rlp.rlp); + TypedTransactionView { + rlp: rlp, + transaction_type, + } + } + + /// Extract transaction type from rlp bytes. + fn extract_transaction_type(rlp: &Rlp) -> TypedTxId { + if rlp.is_list() { + return TypedTxId::Legacy; + } + let tx = rlp.data().expect("unable to decode tx rlp"); + let id = tx[0].try_into().expect("unable to decode tx type"); + if id == TypedTxId::Legacy { + panic!("Transaction RLP View should be valid. Legacy byte found"); + } + id + } + + /// Returns reference to transaction type. + pub fn transaction_type(&self) -> &TypedTxId { + &self.transaction_type + } + + /// Returns transaction hash. + pub fn hash(&self) -> H256 { + match self.transaction_type { + TypedTxId::Legacy => keccak(self.rlp.as_raw()), + _ => keccak(self.rlp.rlp.data().unwrap()), + } + } + + /// Get chain Id field of the transaction. + pub fn chain_id(&self) -> u64 { + match self.transaction_type { + TypedTxId::Legacy => { + signature::extract_chain_id_from_legacy_v(self.rlp.val_at(6)).unwrap_or(0) + } + TypedTxId::AccessList => view!(Self, &self.rlp.rlp.data().unwrap()[1..]) + .rlp + .val_at(1), + } + } + + /// Get the nonce field of the transaction. + pub fn nonce(&self) -> U256 { + match self.transaction_type { + TypedTxId::Legacy => self.rlp.val_at(0), + TypedTxId::AccessList => view!(Self, &self.rlp.rlp.data().unwrap()[1..]) + .rlp + .val_at(1), + } + } + + /// Get the gas_price field of the transaction. + pub fn gas_price(&self) -> U256 { + match self.transaction_type { + TypedTxId::Legacy => self.rlp.val_at(1), + TypedTxId::AccessList => view!(Self, &self.rlp.rlp.data().unwrap()[1..]) + .rlp + .val_at(2), + } + } + + /// Get the gas field of the transaction. + pub fn gas(&self) -> U256 { + match self.transaction_type { + TypedTxId::Legacy => self.rlp.val_at(2), + TypedTxId::AccessList => view!(Self, &self.rlp.rlp.data().unwrap()[1..]) + .rlp + .val_at(3), + } + } + + /// Get the value field of the transaction. + pub fn value(&self) -> U256 { + match self.transaction_type { + TypedTxId::Legacy => self.rlp.val_at(4), + TypedTxId::AccessList => view!(Self, &self.rlp.rlp.data().unwrap()[1..]) + .rlp + .val_at(5), + } + } + + /// Get the data field of the transaction. + pub fn data(&self) -> Bytes { + match self.transaction_type { + TypedTxId::Legacy => self.rlp.val_at(5), + TypedTxId::AccessList => view!(Self, &self.rlp.rlp.data().unwrap()[1..]) + .rlp + .val_at(6), + } + } + + /// Get the v field of the transaction. + pub fn legacy_v(&self) -> u8 { + let r = match self.transaction_type { + TypedTxId::Legacy => self.rlp.val_at(6), + TypedTxId::AccessList => { + let chain_id = match self.chain_id() { + 0 => None, + n => Some(n), + }; + signature::add_chain_replay_protection( + view!(Self, &self.rlp.rlp.data().unwrap()[1..]) + .rlp + .val_at(8), + chain_id, + ) + } + }; + r as u8 + } + + pub fn standard_v(&self) -> u8 { + match self.transaction_type { + TypedTxId::Legacy => signature::extract_standard_v(self.rlp.val_at(6)), + TypedTxId::AccessList => view!(Self, &self.rlp.rlp.data().unwrap()[1..]) + .rlp + .val_at(8), + } + } + + /// Get the r field of the transaction. + pub fn r(&self) -> U256 { + match self.transaction_type { + TypedTxId::Legacy => self.rlp.val_at(7), + TypedTxId::AccessList => view!(Self, &self.rlp.rlp.data().unwrap()[1..]) + .rlp + .val_at(9), + } + } + + /// Get the s field of the transaction. + pub fn s(&self) -> U256 { + match self.transaction_type { + TypedTxId::Legacy => self.rlp.val_at(8), + TypedTxId::AccessList => view!(Self, &self.rlp.rlp.data().unwrap()[1..]) + .rlp + .val_at(10), + } + } +} + +#[cfg(test)] +mod tests { + use super::TypedTransactionView; + use rustc_hex::FromHex; + + #[test] + fn test_transaction_view() { + let rlp = "f87c80018261a894095e7baea6a6c7c4c2dfeb977efac326af552d870a9d00000000000000000000000000000000000000000000000000000000001ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804".from_hex().unwrap(); + + let view = view!(TypedTransactionView, &rlp); + assert_eq!(view.nonce(), 0.into()); + assert_eq!(view.gas_price(), 1.into()); + assert_eq!(view.gas(), 0x61a8.into()); + assert_eq!(view.value(), 0xa.into()); + assert_eq!( + view.data(), + "0000000000000000000000000000000000000000000000000000000000" + .from_hex() + .unwrap() + ); + assert_eq!( + view.r(), + "48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353".into() + ); + assert_eq!( + view.s(), + "efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804".into() + ); + assert_eq!(view.legacy_v(), 0x1b); + } + + #[test] + fn test_access_list_transaction_view() { + let rlp = "b8c101f8be01010a8301e24194000000000000000000000000000000000000aaaa8080f85bf859940000000000000000000000000000000000000000f842a00000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000080a082dc119130f280bd72e3fd4e10220e35b767031b84b8dd1f64085e0158f234dba072228551e678a8a6c6e9bae0ae786b8839c7fda0a994caddd23910f45f385cc0".from_hex().unwrap(); + + let view = view!(TypedTransactionView, &rlp); + assert_eq!(view.nonce(), 0x1.into()); + assert_eq!(view.gas_price(), 0xa.into()); + assert_eq!(view.gas(), 0x1e241.into()); + assert_eq!(view.value(), 0x0.into()); + assert_eq!(view.data(), "".from_hex().unwrap()); + assert_eq!( + view.r(), + "82dc119130f280bd72e3fd4e10220e35b767031b84b8dd1f64085e0158f234db".into() + ); + assert_eq!( + view.s(), + "72228551e678a8a6c6e9bae0ae786b8839c7fda0a994caddd23910f45f385cc0".into() + ); + assert_eq!(view.standard_v(), 0x0); + } +} diff --git a/crates/rpc/src/v1/helpers/dispatch/full.rs b/crates/rpc/src/v1/helpers/dispatch/full.rs index 36874e6d1..87424755e 100644 --- a/crates/rpc/src/v1/helpers/dispatch/full.rs +++ b/crates/rpc/src/v1/helpers/dispatch/full.rs @@ -120,7 +120,7 @@ impl Dispatcher }; Box::new(future::ok(FilledTransactionRequest { - tx_type: request.tx_type, + transaction_type: request.transaction_type, from, used_default_from: request.from.is_none(), to: request.to, diff --git a/crates/rpc/src/v1/helpers/dispatch/signing.rs b/crates/rpc/src/v1/helpers/dispatch/signing.rs index d07cb3ecc..5cc8f9357 100644 --- a/crates/rpc/src/v1/helpers/dispatch/signing.rs +++ b/crates/rpc/src/v1/helpers/dispatch/signing.rs @@ -59,7 +59,7 @@ impl super::Accounts for Signer { value: filled.value, data: filled.data, }; - let t = match filled.tx_type { + let t = match filled.transaction_type { TypedTxId::Legacy => TypedTransaction::Legacy(legacy_tx), TypedTxId::AccessList => { if filled.access_list.is_none() { diff --git a/crates/rpc/src/v1/helpers/external_signer/signing_queue.rs b/crates/rpc/src/v1/helpers/external_signer/signing_queue.rs index deec5c3b4..e7c031938 100644 --- a/crates/rpc/src/v1/helpers/external_signer/signing_queue.rs +++ b/crates/rpc/src/v1/helpers/external_signer/signing_queue.rs @@ -256,7 +256,7 @@ mod test { fn request() -> ConfirmationPayload { ConfirmationPayload::SendTransaction(FilledTransactionRequest { - tx_type: Default::default(), + transaction_type: Default::default(), from: Address::from(1), used_default_from: false, to: Some(Address::from(2)), diff --git a/crates/rpc/src/v1/helpers/fake_sign.rs b/crates/rpc/src/v1/helpers/fake_sign.rs index b692f502f..21cedad1e 100644 --- a/crates/rpc/src/v1/helpers/fake_sign.rs +++ b/crates/rpc/src/v1/helpers/fake_sign.rs @@ -35,7 +35,7 @@ pub fn sign_call(request: CallRequest) -> Result { value: request.value.unwrap_or_default(), data: request.data.unwrap_or_default(), }; - let tx_typed = match request.tx_type { + let tx_typed = match request.transaction_type { TypedTxId::Legacy => TypedTransaction::Legacy(tx_legacy), TypedTxId::AccessList => TypedTransaction::AccessList(AccessListTx::new( tx_legacy, diff --git a/crates/rpc/src/v1/helpers/requests.rs b/crates/rpc/src/v1/helpers/requests.rs index 848a8d415..cc17ac4cd 100644 --- a/crates/rpc/src/v1/helpers/requests.rs +++ b/crates/rpc/src/v1/helpers/requests.rs @@ -24,7 +24,7 @@ use v1::types::{Origin, TransactionCondition}; #[derive(Debug, Clone, Default, Eq, PartialEq, Hash)] pub struct TransactionRequest { /// type of transaction. - pub tx_type: TypedTxId, + pub transaction_type: TypedTxId, /// Sender pub from: Option
, /// Recipient @@ -49,7 +49,7 @@ pub struct TransactionRequest { #[derive(Debug, Clone, Default, Eq, PartialEq, Hash)] pub struct FilledTransactionRequest { /// type of transaction. - pub tx_type: TypedTxId, + pub transaction_type: TypedTxId, /// Sender pub from: Address, /// Indicates if the sender was filled by default value. @@ -75,7 +75,7 @@ pub struct FilledTransactionRequest { impl From for TransactionRequest { fn from(r: FilledTransactionRequest) -> Self { TransactionRequest { - tx_type: r.tx_type, + transaction_type: r.transaction_type, from: Some(r.from), to: r.to, gas_price: Some(r.gas_price), @@ -93,7 +93,7 @@ impl From for TransactionRequest { #[derive(Debug, Default, PartialEq)] pub struct CallRequest { /// type of transaction. - pub tx_type: TypedTxId, + pub transaction_type: TypedTxId, /// From pub from: Option
, /// To diff --git a/crates/rpc/src/v1/tests/mocked/signer.rs b/crates/rpc/src/v1/tests/mocked/signer.rs index 6ef3eb1e7..6c0bcee84 100644 --- a/crates/rpc/src/v1/tests/mocked/signer.rs +++ b/crates/rpc/src/v1/tests/mocked/signer.rs @@ -91,7 +91,7 @@ fn should_return_list_of_items_to_confirm() { .signer .add_request( ConfirmationPayload::SendTransaction(FilledTransactionRequest { - tx_type: Default::default(), + transaction_type: Default::default(), from: Address::from(1), used_default_from: false, to: Some(Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap()), @@ -138,7 +138,7 @@ fn should_reject_transaction_from_queue_without_dispatching() { .signer .add_request( ConfirmationPayload::SendTransaction(FilledTransactionRequest { - tx_type: Default::default(), + transaction_type: Default::default(), from: Address::from(1), used_default_from: false, to: Some(Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap()), @@ -176,7 +176,7 @@ fn should_not_remove_transaction_if_password_is_invalid() { .signer .add_request( ConfirmationPayload::SendTransaction(FilledTransactionRequest { - tx_type: Default::default(), + transaction_type: Default::default(), from: Address::from(1), used_default_from: false, to: Some(Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap()), @@ -242,7 +242,7 @@ fn should_confirm_transaction_and_dispatch() { .signer .add_request( ConfirmationPayload::SendTransaction(FilledTransactionRequest { - tx_type: Default::default(), + transaction_type: Default::default(), from: address, used_default_from: false, to: Some(recipient), @@ -307,7 +307,7 @@ fn should_alter_the_sender_and_nonce() { .signer .add_request( ConfirmationPayload::SendTransaction(FilledTransactionRequest { - tx_type: Default::default(), + transaction_type: Default::default(), from: 0.into(), used_default_from: false, to: Some(recipient), @@ -373,7 +373,7 @@ fn should_confirm_transaction_with_token() { .signer .add_request( ConfirmationPayload::SendTransaction(FilledTransactionRequest { - tx_type: Default::default(), + transaction_type: Default::default(), from: address, used_default_from: false, to: Some(recipient), @@ -441,7 +441,7 @@ fn should_confirm_transaction_with_rlp() { .signer .add_request( ConfirmationPayload::SendTransaction(FilledTransactionRequest { - tx_type: Default::default(), + transaction_type: Default::default(), from: address, used_default_from: false, to: Some(recipient), @@ -507,7 +507,7 @@ fn should_return_error_when_sender_does_not_match() { .signer .add_request( ConfirmationPayload::SendTransaction(FilledTransactionRequest { - tx_type: Default::default(), + transaction_type: Default::default(), from: Address::default(), used_default_from: false, to: Some(recipient), @@ -574,7 +574,7 @@ fn should_confirm_sign_transaction_with_rlp() { .signer .add_request( ConfirmationPayload::SignTransaction(FilledTransactionRequest { - tx_type: Default::default(), + transaction_type: Default::default(), from: address, used_default_from: false, to: Some(recipient), diff --git a/crates/rpc/src/v1/types/call_request.rs b/crates/rpc/src/v1/types/call_request.rs index d27125eed..0972dd6bd 100644 --- a/crates/rpc/src/v1/types/call_request.rs +++ b/crates/rpc/src/v1/types/call_request.rs @@ -25,7 +25,8 @@ use v1::{helpers::CallRequest as Request, types::Bytes}; pub struct CallRequest { /// transaction type #[serde(default)] - pub tx_type: TypedTxId, + #[serde(rename = "type")] + pub transaction_type: TypedTxId, /// From pub from: Option, /// To @@ -47,7 +48,7 @@ pub struct CallRequest { impl Into for CallRequest { fn into(self) -> Request { Request { - tx_type: self.tx_type, + transaction_type: self.transaction_type, from: self.from.map(Into::into), to: self.to.map(Into::into), gas_price: self.gas_price.map(Into::into), @@ -84,7 +85,7 @@ mod tests { assert_eq!( deserialized, CallRequest { - tx_type: Default::default(), + transaction_type: Default::default(), from: Some(H160::from(1)), to: Some(H160::from(2)), gas_price: Some(U256::from(1)), @@ -110,7 +111,7 @@ mod tests { let deserialized: CallRequest = serde_json::from_str(s).unwrap(); assert_eq!(deserialized, CallRequest { - tx_type: Default::default(), + transaction_type: Default::default(), from: Some(H160::from_str("b60e8dd61c5d32be8058bb8eb970870f07233155").unwrap()), to: Some(H160::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap()), gas_price: Some(U256::from_str("9184e72a000").unwrap()), @@ -130,7 +131,7 @@ mod tests { assert_eq!( deserialized, CallRequest { - tx_type: Default::default(), + transaction_type: Default::default(), from: Some(H160::from(1)), to: None, gas_price: None, diff --git a/crates/rpc/src/v1/types/confirmations.rs b/crates/rpc/src/v1/types/confirmations.rs index 200c0afcb..b489f354c 100644 --- a/crates/rpc/src/v1/types/confirmations.rs +++ b/crates/rpc/src/v1/types/confirmations.rs @@ -331,7 +331,7 @@ mod tests { id: 15.into(), payload: helpers::ConfirmationPayload::SendTransaction( helpers::FilledTransactionRequest { - tx_type: Default::default(), + transaction_type: Default::default(), from: 0.into(), used_default_from: false, to: None, @@ -362,7 +362,7 @@ mod tests { id: 15.into(), payload: helpers::ConfirmationPayload::SignTransaction( helpers::FilledTransactionRequest { - tx_type: Default::default(), + transaction_type: Default::default(), from: 0.into(), used_default_from: false, to: None, diff --git a/crates/rpc/src/v1/types/receipt.rs b/crates/rpc/src/v1/types/receipt.rs index 9a978af49..37042ad1a 100644 --- a/crates/rpc/src/v1/types/receipt.rs +++ b/crates/rpc/src/v1/types/receipt.rs @@ -26,7 +26,7 @@ use v1::types::Log; #[serde(rename_all = "camelCase")] pub struct Receipt { /// Transaction Type - #[serde(skip_serializing)] + #[serde(rename = "type")] pub transaction_type: TypedTxId, /// Transaction Hash pub transaction_hash: Option, diff --git a/crates/rpc/src/v1/types/transaction.rs b/crates/rpc/src/v1/types/transaction.rs index 86bb7278c..6d6bf419c 100644 --- a/crates/rpc/src/v1/types/transaction.rs +++ b/crates/rpc/src/v1/types/transaction.rs @@ -30,6 +30,9 @@ use v1::types::{Bytes, TransactionCondition}; #[derive(Debug, Default, Clone, PartialEq, Serialize)] #[serde(rename_all = "camelCase")] pub struct Transaction { + /// transaction type + #[serde(rename = "type")] + pub transaction_type: u8, /// Hash pub hash: H256, /// Nonce @@ -70,11 +73,7 @@ pub struct Transaction { pub s: U256, /// Transaction activates at specified block. pub condition: Option, - /// transaction type - #[serde(skip_serializing)] - pub transaction_type: u8, /// optional access list - #[serde(skip_serializing)] pub access_list: AccessList, } diff --git a/crates/rpc/src/v1/types/transaction_request.rs b/crates/rpc/src/v1/types/transaction_request.rs index 799524408..bace3af04 100644 --- a/crates/rpc/src/v1/types/transaction_request.rs +++ b/crates/rpc/src/v1/types/transaction_request.rs @@ -33,8 +33,8 @@ use std::fmt; pub struct TransactionRequest { /// type of transaction. If none we assume it is legacy #[serde(default)] - #[serde(skip_serializing)] - pub tx_type: TypedTxId, + #[serde(rename = "type")] + pub transaction_type: TypedTxId, /// Sender pub from: Option, /// Recipient @@ -52,7 +52,6 @@ pub struct TransactionRequest { /// Delay until this block condition. pub condition: Option, /// Access list - #[serde(skip_serializing)] pub access_list: Option, } @@ -105,7 +104,7 @@ impl fmt::Display for TransactionRequest { impl From for TransactionRequest { fn from(r: helpers::TransactionRequest) -> Self { TransactionRequest { - tx_type: r.tx_type, + transaction_type: r.transaction_type, from: r.from.map(Into::into), to: r.to.map(Into::into), gas_price: r.gas_price.map(Into::into), @@ -122,7 +121,7 @@ impl From for TransactionRequest { impl From for TransactionRequest { fn from(r: helpers::FilledTransactionRequest) -> Self { TransactionRequest { - tx_type: r.tx_type, + transaction_type: r.transaction_type, from: Some(r.from), to: r.to, gas_price: Some(r.gas_price), @@ -139,7 +138,7 @@ impl From for TransactionRequest { impl Into for TransactionRequest { fn into(self) -> helpers::TransactionRequest { helpers::TransactionRequest { - tx_type: self.tx_type, + transaction_type: self.transaction_type, from: self.from.map(Into::into), to: self.to.map(Into::into), gas_price: self.gas_price.map(Into::into), @@ -179,7 +178,7 @@ mod tests { assert_eq!( deserialized, TransactionRequest { - tx_type: Default::default(), + transaction_type: Default::default(), from: Some(H160::from(1)), to: Some(H160::from(2)), gas_price: Some(U256::from(1)), @@ -206,7 +205,7 @@ mod tests { let deserialized: TransactionRequest = serde_json::from_str(s).unwrap(); assert_eq!(deserialized, TransactionRequest { - tx_type: Default::default(), + transaction_type: Default::default(), from: Some(H160::from_str("b60e8dd61c5d32be8058bb8eb970870f07233155").unwrap()), to: Some(H160::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap()), gas_price: Some(U256::from_str("9184e72a000").unwrap()), @@ -227,7 +226,7 @@ mod tests { assert_eq!( deserialized, TransactionRequest { - tx_type: Default::default(), + transaction_type: Default::default(), from: Some(H160::from(1).into()), to: None, gas_price: None, @@ -256,7 +255,7 @@ mod tests { assert_eq!( deserialized, TransactionRequest { - tx_type: Default::default(), + transaction_type: Default::default(), from: Some(H160::from_str("b5f7502a2807cb23615c7456055e1d65b2508625").unwrap()), to: Some(H160::from_str("895d32f2db7d01ebb50053f9e48aacf26584fe40").unwrap()), gas_price: Some(U256::from_str("0ba43b7400").unwrap()),