Skip to content

Commit

Permalink
feat(evm-utils/evm-state): connect to fast_rlp feature part 4
Browse files Browse the repository at this point in the history
[ ] merge [pull request: < fast-rlp >](velas#443)
├── [ ] merge [pull request: < triedb | fast-rlp >](velas/triedb#51)
└── [ ] make minimal changes to make velas-chain compile with both libs used
    ├── [✓] __evm-utils/evm-state/src/types.rs__:
    │   ├── [✓] `Account`
    │   │   ├── [✓] `Encodable` stub, `Decodable` stub
    │   │   ├── [✓] actual impl
    │   │   │   └── [✓] roundtrip test
    │   │   └── [✓] move old impl to #[cfg(test)]
    │   └── [✓] `EthereumReceipt`
    │       ├── [✓] `Encodable` stub, `Decodable` stub
    │       ├── [✓] roundtrip test
    │       ├── [✓] move old impl to #[cfg(test)]
    │       └── [✓] nested
    │           ├── [✓] `ethbloom::Bloom`
    │           │   ├── [✓] `Encodable` stub, `Decodable` stub
    │           │   ├── [✓] nested
    │           │   └── [✓] roundtrip test
    │           └── [✓] `ethereum::Log`
    │               ├── [✓] `Encodable` stub, `Decodable` stub
    │               ├── [✓] nested
    │               └── [✓] roundtrip test
    └── [ ] __evm-utils/evm-state/src/transactions.rs__:
        └── [✓] `TransactionInReceipt`
            ├── [✓] `Encodable` stub, `Decodable` stub
            ├── [✓] roundtrip test
            │   └── [✓] split roundtrip test in 3
            ├── [ ] move old impl to #[cfg(test)]
            └── [ ] nested
                ├── [✓] `Transaction`
                │   ├── [✓] `Encodable` stub, `Decodable` stub
                │   ├── [✓] roundtrip test
                │   ├── [ ] move old impl to #[cfg(test)]
                │   └── [ ] nested
                │       └── [✓] `TransactionAction`
                │           ├── [✓] `Encodable` stub, `Decodable` stub
                │           └── [✓] nested
                └── [✓] `UnsignedTransactionWithCaller`
                    ├── [✓] `Encodable` stub, `Decodable` stub
                    ├── [✓] roundtrip test
                    ├── [ ] move old impl to #[cfg(test)]
                    └── [ ] nested
                        └── [✓] `UnsignedTransaction`
                            ├── [✓] `Encodable` stub, `Decodable` stub
                            ├── [✓] roundtrip test
                            ├── [✓] move old impl to #[cfg(test)]
                            ├── [✓] return derived `Encodable`, `Decodable` impl
                            └── [✓] nested
                                └── [✓] `TransactionAction`
                                    ├── [✓] `Encodable` stub, `Decodable` stub
                                    ├── [✓] roundtrip test
                                    └── [ ] move old impl to #[cfg(test)]
  • Loading branch information
dj8yf0μl committed Apr 27, 2023
1 parent f270c7b commit 48bd65b
Show file tree
Hide file tree
Showing 2 changed files with 249 additions and 9 deletions.
123 changes: 121 additions & 2 deletions evm-utils/evm-state/src/rlp_roundtrip_tests.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{transaction_roots::EthereumReceipt, TransactionAction, UnsignedTransaction, UnsignedTransactionWithCaller};
use crate::{transaction_roots::EthereumReceipt, TransactionAction, UnsignedTransaction, UnsignedTransactionWithCaller, Transaction, TransactionSignature, TransactionInReceipt};

use super::types::Account;

Expand Down Expand Up @@ -260,4 +260,123 @@ fn test_check_unsigned_transaction_with_caller_roundtrip2() {
{
assert_eq!(old_rlp_raw, rlp_raw);
}
}
}

#[test]
fn test_check_transaction_roundtrip() {

let ta1 = TransactionAction::Create;
let tx1 = Transaction{
nonce: U256([72; 4]),
gas_price: U256([3213;4]),
gas_limit: U256([4324; 4]),
action: ta1,
value: U256([7732; 4]),
signature: TransactionSignature {
v: 88979,
r: H256([34; 32]),
s: H256([78; 32]),
},
input: vec![32, 31, 0, 34, 76, 173],

};

check_roundtrip!(tx1 => Transaction);

let ta2 = TransactionAction::Call(H160([56; 20]));
let tx2 = Transaction{
nonce: U256([79; 4]),
gas_price: U256([3013;4]),
gas_limit: U256([4124; 4]),
action: ta2,
value: U256([7832; 4]),
signature: TransactionSignature {
v: 88979,
r: H256([38; 32]),
s: H256([76; 32]),
},
input: vec![32, 31, 0, 34, 76, 173],

};

check_roundtrip!(tx2 => Transaction);

}

#[test]
fn test_check_transaction_in_receipt_roundtrip1() {

let ta = TransactionAction::Create;
let tx = Transaction{
nonce: U256([72; 4]),
gas_price: U256([3213;4]),
gas_limit: U256([4324; 4]),
action: ta,
value: U256([7732; 4]),
signature: TransactionSignature {
v: 88979,
r: H256([34; 32]),
s: H256([78; 32]),
},
input: vec![32, 31, 0, 34, 76, 173],

};

let tx_in_rec1 = TransactionInReceipt::Signed(tx);

check_roundtrip!(tx_in_rec1 => TransactionInReceipt);

}

#[test]
fn test_check_transaction_in_receipt_roundtrip2() {
let ta = TransactionAction::Create;

let ut = UnsignedTransaction {
nonce: U256([46;4]),
gas_price: U256([543; 4]),
gas_limit: U256([342;4]),
action: ta,
value: U256([23000;4]),
input: vec![34, 45, 12, 123, 243],
};

let ut_c = UnsignedTransactionWithCaller {
unsigned_tx: ut,
caller: H160([23; 20]),
chain_id: 24,
signed_compatible: false,

};

let tx_in_rec2 = TransactionInReceipt::Unsigned(ut_c);


check_roundtrip!(tx_in_rec2 => TransactionInReceipt);
}

#[test]
fn test_check_transaction_in_receipt_roundtrip3() {
let ta2 = TransactionAction::Call(H160([56; 20]));

let ut2 = UnsignedTransaction {
nonce: U256([46;4]),
gas_price: U256([543; 4]),
gas_limit: U256([342;4]),
action: ta2,
value: U256([20000; 4]),
input: vec![34, 45, 12, 123, 243],
};

let ut_c2 = UnsignedTransactionWithCaller {
unsigned_tx: ut2,
caller: H160([23; 20]),
chain_id: 24,
signed_compatible: true,

};
let tx_in_rec3 = TransactionInReceipt::Unsigned(ut_c2);

check_roundtrip!(tx_in_rec3 => TransactionInReceipt);

}
135 changes: 128 additions & 7 deletions evm-utils/evm-state/src/transactions.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use borsh::{BorshDeserialize, BorshSchema, BorshSerialize};
use bytes::BufMut;
use bytes::{BufMut, Buf};
use evm::{backend::Log, ExitReason, ExitRevert};
use primitive_types::{H160, H256, U256};
use rlp::{Decodable as DecodableOld, DecoderError, Encodable as EncodableOld, Rlp, RlpStream};
Expand Down Expand Up @@ -359,7 +359,6 @@ impl<'de> Decodable<'de> for TransactionAction {
fn decode(buf: &mut &'de [u8]) -> Result<Self, triedb::rlp::decode::DecodeError> {
let mut buf_view = *buf;
let h = fastrlp::Header::decode(&mut buf_view)?;
dbg!("header : {:?}", &h);
if h.payload_length == 0 {
let _h = fastrlp::Header::decode(buf)?;
return Ok(Self::Create);
Expand All @@ -385,6 +384,73 @@ impl EncodableOld for Transaction {
}
}

impl Encodable for Transaction {
fn encode(&self,out: &mut dyn BufMut) {

let len = self.nonce.length() + self.gas_price.length()
+ self.gas_limit.length() + self.action.length()
+ self.value.length() + self.input.length()
+ self.signature.v.length() + self.signature.r.length() + self.signature.s.length() ;
fastrlp::Header {
list: true,
payload_length: len,
}.encode(out);
self.nonce.encode(out);
self.gas_price.encode(out);
self.gas_limit.encode(out);
self.action.encode(out);
self.value.encode(out);
self.input.encode(out);
self.signature.v.encode(out);
self.signature.r.encode(out);
self.signature.s.encode(out);
}

fn length(&self) -> usize {

let len = self.nonce.length() + self.gas_price.length()
+ self.gas_limit.length() + self.action.length()
+ self.value.length() + self.input.length()
+ self.signature.v.length() + self.signature.r.length() + self.signature.s.length() ;
fastrlp::Header {
list: true,
payload_length: len,
}
.length()
+ len

}
}

impl<'de> Decodable<'de> for Transaction {
fn decode(buf: &mut &'de [u8]) -> Result<Self, fastrlp::DecodeError> {
let h = fastrlp::Header::decode(buf)?;
if !h.list {
return Err(fastrlp::DecodeError::UnexpectedString);
}
let payload_view = &mut &buf[..h.payload_length];
let cnt = fastrlp::count(payload_view)?;
if cnt!= 9 {
return Err(fastrlp::DecodeError::ListLengthMismatch { expected: 9, got: cnt });
}

let nonce = fastrlp::Decodable::decode(payload_view)?;
let gas_price = fastrlp::Decodable::decode(payload_view)?;
let gas_limit = fastrlp::Decodable::decode(payload_view)?;
let action = fastrlp::Decodable::decode(payload_view)?;
let value = fastrlp::Decodable::decode(payload_view)?;
let input= fastrlp::Decodable::decode(payload_view)?;
let v= fastrlp::Decodable::decode(payload_view)?;
let r = fastrlp::Decodable::decode(payload_view)?;
let s = fastrlp::Decodable::decode(payload_view)?;
buf.advance(h.payload_length);
Ok(Self {
nonce, gas_price, gas_limit, action, value, input,
signature: TransactionSignature { v, r, s},
})
}
}

impl DecodableOld for Transaction {
fn decode(rlp: &Rlp<'_>) -> Result<Self, DecoderError> {
Ok(Self {
Expand Down Expand Up @@ -462,19 +528,74 @@ impl TransactionInReceipt {
impl Encodable for TransactionInReceipt {

fn encode(&self,out: &mut dyn BufMut) {
unimplemented!();
match self {
TransactionInReceipt::Signed(tx) => {
tx.encode(out);
},
TransactionInReceipt::Unsigned(tx) => {
tx.encode(out);
},
}
}
fn length(&self) -> usize {
unimplemented!();

match self {
TransactionInReceipt::Signed(tx) => {
tx.length()
},
TransactionInReceipt::Unsigned(tx) => {
tx.length()
},
}
}
}

pub fn consume(buf: &mut &[u8]) -> Result<(), triedb::rlp::decode::DecodeError> {
let h = fastrlp::Header::decode(buf)?;

buf.advance(h.payload_length);
Ok(())


}
impl<'de> Decodable<'de> for TransactionInReceipt {
fn decode(buf: &mut &'de [u8]) -> Result<Self, triedb::rlp::decode::DecodeError> {
unimplemented!();
let mut count_view = *buf;
let h = fastrlp::Header::decode(&mut count_view)?;
if !h.list {
return Err(fastrlp::DecodeError::UnexpectedString);
}
let count_view = &mut &count_view[..h.payload_length];
let cnt = fastrlp::count(count_view)?;

let res = match cnt {
8 => {
TransactionInReceipt::Unsigned(UnsignedTransactionWithCaller::decode(buf, false)?)
},
9 => {
for _repeat in 0..8 {
consume(count_view)?;
}
let res: Result<u8,_> = fastrlp::Decodable::decode(count_view);
match (count_view.is_empty(), res) {
(true, Ok(UNSIGNED_TX_MARKER)) => {
TransactionInReceipt::Unsigned(UnsignedTransactionWithCaller::decode(buf, true)?)
},
_ => {
TransactionInReceipt::Signed(<Transaction as Decodable>::decode(buf)?)
}

}

},
_ => return Err(fastrlp::DecodeError::Custom(
"list len must be either 8 or 9 for TransactionInReceipt"
) ),

};
Ok(res)
}
}

impl EncodableOld for TransactionInReceipt {
fn rlp_append(&self, s: &mut RlpStream) {
match self {
Expand Down Expand Up @@ -511,7 +632,7 @@ impl DecodableOld for TransactionInReceipt {
rlp, true,
)?)
} else {
TransactionInReceipt::Signed(Transaction::decode(rlp)?)
TransactionInReceipt::Signed(<Transaction as DecodableOld>::decode(rlp)?)
}
}
_ => return Err(DecoderError::RlpInvalidLength),
Expand Down

0 comments on commit 48bd65b

Please sign in to comment.