From e0cc3811722f2c68b5dcf8ed458a3109d49302a1 Mon Sep 17 00:00:00 2001 From: Shoham Chakraborty Date: Mon, 28 Aug 2023 17:35:36 +0800 Subject: [PATCH] Revert "Revert "evm: Move DFIIntrinsics contract, reserve space for additional contracts (#2374)" (#2381)" This reverts commit 2eff775fc22beca1ab632994e10ff79818c1db05. --- lib/ain-contracts/src/lib.rs | 14 ++++-- lib/ain-evm/src/evm.rs | 26 +++++++++-- test/functional/feature_evm_dfi_intrinsics.py | 45 ++++++++++++++++++- 3 files changed, 76 insertions(+), 9 deletions(-) diff --git a/lib/ain-contracts/src/lib.rs b/lib/ain-contracts/src/lib.rs index 73dfec3ef4..f70431b216 100644 --- a/lib/ain-contracts/src/lib.rs +++ b/lib/ain-contracts/src/lib.rs @@ -88,14 +88,22 @@ pub fn dst20_address_from_token_id(token_id: u64) -> Result { Ok(H160::from_str(&final_str)?) } +pub fn intrinsics_address_from_id(id: u64) -> Result { + let number_str = format!("{:x}", id); + let padded_number_str = format!("{number_str:0>37}"); + let final_str = format!("ff1{padded_number_str}"); + + Ok(H160::from_str(&final_str)?) +} + #[derive(Debug, PartialEq, Eq, Hash)] pub enum Contracts { - CounterContract, + Intrinsics, } lazy_static! { pub static ref CONTRACT_ADDRESSES: HashMap = HashMap::from([( - Contracts::CounterContract, - H160::from_str("0x0000000000000000000000000000000000000301").unwrap() + Contracts::Intrinsics, + H160::from_str("0xff10000000000000000000000000000000000000").unwrap() ),]); } diff --git a/lib/ain-evm/src/evm.rs b/lib/ain-evm/src/evm.rs index 076c894166..dbad7fc8d8 100644 --- a/lib/ain-evm/src/evm.rs +++ b/lib/ain-evm/src/evm.rs @@ -192,6 +192,7 @@ impl EVMServices { if is_evm_genesis_block { // reserve DST20 namespace self.reserve_dst20_namespace(&mut executor)?; + self.reserve_intrinsics_namespace(&mut executor)?; let migration_txs = get_dst20_migration_txs(mnview_ptr)?; queue.transactions.extend(migration_txs.into_iter()); @@ -201,13 +202,13 @@ impl EVMServices { address, storage, bytecode, - } = EVMServices::counter_contract(dvm_block_number, current_block_number)?; + } = EVMServices::intrinsics_contract(dvm_block_number, current_block_number)?; executor.deploy_contract(address, bytecode, storage)?; } else { // Ensure that state root changes by updating counter contract storage let DeployContractInfo { address, storage, .. - } = EVMServices::counter_contract(dvm_block_number, current_block_number)?; + } = EVMServices::intrinsics_contract(dvm_block_number, current_block_number)?; executor.update_storage(address, storage)?; } @@ -450,11 +451,11 @@ impl EVMServices { } /// Returns address, bytecode and storage with incremented count for the counter contract - pub fn counter_contract( + pub fn intrinsics_contract( dvm_block_number: u64, evm_block_number: U256, ) -> Result { - let address = *CONTRACT_ADDRESSES.get(&Contracts::CounterContract).unwrap(); + let address = *CONTRACT_ADDRESSES.get(&Contracts::Intrinsics).unwrap(); let bytecode = ain_contracts::get_counter_bytecode()?; let count = SERVICES .evm @@ -630,6 +631,23 @@ impl EVMServices { Ok(()) } + + pub fn reserve_intrinsics_namespace(&self, executor: &mut AinExecutor) -> Result<()> { + let bytecode = ain_contracts::get_system_reserved_bytecode()?; + let addresses = (1..=127) + .map(|token_id| ain_contracts::intrinsics_address_from_id(token_id).unwrap()) + .collect::>(); + + for address in addresses { + debug!( + "[reserve_intrinsics_namespace] Deploying address to {:#?}", + address + ); + executor.deploy_contract(address, bytecode.clone().into(), Vec::new())?; + } + + Ok(()) + } } fn create_deploy_contract_tx(token_id: u64, base_fee: &U256) -> Result<(SignedTx, ReceiptV3)> { diff --git a/test/functional/feature_evm_dfi_intrinsics.py b/test/functional/feature_evm_dfi_intrinsics.py index ae6b4f6867..203a3fbe5b 100755 --- a/test/functional/feature_evm_dfi_intrinsics.py +++ b/test/functional/feature_evm_dfi_intrinsics.py @@ -6,6 +6,7 @@ """Test DFI intrinsics contract""" import os +import json from test_framework.test_framework import DefiTestFramework from test_framework.util import assert_equal @@ -43,7 +44,32 @@ def run_test(self): # Activate EVM node.setgov({"ATTRIBUTES": {"v0/params/feature/evm": "true"}}) - node.generate(1) + node.generate(2) + + # check reserved address space + reserved_bytecode = json.loads( + open( + f"{os.path.dirname(__file__)}/../../lib/ain-contracts/system_reserved/output/bytecode.json", + "r", + encoding="utf8", + ).read() + )["object"] + + for i in range(1, 128): + address = node.w3.to_checksum_address(generate_formatted_string(i)) + assert ( + self.nodes[0].w3.to_hex(self.nodes[0].w3.eth.get_code(address)) + == reserved_bytecode + ) + + assert ( + self.nodes[0].w3.to_hex( + self.nodes[0].w3.eth.get_code( + node.w3.to_checksum_address(generate_formatted_string(129)) + ) + ) + != reserved_bytecode + ) # check counter contract # Temp. workaround @@ -53,7 +79,10 @@ def run_test(self): encoding="utf8", ).read() counter_contract = node.w3.eth.contract( - address="0x0000000000000000000000000000000000000301", abi=abi + address=node.w3.to_checksum_address( + "0xff10000000000000000000000000000000000000" + ), + abi=abi, ) num_blocks = 5 @@ -80,5 +109,17 @@ def run_test(self): assert_equal(len(state_roots), num_blocks) +def generate_formatted_string(input_number): + hex_representation = hex(input_number)[2:] # Convert to hex and remove '0x' prefix + + if len(hex_representation) > 32: + hex_representation = hex_representation[:32] # Truncate if too long + + padding = "0" * (37 - len(hex_representation)) + formatted_string = f"0xff1{padding}{hex_representation}" + + return formatted_string + + if __name__ == "__main__": DFIIntrinsicsTest().main()