Skip to content

Commit

Permalink
Fix: bridge to work better with subchain.
Browse files Browse the repository at this point in the history
  • Loading branch information
vldm committed Aug 22, 2024
1 parent 7bd8747 commit 6415c59
Show file tree
Hide file tree
Showing 7 changed files with 125 additions and 37 deletions.
5 changes: 5 additions & 0 deletions client/src/rpc_request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@ pub enum RpcRequest {
EthTraceReplayBlock,
// vlx methods
VlxCall,
VlxGetTransactionCount,
VlxGetTransactionReceipt,

/// Velas Account scope
GetVelasAccountsByOperationalKey,
Expand Down Expand Up @@ -249,6 +251,9 @@ impl fmt::Display for RpcRequest {
RpcRequest::EthGetLogs => "eth_getLogs",
RpcRequest::EthSyncing => "eth_syncing",
RpcRequest::VlxCall => "vlx_call",
RpcRequest::VlxGetTransactionReceipt => "vlx_getTransactionReceipt",

RpcRequest::VlxGetTransactionCount => "vlx_getTransactionCount",
RpcRequest::GetVelasAccountsByOperationalKey => "getVelasAccountsByOperationalKey",
RpcRequest::GetVelasAccountsByOwnerKey => "getVelasAccountsByOwnerKey",
RpcRequest::GetVelasRelyingPartiesByOwnerKey => "getVelasRelyingPartiesByOwnerKey",
Expand Down
60 changes: 43 additions & 17 deletions evm-utils/evm-bridge/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,13 +305,23 @@ impl EvmBridge {

pub async fn is_transaction_landed(&self, hash: &H256) -> Option<bool> {
async fn is_receipt_exists(bridge: &EvmBridge, hash: &H256) -> Option<bool> {
bridge
.rpc_client
.get_evm_transaction_receipt(hash)
.await
.ok()
.flatten()
.map(|_receipt| true)
if bridge.subchain {
bridge
.rpc_client
.get_evm_subchain_transaction_receipt(bridge.evm_chain_id, hash)
.await
.ok()
.flatten()
.map(|_receipt| true)
} else {
bridge
.rpc_client
.get_evm_transaction_receipt(hash)
.await
.ok()
.flatten()
.map(|_receipt| true)
}
}

async fn is_signature_exists(bridge: &EvmBridge, hash: &H256) -> Option<bool> {
Expand Down Expand Up @@ -487,11 +497,19 @@ impl BridgeERPC for BridgeErpcImpl {

let nonce = match tx.nonce.or_else(|| meta.pool.transaction_count(&address)) {
Some(n) => n,
None => meta
.rpc_client
.get_evm_transaction_count(&address)
.await
.unwrap_or_default(),
None => {
if meta.subchain {
meta.rpc_client
.get_evm_subchain_transaction_count(meta.evm_chain_id, &address)
.await
.unwrap_or_default()
} else {
meta.rpc_client
.get_evm_transaction_count(&address)
.await
.unwrap_or_default()
}
}
};

let tx = UnsignedTransaction {
Expand Down Expand Up @@ -538,11 +556,19 @@ impl BridgeERPC for BridgeErpcImpl {

let nonce = match tx.nonce.or_else(|| meta.pool.transaction_count(&address)) {
Some(n) => n,
None => meta
.rpc_client
.get_evm_transaction_count(&address)
.await
.unwrap_or_default(),
None => {
if meta.subchain {
meta.rpc_client
.get_evm_subchain_transaction_count(meta.evm_chain_id, &address)
.await
.unwrap_or_default()
} else {
meta.rpc_client
.get_evm_transaction_count(&address)
.await
.unwrap_or_default()
}
}
};

let tx_create = evm::UnsignedTransaction {
Expand Down
22 changes: 22 additions & 0 deletions evm-utils/evm-bridge/src/rpc_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,17 @@ impl AsyncRpcClient {
self.send(RpcRequest::EthGetTransactionCount, json!([*address]))
.await
}
pub async fn get_evm_subchain_transaction_count(
&self,
chain_id: u64,
address: &Address,
) -> ClientResult<U256> {
self.send(
RpcRequest::VlxGetTransactionCount,
json!([chain_id, *address]),
)
.await
}

pub async fn get_evm_transaction_receipt(
&self,
Expand All @@ -227,6 +238,17 @@ impl AsyncRpcClient {
self.send::<Option<RPCReceipt>>(RpcRequest::EthGetTransactionReceipt, json!([*hash]))
.await
}
pub async fn get_evm_subchain_transaction_receipt(
&self,
chain_id: u64,
hash: &H256,
) -> ClientResult<Option<RPCReceipt>> {
self.send::<Option<RPCReceipt>>(
RpcRequest::VlxGetTransactionReceipt,
json!([chain_id, *hash]),
)
.await
}

pub async fn get_version(&self) -> ClientResult<RpcVersionInfo> {
self.send(RpcRequest::GetVersion, Value::Null).await
Expand Down
30 changes: 24 additions & 6 deletions evm-utils/programs/evm_loader/src/processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,12 @@ impl EvmProcessor {
ExecuteTransaction::Signed { tx } => {
let tx = match tx {
Some(tx) => tx,
None => Self::get_tx_from_storage(invoke_context, accounts, borsh_used)?,
None => Self::get_tx_from_storage(
invoke_context,
accounts,
borsh_used,
is_subchain,
)?,
};
ic_msg!(
invoke_context,
Expand Down Expand Up @@ -467,7 +472,12 @@ impl EvmProcessor {
)?;
let tx = match tx {
Some(tx) => tx,
None => Self::get_tx_from_storage(invoke_context, accounts, borsh_used)?,
None => Self::get_tx_from_storage(
invoke_context,
accounts,
borsh_used,
is_subchain,
)?,
};
ic_msg!(
invoke_context,
Expand Down Expand Up @@ -511,7 +521,8 @@ impl EvmProcessor {
};

if executor.feature_set.is_unsigned_tx_fix_enabled() && is_big {
let storage = Self::get_big_transaction_storage(invoke_context, &accounts)?;
let storage =
Self::get_big_transaction_storage(invoke_context, &accounts, is_subchain)?;
self.cleanup_storage(invoke_context, storage, sender.unwrap_or(accounts.evm))?;
}
if executor
Expand Down Expand Up @@ -651,7 +662,11 @@ impl EvmProcessor {
) -> Result<(), EvmError> {
debug!("executing big_tx = {:?}", big_tx);

let mut storage = Self::get_big_transaction_storage(invoke_context, &accounts)?;
let mut storage = Self::get_big_transaction_storage(
invoke_context,
&accounts,
false, /* is_subchain */
)?;
let mut tx_chunks = TxChunks::new(storage.data_as_mut_slice());

match big_tx {
Expand Down Expand Up @@ -762,11 +777,12 @@ impl EvmProcessor {
invoke_context: &InvokeContext,
accounts: AccountStructure,
deserialize_chunks_with_borsh: bool,
subchain: bool,
) -> Result<T, EvmError>
where
T: BorshDeserialize + DeserializeOwned,
{
let mut storage = Self::get_big_transaction_storage(invoke_context, &accounts)?;
let mut storage = Self::get_big_transaction_storage(invoke_context, &accounts, subchain)?;
let tx_chunks = TxChunks::new(storage.data_mut().as_mut_slice());
debug!("Tx chunks crc = {:#x}", tx_chunks.crc());

Expand All @@ -788,8 +804,10 @@ impl EvmProcessor {
fn get_big_transaction_storage<'a>(
invoke_context: &InvokeContext,
accounts: &'a AccountStructure,
subchain: bool,
) -> Result<RefMut<'a, AccountSharedData>, EvmError> {
let storage_account = accounts.first().ok_or_else(|| {
let idx = if subchain { 1 } else { 0 };
let storage_account = accounts.users.get(idx).ok_or_else(|| {
ic_msg!(
invoke_context,
"EvmBigTransaction: No storage account found."
Expand Down
41 changes: 29 additions & 12 deletions rpc/src/evm_rpc_impl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ pub struct StateRootWithBank {
pub bank: Option<Arc<Bank>>,
pub block: BlockId,
pub block_timestamp: Option<u64>,
pub chain: EvmChain,
}

impl StateRootWithBank {
Expand All @@ -53,10 +54,10 @@ impl StateRootWithBank {

let root = *self.state_root.as_ref().unwrap();
if let Some(bank) = &self.bank {
let evm = bank.evm().main_chain().state();

assert!(evm.last_root() == root, "we store bank with invalid root");
return Ok(evm.get_account_state(address));
return self.with_evm_state(bank, |evm| {
assert!(evm.last_root() == root, "we store bank with invalid root");
Ok(evm.get_account_state(address))
});
}
let archive_evm_state = meta
.evm_state_archive(self.block_timestamp)
Expand All @@ -70,6 +71,19 @@ impl StateRootWithBank {
.unwrap_or_default())
}

pub fn with_evm_state<F, T>(&self, bank: &Bank, f: F) -> Result<T, Error>
where
F: FnOnce(&evm_state::EvmState) -> Result<T, Error>,
{
if let Some(chain_id) = self.chain {
let evm = &bank.evm().chain_state(chain_id).evm_state;
f(evm)
} else {
let evm = bank.evm().main_chain().state();
f(&evm)
}
}

pub fn get_storage_at(
&self,
meta: &JsonRpcRequestProcessor,
Expand All @@ -83,10 +97,10 @@ impl StateRootWithBank {

let root = *self.state_root.as_ref().unwrap();
if let Some(bank) = &self.bank {
let evm = bank.evm().main_chain().state();

assert!(evm.last_root() == root, "we store bank with invalid root");
return Ok(evm.get_storage(address, idx));
return self.with_evm_state(bank, |evm| {
assert!(evm.last_root() == root, "we store bank with invalid root");
Ok(evm.get_storage(address, idx))
});
}
let archive_evm_state = meta
.evm_state_archive(self.block_timestamp)
Expand Down Expand Up @@ -126,25 +140,26 @@ async fn block_to_state_root(
let block_num = match block_id {
BlockId::RelativeId(BlockRelId::Pending) | BlockId::RelativeId(BlockRelId::Latest) => {
let bank = meta.bank(Some(CommitmentConfig::processed()));
let (bank, last_root) = if let Some(chain_id) = chain {
let last_root = if let Some(chain_id) = chain {
if chain_id == meta.get_main_chain_id() {
return Err(Error::WrongChainId {
chain_id: meta.get_main_chain_id(),
tx_chain_id: None,
});
}
(None, bank.evm().chain_state(chain_id).evm_state.last_root())
bank.evm().chain_state(chain_id).evm_state.last_root()
} else {
let evm = bank.evm().main_chain().state();
let last_root = evm.last_root();
drop(evm);
(Some(bank), last_root)
last_root
};
return Ok(StateRootWithBank {
state_root: Some(last_root),
bank,
bank: Some(bank),
block: block_id,
block_timestamp: None,
chain,
});
}
BlockId::RelativeId(BlockRelId::Earliest) | BlockId::Num(Hex(0)) => {
Expand All @@ -161,6 +176,7 @@ async fn block_to_state_root(
bank: None,
block: block_id,
block_timestamp: None,
chain,
});
}
}
Expand All @@ -183,6 +199,7 @@ async fn block_to_state_root(
.get_evm_block_by_id(chain, block_num)
.await
.map(|(block, _)| block.header.timestamp),
chain,
})
}

Expand Down
2 changes: 1 addition & 1 deletion runtime/src/accounts_background_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ impl AbsRequestHandler {
let mut last_result = Err(evm_state::storage::Error::RootNotFound(
evm_state::H256::zero(),
));
for _ in 0..3 {
for _ in 0..5 {
last_result = storage.purge_slot(pruned_slot);
if last_result.is_ok() {
break;
Expand Down
2 changes: 1 addition & 1 deletion runtime/src/bank.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7181,7 +7181,7 @@ impl Drop for Bank {
use evm_state::{storage, Storage};
fn handle_evm_error(storage: &Storage, slot: u64) -> storage::Result<()> {
let mut last_result = Err(storage::Error::RootNotFound(evm_state::H256::zero()));
for _ in 0..3 {
for _ in 0..5 {
last_result = storage.purge_slot(slot);
if last_result.is_ok() {
break;
Expand Down

0 comments on commit 6415c59

Please sign in to comment.