Add contract creation flag (#1056)

* Add contract creation flag

* Minor

* Fix intrinsic gas test
This commit is contained in:
wborgeaud 2023-05-24 17:49:54 +02:00 committed by GitHub
parent 30b97b29e8
commit e6a7b8c5cb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 46 additions and 25 deletions

View File

@ -407,5 +407,5 @@ contract_creation_fault_4:
JUMP
invalid_txn:
global invalid_txn:
%jump(txn_loop)

View File

@ -21,11 +21,7 @@
// Returns whether the current transaction is a contract creation transaction.
%macro is_contract_creation
// stack: (empty)
%mload_txn_field(@TXN_FIELD_TO)
// stack: to
ISZERO
// If there is no "to" field, then this is a contract creation.
// stack: to == 0
%mload_global_metadata(@GLOBAL_METADATA_CONTRACT_CREATION)
%endmacro
%macro is_precompile

View File

@ -130,7 +130,7 @@ decode_rlp_list_len_big:
// fit in a single (256-bit) word on the stack.
// Pre stack: pos, len, retdest
// Post stack: pos', int
decode_int_given_len:
global decode_int_given_len:
%stack (pos, len, retdest) -> (pos, len, pos, retdest)
ADD
// stack: end_pos, pos, retdest

View File

@ -61,12 +61,30 @@
%endmacro
// Decode the "to" field and store it.
// This field is either 160-bit or empty in the case of a contract creation txn.
%macro decode_and_store_to
// stack: pos
%decode_rlp_scalar
%stack (pos, to) -> (to, pos)
%decode_rlp_string_len
// stack: pos, len
SWAP1
// stack: len, pos
DUP1 ISZERO %jumpi(%%contract_creation)
// stack: len, pos
DUP1 %eq_const(20) ISZERO %jumpi(invalid_txn) // Address is 160-bit
%stack (len, pos) -> (pos, len, %%with_scalar)
%jump(decode_int_given_len)
%%with_scalar:
// stack: pos, int
SWAP1
%mstore_txn_field(@TXN_FIELD_TO)
// stack: pos
%jump(%%end)
%%contract_creation:
// stack: len, pos
POP
PUSH 1 %mstore_global_metadata(@GLOBAL_METADATA_CONTRACT_CREATION)
// stack: pos
%%end:
%endmacro
// Decode the "value" field and store it.

View File

@ -102,13 +102,13 @@ type_0_compute_signed_data:
// stack: rlp_pos, rlp_start, retdest
%mload_txn_field(@TXN_FIELD_TO)
DUP1 %jumpi(nonzero_to)
// stack: to, rlp_pos, rlp_start, retdest
SWAP1 %encode_rlp_scalar
%jump(after_to)
nonzero_to:
%mload_global_metadata(@GLOBAL_METADATA_CONTRACT_CREATION) %jumpi(zero_to)
// stack: to, rlp_pos, rlp_start, retdest
SWAP1 %encode_rlp_160
%jump(after_to)
zero_to:
// stack: to, rlp_pos, rlp_start, retdest
SWAP1 %encode_rlp_scalar
// stack: rlp_pos, rlp_start, retdest
after_to:

View File

@ -57,13 +57,13 @@ type_1_compute_signed_data:
// stack: rlp_pos, rlp_start, retdest
%mload_txn_field(@TXN_FIELD_TO)
DUP1 %jumpi(nonzero_to)
// stack: to, rlp_pos, rlp_start, retdest
SWAP1 %encode_rlp_scalar
%jump(after_to)
nonzero_to:
%mload_global_metadata(@GLOBAL_METADATA_CONTRACT_CREATION) %jumpi(zero_to)
// stack: to, rlp_pos, rlp_start, retdest
SWAP1 %encode_rlp_160
%jump(after_to)
zero_to:
// stack: to, rlp_pos, rlp_start, retdest
SWAP1 %encode_rlp_scalar
// stack: rlp_pos, rlp_start, retdest
after_to:

View File

@ -64,13 +64,13 @@ type_2_compute_signed_data:
// stack: rlp_pos, rlp_start, retdest
%mload_txn_field(@TXN_FIELD_TO)
DUP1 %jumpi(nonzero_to)
// stack: to, rlp_pos, rlp_start, retdest
SWAP1 %encode_rlp_scalar
%jump(after_to)
nonzero_to:
%mload_global_metadata(@GLOBAL_METADATA_CONTRACT_CREATION) %jumpi(zero_to)
// stack: to, rlp_pos, rlp_start, retdest
SWAP1 %encode_rlp_160
%jump(after_to)
zero_to:
// stack: to, rlp_pos, rlp_start, retdest
SWAP1 %encode_rlp_scalar
// stack: rlp_pos, rlp_start, retdest
after_to:

View File

@ -65,10 +65,12 @@ pub(crate) enum GlobalMetadata {
AccessListRlpStart = 31,
// Length of the access list in the RLP for type-1 txns.
AccessListRlpLen = 32,
// Boolean flag indicating if the txn is a contract creation txn.
ContractCreation = 33,
}
impl GlobalMetadata {
pub(crate) const COUNT: usize = 32;
pub(crate) const COUNT: usize = 33;
pub(crate) fn all() -> [Self; Self::COUNT] {
[
@ -104,6 +106,7 @@ impl GlobalMetadata {
Self::AccessListDataCost,
Self::AccessListRlpStart,
Self::AccessListRlpLen,
Self::ContractCreation,
]
}
@ -142,6 +145,7 @@ impl GlobalMetadata {
Self::AccessListDataCost => "GLOBAL_METADATA_ACCESS_LIST_DATA_COST",
Self::AccessListRlpStart => "GLOBAL_METADATA_ACCESS_LIST_RLP_START",
Self::AccessListRlpLen => "GLOBAL_METADATA_ACCESS_LIST_RLP_LEN",
Self::ContractCreation => "GLOBAL_METADATA_CONTRACT_CREATION",
}
}
}

View File

@ -1,6 +1,8 @@
use anyhow::Result;
use ethereum_types::U256;
use crate::cpu::kernel::aggregator::KERNEL;
use crate::cpu::kernel::constants::global_metadata::GlobalMetadata;
use crate::cpu::kernel::constants::txn_fields::NormalizedTxnField;
use crate::cpu::kernel::interpreter::Interpreter;
@ -14,6 +16,7 @@ fn test_intrinsic_gas() -> Result<()> {
// Contract creation transaction.
let initial_stack = vec![0xdeadbeefu32.into()];
let mut interpreter = Interpreter::new_with_kernel(intrinsic_gas, initial_stack.clone());
interpreter.set_global_metadata_field(GlobalMetadata::ContractCreation, U256::one());
interpreter.run()?;
assert_eq!(interpreter.stack(), vec![(GAS_TX + GAS_TXCREATE).into()]);