feat : add eth_getTransactionByBlockHashAndIndex (#157)

* eth_getTransactionByBlockHashAndIndex

* format

* clippy changes

* test check
This commit is contained in:
danilowhk 2023-01-03 11:45:56 -03:00 committed by GitHub
parent ec4beb38e9
commit 9d69c2b2b4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 77 additions and 1 deletions

View File

@ -434,6 +434,18 @@ impl<DB: Database> Client<DB> {
.await .await
} }
pub async fn get_transaction_by_block_hash_and_index(
&self,
block_hash: &Vec<u8>,
index: usize,
) -> Result<Option<Transaction>> {
self.node
.read()
.await
.get_transaction_by_block_hash_and_index(block_hash, index)
.await
}
pub async fn chain_id(&self) -> u64 { pub async fn chain_id(&self) -> u64 {
self.node.read().await.chain_id() self.node.read().await.chain_id()
} }

View File

@ -217,6 +217,18 @@ impl Node {
.await .await
} }
pub async fn get_transaction_by_block_hash_and_index(
&self,
hash: &Vec<u8>,
index: usize,
) -> Result<Option<Transaction>> {
let payload = self.get_payload_by_hash(hash)?;
self.execution
.get_transaction_by_block_hash_and_index(payload.1, index)
.await
}
pub async fn get_logs(&self, filter: &Filter) -> Result<Vec<Log>> { pub async fn get_logs(&self, filter: &Filter) -> Result<Vec<Log>> {
self.execution.get_logs(filter, &self.payloads).await self.execution.get_logs(filter, &self.payloads).await
} }

View File

@ -97,6 +97,12 @@ trait EthRpc {
) -> Result<Option<TransactionReceipt>, Error>; ) -> Result<Option<TransactionReceipt>, Error>;
#[method(name = "getTransactionByHash")] #[method(name = "getTransactionByHash")]
async fn get_transaction_by_hash(&self, hash: &str) -> Result<Option<Transaction>, Error>; async fn get_transaction_by_hash(&self, hash: &str) -> Result<Option<Transaction>, Error>;
#[method(name = "getTransactionByBlockHashAndIndex")]
async fn get_transaction_by_block_hash_and_index(
&self,
hash: &str,
index: usize,
) -> Result<Option<Transaction>, Error>;
#[method(name = "getLogs")] #[method(name = "getLogs")]
async fn get_logs(&self, filter: Filter) -> Result<Vec<Log>, Error>; async fn get_logs(&self, filter: Filter) -> Result<Vec<Log>, Error>;
#[method(name = "getStorageAt")] #[method(name = "getStorageAt")]
@ -252,6 +258,18 @@ impl EthRpcServer for RpcInner {
convert_err(node.get_transaction_by_hash(&hash).await) convert_err(node.get_transaction_by_hash(&hash).await)
} }
async fn get_transaction_by_block_hash_and_index(
&self,
hash: &str,
index: usize,
) -> Result<Option<Transaction>, Error> {
let hash = convert_err(hex_str_to_bytes(hash))?;
let node = self.node.read().await;
convert_err(
node.get_transaction_by_block_hash_and_index(&hash, index)
.await,
)
}
async fn get_logs(&self, filter: Filter) -> Result<Vec<Log>, Error> { async fn get_logs(&self, filter: Filter) -> Result<Vec<Log>, Error> {
let node = self.node.read().await; let node = self.node.read().await;
convert_err(node.get_logs(&filter).await) convert_err(node.get_logs(&filter).await)

View File

@ -179,6 +179,21 @@ impl<R: ExecutionRpc> ExecutionClient<R> {
}) })
} }
pub async fn get_transaction_by_block_hash_and_index(
&self,
payload: &ExecutionPayload,
index: usize,
) -> Result<Option<Transaction>> {
let tx = payload.transactions[index].clone();
let tx_hash = H256::from_slice(&keccak256(tx));
let mut payloads = BTreeMap::new();
payloads.insert(payload.block_number, payload.clone());
let tx_option = self.get_transaction(&tx_hash, &payloads).await?;
let tx = tx_option.ok_or(eyre::eyre!("not reachable"))?;
Ok(Some(tx))
}
pub async fn get_transaction_receipt( pub async fn get_transaction_receipt(
&self, &self,
tx_hash: &H256, tx_hash: &H256,
@ -260,7 +275,6 @@ impl<R: ExecutionRpc> ExecutionClient<R> {
if !txs_encoded.contains(&tx_encoded) { if !txs_encoded.contains(&tx_encoded) {
return Err(ExecutionError::MissingTransaction(hash.to_string()).into()); return Err(ExecutionError::MissingTransaction(hash.to_string()).into());
} }
Ok(Some(tx)) Ok(Some(tx))
} }

View File

@ -200,3 +200,23 @@ async fn test_get_block() {
assert_eq!(block.number, 12345); assert_eq!(block.number, 12345);
} }
#[tokio::test]
async fn test_get_tx_by_block_hash_and_index() {
let execution = get_client();
let tx_hash =
H256::from_str("2dac1b27ab58b493f902dda8b63979a112398d747f1761c0891777c0983e591f").unwrap();
let mut payload = ExecutionPayload {
block_number: 7530933,
..ExecutionPayload::default()
};
payload.transactions.push(List::from_iter(hex_str_to_bytes("0x02f8b20583623355849502f900849502f91082ea6094326c977e6efc84e512bb9c30f76e30c160ed06fb80b844a9059cbb0000000000000000000000007daccf9b3c1ae2fa5c55f1c978aeef700bc83be0000000000000000000000000000000000000000000000001158e460913d00000c080a0e1445466b058b6f883c0222f1b1f3e2ad9bee7b5f688813d86e3fa8f93aa868ca0786d6e7f3aefa8fe73857c65c32e4884d8ba38d0ecfb947fbffb82e8ee80c167").unwrap()));
let tx = execution
.get_transaction_by_block_hash_and_index(&payload, 0)
.await
.unwrap()
.unwrap();
assert_eq!(tx.hash(), tx_hash);
}