mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 21:01:02 +00:00
Make transactions receipts part of transaction inclusion proof (#236)
* make receipts part of tx proof * is_successful_raw_receipt_with_empty_data * cargo fmt --all * clippy * fix everything
This commit is contained in:
committed by
Bastian Köcher
parent
70135cb797
commit
156ec9862f
@@ -31,6 +31,7 @@ use crate::rpc_errors::RpcError;
|
||||
use crate::substrate_client::{
|
||||
SubmitEthereumExchangeTransactionProof, SubstrateConnectionParams, SubstrateRpcClient, SubstrateSigningParams,
|
||||
};
|
||||
use crate::substrate_types::into_substrate_ethereum_receipt;
|
||||
use crate::sync_types::HeaderId;
|
||||
|
||||
use async_trait::async_trait;
|
||||
@@ -169,12 +170,17 @@ impl SourceClient<EthereumToSubstrateExchange> for EthereumTransactionsSource {
|
||||
node are having `raw` field; qed";
|
||||
const BLOCK_HAS_HASH_FIELD_PROOF: &str = "RPC level checks that block has `hash` field; qed";
|
||||
|
||||
let transaction_proof = block
|
||||
.0
|
||||
.transactions
|
||||
.iter()
|
||||
.map(|tx| tx.raw.clone().expect(TRANSACTION_HAS_RAW_FIELD_PROOF).0)
|
||||
.collect();
|
||||
let mut transaction_proof = Vec::with_capacity(block.0.transactions.len());
|
||||
for tx in &block.0.transactions {
|
||||
let raw_tx_receipt = self
|
||||
.client
|
||||
.transaction_receipt(tx.hash)
|
||||
.await
|
||||
.map(|receipt| into_substrate_ethereum_receipt(&receipt))
|
||||
.map(|receipt| receipt.rlp())?;
|
||||
let raw_tx = tx.raw.clone().expect(TRANSACTION_HAS_RAW_FIELD_PROOF).0;
|
||||
transaction_proof.push((raw_tx, raw_tx_receipt));
|
||||
}
|
||||
|
||||
Ok(EthereumTransactionInclusionProof {
|
||||
block: block.0.hash.expect(BLOCK_HAS_HASH_FIELD_PROOF),
|
||||
@@ -221,11 +227,18 @@ impl TargetClient<EthereumToSubstrateExchange> for SubstrateTransactionsTarget {
|
||||
|
||||
async fn filter_transaction_proof(&self, proof: &EthereumTransactionInclusionProof) -> Result<bool, Self::Error> {
|
||||
// let's try to parse transaction locally
|
||||
let parse_result = bridge_node_runtime::exchange::EthTransaction::parse(&proof.proof[proof.index as usize]);
|
||||
let (raw_tx, raw_tx_receipt) = &proof.proof[proof.index as usize];
|
||||
let parse_result = bridge_node_runtime::exchange::EthTransaction::parse(raw_tx);
|
||||
if parse_result.is_err() {
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
// now let's check if transaction is successful
|
||||
match sp_bridge_eth_poa::Receipt::is_successful_raw_receipt(raw_tx_receipt) {
|
||||
Ok(true) => (),
|
||||
_ => return Ok(false),
|
||||
}
|
||||
|
||||
// seems that transaction is relayable - let's check if runtime is able to import it
|
||||
// (we can't if e.g. header is pruned or there's some issue with tx data)
|
||||
self.client.verify_exchange_transaction_proof(proof.clone()).await
|
||||
|
||||
@@ -100,27 +100,29 @@ pub fn into_substrate_ethereum_header(header: &EthereumHeader) -> SubstrateEther
|
||||
pub fn into_substrate_ethereum_receipts(
|
||||
receipts: &Option<Vec<EthereumReceipt>>,
|
||||
) -> Option<Vec<SubstrateEthereumReceipt>> {
|
||||
receipts.as_ref().map(|receipts| {
|
||||
receipts
|
||||
.iter()
|
||||
.map(|receipt| SubstrateEthereumReceipt {
|
||||
gas_used: receipt.gas_used.expect(ETHEREUM_RECEIPT_GAS_USED_PROOF),
|
||||
log_bloom: receipt.logs_bloom.data().into(),
|
||||
logs: receipt
|
||||
.logs
|
||||
.iter()
|
||||
.map(|log_entry| SubstrateEthereumLogEntry {
|
||||
address: log_entry.address,
|
||||
topics: log_entry.topics.clone(),
|
||||
data: log_entry.data.0.clone(),
|
||||
})
|
||||
.collect(),
|
||||
outcome: match (receipt.status, receipt.root) {
|
||||
(Some(status), None) => SubstrateEthereumTransactionOutcome::StatusCode(status.as_u64() as u8),
|
||||
(None, Some(root)) => SubstrateEthereumTransactionOutcome::StateRoot(root),
|
||||
_ => SubstrateEthereumTransactionOutcome::Unknown,
|
||||
},
|
||||
})
|
||||
.collect()
|
||||
})
|
||||
receipts
|
||||
.as_ref()
|
||||
.map(|receipts| receipts.iter().map(into_substrate_ethereum_receipt).collect())
|
||||
}
|
||||
|
||||
/// Convert Ethereum transactions receipt into Ethereum transactions receipt for Substrate.
|
||||
pub fn into_substrate_ethereum_receipt(receipt: &EthereumReceipt) -> SubstrateEthereumReceipt {
|
||||
SubstrateEthereumReceipt {
|
||||
gas_used: receipt.gas_used.expect(ETHEREUM_RECEIPT_GAS_USED_PROOF),
|
||||
log_bloom: receipt.logs_bloom.data().into(),
|
||||
logs: receipt
|
||||
.logs
|
||||
.iter()
|
||||
.map(|log_entry| SubstrateEthereumLogEntry {
|
||||
address: log_entry.address,
|
||||
topics: log_entry.topics.clone(),
|
||||
data: log_entry.data.0.clone(),
|
||||
})
|
||||
.collect(),
|
||||
outcome: match (receipt.status, receipt.root) {
|
||||
(Some(status), None) => SubstrateEthereumTransactionOutcome::StatusCode(status.as_u64() as u8),
|
||||
(None, Some(root)) => SubstrateEthereumTransactionOutcome::StateRoot(root),
|
||||
_ => SubstrateEthereumTransactionOutcome::Unknown,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user