From 1629e283a72de325d1085978ad8a925d84abda88 Mon Sep 17 00:00:00 2001 From: Hiroki Noda Date: Wed, 6 Nov 2024 08:44:08 +0900 Subject: [PATCH] WIP: Add BlockResponse --- source/deth/rpcconnector.d | 29 ++++++++++++++++++ source/deth/util/types.d | 63 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+) diff --git a/source/deth/rpcconnector.d b/source/deth/rpcconnector.d index 7ded090..386920b 100644 --- a/source/deth/rpcconnector.d +++ b/source/deth/rpcconnector.d @@ -115,6 +115,24 @@ class RPCConnector : HttpJsonRpcAutoClient!IEthRPC return super.eth_call(tx.toJSON, _block)[2 .. $].convTo!bytes; } + /// wrapper for eth_getBlockByNumber + /// Params: + /// isFull = if true, it returns the detail of each transaction. + /// If false, only the hashes of the transactions. + /// Returns: block object, or null when no block was found. + Nullable!BlockResponse getBlock(BlockParameter)(bool isFull, + BlockParameter block = BlockNumber.LATEST) @safe + { + mixin BlockNumberToJSON!block; + JSONValue a = eth_getBlockByNumber(_block, isFull); + Nullable!BlockResponse blockResponse; + if (!a.isNull) + { + blockResponse = Nullable!BlockResponse(a.convTo!BlockResponse); + } + return blockResponse; + } + /// Wrapper for eth_getTrasactionCount /// Params: /// address = address of user @@ -251,6 +269,17 @@ class RPCConnector : HttpJsonRpcAutoClient!IEthRPC } } + +@("get latest block with the hashes of the transactions") +unittest +{ + auto conn = new RPCConnector("http://127.0.0.1:8545"); + const block = conn.getBlock(false); + + assert(!block.isNull); + assert(block.get.size > 0); +} + @("sending legacy tx") unittest { diff --git a/source/deth/util/types.d b/source/deth/util/types.d index ec3441c..88282f6 100644 --- a/source/deth/util/types.d +++ b/source/deth/util/types.d @@ -124,6 +124,46 @@ To convTo(To, _From)(const _From f) @safe pure } static if (is(From == JSONValue)) { + static if (is(To == BlockResponse)) + { + BlockResponse blk; + () @trusted { + if (!f[`number`].isNull) + blk.number = f[`number`].str[2 .. $].to!ulong(16); + if (!f[`hash`].isNull) + blk.hash = f[`hash`].str[2 .. $].convTo!Hash; + if (!f[`parentHash`].isNull) + blk.parentHash = f[`parentHash`].str[2 .. $].convTo!Hash; + blk.nonce = f[`nonce`].str[2 .. $].to!ulong(16); + blk.sha3Uncles = f[`sha3Uncles`].str[2 .. $].convTo!Hash; + if (!f[`logsBloom`].isNull) + blk.logsBloom = f[`logsBloom`].str[2 .. $].hexToBytes; + blk.transactionsRoot = f[`transactionsRoot`].str[2 .. $].convTo!Hash; + blk.stateRoot = f[`stateRoot`].str[2 .. $].convTo!Hash; + blk.receiptsRoot = f[`receiptsRoot`].str[2 .. $].convTo!Hash; + blk.miner = f[`miner`].str[2 .. $].convTo!Address; + if (const difficulty = `difficulty` in f) + blk.difficulty = difficulty.str.BigInt; + if (const totalDifficulty = `totalDifficulty` in f) + blk.totalDifficulty = totalDifficulty.str.BigInt; + blk.extraData = f[`extraData`].str[2 .. $].hexToBytes; + blk.size = f[`size`].str[2 .. $].to!ulong(16); + blk.gasLimit = f[`gasLimit`].str.BigInt; + blk.gasUsed = f[`gasUsed`].str.BigInt; + blk.timestamp = f[`timestamp`].str.BigInt; + blk.transactions = new bytes[f[`transactions`].array.length]; + foreach (i, transaction; f[`transactions`].array) + { + blk.transactions[i] = transaction.str[2 .. $].hexToBytes; + } + blk.uncles = new Hash[f[`uncles`].array.length]; + foreach (i, uncleHash; f[`uncles`].array) + { + blk.uncles[i] = uncleHash.str[2 .. $].convTo!Hash; + } + }(); + return blk; + } static if (is(To == TransactionReceipt)) { TransactionReceipt tx; @@ -279,6 +319,29 @@ unittest assert(t.ox == "0xaaaa"); } +struct BlockResponse +{ + Nullable!ulong number; + Nullable!Hash hash; + Nullable!Hash parentHash; + ulong nonce; + Hash sha3Uncles; + Nullable!bytes logsBloom; + Hash transactionsRoot; + Hash stateRoot; + Hash receiptsRoot; + Address miner; + BigInt difficulty; + BigInt totalDifficulty; + bytes extraData; + ulong size; + BigInt gasLimit; + BigInt gasUsed; + BigInt timestamp; + bytes[] transactions; + Hash[] uncles; +} + struct TransactionReceipt { Hash transactionHash; // DATA, 32 Bytes - hash of the transaction.