diff --git a/api/server.go b/api/server.go index bb2f57436..4814498d1 100644 --- a/api/server.go +++ b/api/server.go @@ -53,7 +53,9 @@ type httpServer struct { } const ( - shutdownTimeout = 5 * time.Second + shutdownTimeout = 5 * time.Second + batchRequestLimit = 5 + batchResponseMaxSize = 5 * 1000 * 1000 // 5 MB ) func NewHTTPServer(logger zerolog.Logger, cfg *config.Config) *httpServer { @@ -107,6 +109,7 @@ func (h *httpServer) EnableRPC(apis []rpc.API) error { // Create RPC server and handler. srv := rpc.NewServer() + srv.SetBatchLimits(batchRequestLimit, batchResponseMaxSize) // Register all the APIs exposed by the services for _, api := range apis { diff --git a/tests/web3js/eth_non_interactive_test.js b/tests/web3js/eth_non_interactive_test.js index 7dffb1fb4..0a9b9b7e6 100644 --- a/tests/web3js/eth_non_interactive_test.js +++ b/tests/web3js/eth_non_interactive_test.js @@ -3,7 +3,7 @@ const { assert } = require('chai') const conf = require('./config') const web3 = conf.web3 -it('get chain ID', async() => { +it('get chain ID', async () => { let chainID = await web3.eth.getChainId() assert.isDefined(chainID) assert.equal(chainID, 646n) @@ -43,7 +43,7 @@ it('get block', async () => { assert.isNull(no) }) -it('get balance', async() => { +it('get balance', async () => { let wei = await web3.eth.getBalance(conf.eoa.address) assert.isNotNull(wei) @@ -54,22 +54,22 @@ it('get balance', async() => { assert.equal(wei, weiAtBlock) }) -it('get code', async() => { +it('get code', async () => { let code = await web3.eth.getCode(conf.eoa.address) assert.equal(code, "0x") // empty }) -it('get coinbase', async() => { +it('get coinbase', async () => { let coinbase = await web3.eth.getCoinbase() assert.equal(coinbase, conf.serviceEOA) // e2e configured account }) -it('get gas price', async() => { +it('get gas price', async () => { let gasPrice = await web3.eth.getGasPrice() assert.equal(gasPrice, 0n) // 0 by default in tests }) -it('get transaction', async() => { +it('get transaction', async () => { let blockTx = await web3.eth.getTransactionFromBlock(conf.startBlockHeight, 0) assert.isNotNull(blockTx) @@ -95,12 +95,12 @@ it('get transaction', async() => { assert.equal(rcp.gasUsed, tx.gas) }) -it('get mining status', async() => { +it('get mining status', async () => { let mining = await web3.eth.isMining() assert.isFalse(mining) }) -it('get syncing status', async() => { +it('get syncing status', async () => { let height = await web3.eth.getBlockNumber() assert.equal(height, conf.startBlockHeight) @@ -110,3 +110,87 @@ it('get syncing status', async() => { assert.equal(syncInfo.currentBlock, height) assert.equal(syncInfo.highestBlock, height) }) + +it('can make batch requests', async () => { + let batch = new web3.BatchRequest() + let getBlockNumber = { + jsonrpc: '2.0', + id: 1, + method: 'eth_blockNumber', + params: [], + } + let getChainId = { + jsonrpc: '2.0', + id: 2, + method: 'eth_chainId', + params: [], + } + let getSyncing = { + jsonrpc: '2.0', + id: 3, + method: 'eth_syncing', + params: [], + } + let getNetVersion = { + jsonrpc: '2.0', + id: 4, + method: 'net_version', + params: [], + } + let getBlockTransactionCount = { + jsonrpc: '2.0', + id: 5, + method: 'eth_getBlockTransactionCountByNumber', + params: ['0x2'], + } + + batch.add(getBlockNumber) + batch.add(getChainId) + batch.add(getSyncing) + batch.add(getNetVersion) + batch.add(getBlockTransactionCount) + + let results = await batch.execute() + + assert.deepEqual( + results[0], + { jsonrpc: '2.0', id: 1, result: '0x3' } + ) + assert.deepEqual( + results[1], + { jsonrpc: '2.0', id: 2, result: '0x286' } + ) + assert.deepEqual( + results[2], + { + jsonrpc: '2.0', + id: 3, + result: { startingBlock: '0x3', currentBlock: '0x3', highestBlock: '0x3' } + } + ) + assert.deepEqual( + results[3], + { jsonrpc: '2.0', id: 4, result: '545' } + ) + assert.deepEqual( + results[4], + { jsonrpc: '2.0', id: 5, result: '0x1' } + ) + + // The maximum number of batch requests is 5, + // so this next batch should fail. + let getTransactionCount = { + jsonrpc: '2.0', + id: 6, + method: 'eth_getTransactionCount', + params: ['0x658Bdf435d810C91414eC09147DAA6DB62406379', 'latest'], + } + + batch.add(getTransactionCount) + + try { + results = await batch.execute() + } catch (error) { + assert.equal(error.innerError[0].message, 'batch too large') + } +})