Skip to content

Commit

Permalink
Merge branch 'master' into feature/accountintg_consensus
Browse files Browse the repository at this point in the history
  • Loading branch information
Mixa84 authored Aug 23, 2023
2 parents 69f30df + ea7b180 commit ac08fb3
Show file tree
Hide file tree
Showing 27 changed files with 952 additions and 192 deletions.
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ define(_CLIENT_VERSION_MAJOR, 4)
define(_CLIENT_VERSION_MINOR, 0)
define(_CLIENT_VERSION_REVISION, 0)
define(_CLIENT_VERSION_BUILD, 0)
define(_CLIENT_VERSION_RC, 1)
define(_CLIENT_VERSION_RC, 10)
define(_CLIENT_VERSION_IS_RELEASE, false)
define(_COPYRIGHT_YEAR, 2023)
define(_COPYRIGHT_HOLDERS,[The %s developers])
Expand Down
2 changes: 1 addition & 1 deletion lib/ain-contracts/dfi_intrinsics/DFIIntrinsics.sol
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: GPL-3.0
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.2 <0.9.0;

Expand Down
2 changes: 1 addition & 1 deletion lib/ain-contracts/dst20/ERC20.sol
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@

// SPDX-License-Identifier: MIT
// File: @openzeppelin/[email protected]/utils/Context.sol


Expand Down
3 changes: 2 additions & 1 deletion lib/ain-contracts/system_reserved/SystemReservedContract.sol
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// SPDX-License-Identifier: UNLICENSED
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

