mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-03 06:13:07 +00:00
Gas fees go to coinbase
This commit is contained in:
parent
6dd99e4372
commit
d5003b7cf2
@ -11,6 +11,8 @@ pub static KERNEL: Lazy<Kernel> = Lazy::new(combined_kernel);
|
||||
|
||||
pub(crate) fn combined_kernel() -> Kernel {
|
||||
let files = vec![
|
||||
"global jumped_to_0: PANIC",
|
||||
"global jumped_to_1: PANIC",
|
||||
include_str!("asm/core/bootloader.asm"),
|
||||
include_str!("asm/core/call.asm"),
|
||||
include_str!("asm/core/create.asm"),
|
||||
|
||||
@ -7,15 +7,7 @@
|
||||
// Post stack: (empty)
|
||||
global process_normalized_txn:
|
||||
// stack: retdest
|
||||
PUSH 0 // TODO: Load block's base fee
|
||||
%mload_txn_field(@TXN_FIELD_MAX_PRIORITY_FEE_PER_GAS)
|
||||
ADD
|
||||
// stack: priority_fee + base_fee, retdest
|
||||
%mload_txn_field(@TXN_FIELD_MAX_FEE_PER_GAS)
|
||||
// stack: max_fee, priority_fee + base_fee, retdest
|
||||
%min
|
||||
// stack: computed_fee, retdest
|
||||
%mstore_txn_field(@TXN_FIELD_COMPUTED_FEE_PER_GAS)
|
||||
%compute_fees
|
||||
// stack: retdest
|
||||
|
||||
// Compute this transaction's intrinsic gas and store it.
|
||||
@ -42,9 +34,8 @@ global buy_gas:
|
||||
// stack: gas_cost, retdest
|
||||
%mload_txn_field(@TXN_FIELD_ORIGIN)
|
||||
// stack: sender_addr, gas_cost, retdest
|
||||
%deduct_eth // TODO: It should be transferred to coinbase instead?
|
||||
%deduct_eth
|
||||
// stack: deduct_eth_status, retdest
|
||||
global txn_failure_insufficient_balance:
|
||||
%jumpi(panic)
|
||||
// stack: retdest
|
||||
|
||||
@ -113,13 +104,12 @@ global process_message_txn_insufficient_balance:
|
||||
PANIC // TODO
|
||||
|
||||
global process_message_txn_return:
|
||||
// Refund leftover gas.
|
||||
// stack: retdest
|
||||
%mload_txn_field(@TXN_FIELD_INTRINSIC_GAS)
|
||||
%mload_txn_field(@TXN_FIELD_GAS_LIMIT)
|
||||
SUB
|
||||
// stack: leftover_gas, retdest
|
||||
%refund_leftover_gas_cost
|
||||
%pay_coinbase_and_refund_sender
|
||||
// stack: retdest
|
||||
JUMP
|
||||
|
||||
@ -151,17 +141,68 @@ global process_message_txn_after_call:
|
||||
// stack: success, leftover_gas, new_ctx, retdest
|
||||
POP // TODO: Success will go into the receipt when we support that.
|
||||
// stack: leftover_gas, new_ctx, retdest
|
||||
%refund_leftover_gas_cost
|
||||
%pay_coinbase_and_refund_sender
|
||||
// stack: new_ctx, retdest
|
||||
POP
|
||||
JUMP
|
||||
|
||||
%macro refund_leftover_gas_cost
|
||||
%macro pay_coinbase_and_refund_sender
|
||||
// stack: leftover_gas
|
||||
DUP1
|
||||
// stack: leftover_gas, leftover_gas
|
||||
%mload_txn_field(@TXN_FIELD_GAS_LIMIT)
|
||||
SUB
|
||||
// stack: used_gas, leftover_gas
|
||||
%mload_global_metadata(@GLOBAL_METADATA_REFUND_COUNTER)
|
||||
// stack: refund, used_gas, leftover_gas
|
||||
DUP2 %div_const(2) // max_refund = used_gas/2
|
||||
// stack: max_refund, refund, used_gas, leftover_gas
|
||||
%min
|
||||
%stack (refund, used_gas, leftover_gas) -> (leftover_gas, refund, refund, used_gas)
|
||||
ADD
|
||||
// stack: leftover_gas', refund, used_gas
|
||||
SWAP2
|
||||
// stack: used_gas, refund, leftover_gas'
|
||||
SUB
|
||||
// stack: used_gas', leftover_gas'
|
||||
|
||||
// Pay the coinbase.
|
||||
%mload_txn_field(@TXN_FIELD_COMPUTED_PRIORITY_FEE_PER_GAS)
|
||||
MUL
|
||||
// stack: used_gas_tip, leftover_gas'
|
||||
%mload_global_metadata(@GLOBAL_METADATA_BLOCK_BENEFICIARY)
|
||||
// stack: coinbase, used_gas_tip, leftover_gas'
|
||||
%add_eth
|
||||
// stack: leftover_gas'
|
||||
|
||||
// Refund gas to the origin.
|
||||
%mload_txn_field(@TXN_FIELD_COMPUTED_FEE_PER_GAS)
|
||||
MUL
|
||||
// stack: leftover_gas_cost
|
||||
%mload_txn_field(@TXN_FIELD_ORIGIN)
|
||||
// stack: origin, leftover_gas_cost
|
||||
%add_eth
|
||||
// stack: (empty)
|
||||
%endmacro
|
||||
|
||||
// Sets @TXN_FIELD_MAX_FEE_PER_GAS and @TXN_FIELD_MAX_PRIORITY_FEE_PER_GAS.
|
||||
%macro compute_fees
|
||||
// stack: (empty)
|
||||
%mload_global_metadata(@GLOBAL_METADATA_BLOCK_BASE_FEE)
|
||||
%mload_txn_field(@TXN_FIELD_MAX_PRIORITY_FEE_PER_GAS)
|
||||
%mload_txn_field(@TXN_FIELD_MAX_FEE_PER_GAS)
|
||||
// stack: max_fee, max_priority_fee, base_fee
|
||||
DUP3 DUP2 %assert_ge // Assert max_fee >= base_fee
|
||||
// stack: max_fee, max_priority_fee, base_fee
|
||||
%stack (max_fee, max_priority_fee, base_fee) -> (max_fee, base_fee, max_priority_fee, base_fee)
|
||||
SUB
|
||||
// stack: max_fee - base_fee, max_priority_fee, base_fee
|
||||
%min
|
||||
// stack: computed_priority_fee, base_fee
|
||||
%stack (computed_priority_fee, base_fee) -> (computed_priority_fee, base_fee, computed_priority_fee)
|
||||
ADD
|
||||
// stack: computed_fee, computed_priority_fee
|
||||
%mstore_txn_field(@TXN_FIELD_COMPUTED_FEE_PER_GAS)
|
||||
%mstore_txn_field(@TXN_FIELD_COMPUTED_PRIORITY_FEE_PER_GAS)
|
||||
// stack: (empty)
|
||||
%endmacro
|
||||
|
||||
@ -219,8 +219,8 @@
|
||||
DUP2
|
||||
DUP2
|
||||
// stack: x, y, x, y
|
||||
LT
|
||||
// stack: x < y, x, y
|
||||
GT
|
||||
// stack: x > y, x, y
|
||||
%select_bool
|
||||
// stack: min
|
||||
%endmacro
|
||||
@ -230,8 +230,8 @@
|
||||
DUP2
|
||||
DUP2
|
||||
// stack: x, y, x, y
|
||||
GT
|
||||
// stack: x > y, x, y
|
||||
LT
|
||||
// stack: x < y, x, y
|
||||
%select_bool
|
||||
// stack: max
|
||||
%endmacro
|
||||
|
||||
@ -39,10 +39,13 @@ pub(crate) enum GlobalMetadata {
|
||||
BlockGasLimit = 19,
|
||||
BlockChainId = 20,
|
||||
BlockBaseFee = 21,
|
||||
|
||||
/// Gas to refund at the end of the transaction.
|
||||
RefundCounter = 22,
|
||||
}
|
||||
|
||||
impl GlobalMetadata {
|
||||
pub(crate) const COUNT: usize = 20;
|
||||
pub(crate) const COUNT: usize = 21;
|
||||
|
||||
pub(crate) fn all() -> [Self; Self::COUNT] {
|
||||
[
|
||||
@ -66,6 +69,7 @@ impl GlobalMetadata {
|
||||
Self::BlockGasLimit,
|
||||
Self::BlockChainId,
|
||||
Self::BlockBaseFee,
|
||||
Self::RefundCounter,
|
||||
]
|
||||
}
|
||||
|
||||
@ -92,6 +96,7 @@ impl GlobalMetadata {
|
||||
Self::BlockGasLimit => "GLOBAL_METADATA_BLOCK_GAS_LIMIT",
|
||||
Self::BlockChainId => "GLOBAL_METADATA_BLOCK_CHAIN_ID",
|
||||
Self::BlockBaseFee => "GLOBAL_METADATA_BLOCK_BASE_FEE",
|
||||
Self::RefundCounter => "GLOBAL_METADATA_REFUND_COUNTER",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,9 +9,6 @@ pub(crate) enum NormalizedTxnField {
|
||||
Nonce = 2,
|
||||
MaxPriorityFeePerGas = 3,
|
||||
MaxFeePerGas = 4,
|
||||
/// The actual computed gas price for this transaction in the block.
|
||||
/// This is not technically a transaction field, as it depends on the block's base fee.
|
||||
ComputedFeePerGas = 5,
|
||||
GasLimit = 6,
|
||||
IntrinsicGas = 7,
|
||||
To = 8,
|
||||
@ -22,10 +19,15 @@ pub(crate) enum NormalizedTxnField {
|
||||
R = 12,
|
||||
S = 13,
|
||||
Origin = 14,
|
||||
|
||||
/// The actual computed gas price for this transaction in the block.
|
||||
/// This is not technically a transaction field, as it depends on the block's base fee.
|
||||
ComputedFeePerGas = 15,
|
||||
ComputedPriorityFeePerGas = 16,
|
||||
}
|
||||
|
||||
impl NormalizedTxnField {
|
||||
pub(crate) const COUNT: usize = 15;
|
||||
pub(crate) const COUNT: usize = 16;
|
||||
|
||||
pub(crate) fn all() -> [Self; Self::COUNT] {
|
||||
[
|
||||
@ -34,7 +36,6 @@ impl NormalizedTxnField {
|
||||
Self::Nonce,
|
||||
Self::MaxPriorityFeePerGas,
|
||||
Self::MaxFeePerGas,
|
||||
Self::ComputedFeePerGas,
|
||||
Self::GasLimit,
|
||||
Self::IntrinsicGas,
|
||||
Self::To,
|
||||
@ -44,6 +45,8 @@ impl NormalizedTxnField {
|
||||
Self::R,
|
||||
Self::S,
|
||||
Self::Origin,
|
||||
Self::ComputedFeePerGas,
|
||||
Self::ComputedPriorityFeePerGas,
|
||||
]
|
||||
}
|
||||
|
||||
@ -55,7 +58,6 @@ impl NormalizedTxnField {
|
||||
NormalizedTxnField::Nonce => "TXN_FIELD_NONCE",
|
||||
NormalizedTxnField::MaxPriorityFeePerGas => "TXN_FIELD_MAX_PRIORITY_FEE_PER_GAS",
|
||||
NormalizedTxnField::MaxFeePerGas => "TXN_FIELD_MAX_FEE_PER_GAS",
|
||||
NormalizedTxnField::ComputedFeePerGas => "TXN_FIELD_COMPUTED_FEE_PER_GAS",
|
||||
NormalizedTxnField::GasLimit => "TXN_FIELD_GAS_LIMIT",
|
||||
NormalizedTxnField::IntrinsicGas => "TXN_FIELD_INTRINSIC_GAS",
|
||||
NormalizedTxnField::To => "TXN_FIELD_TO",
|
||||
@ -65,6 +67,10 @@ impl NormalizedTxnField {
|
||||
NormalizedTxnField::R => "TXN_FIELD_R",
|
||||
NormalizedTxnField::S => "TXN_FIELD_S",
|
||||
NormalizedTxnField::Origin => "TXN_FIELD_ORIGIN",
|
||||
NormalizedTxnField::ComputedFeePerGas => "TXN_FIELD_COMPUTED_FEE_PER_GAS",
|
||||
NormalizedTxnField::ComputedPriorityFeePerGas => {
|
||||
"TXN_FIELD_COMPUTED_PRIORITY_FEE_PER_GAS"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use eth_trie_utils::partial_trie::PartialTrie;
|
||||
use ethereum_types::{Address, BigEndianHash, H256};
|
||||
use ethereum_types::{Address, BigEndianHash, H256, U256};
|
||||
use plonky2::field::extension::Extendable;
|
||||
use plonky2::field::polynomial::PolynomialValues;
|
||||
use plonky2::hash::hash_types::RichField;
|
||||
@ -24,7 +24,7 @@ use crate::generation::state::GenerationState;
|
||||
use crate::generation::trie_extractor::read_state_trie_value;
|
||||
use crate::memory::segments::Segment;
|
||||
use crate::proof::{BlockMetadata, PublicValues, TrieRoots};
|
||||
use crate::witness::memory::MemoryAddress;
|
||||
use crate::witness::memory::{MemoryAddress, MemoryChannel};
|
||||
use crate::witness::transition::transition;
|
||||
|
||||
pub mod mpt;
|
||||
@ -33,6 +33,7 @@ pub(crate) mod rlp;
|
||||
pub(crate) mod state;
|
||||
mod trie_extractor;
|
||||
use crate::generation::trie_extractor::read_trie;
|
||||
use crate::witness::util::mem_write_log;
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, Default)]
|
||||
/// Inputs needed for trace generation.
|
||||
@ -67,6 +68,37 @@ pub struct TrieInputs {
|
||||
pub storage_tries: Vec<(Address, PartialTrie)>,
|
||||
}
|
||||
|
||||
fn apply_metadata_memops<F: RichField + Extendable<D>, const D: usize>(
|
||||
state: &mut GenerationState<F>,
|
||||
metadata: &BlockMetadata,
|
||||
) {
|
||||
let fields = [
|
||||
(
|
||||
GlobalMetadata::BlockBeneficiary,
|
||||
U256::from_big_endian(&metadata.block_beneficiary.0),
|
||||
),
|
||||
(GlobalMetadata::BlockTimestamp, metadata.block_timestamp),
|
||||
(GlobalMetadata::BlockNumber, metadata.block_number),
|
||||
(GlobalMetadata::BlockDifficulty, metadata.block_difficulty),
|
||||
(GlobalMetadata::BlockGasLimit, metadata.block_gaslimit),
|
||||
(GlobalMetadata::BlockChainId, metadata.block_chain_id),
|
||||
(GlobalMetadata::BlockBaseFee, metadata.block_base_fee),
|
||||
];
|
||||
|
||||
let channel = MemoryChannel::GeneralPurpose(0);
|
||||
let ops = fields.map(|(field, val)| {
|
||||
mem_write_log(
|
||||
channel,
|
||||
MemoryAddress::new(0, Segment::GlobalMetadata, field as usize),
|
||||
state,
|
||||
val,
|
||||
)
|
||||
});
|
||||
|
||||
state.memory.apply_ops(&ops);
|
||||
state.traces.memory_ops.extend(ops);
|
||||
}
|
||||
|
||||
pub(crate) fn generate_traces<F: RichField + Extendable<D>, const D: usize>(
|
||||
all_stark: &AllStark<F, D>,
|
||||
inputs: GenerationInputs,
|
||||
@ -75,6 +107,8 @@ pub(crate) fn generate_traces<F: RichField + Extendable<D>, const D: usize>(
|
||||
) -> anyhow::Result<([Vec<PolynomialValues<F>>; NUM_TABLES], PublicValues)> {
|
||||
let mut state = GenerationState::<F>::new(inputs.clone(), &KERNEL.code);
|
||||
|
||||
apply_metadata_memops(&mut state, &inputs.block_metadata);
|
||||
|
||||
generate_bootstrap_kernel::<F>(&mut state);
|
||||
|
||||
timed!(timing, "simulate CPU", simulate_cpu(&mut state)?);
|
||||
|
||||
@ -3,7 +3,7 @@ use std::time::Duration;
|
||||
|
||||
use env_logger::{try_init_from_env, Env, DEFAULT_FILTER_ENV};
|
||||
use eth_trie_utils::partial_trie::{Nibbles, PartialTrie};
|
||||
use ethereum_types::U256;
|
||||
use ethereum_types::{Address, U256};
|
||||
use hex_literal::hex;
|
||||
use keccak_hash::keccak;
|
||||
use plonky2::field::goldilocks_field::GoldilocksField;
|
||||
@ -30,13 +30,17 @@ fn test_basic_smart_contract() -> anyhow::Result<()> {
|
||||
let all_stark = AllStark::<F, D>::default();
|
||||
let config = StarkConfig::standard_fast_config();
|
||||
|
||||
let beneficiary = hex!("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef");
|
||||
let sender = hex!("2c7536e3605d9c16a7a3d7b1898e529396a65c23");
|
||||
let to = hex!("a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0");
|
||||
|
||||
let beneficiary_state_key = keccak(beneficiary);
|
||||
let sender_state_key = keccak(sender);
|
||||
let to_state_key = keccak(to);
|
||||
|
||||
let beneficiary_nibbles = Nibbles::from_bytes_be(beneficiary_state_key.as_bytes()).unwrap();
|
||||
let sender_nibbles = Nibbles::from_bytes_be(sender_state_key.as_bytes()).unwrap();
|
||||
let to_nibbles = Nibbles::from_bytes_be(to_state_key.as_bytes()).unwrap();
|
||||
let value = U256::from(100u32);
|
||||
|
||||
let push1 = get_push_opcode(1);
|
||||
let add = get_opcode("ADD");
|
||||
@ -45,12 +49,12 @@ fn test_basic_smart_contract() -> anyhow::Result<()> {
|
||||
let code_gas = 3 + 3 + 3;
|
||||
let code_hash = keccak(code);
|
||||
|
||||
let beneficiary_account_before = AccountRlp::default();
|
||||
let sender_account_before = AccountRlp {
|
||||
nonce: 5.into(),
|
||||
balance: eth_to_wei(100_000.into()),
|
||||
..AccountRlp::default()
|
||||
};
|
||||
|
||||
let to_account_before = AccountRlp {
|
||||
code_hash,
|
||||
..AccountRlp::default()
|
||||
@ -83,8 +87,12 @@ fn test_basic_smart_contract() -> anyhow::Result<()> {
|
||||
|
||||
// Generated using a little py-evm script.
|
||||
let txn = hex!("f861050a8255f094a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0648242421ba02c89eb757d9deeb1f5b3859a9d4d679951ef610ac47ad4608dc142beb1b7e313a05af7e9fbab825455d36c36c7f4cfcafbeafa9a77bdff936b52afb36d4fe4bcdd");
|
||||
let value = U256::from(100u32);
|
||||
|
||||
let block_metadata = BlockMetadata::default();
|
||||
let block_metadata = BlockMetadata {
|
||||
block_beneficiary: Address::from(beneficiary),
|
||||
..BlockMetadata::default()
|
||||
};
|
||||
|
||||
let mut contract_code = HashMap::new();
|
||||
contract_code.insert(code_hash, code.to_vec());
|
||||
@ -102,6 +110,11 @@ fn test_basic_smart_contract() -> anyhow::Result<()> {
|
||||
let expected_state_trie_after = {
|
||||
let txdata_gas = 2 * 16;
|
||||
let gas_used = 21_000 + code_gas + txdata_gas;
|
||||
|
||||
let beneficiary_account_after = AccountRlp {
|
||||
balance: beneficiary_account_before.balance + gas_used * 10,
|
||||
..beneficiary_account_before
|
||||
};
|
||||
let sender_account_after = AccountRlp {
|
||||
balance: sender_account_before.balance - value - gas_used * 10,
|
||||
nonce: sender_account_before.nonce + 1,
|
||||
@ -113,6 +126,11 @@ fn test_basic_smart_contract() -> anyhow::Result<()> {
|
||||
};
|
||||
|
||||
let mut children = core::array::from_fn(|_| PartialTrie::Empty.into());
|
||||
children[beneficiary_nibbles.get_nibble(0) as usize] = PartialTrie::Leaf {
|
||||
nibbles: beneficiary_nibbles.truncate_n_nibbles_front(1),
|
||||
value: rlp::encode(&beneficiary_account_after).to_vec(),
|
||||
}
|
||||
.into();
|
||||
children[sender_nibbles.get_nibble(0) as usize] = PartialTrie::Leaf {
|
||||
nibbles: sender_nibbles.truncate_n_nibbles_front(1),
|
||||
value: rlp::encode(&sender_account_after).to_vec(),
|
||||
@ -123,7 +141,6 @@ fn test_basic_smart_contract() -> anyhow::Result<()> {
|
||||
value: rlp::encode(&to_account_after).to_vec(),
|
||||
}
|
||||
.into();
|
||||
// TODO: Beneficiary should receive gas...
|
||||
PartialTrie::Branch {
|
||||
children,
|
||||
value: vec![],
|
||||
|
||||
@ -3,7 +3,7 @@ use std::time::Duration;
|
||||
|
||||
use env_logger::{try_init_from_env, Env, DEFAULT_FILTER_ENV};
|
||||
use eth_trie_utils::partial_trie::{Nibbles, PartialTrie};
|
||||
use ethereum_types::U256;
|
||||
use ethereum_types::{Address, U256};
|
||||
use hex_literal::hex;
|
||||
use keccak_hash::keccak;
|
||||
use plonky2::field::goldilocks_field::GoldilocksField;
|
||||
@ -29,20 +29,26 @@ fn test_simple_transfer() -> anyhow::Result<()> {
|
||||
let all_stark = AllStark::<F, D>::default();
|
||||
let config = StarkConfig::standard_fast_config();
|
||||
|
||||
let beneficiary = hex!("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef");
|
||||
let sender = hex!("2c7536e3605d9c16a7a3d7b1898e529396a65c23");
|
||||
let to = hex!("a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0");
|
||||
|
||||
let beneficiary_state_key = keccak(beneficiary);
|
||||
let sender_state_key = keccak(sender);
|
||||
let to_state_key = keccak(to);
|
||||
|
||||
let beneficiary_nibbles = Nibbles::from_bytes_be(beneficiary_state_key.as_bytes()).unwrap();
|
||||
let sender_nibbles = Nibbles::from_bytes_be(sender_state_key.as_bytes()).unwrap();
|
||||
let to_nibbles = Nibbles::from_bytes_be(to_state_key.as_bytes()).unwrap();
|
||||
let value = U256::from(100u32);
|
||||
|
||||
let beneficiary_account_before = AccountRlp::default();
|
||||
let sender_account_before = AccountRlp {
|
||||
nonce: 5.into(),
|
||||
balance: eth_to_wei(100_000.into()),
|
||||
storage_root: PartialTrie::Empty.calc_hash(),
|
||||
code_hash: keccak([]),
|
||||
};
|
||||
let to_account_before = AccountRlp::default();
|
||||
|
||||
let state_trie_before = PartialTrie::Leaf {
|
||||
nibbles: sender_nibbles,
|
||||
@ -57,8 +63,12 @@ fn test_simple_transfer() -> anyhow::Result<()> {
|
||||
|
||||
// Generated using a little py-evm script.
|
||||
let txn = hex!("f861050a8255f094a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0648242421ba02c89eb757d9deeb1f5b3859a9d4d679951ef610ac47ad4608dc142beb1b7e313a05af7e9fbab825455d36c36c7f4cfcafbeafa9a77bdff936b52afb36d4fe4bcdd");
|
||||
let value = U256::from(100u32);
|
||||
|
||||
let block_metadata = BlockMetadata::default();
|
||||
let block_metadata = BlockMetadata {
|
||||
block_beneficiary: Address::from(beneficiary),
|
||||
..BlockMetadata::default()
|
||||
};
|
||||
|
||||
let inputs = GenerationInputs {
|
||||
signed_txns: vec![txn.to_vec()],
|
||||
@ -74,6 +84,11 @@ fn test_simple_transfer() -> anyhow::Result<()> {
|
||||
let expected_state_trie_after = {
|
||||
let txdata_gas = 2 * 16;
|
||||
let gas_used = 21_000 + txdata_gas;
|
||||
|
||||
let beneficiary_account_after = AccountRlp {
|
||||
balance: beneficiary_account_before.balance + gas_used * 10,
|
||||
..beneficiary_account_before
|
||||
};
|
||||
let sender_account_after = AccountRlp {
|
||||
balance: sender_account_before.balance - value - gas_used * 10,
|
||||
nonce: sender_account_before.nonce + 1,
|
||||
@ -81,10 +96,15 @@ fn test_simple_transfer() -> anyhow::Result<()> {
|
||||
};
|
||||
let to_account_after = AccountRlp {
|
||||
balance: value,
|
||||
..AccountRlp::default()
|
||||
..to_account_before
|
||||
};
|
||||
|
||||
let mut children = core::array::from_fn(|_| PartialTrie::Empty.into());
|
||||
children[beneficiary_nibbles.get_nibble(0) as usize] = PartialTrie::Leaf {
|
||||
nibbles: beneficiary_nibbles.truncate_n_nibbles_front(1),
|
||||
value: rlp::encode(&beneficiary_account_after).to_vec(),
|
||||
}
|
||||
.into();
|
||||
children[sender_nibbles.get_nibble(0) as usize] = PartialTrie::Leaf {
|
||||
nibbles: sender_nibbles.truncate_n_nibbles_front(1),
|
||||
value: rlp::encode(&sender_account_after).to_vec(),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user