Skip to content

Commit

Permalink
feat: implement eth_getTransactionByBlockNumberAndIndex (#445)
Browse files Browse the repository at this point in the history
* feat: implement eth_getTransactionByBlockNumberAndIndex

* fixup! imports
  • Loading branch information
eshaan7 authored Nov 24, 2024
1 parent dde0e53 commit aee6c31
Show file tree
Hide file tree
Showing 9 changed files with 104 additions and 2 deletions.
10 changes: 10 additions & 0 deletions core/src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,16 @@ impl<N: NetworkSpec, C: Consensus<N::TransactionResponse>> Client<N, C> {
.await
}

pub async fn get_transaction_by_block_number_and_index(
&self,
block: BlockTag,
index: u64,
) -> Result<Option<N::TransactionResponse>> {
self.node
.get_transaction_by_block_number_and_index(block, index)
.await
}

pub async fn chain_id(&self) -> u64 {
self.node.chain_id()
}
Expand Down
13 changes: 13 additions & 0 deletions core/src/client/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,19 @@ impl<N: NetworkSpec, C: Consensus<N::TransactionResponse>> Node<N, C> {
.await
}

pub async fn get_transaction_by_block_number_and_index(
&self,
block: BlockTag,
index: u64,
) -> Result<Option<N::TransactionResponse>> {
self.check_blocktag_age(&block).await?;

Ok(self
.execution
.get_transaction_by_block_number_and_index(block, index)
.await)
}

pub async fn get_logs(&self, filter: &Filter) -> Result<Vec<Log>> {
self.execution.get_logs(filter).await
}
Expand Down
18 changes: 18 additions & 0 deletions core/src/client/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,12 @@ trait EthRpc<TX: TransactionResponse + RpcObject, TXR: RpcObject, R: ReceiptResp
hash: B256,
index: U64,
) -> Result<Option<TX>, ErrorObjectOwned>;
#[method(name = "getTransactionByBlockNumberAndIndex")]
async fn get_transaction_by_block_number_and_index(
&self,
block: BlockTag,
index: U64,
) -> Result<Option<TX>, ErrorObjectOwned>;
#[method(name = "getLogs")]
async fn get_logs(&self, filter: Filter) -> Result<Vec<Log>, ErrorObjectOwned>;
#[method(name = "getFilterChanges")]
Expand Down Expand Up @@ -295,6 +301,18 @@ impl<N: NetworkSpec, C: Consensus<N::TransactionResponse>>
.await)
}

async fn get_transaction_by_block_number_and_index(
&self,
block: BlockTag,
index: U64,
) -> Result<Option<N::TransactionResponse>, ErrorObjectOwned> {
convert_err(
self.node
.get_transaction_by_block_number_and_index(block, index.to())
.await,
)
}

async fn coinbase(&self) -> Result<Address, ErrorObjectOwned> {
convert_err(self.node.get_coinbase().await)
}
Expand Down
12 changes: 11 additions & 1 deletion core/src/execution/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,17 @@ impl<N: NetworkSpec, R: ExecutionRpc<N>> ExecutionClient<N, R> {
index: u64,
) -> Option<N::TransactionResponse> {
self.state
.get_transaction_by_block_and_index(block_hash, index)
.get_transaction_by_block_hash_and_index(block_hash, index)
.await
}

pub async fn get_transaction_by_block_number_and_index(
&self,
tag: BlockTag,
index: u64,
) -> Option<N::TransactionResponse> {
self.state
.get_transaction_by_block_and_index(tag, index)
.await
}

Expand Down
14 changes: 13 additions & 1 deletion core/src/execution/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ impl<N: NetworkSpec, R: ExecutionRpc<N>> State<N, R> {
.cloned()
}

