Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

evm: Move DFIIntrinsics contract, reserve space for additional contracts #2389

Merged
merged 2 commits into from
Sep 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions lib/ain-contracts/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@ pub fn dst20_address_from_token_id(token_id: u64) -> Result<H160> {
Ok(H160::from_str(&final_str)?)
}

pub fn intrinsics_address_from_id(id: u64) -> Result<H160> {
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,
Expand Down
2 changes: 1 addition & 1 deletion lib/ain-evm/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
26 changes: 22 additions & 4 deletions lib/ain-evm/src/evm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand Down Expand Up @@ -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);
Expand All @@ -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)?;
Expand All @@ -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();
}
Expand Down Expand Up @@ -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::<Vec<H160>>();

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<SignedTx>, ReceiptV3)> {
Expand Down
45 changes: 43 additions & 2 deletions test/functional/feature_evm_dfi_intrinsics.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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"):
Expand All @@ -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
Expand All @@ -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()
Loading