From bc97c78e2ea1c724c79a964f03a440793d751306 Mon Sep 17 00:00:00 2001 From: Shoham Chakraborty Date: Wed, 6 Sep 2023 11:30:18 +0800 Subject: [PATCH] Revert "Revert "evm: Move DFIIntrinsics contract, reserve space for additional contracts (#2374)" (#2381)" (#2389) This reverts commit 2eff775fc22beca1ab632994e10ff79818c1db05. --- lib/ain-contracts/src/lib.rs | 8 ++++ lib/ain-evm/src/contract.rs | 2 +- lib/ain-evm/src/evm.rs | 26 +++++++++-- test/functional/feature_evm_dfi_intrinsics.py | 45 ++++++++++++++++++- 4 files changed, 74 insertions(+), 7 deletions(-) diff --git a/lib/ain-contracts/src/lib.rs b/lib/ain-contracts/src/lib.rs index 035377203e..948160f8bf 100644 --- a/lib/ain-contracts/src/lib.rs +++ b/lib/ain-contracts/src/lib.rs @@ -23,6 +23,14 @@ 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(Clone)] pub struct Contract { pub codehash: H256, diff --git a/lib/ain-evm/src/contract.rs b/lib/ain-evm/src/contract.rs index 57ad5894f5..1f9307b0df 100644 --- a/lib/ain-evm/src/contract.rs +++ b/lib/ain-evm/src/contract.rs @@ -54,7 +54,7 @@ pub struct DST20BridgeInfo { } /// Returns address, bytecode and storage with incremented count for the counter contract -pub fn counter_contract( +pub fn intrinsics_contract( backend: &EVMBackend, dvm_block_number: u64, evm_block_number: U256, diff --git a/lib/ain-evm/src/evm.rs b/lib/ain-evm/src/evm.rs index 9cdb27119a..207d9ff49b 100644 --- a/lib/ain-evm/src/evm.rs +++ b/lib/ain-evm/src/evm.rs @@ -15,8 +15,8 @@ use crate::{ backend::{EVMBackend, Vicinity}, block::BlockService, contract::{ - bridge_dst20, counter_contract, dst20_contract, transfer_domain_contract, DST20BridgeInfo, - DeployContractInfo, + bridge_dst20, dst20_contract, intrinsics_contract, transfer_domain_contract, + DST20BridgeInfo, DeployContractInfo, }, core::{EVMCoreService, XHash}, executor::{AinExecutor, TxResponse}, @@ -187,6 +187,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); @@ -196,7 +197,7 @@ impl EVMServices { address, storage, bytecode, - } = counter_contract(executor.backend, dvm_block_number, current_block_number)?; + } = intrinsics_contract(executor.backend, dvm_block_number, current_block_number)?; debug!("deploying {:x?} bytecode {:#?}", address, bytecode); executor.deploy_contract(address, bytecode, storage)?; @@ -220,7 +221,7 @@ impl EVMServices { // Ensure that state root changes by updating counter contract storage let DeployContractInfo { address, storage, .. - } = counter_contract(executor.backend, dvm_block_number, current_block_number)?; + } = intrinsics_contract(executor.backend, dvm_block_number, current_block_number)?; executor.update_storage(address, storage)?; executor.commit(); } @@ -635,6 +636,23 @@ impl EVMServices { Ok(()) } + + pub fn reserve_intrinsics_namespace(&self, executor: &mut AinExecutor) -> Result<()> { + let Contract { bytecode, .. } = get_reserved_contract(); + 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 dst20_deploy_contract_tx(token_id: u64, base_fee: &U256) -> Result<(Box, ReceiptV3)> { diff --git a/test/functional/feature_evm_dfi_intrinsics.py b/test/functional/feature_evm_dfi_intrinsics.py index 350b54b9f7..e978d29b11 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__)}/../../build/lib/target/ain_contracts/system_reserved/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 if os.getenv("BUILD_DIR"): @@ -60,7 +86,10 @@ def run_test(self): ).read() counter_contract = node.w3.eth.contract( - address="0x0000000000000000000000000000000000000301", abi=abi + address=node.w3.to_checksum_address( + "0x0000000000000000000000000000000000000301" + ), + abi=abi, ) num_blocks = 5 @@ -87,5 +116,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()