contract SystemReservedContract {
Expand Down
3 changes: 2 additions & 1 deletion lib/ain-evm/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,8 @@ impl BlockService {
let block = self
.storage
.get_latest_block()?
.expect("Unable to find latest block");
.ok_or(format_err!("Unable to find latest block"))?;

blocks.push(block.clone());
let mut parent_hash = block.header.parent_hash;

Expand Down
31 changes: 18 additions & 13 deletions lib/ain-evm/src/evm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,12 +134,6 @@ impl EVMServices {
let tx_queue = self.core.tx_queues.get(queue_id)?;
let mut queue = tx_queue.data.lock().unwrap();

let is_evm_genesis_block = queue.target_block == U256::zero();
if is_evm_genesis_block {
let migration_txs = get_dst20_migration_txs(mnview_ptr)?;
queue.transactions.extend(migration_txs.into_iter())
}

let queue_txs_len = queue.transactions.len();
let mut all_transactions = Vec::with_capacity(queue_txs_len);
let mut failed_transactions = Vec::with_capacity(queue_txs_len);
Expand Down Expand Up @@ -194,25 +188,30 @@ impl EVMServices {

let mut executor = AinExecutor::new(&mut backend);

// Ensure that state root changes by updating counter contract storage
if current_block_number == U256::zero() {
let is_evm_genesis_block = queue.target_block == U256::zero();
if is_evm_genesis_block {
// reserve DST20 namespace
self.reserve_dst20_namespace(&mut executor)?;

// Deploy contract on the first block
let migration_txs = get_dst20_migration_txs(mnview_ptr)?;
queue.transactions.extend(migration_txs.into_iter());

// Deploy counter contract on the first block
let DeployContractInfo {
address,
storage,
bytecode,
} = EVMServices::counter_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)?;
executor.update_storage(address, storage)?;
}
for (_idx, queue_item) in queue.transactions.clone().into_iter().enumerate() {

for queue_item in queue.transactions.clone() {
match queue_item.tx {
QueueTx::SignedTx(signed_tx) => {
let nonce = executor.get_nonce(&signed_tx.sender);
Expand Down Expand Up @@ -505,7 +504,7 @@ impl EVMServices {
None => {}
Some(account) => {
if account.code_hash != ain_contracts::get_system_reserved_codehash()? {
debug!("Token address is already in use for {name} {symbol}");
return Err(format_err!("Token address is already in use").into());
}
}
}
Expand Down Expand Up @@ -643,7 +642,10 @@ impl EVMServices {
.collect::<Vec<H160>>();

for address in addresses {
debug!("Deploying address to {:#?}", address);
debug!(
"[reserve_dst20_namespace] Deploying address to {:#?}",
address
);
executor.deploy_contract(address, bytecode.clone().into(), Vec::new())?;
}

Expand Down Expand Up @@ -678,7 +680,10 @@ fn get_dst20_migration_txs(mnview_ptr: usize) -> Result<Vec<QueueTxItem>> {
let mut txs = Vec::new();
for token in ain_cpp_imports::get_dst20_tokens(mnview_ptr) {
let address = ain_contracts::dst20_address_from_token_id(token.id)?;
debug!("Deploying to address {:#?}", address);
debug!(
"[get_dst20_migration_txs] Deploying to address {:#?}",
address
);

let tx = QueueTx::SystemTx(SystemTx::DeployContract(DeployContractData {
name: token.name,
Expand Down
2 changes: 1 addition & 1 deletion lib/ain-evm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ pub type MaybeTransactionV2 = Option<ethereum::TransactionV2>;
pub enum EVMError {
#[error("EVM: Backend error: {0:?}")]
TrieCreationFailed(#[from] BackendError),
#[error("EVM: Queue error")]
#[error("EVM: Queue error {0:?}")]
QueueError(#[from] QueueError),
#[error("EVM: Queue invalid nonce error {0:?}")]
QueueInvalidNonce((Box<transaction::SignedTx>, ethereum_types::U256)),
Expand Down
104 changes: 104 additions & 0 deletions lib/ain-evm/src/transaction/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,19 @@ impl<T> From<EnvelopedDecoderError<T>> for TransactionError {
}
}

#[cfg(test)]
mod tests {
use std::error::Error;
use std::fs;
use std::path::Path;

use ethereum::{AccessListItem, EnvelopedEncodable};
use ethereum_types::{H160, U64};
use primitive_types::{H256, U256};
use serde::Deserialize;

use crate::bytes::Bytes;
use crate::transaction::SignedTx;

#[test]
fn test_signed_tx_from_raw_tx() {
Expand Down Expand Up @@ -381,4 +393,96 @@ mod tests {
"f829754bae400b679febefdcfc9944c323e1f94e"
);
}

#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
struct ExpectedTx {
hash: H256,
from: H160,
to: Option<H160>,
gas: U256,
gas_price: U256,
value: U256,
input: Bytes,
nonce: U256,
v: U64,
r: H256,
s: H256,
_block_hash: H256,
_block_number: U256,
_transaction_index: U256,
#[serde(rename = "type")]
r#type: U64,
max_fee_per_gas: Option<U256>,
max_priority_fee_per_gas: Option<U256>,
#[serde(default)]
access_list: Vec<AccessListItem>,
chain_id: Option<U64>,
}

#[cfg(test)]
fn get_test_data(path: &Path) -> Result<Vec<(String, ExpectedTx)>, Box<dyn Error>> {
let content = fs::read_to_string(path)?;

let r = serde_json::from_str(&content)?;
Ok(r)
}

fn assert_raw_hash_matches_expected_tx((raw_hash, tx): (String, ExpectedTx)) {
let signed_tx: SignedTx = (&raw_hash[2..]).try_into().unwrap();

assert_eq!(signed_tx.sender, tx.from);
assert_eq!(signed_tx.gas_limit(), tx.gas);
assert_eq!(signed_tx.to(), tx.to);
assert_eq!(signed_tx.hash(), tx.hash);
assert_eq!(signed_tx.data().to_vec(), tx.input.0);
assert_eq!(signed_tx.nonce(), tx.nonce);
assert_eq!(signed_tx.value(), tx.value);
assert_eq!(signed_tx.access_list(), tx.access_list);
assert_eq!(signed_tx.max_fee_per_gas(), tx.max_fee_per_gas);
assert_eq!(
signed_tx.max_priority_fee_per_gas(),
tx.max_priority_fee_per_gas
);
assert_eq!(U64::from(signed_tx.v()), tx.v);
assert_eq!(signed_tx.r(), tx.r);
assert_eq!(signed_tx.s(), tx.s);

if let Some(chain_id) = tx.chain_id {
assert_eq!(U64::from(signed_tx.chain_id()), chain_id);
}

let r#type =
U64::from(EnvelopedEncodable::type_id(&signed_tx.transaction).unwrap_or_default());
assert_eq!(r#type, tx.r#type);

// Can't get gas_price without block base fee
if r#type == U64::zero() || r#type == U64::one() {
assert_eq!(signed_tx.gas_price(), tx.gas_price);
}
}

#[test]
fn test_transfer_txs() -> Result<(), Box<dyn Error>> {
get_test_data(Path::new("./testdata/transfer_txs.json"))?
.into_iter()
.for_each(assert_raw_hash_matches_expected_tx);
Ok(())
}

#[test]
fn test_call_smart_contract_txs() -> Result<(), Box<dyn Error>> {
get_test_data(Path::new("./testdata/call_smart_contract_txs.json"))?
.into_iter()
.for_each(assert_raw_hash_matches_expected_tx);
Ok(())
}

#[test]
fn test_deploy_smart_contract_txs() -> Result<(), Box<dyn Error>> {
get_test_data(Path::new("./testdata/deploy_smart_contract_txs.json"))?
.into_iter()
.for_each(assert_raw_hash_matches_expected_tx);
Ok(())
}
}
Loading

0 comments on commit ac08fb3

Please sign in to comment.