pub async fn get_transaction_by_block_and_index(
pub async fn get_transaction_by_block_hash_and_index(
&self,
block_hash: B256,
index: u64,
Expand All @@ -125,6 +125,18 @@ impl<N: NetworkSpec, R: ExecutionRpc<N>> State<N, R> {
.cloned()
}

pub async fn get_transaction_by_block_and_index(
&self,
tag: BlockTag,
index: u64,
) -> Option<N::TransactionResponse> {
let block = self.get_block(tag).await?;
match &block.transactions {
Transactions::Full(txs) => txs.get(index as usize).cloned(),
Transactions::Hashes(_) => unreachable!(),
}
}

// block field fetch

pub async fn get_state_root(&self, tag: BlockTag) -> Option<B256> {
Expand Down
6 changes: 6 additions & 0 deletions helios-ts/lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,12 @@ export class HeliosProvider {
req.params[1]
);
}
case "eth_getTransactionByBlockNumberAndIndex": {
return this.#client.get_transaction_by_block_number_and_index(
req.params[0],
req.params[1]
);
}
case "eth_getBlockReceipts": {
return this.#client.get_block_receipts(req.params[0]);
}
Expand Down
16 changes: 16 additions & 0 deletions helios-ts/src/ethereum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,22 @@ impl EthereumClient {
Ok(serde_wasm_bindgen::to_value(&tx)?)
}

#[wasm_bindgen]
pub async fn get_transaction_by_block_number_and_index(
&self,
block: JsValue,
index: JsValue,
) -> Result<JsValue, JsError> {
let block: BlockTag = serde_wasm_bindgen::from_value(block)?;
let index: u64 = serde_wasm_bindgen::from_value(index)?;
let tx = map_err(
self.inner
.get_transaction_by_block_number_and_index(block, index)
.await,
)?;
Ok(serde_wasm_bindgen::to_value(&tx)?)
}

#[wasm_bindgen]
pub async fn get_transaction_count(
&self,
Expand Down
16 changes: 16 additions & 0 deletions helios-ts/src/opstack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,22 @@ impl OpStackClient {
Ok(serde_wasm_bindgen::to_value(&tx)?)
}

#[wasm_bindgen]
pub async fn get_transaction_by_block_number_and_index(
&self,
block: JsValue,
index: JsValue,
) -> Result<JsValue, JsError> {
let block: BlockTag = serde_wasm_bindgen::from_value(block)?;
let index: u64 = serde_wasm_bindgen::from_value(index)?;
let tx = map_err(
self.inner
.get_transaction_by_block_number_and_index(block, index)
.await,
)?;
Ok(serde_wasm_bindgen::to_value(&tx)?)
}

#[wasm_bindgen]
pub async fn get_transaction_count(
&self,
Expand Down
1 change: 1 addition & 0 deletions rpc.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Helios provides a variety of RPC methods for interacting with the Ethereum netwo
| `eth_getTransactionReceipt` | `get_transaction_receipt` | Returns the receipt of a transaction by transaction hash. | `client.get_transaction_receipt(&self, hash: &str)` |
| `eth_getTransactionByHash` | `get_transaction_by_hash` | Returns the information about a transaction requested by transaction hash. | `client.get_transaction_by_hash(&self, hash: &str)`
| `eth_getTransactionByBlockHashAndIndex` | `get_transaction_by_block_hash_and_index` | Returns information about a transaction by block hash and transaction index position. | `client.get_transaction_by_block_hash_and_index(&self, hash: &str, index: u64)`
| `eth_getTransactionByBlockNumberAndIndex` | `get_transaction_by_block_number_and_index` | Returns information about a transaction by block number and transaction index position. | `client.get_transaction_by_block_number_and_index(&self, block: BlockTag, index: u64)`
| `eth_getBlockReceipts` | `get_block_receipts` | Returns all transaction receipts of a block by number. | `client.get_block_receipts(&self, block: BlockTag)` |
| `eth_getLogs` | `get_logs` | Returns an array of logs matching the filter. | `client.get_logs(&self, filter: Filter)` |
| `eth_getStorageAt` | `get_storage_at` | Returns the value from a storage position at a given address. | `client.get_storage_at(&self, address: &str, slot: H256, block: BlockTag)` |
Expand Down

0 comments on commit aee6c31

Please sign in to comment.