├── .gitignore ├── .gitmodules ├── Makefile ├── README.md ├── RPCTestContract.sol ├── lib ├── config.js ├── getIpcPath.js ├── helpers.js └── ipcProvider.js ├── package.json └── test ├── 1_testConnection.js ├── RPC_Batch_call.js ├── db_getHex.js ├── db_getString.js ├── db_putHex.js ├── db_putString.js ├── eth_accounts.js ├── eth_blockNumber.js ├── eth_call.js ├── eth_coinbase.js ├── eth_gasPrice.js ├── eth_getBalance.js ├── eth_getBlockBy.js ├── eth_getBlockTransactionCountByHash.js ├── eth_getBlockTransactionCountByNumber.js ├── eth_getCode.js ├── eth_getCompilers.js ├── eth_getFilterChanges.js ├── eth_getFilterLogs.js ├── eth_getFilterLogsEx.js_ ├── eth_getFilterLogs_fromExFilter.js_ ├── eth_getStorageAt.js ├── eth_getTransactionBy.js ├── eth_getTransactionCount.js ├── eth_getTransactionReceipt.js ├── eth_getUncleBy.js ├── eth_getUncleCountByBlockHash.js ├── eth_getUncleCountByBlockNumber.js ├── eth_mining.js ├── eth_newBlockFilter.js ├── eth_newFilter.js ├── eth_newPendingTransactionFilter.js ├── eth_protocolVersion.js ├── eth_uninstallFilter.js ├── mocha.opts ├── net_listening.js ├── net_peerCount.js ├── net_version.js ├── shh_hasIdentity.js ├── shh_newFilter.js ├── shh_newIdentity.js ├── shh_uninstallFilter.js ├── shh_version.js ├── web3_clientVersion.js └── web3_sha3.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | *.swp 3 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "lib/tests"] 2 | path = lib/tests 3 | url = https://github.com/ethereum/tests 4 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | REPORTER = dot 2 | 3 | MOCHA = @./node_modules/mocha/bin/mocha --reporter $(REPORTER) 4 | 5 | test: 6 | $(MOCHA) test/*.js 7 | 8 | test.eth: 9 | $(MOCHA) test/1_testConnection.js test/eth_*.js 10 | 11 | test.shh: 12 | $(MOCHA) test/1_testConnection.js test/shh_*.js 13 | 14 | test.net: 15 | $(MOCHA) test/1_testConnection.js test/net_*.js 16 | 17 | test.ipc: 18 | $(MOCHA) test/*.js --ipc 19 | 20 | test.eth.ipc: 21 | $(MOCHA) test/1_testConnection.js test/eth_*.js --ipc 22 | 23 | test.shh.ipc: 24 | $(MOCHA) test/1_testConnection.js test/shh_*.js --ipc 25 | 26 | test.net.ipc: 27 | $(MOCHA) test/1_testConnection.js test/net_*.js --ipc 28 | 29 | 30 | .PHONY: test 31 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Ethereum RPC tests 2 | 3 | 4 | Untested: 5 | 6 | - eth_sendTransaction 7 | - eth_compileSolidity 8 | - eth_getFilterChanges 9 | - eth_getWork 10 | - eth_submitWork 11 | - shh_post 12 | - shh_newGroup 13 | - shh_addToGroup 14 | - shh_getFilterChanges 15 | - shh_getMessages 16 | 17 | A note on tests: everything in the pending state or which requires newly created logs or transcations can't be tested, as the fixed blockchain is not mining. 18 | 19 | 20 | ## Usage 21 | 22 | 1. clone `$ git clone https://github.com/ethereum/rpc-tests` 23 | 2. `$ cd rpc-tests` 24 | 3. `$ git submodule update --init` 25 | 4. `$ npm install` 26 | 5. start a local CPP node at `http://localhost:8080` and local GO node at `http://localhost:8545` 27 | 6. The nodes need the following state to work: https://github.com/ethereum/tests/blob/develop/BlockchainTests/bcRPC_API_Test.json 28 | 29 | **NOTE** If you run the tests make sure you update the `lib/tests` submodule as well as the `tests` repository, which you use to load the blockchain state so that both are in the same state. 30 | 31 | ### Running the tests 32 | 33 | To run the tests start the node(s) at the ports described in `lib/config.js` (See [Start a node with a certain state](#start-a-node-with-a-certain-state)) and run: 34 | 35 | $ make test 36 | 37 | **NOTE** you need to restart and reload the blocktests in the nodes, so that all pending and mined transactions get cleared from the test chain. 38 | 39 | ### Running test only for specific protocols 40 | 41 | You can also run only tests for `eth_`, `shh_` or `net_` RPC methods as follows: 42 | 43 | $ make test.eth 44 | $ make test.shh 45 | $ make test.net 46 | 47 | If you don't want to run the tests against all nodes, or run against remote nodes, just change the `hosts` in the `lib/config.js`. 48 | 49 | 50 | ### Running over an IPC connection 51 | 52 | To test using the IPC connection, your node needs to run on the default IPC path. Then start with the following: 53 | 54 | $ make test.ipc 55 | $ make test.eth.ipc 56 | $ make test.shh.ipc 57 | $ make test.net.ipc 58 | 59 | ### Running single tests 60 | 61 | To run a single test you need to install mocha globally: 62 | 63 | ```bash 64 | $ npm install -g mocha 65 | $ cd rpc-tests 66 | $ mocha test/1_testConnection.js test/eth_myMethod.js 67 | # add --ipc when you want to use the IPC connection 68 | $ mocha test/1_testConnection.js test/eth_myMethod.js --ipc 69 | ``` 70 | 71 | By changing the last file name to whatever method you want to test, you can run test only for that specifc method. 72 | 73 | ### Start a node with a certain state 74 | 75 | To load a fixed state, clone the ethereum test repo as follows: 76 | 77 | $ git clone https://github.com/ethereum/tests 78 | 79 | #### Go 80 | 81 | Run the following go cli command to load the `RPC_API_Test` test: 82 | 83 | $ gethrpctest --json /lib/tests/BlockchainTests/bcRPC_API_Test.json --test RPC_API_Test 84 | 85 | #### C++ 86 | 87 | Run the following c++ cli command to load the `RPC_API_Test` test: 88 | 89 | $ ethrpctest --json /lib/tests/BlockchainTests/bcRPC_API_Test.json --test RPC_API_Test 90 | 91 | #### Python 92 | 93 | Run the following python cli command to load the `RPC_API_Test` test: 94 | 95 | $ pyethapp -l :info,eth.chainservice:debug,jsonrpc:debug -c jsonrpc.listen_port=8081 -c p2p.max_peers=0 -c p2p.min_peers=0 blocktest /lib/tests/BlockchainTests/bcRPC_API_Test.json RPC_API_Test 96 | 97 | For also testing/using ipc, use the the following command: 98 | 99 | $ pyethapp -l :info,eth.chainservice:debug,jsonrpc:debug -c jsonrpc.listen_port=8081 -c p2p.max_peers=0 -c p2p.min_peers=0 -c ipc.ipcpath=$HOME/.ethereum/geth.ipc blocktest /lib/tests/BlockchainTests/bcRPC_API_Test.json RPC_API_Test 100 | 101 | ## License 102 | 103 | The MIT License 104 | 105 | Copyright (c) 2015 Fabian Vogelsteller 106 | 107 | Permission is hereby granted, free of charge, to any person obtaining 108 | a copy of this software and associated documentation files (the 109 | 'Software'), to deal in the Software without restriction, including 110 | without limitation the rights to use, copy, modify, merge, publish, 111 | distribute, sublicense, and/or sell copies of the Software, and to 112 | permit persons to whom the Software is furnished to do so, subject to 113 | the following conditions: 114 | 115 | The above copyright notice and this permission notice shall be 116 | included in all copies or substantial portions of the Software. 117 | 118 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 119 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 120 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 121 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 122 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 123 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 124 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 125 | -------------------------------------------------------------------------------- /RPCTestContract.sol: -------------------------------------------------------------------------------- 1 | contract JSON_Test { 2 | event Log0(uint value); 3 | event Log0Anonym (uint value) anonymous; 4 | event Log1(bool indexed aBool, uint value); 5 | event Log1Anonym(bool indexed aBool, uint value) anonymous; 6 | event Log2(bool indexed aBool, address indexed aAddress, uint value); 7 | event Log2Anonym(bool indexed aBool, address indexed aAddress, uint value) anonymous; 8 | event Log3(bool indexed aBool, address indexed aAddress, bytes32 indexed aBytes32, uint value); 9 | event Log3Anonym(bool indexed aBool, address indexed aAddress, bytes32 indexed aBytes32, uint value) anonymous; 10 | event Log4(bool indexed aBool, address indexed aAddress, bytes32 indexed aBytes32, int8 aInt8, uint value); 11 | event Log4Anonym(bool indexed aBool, address indexed aAddress, bytes32 indexed aBytes32, int8 aInt8, uint value) anonymous; 12 | 13 | function JSON_Test() { 14 | 15 | } 16 | 17 | function setBool(bool _bool) { 18 | myBool = _bool; 19 | } 20 | 21 | function setInt8(int8 _int8) { 22 | myInt8 = _int8; 23 | } 24 | 25 | function setUint8(uint8 _uint8) { 26 | myUint8 = _uint8; 27 | } 28 | 29 | function setInt256(int256 _int256) { 30 | myInt256 = _int256; 31 | } 32 | 33 | function setUint256(uint256 _uint256) { 34 | myUint256 = _uint256; 35 | } 36 | 37 | function setAddress(address _address) { 38 | myAddress = _address; 39 | } 40 | 41 | //function setBytes0(bytes0 _bytes0) { 42 | // myBytes0 = _bytes0; 43 | //} 44 | 45 | function setBytes32(bytes32 _bytes32) { 46 | myBytes32 = _bytes32; 47 | } 48 | 49 | function getBool() returns (bool ret) { 50 | return myBool; 51 | } 52 | 53 | function getInt8() returns (int8 ret) { 54 | return myInt8; 55 | } 56 | 57 | function getUint8() returns (uint8 ret) { 58 | return myUint8; 59 | } 60 | 61 | function getInt256() returns (int256 ret) { 62 | return myInt256; 63 | } 64 | 65 | function getUint256() returns (uint256 ret) { 66 | return myUint256; 67 | } 68 | 69 | function getAddress() returns (address ret) { 70 | return myAddress; 71 | } 72 | 73 | //function getBytes0() returns (bytes0 ret) { 74 | // return myBytes0; 75 | //} 76 | 77 | function getBytes32() returns (bytes32 ret) { 78 | return myBytes32; 79 | } 80 | 81 | function fireEventLog0() { 82 | Log0(42); 83 | } 84 | 85 | function fireEventLog0Anonym() { 86 | Log0Anonym(42); 87 | } 88 | 89 | function fireEventLog1() { 90 | Log1(true, 42); 91 | } 92 | 93 | function fireEventLog1Anonym() { 94 | Log1Anonym(true, 42); 95 | } 96 | 97 | function fireEventLog2() { 98 | Log2(true, msg.sender, 42); 99 | } 100 | 101 | function fireEventLog2Anonym() { 102 | Log2Anonym(true, msg.sender, 42); 103 | } 104 | 105 | function fireEventLog3() { 106 | Log3(true, msg.sender, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 42); 107 | } 108 | 109 | function fireEventLog3Anonym() { 110 | Log3Anonym(true, msg.sender, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 42); 111 | } 112 | 113 | function fireEventLog4() { 114 | Log4(true, msg.sender, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -23, 42); 115 | } 116 | 117 | function fireEventLog4Anonym() { 118 | Log4Anonym(true, msg.sender, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -23, 42); 119 | } 120 | 121 | bool myBool; 122 | int8 myInt8; 123 | uint8 myUint8; 124 | int256 myInt256; 125 | uint256 myUint256; 126 | address myAddress; 127 | //bytes0 myBytes0; 128 | bytes32 myBytes32; 129 | 130 | } 131 | -------------------------------------------------------------------------------- /lib/config.js: -------------------------------------------------------------------------------- 1 | var assert = require('chai').assert, 2 | _ = require('underscore'), 3 | getIpcPath = require('./getIpcPath.js'); 4 | // var chai = require('chai'); 5 | // chai.config.includeStack = false; 6 | // chai.config.showDiff = false; 7 | 8 | var config = { 9 | rpcMessageId: 1, 10 | hosts: { 11 | cpp: 'http://localhost:8080', 12 | python: 'http://localhost:8081', 13 | go: 'http://localhost:8545', 14 | ipc: getIpcPath(), 15 | }, 16 | testBlocks: require('./tests/BlockchainTests/bcRPC_API_Test.json').RPC_API_Test, 17 | senderAddress: '0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b', 18 | contractAddress: '0x6295ee1b4f6dd65047762f924ecd367c17eabf8f', 19 | compiledTestContract: '0xf90942f901faa002aa46ee7e8a588ecb36ae05a225f442a4410e7dca91b4e2e8fa351148a418c5a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a06d030caaafd4575d820b495c72c2471cd427c1f314e675045227d1646ef862f1a00337bf35b741bf9be4594a78cbdcd220d7736eb452c9711343637f75508d73a7a0843716b02b7b22c1c8beb74a8ce2421471f9f35bccaf454b06ca1a6e796dee52b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000001832fefd8830767eb84552ce19880a0e7c0ac40e41e32853cd7fd612fce5c5d199515fcb0f41182817a7ecdf57cadf588648151f718824fd6f90741f9073e8001832fefd8800ab906f05b5b6106e0806100106000396000f3006000357c010000000000000000000000000000000000000000000000000000000090048063102accc11461012c57806312a7b9141461013a5780631774e6461461014c5780631e26fd331461015d5780631f9030371461016e578063343a875d1461018057806338cc4831146101955780634e7ad367146101bd57806357cb2fc4146101cb57806365538c73146101e057806368895979146101ee57806376bc21d9146102005780639a19a9531461020e5780639dc2c8f51461021f578063a53b1c1e1461022d578063a67808571461023e578063b61c05031461024c578063c2b12a731461025a578063d2282dc51461026b578063e30081a01461027c578063e8beef5b1461028d578063f38b06001461029b578063f5b53e17146102a9578063fd408767146102bb57005b6101346104b1565b60006000f35b610142610376565b8060005260206000f35b610157600435610301565b60006000f35b6101686004356102c9565b60006000f35b61017661041d565b8060005260206000f35b6101886103ae565b8060ff1660005260206000f35b61019d6103ee565b8073ffffffffffffffffffffffffffffffffffffffff1660005260206000f35b6101c56104a0565b60006000f35b6101d3610392565b8060000b60005260206000f35b6101e861042f565b60006000f35b6101f66103dc565b8060005260206000f35b6102086104fa565b60006000f35b6102196004356102e5565b60006000f35b61022761066e565b60006000f35b61023860043561031d565b60006000f35b61024661045f565b60006000f35b61025461046e565b60006000f35b610265600435610368565b60006000f35b61027660043561032b565b60006000f35b610287600435610339565b60006000f35b61029561058f565b60006000f35b6102a3610522565b60006000f35b6102b16103ca565b8060005260206000f35b6102c36105db565b60006000f35b80600060006101000a81548160ff021916908302179055505b50565b80600060016101000a81548160ff021916908302179055505b50565b80600060026101000a81548160ff021916908302179055505b50565b806001600050819055505b50565b806002600050819055505b50565b80600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908302179055505b50565b806004600050819055505b50565b6000600060009054906101000a900460ff16905061038f565b90565b6000600060019054906101000a900460ff1690506103ab565b90565b6000600060029054906101000a900460ff1690506103c7565b90565b600060016000505490506103d9565b90565b600060026000505490506103eb565b90565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905061041a565b90565b6000600460005054905061042c565b90565b7f65c9ac8011e286e89d02a269890f41d67ca2cc597b2c76c7c69321ff492be5806000602a81526020016000a15b565b6000602a81526020016000a05b565b60017f81933b308056e7e85668661dcd102b1f22795b4431f9cf4625794f381c271c6b6000602a81526020016000a25b565b60016000602a81526020016000a15b565b3373ffffffffffffffffffffffffffffffffffffffff1660017f0e216b62efbb97e751a2ce09f607048751720397ecfb9eef1e48a6644948985b6000602a81526020016000a35b565b3373ffffffffffffffffffffffffffffffffffffffff1660016000602a81526020016000a25b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001023373ffffffffffffffffffffffffffffffffffffffff1660017f317b31292193c2a4f561cc40a95ea0d97a2733f14af6d6d59522473e1f3ae65f6000602a81526020016000a45b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001023373ffffffffffffffffffffffffffffffffffffffff1660016000602a81526020016000a35b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001023373ffffffffffffffffffffffffffffffffffffffff1660017fd5f0a30e4be0c6be577a71eceb7464245a796a7e6a55c0d971837b250de05f4e60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe98152602001602a81526020016000a45b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001023373ffffffffffffffffffffffffffffffffffffffff16600160007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe98152602001602a81526020016000a35b561ca0f3ad419ce7510ae207aaa5aaefa0809d70e5dc2cc8eaae13918b5225631b9bfda0ed8214956dac9f349be703fe3a7c4061614066e5dc491047f66bbc71074d0f7cc0', 20 | logs: [{ 21 | eventName: "log4a", // for debug purposes only 22 | call: '0x9dc2c8f5', 23 | anonymous: true, 24 | indexArgs: [true, 'msg.sender', '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'], 25 | args: [-23, 42] 26 | },{ 27 | eventName: "log4", 28 | call: '0xfd408767', 29 | anonymous: false, 30 | indexArgs: [true, 'msg.sender', '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'], 31 | args: [-23, 42] 32 | },{ 33 | eventName: "log3a", 34 | call: '0xe8beef5b', 35 | anonymous: true, 36 | indexArgs: [true, 'msg.sender', '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'], 37 | args: [42] 38 | },{ 39 | eventName: "log3", 40 | call: '0xf38b0600', 41 | anonymous: false, 42 | indexArgs: [true, 'msg.sender', '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'], 43 | args: [42] 44 | },{ 45 | eventName: "log2a", 46 | call: '0x76bc21d9', 47 | anonymous: true, 48 | indexArgs: [true, 'msg.sender'], 49 | args: [42] 50 | },{ 51 | eventName: "log2", 52 | call: '0x102accc1', 53 | anonymous: false, 54 | indexArgs: [true, 'msg.sender'], 55 | args: [42] 56 | },{ 57 | eventName: "log1a", 58 | call: '0x4e7ad367', 59 | anonymous: true, 60 | indexArgs: [true], 61 | args: [42] 62 | },{ 63 | eventName: "log1", 64 | call: '0xb61c0503', 65 | anonymous: false, 66 | indexArgs: [true], 67 | args: [42] 68 | },{ 69 | eventName: "log0a", 70 | call: '0xa6780857', 71 | anonymous: true, 72 | indexArgs: [], 73 | args: [42] 74 | },{ 75 | eventName: "log0", 76 | call: '0x65538c73', 77 | anonymous: false, 78 | indexArgs: [], 79 | args: [42] 80 | }] 81 | }; 82 | 83 | // from the oldest to the newest! 84 | config.logs.reverse(); 85 | 86 | // add the log.block, log.tx and log.txIndex 87 | config.logs = _.map(config.logs, function(log){ 88 | var transaction = null, 89 | txIndex = null; 90 | log.block = _.find(config.testBlocks.blocks, function(block){ 91 | return _.find(block.transactions, function(tx, index){ 92 | if (tx.data === log.call){ 93 | transaction = tx; 94 | txIndex = index; 95 | return true; 96 | } else 97 | return false; 98 | }); 99 | }); 100 | log.tx = transaction; 101 | log.txIndex = txIndex; 102 | //console.log(log.eventName + " : " + log.block.blockHeader.hash); 103 | return log; 104 | }); 105 | 106 | // prepare test for querying forked blocks 107 | var reverted = config.testBlocks.blocks.filter(function (block) { 108 | return block.reverted === true; 109 | }); 110 | 111 | var decent = config.testBlocks.blocks.filter(function (block) { 112 | if (block.reverted === true) { 113 | return false; 114 | } 115 | 116 | return !!_.findWhere(reverted, { blocknumber: block.blocknumber}); 117 | }); 118 | 119 | // assuming there is only 1 fork 120 | config.specialLogQuery = { 121 | fromBlock: '0x' + _.last(reverted).blockHeader.hash, 122 | toBlock: '0x' + _.last(decent).blockHeader.hash 123 | }; 124 | 125 | var route = reverted.reverse().concat(decent); 126 | 127 | var specialLogs = _.map(route, function (block) { 128 | var tx = block.transactions[0]; 129 | var log = _.findWhere(config.logs, { call: tx.data}); 130 | log = _.extend({}, log); // copy it 131 | log.tx = tx; 132 | log.txIndex = 0; 133 | log.block = block; 134 | return log; 135 | }); 136 | 137 | config.specialLogResult = specialLogs; 138 | 139 | module.exports = config; 140 | 141 | -------------------------------------------------------------------------------- /lib/getIpcPath.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = function() { 3 | var p = require('path'); 4 | var path = process.env.HOME; 5 | 6 | if(process.platform === 'darwin') 7 | path += '/Library/Ethereum/geth.ipc'; 8 | 9 | if(process.platform === 'freebsd' || 10 | process.platform === 'linux' || 11 | process.platform === 'sunos') 12 | path += '/.ethereum/geth.ipc'; 13 | 14 | if(process.platform === 'win32') 15 | path = '\\\\.\\pipe\\geth.ipc'; 16 | 17 | console.log('CONNECT to IPC PATH: '+ path); 18 | return path; 19 | }; -------------------------------------------------------------------------------- /lib/helpers.js: -------------------------------------------------------------------------------- 1 | var config = require('../lib/config'), 2 | XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest, 3 | IpcProvider = require('./ipcProvider.js'), 4 | net = require('net'); 5 | _ = require('underscore'), 6 | BigNumber = require('bignumber.js'), 7 | assert = require('chai').assert; 8 | 9 | var useIpc = process.argv[process.argv.length-1] === '--ipc'; 10 | 11 | if(useIpc) { 12 | var ipcProvider = new IpcProvider(config.hosts.ipc, net); 13 | } 14 | 15 | var Helpers = { 16 | send: function(host, data, callback) { 17 | 18 | // IPC 19 | if(useIpc) { 20 | 21 | // ASYNC 22 | if(typeof callback === 'function') { 23 | 24 | ipcProvider.sendAsync(data, callback); 25 | 26 | // SYNC 27 | } else { 28 | return ipcProvider.send(data); 29 | } 30 | 31 | } else { 32 | 33 | var xhr = new XMLHttpRequest(); 34 | 35 | // ASYNC 36 | if(typeof callback === 'function') { 37 | xhr.onreadystatechange = function() { 38 | if(xhr.readyState === 4) { 39 | if(xhr.status === 200) { 40 | callback(JSON.parse(xhr.responseText), xhr.status); 41 | } else { 42 | // remove offline host from config 43 | throw new Error('Can\'t connect to '+ host + "\n Send: "+ JSON.stringify(data, null, 2)); 44 | } 45 | } 46 | }; 47 | 48 | xhr.open('POST', host, true); 49 | xhr.send(JSON.stringify(data)); 50 | 51 | // SYNC 52 | } else { 53 | xhr.open('POST', host, false); 54 | xhr.send(JSON.stringify(data)); 55 | 56 | if(xhr.readyState === 4 && xhr.status !== 200) { 57 | throw new Error('Can\'t connect to '+ host + "\n Send: "+ JSON.stringify(data, null, 2)); 58 | } 59 | 60 | return JSON.parse(xhr.responseText); 61 | } 62 | } 63 | 64 | }, 65 | eachHost: function(callback){ 66 | for (var key in config.hosts) { 67 | (function(key){ 68 | callback(key.toUpperCase(), config.hosts[key]); 69 | })(key); 70 | } 71 | }, 72 | getKeyByValue: function(object, value) { 73 | for( var prop in object ) { 74 | if( object.hasOwnProperty( prop ) ) { 75 | if( object[ prop ] === value ) 76 | return prop; 77 | } 78 | } 79 | }, 80 | getBlockByNumber: function(number){ 81 | return _.find(config.testBlocks.blocks, function(bl){ 82 | return (bl.blockHeader.number == number) ? bl : false; 83 | }); 84 | }, 85 | fromDecimal: function(number){ 86 | return '0x' + new BigNumber((number).toString(10),10).toString(16); 87 | }, 88 | fromAscii: function(str) { 89 | var hex = ""; 90 | for(var i = 0; i < str.length; i++) { 91 | var n = str.charCodeAt(i).toString(16); 92 | hex += n.length < 2 ? '0' + n : n; 93 | } 94 | 95 | return '0x'+ hex; 96 | }, 97 | toAscii: function(hex) { 98 | // Find termination 99 | var str = ""; 100 | var i = 0, l = hex.length; 101 | if (hex.substring(0, 2) === '0x') { 102 | i = 2; 103 | } 104 | for (; i < l; i+=2) { 105 | var code = parseInt(hex.substr(i, 2), 16); 106 | if (code === 0) { 107 | break; 108 | } 109 | 110 | str += String.fromCharCode(code); 111 | } 112 | 113 | return str; 114 | }, 115 | padLeft: function (string, chars) { 116 | string = string.replace('0x',''); 117 | return '0x'+ new Array(chars - string.length + 1).join("0") + string; 118 | }, 119 | // toDecimal: function (value) { 120 | // return toBigNumber(value).toNumber(); 121 | // }, 122 | isAddress: function(address) { 123 | if (!_.isString(address)) { 124 | return false; 125 | } 126 | 127 | return (/^[x0-9a-f]{0,42}$/i.test(address) && (address.length === 42|| address.length === 40)); 128 | }, 129 | 130 | // TESTS 131 | blockTest: function(result, blockHeader){ 132 | assert.strictEqual(+result.number, +blockHeader.number, 'block number should be ' + (+blockHeader.number)); 133 | assert.strictEqual(result.hash, '0x'+ blockHeader.hash, 'blockHash should be 0x' + blockHeader.hash); 134 | assert.strictEqual(result.parentHash, '0x'+ blockHeader.parentHash, 'parentHash should be 0x' + blockHeader.parentHash); 135 | assert.strictEqual(result.nonce, '0x'+ blockHeader.nonce, 'block nonce should be ' + (+blockHeader.nonce)); 136 | assert.strictEqual(result.sha3Uncles, '0x'+ blockHeader.uncleHash, 'uncleHash should be 0x' + blockHeader.uncleHash); 137 | assert.strictEqual(result.logsBloom, '0x'+ blockHeader.bloom, 'bloom should be 0x' + blockHeader.bloom); 138 | assert.strictEqual(result.transactionsRoot, '0x'+ blockHeader.transactionsTrie, 'transactionsRoot should be 0x' + blockHeader.transactionsTrie); 139 | assert.strictEqual(result.stateRoot, '0x'+ blockHeader.stateRoot, 'stateRoot should be ' + blockHeader.stateRoot); 140 | assert.strictEqual(result.miner, '0x'+ blockHeader.coinbase, 'miner should be 0x' + blockHeader.coinbase); 141 | assert.strictEqual(+result.difficulty, +blockHeader.difficulty, 'difficulty should be ' + blockHeader.difficulty); 142 | assert.strictEqual(result.extraData, blockHeader.extraData, 'extraData should be ' + blockHeader.extraData); 143 | assert.strictEqual(+result.gasLimit, +blockHeader.gasLimit, 'gasLimit should be ' + (+blockHeader.gasLimit)); 144 | assert.strictEqual(+result.gasUsed, +blockHeader.gasUsed, 'gasUsed should be ' + (+blockHeader.gasUsed)); 145 | assert.strictEqual(+result.timestamp, +blockHeader.timestamp, 'timestamp should be ' + (+blockHeader.timestamp)); 146 | assert.isNumber(+result.size, 'size should be a number'); 147 | assert.isNumber(+result.totalDifficulty, 'totalDifficulty should be a number'); 148 | }, 149 | transactionTest: function(result, tx, index, block){ 150 | 151 | assert.strictEqual(result.blockHash, '0x'+ block.blockHeader.hash, 'transaction blockHash should be 0x' + block.blockHeader.hash); 152 | assert.strictEqual(+result.blockNumber, +block.blockHeader.number, 'transaction block number should be ' + (+block.blockHeader.number)); 153 | 154 | assert.strictEqual(+result.transactionIndex, index, 'transactionIndex should be ' + index); 155 | assert.match(result.hash, /^0x/, 'transaction hash should start with 0x'); 156 | assert.strictEqual(+result.nonce, +tx.nonce, 'transaction nonce should be ' + (+tx.nonce)); 157 | assert.strictEqual(+result.gas, +tx.gasLimit, 'transaction gasLimit should be ' + (+tx.gasLimit)); 158 | assert.strictEqual(+result.gasPrice, +tx.gasPrice, 'transaction gasPrice should be ' + (+tx.gasPrice)); 159 | assert.strictEqual(+result.value, +tx.value, 'transaction value should be ' + (+tx.value)); 160 | assert.strictEqual(result.input, tx.data, 'transaction data should be ' + (+tx.data)); 161 | assert.match(result.from, /^0x/, 'transaction from should be an address'); 162 | 163 | if(!result.to) 164 | assert.isNull(result.to, 'transaction to should be null in an contract creation transaction'); 165 | else 166 | assert.strictEqual(result.to, '0x'+ tx.to, 'transaction to should be 0x'+ tx.to); 167 | 168 | }, 169 | transactionReceiptTest: function(result, tx, index, block){ 170 | 171 | assert.strictEqual(result.blockHash, '0x'+ block.blockHeader.hash, 'transaction blockHash should be 0x' + block.blockHeader.hash); 172 | assert.strictEqual(+result.blockNumber, +block.blockHeader.number, 'transaction block number should be ' + (+block.blockHeader.number)); 173 | 174 | assert.strictEqual(+result.transactionIndex, index, 'transactionIndex should be ' + index); 175 | assert.isNumber(+result.cumulativeGasUsed, 'cumulativeGasUsed is a number'); 176 | assert.isNumber(+result.gasUsed, 'gasUsed is a number'); 177 | if(result.contractAddress) 178 | assert.isTrue(Helpers.isAddress(result.contractAddress)); 179 | 180 | assert.isArray(result.logs); 181 | 182 | 183 | if(result.logs.length) { 184 | assert.strictEqual(result.logs.length, 1 ,'should contain one log'); 185 | 186 | log = _.find(config.logs, function(log){ 187 | return ('0x'+ log.block.blockHeader.hash === tx.blockHash || log.call === tx.data); 188 | }); 189 | 190 | // if(tx.data === '0x4e7ad367') 191 | // console.log('TXXX',tx) 192 | 193 | // try { 194 | 195 | Helpers.logTest(result.logs[0], log); 196 | // } catch(e) { 197 | 198 | // console.log('TX',tx) 199 | // } 200 | 201 | // console.log('LOG received:',result.logs) 202 | // console.log('LOG', log); 203 | } 204 | }, 205 | /** 206 | Tests a log based on an "logInfo" given. 207 | The logs are based on the RPCTestContract.sol logs. 208 | 209 | 210 | @param {Object} logInfo contains the calling code and its expected arguments: 211 | 212 | { 213 | call: '0x9dc2c8f5', 214 | anonymous: true, 215 | indexArgs: [true, 'msg.sender', '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', -23], 216 | args: [42] 217 | } 218 | 219 | */ 220 | logTest: function(result, logInfo){ 221 | 222 | assert.isNumber(+result.logIndex, 'logIndex should be a number'); 223 | assert.strictEqual(+result.transactionIndex, logInfo.txIndex, 'transactionIndex should be ' + logInfo.txIndex); 224 | assert.match(result.transactionHash, /^0x/, 'transactionHash should start with 0x'); 225 | assert.isAbove(result.transactionHash.length, 19, 'transactionHash should be not just "0x"'); 226 | 227 | // if there was a fork 228 | if(result.blockHash !== '0x'+ logInfo.block.blockHeader.hash) { 229 | assert.match(result.blockHash, /^0x/, 'log blockHash should start with 0x'); 230 | assert.strictEqual(result.blockHash.length, 66, 'log blockHash should be 32bytes'); 231 | assert.isNumber(+result.blockNumber, 'log block number should be a number'); 232 | 233 | } else { 234 | assert.strictEqual(result.blockHash, '0x'+ logInfo.block.blockHeader.hash, 'log blockHash should be 0x' + logInfo.block.blockHeader.hash); 235 | assert.strictEqual(+result.blockNumber, +logInfo.block.blockHeader.number, 'log block number should be ' + (+logInfo.block.blockHeader.number)); 236 | } 237 | assert.strictEqual(result.address, '0x'+ logInfo.tx.to, 'log address should 0x'+ logInfo.tx.to); 238 | assert.isArray(result.topics); 239 | assert.match(result.data, /^0x/, 'log data should start with 0x'); 240 | if(logInfo.block.reverted && !_.isUndefined(result.polarity)) 241 | assert.equal(!result.polarity, !!logInfo.block.reverted); 242 | 243 | if(!logInfo.anonymous) { 244 | assert.include(config.compiledTestContract, result.topics[0].replace('0x',''), 'the topic signature should be in the compiled code'); 245 | // and then remove the signature from the topics 246 | result.topics.shift(); 247 | } 248 | 249 | // test non-indexed params 250 | var data = (result.data.length <= 66) ? [result.data] : [result.data.slice(0,66), '0x'+ result.data.slice(66)]; 251 | _.each(logInfo.args, function(arg, index){ 252 | if(arg > 0) 253 | assert.strictEqual(+data[index], arg, 'log data should be a positive number'); 254 | else 255 | assert.strictEqual(new BigNumber(data[index], 16).minus(new BigNumber('ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', 16)).minus(1).toNumber(), arg, 'log data should be a negative number'); 256 | }); 257 | 258 | // test index args 259 | _.each(logInfo.indexArgs, function(arg, index){ 260 | if(arg === true) { 261 | assert.strictEqual(Boolean(result.topics[index]), arg, 'should be TRUE'); 262 | } 263 | else if(arg === 'msg.sender') { 264 | assert.isObject(_.find(config.testBlocks.postState, function(value, key){ return key === result.topics[index].slice(26); }), 'should be a existing address in the "postState"'); 265 | } else { 266 | assert.strictEqual(result.topics[index], arg, 'log topic should match '+ arg); 267 | } 268 | }); 269 | }, 270 | 271 | logExTest: function (result, logInfo) { 272 | assert.strictEqual(result.blockHash, '0x'+ logInfo.block.blockHeader.hash, 'transaction blockHash should be 0x' + logInfo.block.blockHeader.hash); 273 | assert.strictEqual(+result.blockNumber, +logInfo.block.blockHeader.number, 'transaction block number should be ' + (+logInfo.block.blockHeader.number)); 274 | assert.equal(!result.polarity, !!logInfo.block.reverted); 275 | assert.isArray(result.logs); 276 | var log = result.logs[0] 277 | // there is only one log in each block in tests 278 | if (log) { 279 | assert.isNumber(+log.logIndex, 'logIndex should be a number'); 280 | assert.strictEqual(+log.transactionIndex, logInfo.txIndex, 'transactionIndex should be ' + logInfo.txIndex); 281 | assert.match(log.transactionHash, /^0x/, 'transactionHash should start with 0x'); 282 | assert.match(log.data, /^0x/, 'log data should start with 0x'); 283 | assert.isArray(log.topics); 284 | } 285 | 286 | } 287 | }; 288 | 289 | 290 | module.exports = Helpers; 291 | -------------------------------------------------------------------------------- /lib/ipcProvider.js: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of web3.js. 3 | 4 | web3.js is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | web3.js is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public License 15 | along with web3.js. If not, see . 16 | */ 17 | /** @file ipcprovider.js 18 | * @authors: 19 | * Fabian Vogelsteller 20 | * @date 2015 21 | */ 22 | 23 | "use strict"; 24 | 25 | 26 | var IpcProvider = function (path, net) { 27 | var _this = this; 28 | this.responseCallbacks = {}; 29 | this.path = path; 30 | 31 | this.connection = net.connect({path: this.path}); 32 | 33 | this.connection.on('error', function(e){ 34 | console.error('IPC Connection Error', e); 35 | _this._timeout(); 36 | }); 37 | 38 | this.connection.on('end', function(){ 39 | _this._timeout(); 40 | }); 41 | 42 | 43 | // LISTEN FOR CONNECTION RESPONSES 44 | this.connection.on('data', function(data) { 45 | /*jshint maxcomplexity: 6 */ 46 | 47 | _this._parseResponse(data.toString()).forEach(function(result){ 48 | 49 | var id = null; 50 | 51 | // get the id which matches the returned id 52 | if(result instanceof Array) { 53 | result.forEach(function(load){ 54 | if(_this.responseCallbacks[load.id]) 55 | id = load.id; 56 | }); 57 | } else { 58 | id = result.id; 59 | } 60 | 61 | // fire the callback 62 | if(_this.responseCallbacks[id]) { 63 | _this.responseCallbacks[id](result, 200); 64 | delete _this.responseCallbacks[id]; 65 | } 66 | }); 67 | }); 68 | }; 69 | 70 | /** 71 | Will parse the response and make an array out of it. 72 | 73 | @method _parseResponse 74 | @param {String} data 75 | */ 76 | IpcProvider.prototype._parseResponse = function(data) { 77 | var _this = this, 78 | returnValues = []; 79 | 80 | // DE-CHUNKER 81 | var dechunkedData = data 82 | .replace(/\}\{/g,'}|--|{') // }{ 83 | .replace(/\}\]\[\{/g,'}]|--|[{') // }][{ 84 | .replace(/\}\[\{/g,'}|--|[{') // }[{ 85 | .replace(/\}\]\{/g,'}]|--|{') // }]{ 86 | .split('|--|'); 87 | 88 | dechunkedData.forEach(function(data){ 89 | 90 | // prepend the last chunk 91 | if(_this.lastChunk) 92 | data = _this.lastChunk + data; 93 | 94 | var result = null; 95 | 96 | try { 97 | result = JSON.parse(data); 98 | 99 | } catch(e) { 100 | 101 | _this.lastChunk = data; 102 | 103 | // start timeout to cancel all requests 104 | clearTimeout(_this.lastChunkTimeout); 105 | _this.lastChunkTimeout = setTimeout(function(){ 106 | _this.timeout(); 107 | throw new Error('Invalidresponse '+ JSON.stringify(data)); 108 | }, 1000 * 15); 109 | 110 | return; 111 | } 112 | 113 | // cancel timeout and set chunk to null 114 | clearTimeout(_this.lastChunkTimeout); 115 | _this.lastChunk = null; 116 | 117 | if(result) 118 | returnValues.push(result); 119 | }); 120 | 121 | return returnValues; 122 | }; 123 | 124 | 125 | /** 126 | Get the adds a callback to the responseCallbacks object, 127 | which will be called if a response matching the response Id will arrive. 128 | 129 | @method _addResponseCallback 130 | */ 131 | IpcProvider.prototype._addResponseCallback = function(payload, callback) { 132 | var id = payload.id || payload[0].id; 133 | var method = payload.method || payload[0].method; 134 | 135 | this.responseCallbacks[id] = callback; 136 | this.responseCallbacks[id].method = method; 137 | }; 138 | 139 | /** 140 | Timeout all requests when the end/error event is fired 141 | 142 | @method _timeout 143 | */ 144 | IpcProvider.prototype._timeout = function() { 145 | for(var key in this.responseCallbacks) { 146 | if(this.responseCallbacks.hasOwnProperty(key)){ 147 | this.responseCallbacks[key](new Error('IPC connection timout')); 148 | delete this.responseCallbacks[key]; 149 | } 150 | } 151 | }; 152 | 153 | 154 | /** 155 | Check if the current connection is still valid. 156 | 157 | @method isConnected 158 | */ 159 | IpcProvider.prototype.isConnected = function() { 160 | var _this = this; 161 | 162 | // try reconnect, when connection is gone 163 | if(!_this.connection.writable) 164 | _this.connection.connect({path: _this.path}); 165 | 166 | return !!this.connection.writable; 167 | }; 168 | 169 | IpcProvider.prototype.send = function (payload) { 170 | 171 | if(this.connection.writeSync) { 172 | var result; 173 | 174 | // try reconnect, when connection is gone 175 | if(!this.connection.writable) 176 | this.connection.connect({path: this.path}); 177 | 178 | var data = this.connection.writeSync(JSON.stringify(payload)); 179 | 180 | try { 181 | result = JSON.parse(data); 182 | } catch(e) { 183 | throw new Error('Invalidresponse '+ JSON.stringify(data)); 184 | } 185 | 186 | return result; 187 | 188 | } else { 189 | throw new Error('You tried to send "'+ payload.method +'" synchronously. Synchronous requests are not supported by the IPC provider.'); 190 | } 191 | }; 192 | 193 | IpcProvider.prototype.sendAsync = function (payload, callback) { 194 | // try reconnect, when connection is gone 195 | if(!this.connection.writable) 196 | this.connection.connect({path: this.path}); 197 | 198 | 199 | this.connection.write(JSON.stringify(payload)); 200 | this._addResponseCallback(payload, callback); 201 | }; 202 | 203 | module.exports = IpcProvider; 204 | 205 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rpc-tests", 3 | "version": "0.0.1", 4 | "description": "Test suite for the ethreum node RPC interface.", 5 | "author": "Fabian Vogelsteller ", 6 | "main": "index", 7 | "engines": { 8 | "node": ">= 0.4.x < 0.8.0" 9 | }, 10 | "scripts": { 11 | "test": "make test" 12 | }, 13 | "dependencies": {}, 14 | "devDependencies": { 15 | "bignumber.js": "^2.0.3", 16 | "chai": "*", 17 | "mocha": ">= 0.11.0", 18 | "underscore": "*", 19 | "xmlhttprequest": "*" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /test/1_testConnection.js: -------------------------------------------------------------------------------- 1 | var config = require('../lib/config'); 2 | var useIpc = process.argv[process.argv.length-1] === '--ipc'; 3 | 4 | if(useIpc) { 5 | 6 | // remove http hosts from config 7 | delete config.hosts.cpp; 8 | delete config.hosts.go; 9 | delete config.hosts.python; 10 | 11 | } else { 12 | var Helpers = require('../lib/helpers'); 13 | 14 | delete config.hosts.ipc; 15 | 16 | Helpers.eachHost(function(key, host){ 17 | try { 18 | Helpers.send(host); 19 | 20 | } catch(e) { 21 | // remove offline host from config 22 | delete config.hosts[Helpers.getKeyByValue(config.hosts, host)]; 23 | 24 | console.log('Can\'t connect to '+ key + ' at '+ host); 25 | } 26 | }); 27 | } 28 | 29 | -------------------------------------------------------------------------------- /test/RPC_Batch_call.js: -------------------------------------------------------------------------------- 1 | var config = require('../lib/config'), 2 | Helpers = require('../lib/helpers'), 3 | assert = require('chai').assert; 4 | 5 | // TEST 6 | var asyncTest = function(host, done){ 7 | Helpers.send(host, [{ 8 | id: config.rpcMessageId++, jsonrpc: "2.0", method: 'eth_accounts', 9 | 10 | // PARAMETERS 11 | params: [] 12 | 13 | }, 14 | { 15 | id: config.rpcMessageId++, jsonrpc: "2.0", method: 'eth_getBalance', 16 | 17 | // PARAMETERS 18 | params: ['0xbcde5374fce5edbc8e2a8697c15331677e6ebf0b','latest'] 19 | 20 | }, 21 | { 22 | id: config.rpcMessageId++, jsonrpc: "2.0", method: 'net_listening', 23 | 24 | // PARAMETERS 25 | params: [] 26 | 27 | }, 28 | { 29 | id: config.rpcMessageId++, jsonrpc: "2.0", method: 'eth_gasPrice', 30 | 31 | // PARAMETERS 32 | params: [] 33 | 34 | }], function(result, status) { 35 | assert.equal(status, 200, 'has status code'); 36 | assert.isArray(result, 'is array'); 37 | assert.property(result[0], 'result', (result.error) ? result.error.message : 'error'); 38 | 39 | // eth_accounts 40 | assert.isArray(result[0].result, 'is array'); 41 | 42 | // eth_getBalance 43 | var balance = config.testBlocks.postState['bcde5374fce5edbc8e2a8697c15331677e6ebf0b'].balance; 44 | assert.isNumber(+result[1].result, 'is a number'); 45 | assert.equal(+result[1].result, balance, 'is the same as '+ balance); 46 | 47 | // net_listening 48 | assert.isBoolean(result[2].result, 'is boolean'); 49 | 50 | // eth_gasPrice 51 | assert.isNumber(+result[3].result, 'is a number'); 52 | assert.isAbove(+result[3].result, 0, 'is a number'); 53 | 54 | done(); 55 | }); 56 | }; 57 | 58 | 59 | describe('RPC Batch call', function(){ 60 | Helpers.eachHost(function(key, host){ 61 | describe(key, function(){ 62 | it('should return an array with the results of each of the method calls', function(done){ 63 | asyncTest(host, done); 64 | }); 65 | }); 66 | }); 67 | }); 68 | 69 | -------------------------------------------------------------------------------- /test/db_getHex.js: -------------------------------------------------------------------------------- 1 | var config = require('../lib/config'), 2 | Helpers = require('../lib/helpers'), 3 | assert = require('chai').assert; 4 | 5 | // METHOD 6 | var method = 'db_getHex'; 7 | 8 | 9 | // TEST 10 | var asyncTest = function(host, params, expectedResult, done){ 11 | Helpers.send(host, { 12 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 13 | 14 | // PARAMETERS 15 | params: params 16 | 17 | }, function(result, status){ 18 | 19 | assert.property(result, 'result', (result.error) ? result.error.message : 'error'); 20 | assert.isString(result.result, 'is string'); 21 | assert.match(result.result, /^0x/, 'should be HEX starting with 0x'); 22 | 23 | assert.equal(result.result, expectedResult, 'should match '+ expectedResult); 24 | 25 | done(); 26 | }); 27 | }; 28 | 29 | 30 | var asyncErrorTest = function(host, done){ 31 | Helpers.send(host, { 32 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 33 | 34 | // PARAMETERS 35 | params: [] 36 | 37 | }, function(result, status) { 38 | 39 | assert.equal(status, 200, 'has status code'); 40 | assert.property(result, 'error'); 41 | assert.equal(result.error.code, -32602); 42 | 43 | done(); 44 | }); 45 | }; 46 | 47 | 48 | 49 | describe(method, function(){ 50 | 51 | Helpers.eachHost(function(key, host){ 52 | describe(key, function(){ 53 | it('should return the previously stored value', function(done){ 54 | var randomHex = '0x'+ Math.random().toString().replace('.','').replace(/0/g,''); 55 | 56 | if(randomHex.length % 2 !== 0) 57 | randomHex += 'f'; 58 | 59 | Helpers.send(host, { 60 | id: config.rpcMessageId++, jsonrpc: "2.0", method: 'db_putHex', 61 | 62 | // PARAMETERS 63 | params: [ 64 | 'myDb', 65 | 'myKey', 66 | randomHex 67 | ] 68 | 69 | }, function(result){ 70 | 71 | asyncTest(host, [ 72 | 'myDb', 73 | 'myKey' 74 | ], randomHex, done); 75 | }); 76 | 77 | }); 78 | 79 | it('should return an error when no parameter is passed', function(done){ 80 | asyncErrorTest(host, done); 81 | }); 82 | }); 83 | }); 84 | }); 85 | -------------------------------------------------------------------------------- /test/db_getString.js: -------------------------------------------------------------------------------- 1 | var config = require('../lib/config'), 2 | Helpers = require('../lib/helpers'), 3 | assert = require('chai').assert; 4 | 5 | // METHOD 6 | var method = 'db_getString'; 7 | 8 | 9 | // TEST 10 | var asyncTest = function(host, params, expectedResult, done){ 11 | Helpers.send(host, { 12 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 13 | 14 | // PARAMETERS 15 | params: params 16 | 17 | }, function(result, status) { 18 | 19 | assert.property(result, 'result', (result.error) ? result.error.message : 'error'); 20 | assert.isString(result.result, 'is string'); 21 | 22 | assert.equal(result.result, expectedResult, 'should match '+ expectedResult); 23 | 24 | done(); 25 | }); 26 | 27 | }; 28 | 29 | 30 | var asyncErrorTest = function(host, done){ 31 | Helpers.send(host, { 32 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 33 | 34 | // PARAMETERS 35 | params: [] 36 | 37 | }, function(result, status) { 38 | 39 | assert.equal(status, 200, 'has status code'); 40 | assert.property(result, 'error'); 41 | assert.equal(result.error.code, -32602); 42 | 43 | done(); 44 | }); 45 | }; 46 | 47 | 48 | 49 | describe(method, function(){ 50 | 51 | Helpers.eachHost(function(key, host){ 52 | describe(key, function(){ 53 | it('should return the previously stored value', function(done){ 54 | var randomString = Math.random().toString(); 55 | 56 | Helpers.send(host, { 57 | id: config.rpcMessageId++, jsonrpc: "2.0", method: 'db_putString', 58 | 59 | // PARAMETERS 60 | params: [ 61 | 'myDb', 62 | 'myKey', 63 | randomString 64 | ] 65 | 66 | }, function(){ 67 | 68 | asyncTest(host, [ 69 | 'myDb', 70 | 'myKey' 71 | ], randomString, done); 72 | }); 73 | 74 | }); 75 | 76 | it('should return an error when no parameter is passed', function(done){ 77 | asyncErrorTest(host, done); 78 | }); 79 | }); 80 | }); 81 | }); 82 | -------------------------------------------------------------------------------- /test/db_putHex.js: -------------------------------------------------------------------------------- 1 | var config = require('../lib/config'), 2 | Helpers = require('../lib/helpers'), 3 | assert = require('chai').assert; 4 | 5 | // METHOD 6 | var method = 'db_putHex'; 7 | 8 | 9 | // TEST 10 | var asyncTest = function(host, done, params, expectedResult){ 11 | Helpers.send(host, { 12 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 13 | 14 | // PARAMETERS 15 | params: params 16 | 17 | }, function(result, status) { 18 | 19 | 20 | assert.equal(status, 200, 'has status code'); 21 | assert.property(result, 'result', (result.error) ? result.error.message : 'error'); 22 | 23 | assert.equal(result.result, expectedResult, 'should match '+ expectedResult); 24 | 25 | done(); 26 | }); 27 | }; 28 | 29 | 30 | var asyncErrorTest = function(host, done){ 31 | Helpers.send(host, { 32 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 33 | 34 | // PARAMETERS 35 | params: [] 36 | 37 | }, function(result, status) { 38 | 39 | assert.equal(status, 200, 'has status code'); 40 | assert.property(result, 'error'); 41 | assert.equal(result.error.code, -32602); 42 | 43 | done(); 44 | }); 45 | }; 46 | 47 | 48 | 49 | describe(method, function(){ 50 | 51 | Helpers.eachHost(function(key, host){ 52 | describe(key, function(){ 53 | it('should return TRUE', function(done){ 54 | asyncTest(host, done, [ 55 | 'myDb', 56 | 'myKey', 57 | '0x4545b1f324' 58 | ], true); 59 | }); 60 | 61 | it('should return an error when no parameter is passed', function(done){ 62 | asyncErrorTest(host, done); 63 | }); 64 | }); 65 | }); 66 | }); 67 | -------------------------------------------------------------------------------- /test/db_putString.js: -------------------------------------------------------------------------------- 1 | var config = require('../lib/config'), 2 | Helpers = require('../lib/helpers'), 3 | assert = require('chai').assert; 4 | 5 | // METHOD 6 | var method = 'db_putString'; 7 | 8 | 9 | // TEST 10 | var asyncTest = function(host, done, params, expectedResult){ 11 | Helpers.send(host, { 12 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 13 | 14 | // PARAMETERS 15 | params: params 16 | 17 | }, function(result, status) { 18 | 19 | 20 | assert.equal(status, 200, 'has status code'); 21 | assert.property(result, 'result', (result.error) ? result.error.message : 'error'); 22 | 23 | assert.equal(result.result, expectedResult, 'should match '+ expectedResult); 24 | 25 | done(); 26 | }); 27 | }; 28 | 29 | 30 | var asyncErrorTest = function(host, done){ 31 | Helpers.send(host, { 32 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 33 | 34 | // PARAMETERS 35 | params: [] 36 | 37 | }, function(result, status) { 38 | 39 | assert.equal(status, 200, 'has status code'); 40 | assert.property(result, 'error'); 41 | assert.equal(result.error.code, -32602); 42 | 43 | done(); 44 | }); 45 | }; 46 | 47 | 48 | 49 | describe(method, function(){ 50 | 51 | Helpers.eachHost(function(key, host){ 52 | describe(key, function(){ 53 | it('should return TRUE', function(done){ 54 | asyncTest(host, done, [ 55 | 'myDb', 56 | 'myKey', 57 | 'myString' 58 | ], true); 59 | }); 60 | 61 | it('should return an error when no parameter is passed', function(done){ 62 | asyncErrorTest(host, done); 63 | }); 64 | }); 65 | }); 66 | }); 67 | -------------------------------------------------------------------------------- /test/eth_accounts.js: -------------------------------------------------------------------------------- 1 | var config = require('../lib/config'), 2 | Helpers = require('../lib/helpers'), 3 | assert = require('chai').assert; 4 | 5 | // METHOD 6 | var method = 'eth_accounts'; 7 | 8 | // TEST 9 | var asyncTest = function(host, done){ 10 | Helpers.send(host, { 11 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 12 | 13 | // PARAMETERS 14 | params: [] 15 | 16 | }, function(result, status) { 17 | assert.equal(status, 200, 'has status code'); 18 | assert.property(result, 'result', (result.error) ? result.error.message : 'error'); 19 | assert.isArray(result.result, 'is array'); 20 | // we should have at least one account here (coinbase) 21 | assert.isTrue(Helpers.isAddress(result.result[0])); 22 | 23 | done(); 24 | }); 25 | }; 26 | 27 | 28 | describe(method, function(){ 29 | Helpers.eachHost(function(key, host){ 30 | describe(key, function(){ 31 | it('should return an array with accounts', function(done){ 32 | asyncTest(host, done); 33 | }); 34 | }); 35 | }); 36 | }); 37 | 38 | -------------------------------------------------------------------------------- /test/eth_blockNumber.js: -------------------------------------------------------------------------------- 1 | var config = require('../lib/config'), 2 | Helpers = require('../lib/helpers'), 3 | assert = require('chai').assert; 4 | 5 | // METHOD 6 | var method = 'eth_blockNumber'; 7 | 8 | // TEST 9 | var asyncTest = function(host, done){ 10 | Helpers.send(host, { 11 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 12 | 13 | // PARAMETERS 14 | params: [] 15 | 16 | }, function(result, status) { 17 | 18 | assert.equal(status, 200, 'has status code'); 19 | assert.property(result, 'result', (result.error) ? result.error.message : 'error'); 20 | assert.isString(result.result, 'is string'); 21 | assert.match(result.result, /^0x/, 'should be HEX starting with 0x'); 22 | assert.isNumber(+result.result, 'can be converted to a number'); 23 | 24 | var expectedBlockNumber = config.testBlocks.blocks.reduce(function (acc, current) { 25 | return Math.max(acc, current.blockHeader.number); // let's take the longest chain 26 | }, 0); 27 | 28 | assert.equal(+result.result, expectedBlockNumber, 'should have the right length'); 29 | 30 | done(); 31 | }); 32 | }; 33 | 34 | describe(method, function(){ 35 | Helpers.eachHost(function(key, host){ 36 | describe(key, function(){ 37 | it('should return a number as hexstring', function(done){ 38 | asyncTest(host, done); 39 | }); 40 | }); 41 | }); 42 | }); 43 | -------------------------------------------------------------------------------- /test/eth_call.js: -------------------------------------------------------------------------------- 1 | var config = require('../lib/config'), 2 | Helpers = require('../lib/helpers'), 3 | assert = require('chai').assert, 4 | _ = require('underscore'); 5 | 6 | // METHOD 7 | var method = 'eth_call'; 8 | 9 | 10 | // TEST 11 | var asyncTest = function(host, done, params, expectedResult, type, call){ 12 | Helpers.send(host, { 13 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 14 | 15 | // PARAMETERS 16 | params: params 17 | 18 | }, function(result, status) { 19 | 20 | assert.equal(status, 200, 'has status code'); 21 | assert.property(result, 'result', (result.error) ? result.error.message : 'error'); 22 | assert.isString(result.result, 'should be a string'); 23 | assert.match(result.result, /^0x/, 'should be HEX starting with 0x'); 24 | 25 | if(type === 'empty') 26 | assert.equal(result.result, expectedResult, 'should be "0x"'); 27 | else 28 | assert.equal(result.result.length, 66, 'should be 32 Bytes long'); 29 | 30 | if(type === 'getAddress') 31 | assert.equal(result.result.slice(-20), expectedResult.slice(-20), 'should return '+ expectedResult.slice(-20)); 32 | else 33 | assert.equal(result.result, expectedResult, 'should return '+ expectedResult); 34 | 35 | done(); 36 | }); 37 | }; 38 | 39 | 40 | var asyncErrorTest = function(host, done, param){ 41 | Helpers.send(host, { 42 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 43 | 44 | // PARAMETERS 45 | params: param 46 | 47 | }, function(result, status) { 48 | 49 | assert.equal(status, 200, 'has status code'); 50 | assert.property(result, 'error'); 51 | assert.equal(result.error.code, -32602); 52 | 53 | done(); 54 | }); 55 | }; 56 | 57 | 58 | 59 | describe(method, function(){ 60 | 61 | Helpers.eachHost(function(key, host){ 62 | describe(key, function(){ 63 | 64 | var calls = [{ 65 | name: 'getBool', 66 | call: '0x12a7b914', 67 | setter: '0x1e26fd33', 68 | }, 69 | { 70 | name: 'getBytes32', 71 | call: '0x1f903037', 72 | setter: '0xc2b12a73' 73 | }, 74 | { 75 | name: 'getUint8', 76 | call: '0x343a875d', 77 | setter: '0x1774e646' 78 | }, 79 | { 80 | name: 'getAddress', 81 | call: '0x38cc4831', 82 | setter: '0xe30081a0' 83 | }, 84 | { 85 | name: 'getInt8', 86 | call: '0x57cb2fc4', 87 | setter: '0x9a19a953' 88 | }, 89 | { 90 | name: 'getUint256', 91 | call: '0x68895979', 92 | setter: '0xd2282dc5' 93 | }, 94 | { 95 | name: 'getInt256', 96 | call: '0xf5b53e17', 97 | setter: '0xa53b1c1e' 98 | }]; 99 | // add the block and the result 100 | calls = _.map(calls, function(call){ 101 | var result = null, 102 | to = null; 103 | call.block = _.find(config.testBlocks.blocks, function(block){ 104 | return _.find(block.transactions, function(tx, index){ 105 | if (tx.data.indexOf(call.setter) === 0){ 106 | result = tx.data.replace(call.setter, ''); 107 | to = tx.to; 108 | return true; 109 | } else 110 | return false; 111 | }); 112 | }); 113 | call.result = '0x'+ result; 114 | call.to = '0x'+ to; 115 | call.blockNumber = Number(call.block.blockHeader.number); 116 | delete call.block; 117 | return call; 118 | }); 119 | 120 | _.each(calls, function(call){ 121 | it('calling '+ call.name +' ('+ call.call +') should return the correct value, when the using the correct block ('+ call.blockNumber +') as default block', function(done){ 122 | asyncTest(host, done, [{ 123 | to: call.to, 124 | data: call.call 125 | }, Helpers.fromDecimal(call.blockNumber)], call.result, call.name); 126 | }); 127 | 128 | it('calling '+ call.name +' ('+ call.call +') should return "0x0000000000000000000000000000000000000000000000000000000000000000", when using the wrong block ('+ call.blockNumber - 1 +') as default block', function(done){ 129 | asyncTest(host, done, [{ 130 | to: call.to, 131 | data: call.call 132 | }, Helpers.fromDecimal(call.blockNumber -1)], '0x0000000000000000000000000000000000000000000000000000000000000000', null, call); 133 | }); 134 | 135 | it('calling '+ call.name +' ('+ call.call +') should return "0x", when using a block (0) where no contract is deployed', function(done){ 136 | asyncTest(host, done, [{ 137 | to: call.to, 138 | data: call.call 139 | }, '0x0'], '0x', 'empty'); 140 | }); 141 | }); 142 | 143 | it('should return an error when no parameter is passed', function(done){ 144 | asyncErrorTest(host, done, []); 145 | }); 146 | 147 | // it('should return an error when no second parameter is passed', function(done){ 148 | // asyncErrorTest(host, done, [{to: '0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b'}]); 149 | // }); 150 | }); 151 | }); 152 | }); 153 | -------------------------------------------------------------------------------- /test/eth_coinbase.js: -------------------------------------------------------------------------------- 1 | var config = require('../lib/config'), 2 | Helpers = require('../lib/helpers'), 3 | assert = require('chai').assert; 4 | 5 | // METHOD 6 | var method = 'eth_coinbase'; 7 | 8 | // TEST 9 | var asyncTest = function(host, done){ 10 | Helpers.send(host, { 11 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 12 | 13 | // PARAMETERS 14 | params: [] 15 | 16 | }, function(result, status) { 17 | 18 | assert.equal(status, 200, 'has status code'); 19 | assert.property(result, 'result', (result.error) ? result.error.message : 'error'); 20 | assert.isTrue(result.result === null || Helpers.isAddress(result.result), 'is coinbase address'); 21 | 22 | config.coinbase = result.result; 23 | 24 | done(); 25 | 26 | }); 27 | }; 28 | 29 | 30 | describe(method, function(){ 31 | Helpers.eachHost(function(key, host){ 32 | describe(key, function(){ 33 | it('should return a coinbase address', function(done){ 34 | asyncTest(host, done); 35 | }); 36 | }); 37 | }); 38 | }); 39 | -------------------------------------------------------------------------------- /test/eth_gasPrice.js: -------------------------------------------------------------------------------- 1 | var config = require('../lib/config'), 2 | Helpers = require('../lib/helpers'), 3 | assert = require('chai').assert; 4 | 5 | // METHOD 6 | var method = 'eth_gasPrice'; 7 | 8 | // TEST 9 | var asyncTest = function(host, done){ 10 | Helpers.send(host, { 11 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 12 | 13 | // PARAMETERS 14 | params: [] 15 | 16 | }, function(result, status) { 17 | 18 | assert.equal(status, 200, 'has status code'); 19 | assert.property(result, 'result', (result.error) ? result.error.message : 'error'); 20 | assert.isString(result.result, 'is string'); 21 | assert.match(result.result, /^0x/, 'should be HEX starting with 0x'); 22 | assert.isNumber(+result.result, 'can be converted to a number'); 23 | 24 | done(); 25 | }); 26 | }; 27 | 28 | describe(method, function(){ 29 | Helpers.eachHost(function(key, host){ 30 | describe(key, function(){ 31 | it('should return a number as hexstring', function(done){ 32 | asyncTest(host, done); 33 | }); 34 | }); 35 | }); 36 | }); 37 | -------------------------------------------------------------------------------- /test/eth_getBalance.js: -------------------------------------------------------------------------------- 1 | var config = require('../lib/config'), 2 | Helpers = require('../lib/helpers'), 3 | assert = require('chai').assert, 4 | _ = require('underscore'); 5 | 6 | // METHOD 7 | var method = 'eth_getBalance'; 8 | 9 | 10 | // TEST 11 | var asyncTest = function(host, done, params, expectedResult){ 12 | Helpers.send(host, { 13 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 14 | 15 | // PARAMETERS 16 | params: params 17 | 18 | }, function(result, status) { 19 | 20 | 21 | assert.equal(status, 200, 'has status code'); 22 | assert.property(result, 'result', (result.error) ? result.error.message : 'error'); 23 | assert.isString(result.result, 'is string'); 24 | assert.match(result.result, /^0x/, 'should be HEX starting with 0x'); 25 | assert.isNumber(+result.result, 'can be converted to a number'); 26 | 27 | assert.equal(+result.result, expectedResult, 'should have balance '+ expectedResult); 28 | 29 | done(); 30 | }); 31 | }; 32 | 33 | 34 | var asyncErrorTest = function(host, done){ 35 | Helpers.send(host, { 36 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 37 | 38 | // PARAMETERS 39 | params: [] 40 | 41 | }, function(result, status) { 42 | 43 | assert.equal(status, 200, 'has status code'); 44 | assert.property(result, 'error'); 45 | assert.equal(result.error.code, -32602); 46 | 47 | done(); 48 | }); 49 | }; 50 | 51 | 52 | 53 | describe(method, function(){ 54 | 55 | Helpers.eachHost(function(key, host){ 56 | describe(key, function(){ 57 | 58 | _.each(config.testBlocks.postState, function(state, key){ 59 | it('should return the correct balance at defaultBlock "latest" at address 0x'+key, function(done){ 60 | asyncTest(host, done, ['0x'+ key, 'latest'], state.balance); 61 | }); 62 | }); 63 | 64 | _.each(config.testBlocks.pre, function(state, key){ 65 | it('should return the correct balance at defaultBlock 0 at address 0x'+key, function(done){ 66 | asyncTest(host, done, ['0x'+ key, '0x0'], state.balance); 67 | }); 68 | }); 69 | 70 | it('should return an error when no parameter is passed', function(done){ 71 | asyncErrorTest(host, done); 72 | }); 73 | }); 74 | }); 75 | }); 76 | -------------------------------------------------------------------------------- /test/eth_getBlockBy.js: -------------------------------------------------------------------------------- 1 | var config = require('../lib/config'), 2 | Helpers = require('../lib/helpers'), 3 | assert = require('chai').assert; 4 | _ = require('underscore'); 5 | 6 | 7 | // TEST 8 | var asyncTest = function(host, done, method, params, block){ 9 | 10 | Helpers.send(host, { 11 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 12 | 13 | // PARAMETERS 14 | params: params 15 | 16 | }, function(result, status) { 17 | 18 | assert.equal(status, 200, 'has status code'); 19 | assert.property(result, 'result', (result.error) ? result.error.message : 'error'); 20 | 21 | if(!block) 22 | assert.isNull(result.result); 23 | else if(block === 'pending') { 24 | 25 | assert.isNull(result.result.hash, 'block hash should be null'); 26 | assert.isNull(result.result.nonce, 'block nonce should be null'); 27 | assert.isNull(result.result.logsBloom, 'block logsBloom should be null'); 28 | assert.isNull(result.result.miner, 'block miner should be null'); 29 | assert.match(result.result.parentHash, /^0x/, 'parentHash should start with 0x'); 30 | assert.match(result.result.sha3Uncles, /^0x/, 'sha3Uncles should start with 0x'); 31 | assert.match(result.result.stateRoot, /^0x/, 'stateRoot should start with 0x'); 32 | assert.match(result.result.transactionsRoot, /^0x/, 'transactionsRoot should start with 0x'); 33 | assert.match(result.result.parentHash, /^0x/, 'block hash should start with 0x'); 34 | 35 | } else { 36 | assert.isObject(result.result, 'is object'); 37 | 38 | Helpers.blockTest(result.result, block.blockHeader); 39 | 40 | // test for transaction objects 41 | if(params[1]) { 42 | _.each(result.result.transactions, function(tx, index){ 43 | Helpers.transactionTest(tx, block.transactions[index], index, block); 44 | }); 45 | 46 | // test for correct transaction hashes 47 | } else { 48 | _.each(result.result.transactions, function(tx, index){ 49 | assert.match(tx, /^0x/, 'should be an transaction hash'); 50 | }); 51 | } 52 | 53 | // test uncles 54 | if(block.uncleHeaders.length > 0) { 55 | assert.isArray(result.result.uncles, 'should contain uncles'); 56 | 57 | _.each(block.uncleHeaders, function(uncle, index){ 58 | assert.strictEqual(result.result.uncles[index], '0x'+ uncle.hash); 59 | }); 60 | } 61 | } 62 | 63 | 64 | done(); 65 | }); 66 | }; 67 | 68 | 69 | var asyncErrorTest = function(host, done, method, params){ 70 | Helpers.send(host, { 71 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 72 | 73 | // PARAMETERS 74 | params: params 75 | 76 | }, function(result, status) { 77 | 78 | assert.equal(status, 200, 'has status code'); 79 | assert.property(result, 'error'); 80 | assert.equal(result.error.code, -32602); 81 | 82 | done(); 83 | }); 84 | }; 85 | 86 | 87 | 88 | var method1 = 'eth_getBlockByNumber'; 89 | describe(method1, function(){ 90 | 91 | Helpers.eachHost(function(key, host){ 92 | describe(key, function(){ 93 | 94 | _.each(config.testBlocks.blocks.filter(function (block) { return block.reverted !== true; }), function(block){ 95 | 96 | it('should return a block with the proper structure, containing array of transaction objects', function(done){ 97 | asyncTest(host, done, method1, [Helpers.fromDecimal(block.blockHeader.number), true], block); 98 | }); 99 | 100 | it('should return a block with the proper structure, containing array of transaction hashes', function(done){ 101 | asyncTest(host, done, method1, [Helpers.fromDecimal(block.blockHeader.number), false], block); 102 | }); 103 | 104 | }); 105 | 106 | it('should return a the genisis block when using "earliest"', function(done){ 107 | asyncTest(host, done, method1, ['earliest', false], {blockHeader: config.testBlocks.genesisBlockHeader, transactions: [], uncleHeaders: []}); 108 | }); 109 | 110 | it('should return the last block when using "latest"', function(done){ 111 | asyncTest(host, done, method1, ['latest', false], config.testBlocks.blocks[config.testBlocks.blocks.length-1]); 112 | }); 113 | 114 | it('should return the pending block when using "pending"', function(done){ 115 | asyncTest(host, done, method1, ['pending', false], 'pending'); 116 | }); 117 | 118 | it('should return null when no block was found', function(done){ 119 | asyncTest(host, done, method1, ['0xbbbbbb', true], null); 120 | }); 121 | it('should return an error when the wrong parameters is passed', function(done){ 122 | asyncErrorTest(host, done, method1, ['0xbbb']); 123 | }); 124 | it('should return an error when no parameter is passed', function(done){ 125 | asyncErrorTest(host, done, method1, []); 126 | }); 127 | }); 128 | }); 129 | }); 130 | 131 | 132 | var method2 = 'eth_getBlockByHash'; 133 | describe(method2, function(){ 134 | 135 | Helpers.eachHost(function(key, host){ 136 | describe(key, function(){ 137 | 138 | _.each(config.testBlocks.blocks, function(block){ 139 | it('should return a block with the proper structure, containing array of transaction objects', function(done){ 140 | asyncTest(host, done, method2, ['0x'+ block.blockHeader.hash, true], block); 141 | }); 142 | 143 | it('should return a block with the proper structure, containing array of transaction hashes', function(done){ 144 | asyncTest(host, done, method2, ['0x'+ block.blockHeader.hash, false], block); 145 | }); 146 | }); 147 | 148 | it('should return null when no block was found', function(done){ 149 | asyncTest(host, done, method2, ['0x878a132155f53adb7c993ded4cfb687977397d63d873fcdbeb06c18cac907a5c', true], null); 150 | }); 151 | it('should return an error when the wrong parameters is passed', function(done){ 152 | asyncErrorTest(host, done, method2, ['0x878a132155f53adb7c993ded4cfb687977397d63d873fcdbeb06c18cac907a5c']); 153 | }); 154 | it('should return an error when no parameter is passed', function(done){ 155 | asyncErrorTest(host, done, method2, []); 156 | }); 157 | }); 158 | }); 159 | }); 160 | -------------------------------------------------------------------------------- /test/eth_getBlockTransactionCountByHash.js: -------------------------------------------------------------------------------- 1 | var config = require('../lib/config'), 2 | Helpers = require('../lib/helpers'), 3 | assert = require('chai').assert, 4 | _ = require('underscore'); 5 | 6 | // METHOD 7 | var method = 'eth_getBlockTransactionCountByHash'; 8 | 9 | 10 | // TEST 11 | var asyncTest = function(host, done, params, expectedResult){ 12 | Helpers.send(host, { 13 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 14 | 15 | // PARAMETERS 16 | params: params 17 | 18 | }, function(result, status) { 19 | 20 | 21 | assert.equal(status, 200, 'has status code'); 22 | assert.property(result, 'result', (result.error) ? result.error.message : 'error'); 23 | 24 | if(!result.result) { 25 | assert.isNull(result.result); 26 | } else { 27 | assert.isString(result.result, 'is string'); 28 | assert.match(result.result, /^0x/, 'should be HEX starting with 0x'); 29 | assert.isNumber(+result.result, 'can be converted to a number'); 30 | 31 | assert.equal(+result.result, expectedResult, 'should be '+ expectedResult); 32 | } 33 | 34 | done(); 35 | }); 36 | }; 37 | 38 | 39 | var asyncErrorTest = function(host, done){ 40 | Helpers.send(host, { 41 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 42 | 43 | // PARAMETERS 44 | params: [] 45 | 46 | }, function(result, status) { 47 | 48 | assert.equal(status, 200, 'has status code'); 49 | assert.property(result, 'error'); 50 | assert.equal(result.error.code, -32602); 51 | 52 | done(); 53 | }); 54 | }; 55 | 56 | 57 | describe(method, function(){ 58 | 59 | Helpers.eachHost(function(key, host){ 60 | describe(key, function(){ 61 | _.each(config.testBlocks.blocks, function(block){ 62 | it('should return '+block.transactions.length+' as a hexstring', function(done){ 63 | asyncTest(host, done, ['0x'+ block.blockHeader.hash], block.transactions.length); 64 | }); 65 | }); 66 | 67 | it('should return null if the block doesnt exist', function(done){ 68 | asyncTest(host, done, ['0x878a132155f53adb7c993ded4cfb687977397d63d873fcdbeb06c18cac907a5c'], null); 69 | }); 70 | 71 | it('should return an error when no parameter is passed', function(done){ 72 | asyncErrorTest(host, done); 73 | }); 74 | }); 75 | }); 76 | }); 77 | -------------------------------------------------------------------------------- /test/eth_getBlockTransactionCountByNumber.js: -------------------------------------------------------------------------------- 1 | var config = require('../lib/config'), 2 | Helpers = require('../lib/helpers'), 3 | assert = require('chai').assert, 4 | _ = require('underscore'); 5 | 6 | // METHOD 7 | var method = 'eth_getBlockTransactionCountByNumber'; 8 | 9 | 10 | // TEST 11 | var asyncTest = function(host, done, params, expectedResult){ 12 | Helpers.send(host, { 13 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 14 | 15 | // PARAMETERS 16 | params: params 17 | 18 | }, function(result, status) { 19 | 20 | 21 | assert.equal(status, 200, 'has status code'); 22 | assert.property(result, 'result', (result.error) ? result.error.message : 'error'); 23 | if(!result.result) { 24 | assert.isNull(result.result); 25 | } else { 26 | assert.isString(result.result, 'is string'); 27 | assert.match(result.result, /^0x/, 'should be HEX starting with 0x'); 28 | assert.isNumber(+result.result, 'can be converted to a number'); 29 | assert.equal(+result.result, expectedResult, 'should be '+ expectedResult); 30 | } 31 | 32 | done(); 33 | }); 34 | }; 35 | 36 | 37 | var asyncErrorTest = function(host, done){ 38 | Helpers.send(host, { 39 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 40 | 41 | // PARAMETERS 42 | params: [] 43 | 44 | }, function(result, status) { 45 | 46 | assert.equal(status, 200, 'has status code'); 47 | assert.property(result, 'error'); 48 | assert.equal(result.error.code, -32602); 49 | 50 | done(); 51 | }); 52 | }; 53 | 54 | 55 | 56 | describe(method, function(){ 57 | 58 | Helpers.eachHost(function(key, host){ 59 | describe(key, function(){ 60 | _.each(config.testBlocks.blocks, function(block){ 61 | it('should return '+block.transactions.length+' as a hexstring', function(done){ 62 | asyncTest(host, done, [Helpers.fromDecimal(block.blockHeader.number)], block.transactions.length); 63 | }); 64 | }); 65 | 66 | it('should return '+config.testBlocks.blocks[config.testBlocks.blocks.length-1].transactions.length+' as a hexstring when "latest" (block: '+config.testBlocks.blocks[config.testBlocks.blocks.length-1].blockHeader.hash+')', function(done){ 67 | asyncTest(host, done, ['latest'], config.testBlocks.blocks[config.testBlocks.blocks.length-1].transactions.length); 68 | }); 69 | 70 | it('should return 0 as a hexstring when "pending"', function(done){ 71 | asyncTest(host, done, ['pending'], 0); 72 | }); 73 | 74 | it('should return 0 as a hexstring when "earliest" (block: '+config.testBlocks.genesisBlockHeader.hash+')', function(done){ 75 | asyncTest(host, done, ['earliest'], 0); 76 | }); 77 | 78 | it('should return null if the block doesnt exist', function(done){ 79 | asyncTest(host, done, [Helpers.fromDecimal(99999)], null); 80 | }); 81 | 82 | it('should return an error when no parameter is passed', function(done){ 83 | asyncErrorTest(host, done); 84 | }); 85 | }); 86 | }); 87 | }); 88 | -------------------------------------------------------------------------------- /test/eth_getCode.js: -------------------------------------------------------------------------------- 1 | var config = require('../lib/config'), 2 | Helpers = require('../lib/helpers'), 3 | assert = require('chai').assert, 4 | _ = require('underscore'); 5 | 6 | // METHOD 7 | var method = 'eth_getCode'; 8 | 9 | 10 | // TEST 11 | var asyncTest = function(host, done, params, expectedResult){ 12 | Helpers.send(host, { 13 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 14 | 15 | // PARAMETERS 16 | params: params 17 | 18 | }, function(result, status) { 19 | 20 | 21 | assert.equal(status, 200, 'has status code'); 22 | assert.property(result, 'result', (result.error) ? result.error.message : 'error'); 23 | assert.isString(result.result, 'is string'); 24 | assert.match(result.result, /^0x/, 'should be HEX starting with 0x'); 25 | 26 | assert.equal(result.result, expectedResult, 'should be '+ expectedResult); 27 | 28 | done(); 29 | }); 30 | }; 31 | 32 | 33 | var asyncErrorTest = function(host, done){ 34 | Helpers.send(host, { 35 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 36 | 37 | // PARAMETERS 38 | params: [] 39 | 40 | }, function(result, status) { 41 | 42 | assert.equal(status, 200, 'has status code'); 43 | assert.property(result, 'error'); 44 | assert.equal(result.error.code, -32602); 45 | 46 | done(); 47 | }); 48 | }; 49 | 50 | 51 | 52 | describe(method, function(){ 53 | 54 | Helpers.eachHost(function(key, host){ 55 | describe(key, function(){ 56 | 57 | _.each(config.testBlocks.postState, function(state, key){ 58 | it('should return the code when defaultBlock is "latest" at 0x'+ key, function(done){ 59 | asyncTest(host, done, ['0x'+ key, 'latest'], state.code); 60 | }); 61 | }); 62 | 63 | _.each(config.testBlocks.pre, function(state, key){ 64 | it('should return code as when defaultBlock is 0 at 0x'+ key, function(done){ 65 | asyncTest(host, done, ['0x'+ key, '0x0'], state.code); 66 | }); 67 | }); 68 | 69 | _.each(config.testBlocks.pre, function(state, key){ 70 | if(state.code === '0x') { 71 | it('should return nothing as there is no code at block 0', function(done){ 72 | asyncTest(host, done, ['0x'+ key, '0x0'], '0x'); 73 | }); 74 | } 75 | }); 76 | 77 | it('should return an error when no parameter is passed', function(done){ 78 | asyncErrorTest(host, done); 79 | }); 80 | }); 81 | }); 82 | }); 83 | -------------------------------------------------------------------------------- /test/eth_getCompilers.js: -------------------------------------------------------------------------------- 1 | var config = require('../lib/config'), 2 | Helpers = require('../lib/helpers'), 3 | assert = require('chai').assert; 4 | 5 | // METHOD 6 | var method = 'eth_getCompilers'; 7 | 8 | // TEST 9 | var asyncTest = function(host, done){ 10 | Helpers.send(host, { 11 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 12 | 13 | // PARAMETERS 14 | params: [] 15 | 16 | }, function(result, status) { 17 | 18 | assert.equal(status, 200, 'has status code'); 19 | assert.property(result, 'result', (result.error) ? result.error.message : 'error'); 20 | assert.isArray(result.result, 'is array'); 21 | // assert.include(result.result, "lll"); 22 | // assert.include(result.result, "solidity"); 23 | // assert.include(result.result, "serpent"); 24 | 25 | done(); 26 | }); 27 | }; 28 | 29 | describe(method, function(){ 30 | Helpers.eachHost(function(key, host){ 31 | describe(key, function(){ 32 | it('should return an array with compilers', function(done){ 33 | asyncTest(host, done); 34 | }); 35 | }); 36 | }); 37 | }); 38 | -------------------------------------------------------------------------------- /test/eth_getFilterChanges.js: -------------------------------------------------------------------------------- 1 | var config = require('../lib/config'), 2 | Helpers = require('../lib/helpers'), 3 | assert = require('chai').assert, 4 | _ = require('underscore'); 5 | 6 | return; 7 | 8 | // METHOD 9 | var method = 'eth_getFilterChanges', 10 | uninstallFilter = function(host, id) { 11 | Helpers.send(host, {id: config.rpcMessageId++, jsonrpc: "2.0", method: 'eth_uninstallFilter', params: [id] }, function(){}); 12 | }; 13 | 14 | // TEST 15 | var asyncTest = function(host, filterId, logsInfo, done){ 16 | 17 | Helpers.send(host, { 18 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 19 | 20 | // PARAMETERS 21 | params: [filterId] 22 | 23 | }, function(result, status){ 24 | 25 | // console.log(filterId, result.result); 26 | 27 | assert.property(result, 'result', (result.error) ? result.error.message : 'error'); 28 | assert.equal(result.result.length, logsInfo.length, 'logs should be '+ logsInfo.length); 29 | 30 | _.each(result.result, function(log, index){ 31 | Helpers.logTest(log, logsInfo[index]); 32 | }); 33 | 34 | done(); 35 | }); 36 | 37 | }; 38 | 39 | var asyncErrorTest = function(host, done, param){ 40 | Helpers.send(host, { 41 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 42 | 43 | // PARAMETERS 44 | params: param ? [param] : [] 45 | 46 | }, function(result, status) { 47 | 48 | assert.equal(status, 200, 'has status code'); 49 | assert.property(result, 'error'); 50 | assert.equal(result.error.code, -32602); 51 | 52 | done(); 53 | }); 54 | }; 55 | 56 | 57 | 58 | describe(method, function(){ 59 | Helpers.eachHost(function(key, host){ 60 | 61 | // OPTIONS FILTER 62 | describe(key, function(){ 63 | 64 | _.each(config.logs, function(log){ 65 | it('should return the correct log once after a transaction was send and when filtering without defining an address', function(done){ 66 | // INSTALL a options filter first 67 | var optionsFilterId = Helpers.send(host, { 68 | id: config.rpcMessageId++, jsonrpc: "2.0", method: 'eth_newFilter', 69 | 70 | // PARAMETERS 71 | params: [{ 72 | "fromBlock": Helpers.fromDecimal(log.block.blockHeader.number), 73 | "toBlock": Helpers.fromDecimal(log.block.blockHeader.number) 74 | }] 75 | 76 | }, function(){ 77 | 78 | asyncTest(host, optionsFilterId.result, [], function(){ 79 | 80 | // send transaction 81 | Helpers.send(host, { 82 | id: config.rpcMessageId++, jsonrpc: "2.0", method: 'eth_sendTransaction', 83 | 84 | // PARAMETERS 85 | params: [{ 86 | "from": config.senderAddress, 87 | "to": config.contractAddress, 88 | "data": log.call, 89 | "gas" : "0x4cb2f", 90 | "gasPrice" : "0x1", 91 | }] 92 | 93 | }, function(){ 94 | 95 | // MINE! 96 | 97 | syncTest(host, optionsFilterId.result, [log], function(){ 98 | 99 | syncTest(host, optionsFilterId.result, [], function(){ 100 | 101 | // remove filter 102 | uninstallFilter(host, optionsFilterId.result); 103 | 104 | done(); 105 | }); 106 | }); 107 | 108 | 109 | }); 110 | 111 | }); 112 | 113 | }); 114 | 115 | }); 116 | 117 | it('should return the correct log once after a transaction was send and when filtering with address', function(done){ 118 | // INSTALL a options filter first 119 | var optionsFilterId = Helpers.send(host, { 120 | id: config.rpcMessageId++, jsonrpc: "2.0", method: 'eth_newFilter', 121 | 122 | // PARAMETERS 123 | params: [{ 124 | "address": '0x'+ log.tx.to, 125 | "fromBlock": Helpers.fromDecimal(log.block.blockHeader.number), 126 | "toBlock": Helpers.fromDecimal(log.block.blockHeader.number) 127 | }] 128 | 129 | }, function(){ 130 | 131 | asyncTest(host, optionsFilterId.result, [], function(){ 132 | 133 | // send transaction 134 | Helpers.send(host, { 135 | id: config.rpcMessageId++, jsonrpc: "2.0", method: 'eth_sendTransaction', 136 | 137 | // PARAMETERS 138 | params: [{ 139 | "from": config.senderAddress, 140 | "to": config.contractAddress, 141 | "data": log.call, 142 | "gas" : "0x4cb2f", 143 | "gasPrice" : "0x1", 144 | }] 145 | 146 | }, function(){ 147 | 148 | // MINE! 149 | 150 | syncTest(host, optionsFilterId.result, [log], function(){ 151 | 152 | syncTest(host, optionsFilterId.result, [], function(){ 153 | 154 | // remove filter 155 | uninstallFilter(host, optionsFilterId.result); 156 | 157 | done(); 158 | }); 159 | 160 | }); 161 | 162 | }); 163 | 164 | }); 165 | 166 | }); 167 | 168 | }); 169 | }); 170 | 171 | 172 | it('should return an error when no parameter is passed', function(done){ 173 | asyncErrorTest(host, done); 174 | }); 175 | }); 176 | }); 177 | }); 178 | -------------------------------------------------------------------------------- /test/eth_getFilterLogs.js: -------------------------------------------------------------------------------- 1 | var config = require('../lib/config'), 2 | Helpers = require('../lib/helpers'), 3 | assert = require('chai').assert, 4 | _ = require('underscore'); 5 | 6 | // METHOD 7 | var method = 'eth_getFilterLogs', 8 | uninstallFilter = function(host, id, done) { 9 | Helpers.send(host, {id: config.rpcMessageId++, jsonrpc: "2.0", method: 'eth_uninstallFilter', params: [id] }, function(){ done(); }); 10 | }; 11 | 12 | // TEST 13 | var asyncTest = function(host, filterId, logsInfo, done){ 14 | 15 | Helpers.send(host, { 16 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 17 | 18 | // PARAMETERS 19 | params: [filterId] 20 | 21 | }, function(result, status){ 22 | 23 | assert.property(result, 'result', (result.error) ? result.error.message : 'error'); 24 | assert.equal(result.result.length, logsInfo.length, 'logs should be '+ logsInfo.length); 25 | 26 | _.each(result.result, function(log, index){ 27 | Helpers.logTest(log, logsInfo[index]); 28 | }); 29 | 30 | done(); 31 | }); 32 | 33 | }; 34 | 35 | var asyncErrorTest = function(host, done, param){ 36 | Helpers.send(host, { 37 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 38 | 39 | // PARAMETERS 40 | params: param ? [param] : [] 41 | 42 | }, function(result, status) { 43 | 44 | assert.equal(status, 200, 'has status code'); 45 | assert.property(result, 'error'); 46 | assert.equal(result.error.code, -32602); 47 | 48 | done(); 49 | }); 50 | }; 51 | 52 | 53 | 54 | describe(method, function(){ 55 | Helpers.eachHost(function(key, host){ 56 | 57 | // OPTIONS FILTER 58 | describe(key, function(){ 59 | 60 | _.each(config.logs, function(log){ 61 | it('should return the correct log, when filtering without defining an address', function(done){ 62 | // INSTALL a options filter first 63 | Helpers.send(host, { 64 | id: config.rpcMessageId++, jsonrpc: "2.0", method: 'eth_newFilter', 65 | 66 | // PARAMETERS 67 | params: [{ 68 | "fromBlock": Helpers.fromDecimal(log.block.blockHeader.number), 69 | "toBlock": Helpers.fromDecimal(log.block.blockHeader.number) 70 | }] 71 | 72 | }, function(optionsFilterId){ 73 | 74 | asyncTest(host, optionsFilterId.result, [log], function(){ 75 | 76 | // remove filter 77 | uninstallFilter(host, optionsFilterId.result, done); 78 | }); 79 | }); 80 | 81 | 82 | }); 83 | 84 | it('should return the correct log, when filtering with address', function(done){ 85 | // INSTALL a options filter first 86 | Helpers.send(host, { 87 | id: config.rpcMessageId++, jsonrpc: "2.0", method: 'eth_newFilter', 88 | 89 | // PARAMETERS 90 | params: [{ 91 | "address": '0x'+ log.tx.to, 92 | "fromBlock": Helpers.fromDecimal(log.block.blockHeader.number), 93 | "toBlock": Helpers.fromDecimal(log.block.blockHeader.number) 94 | }] 95 | 96 | }, function(optionsFilterId){ 97 | 98 | asyncTest(host, optionsFilterId.result, [log], function(){ 99 | 100 | // remove filter 101 | uninstallFilter(host, optionsFilterId.result, done); 102 | }); 103 | 104 | }); 105 | 106 | }); 107 | }); 108 | 109 | it('should return a list of logs, when asking without defining an address and using toBlock "latest"', function(done){ 110 | // INSTALL a options filter first 111 | Helpers.send(host, { 112 | id: config.rpcMessageId++, jsonrpc: "2.0", method: 'eth_newFilter', 113 | 114 | // PARAMETERS 115 | params: [{ 116 | "fromBlock": '0x0', 117 | "toBlock": 'latest' 118 | }] 119 | 120 | }, function(optionsFilterId){ 121 | 122 | asyncTest(host, optionsFilterId.result, config.logs, function(){ 123 | 124 | // remove filter 125 | uninstallFilter(host, optionsFilterId.result, done); 126 | }); 127 | }); 128 | }); 129 | 130 | it('should return a list of logs, when asking without defining an address and using toBlock "pending"', function(done){ 131 | // INSTALL a options filter first 132 | Helpers.send(host, { 133 | id: config.rpcMessageId++, jsonrpc: "2.0", method: 'eth_newFilter', 134 | 135 | // PARAMETERS 136 | params: [{ 137 | "fromBlock": '0x0', 138 | "toBlock": 'pending' 139 | }] 140 | 141 | }, function(optionsFilterId){ 142 | 143 | asyncTest(host, optionsFilterId.result, config.logs, function(){ 144 | 145 | // remove filter 146 | uninstallFilter(host, optionsFilterId.result, done); 147 | }); 148 | }); 149 | }); 150 | 151 | it('should return a list of logs, when filtering with defining an address and using toBlock "latest"', function(done){ 152 | // INSTALL a options filter first 153 | Helpers.send(host, { 154 | id: config.rpcMessageId++, jsonrpc: "2.0", method: 'eth_newFilter', 155 | 156 | // PARAMETERS 157 | params: [{ 158 | "fromBlock": '0x0', 159 | "toBlock": 'latest', 160 | 'address': "0x"+ config.logs[0].tx.to 161 | }] 162 | 163 | }, function(optionsFilterId){ 164 | 165 | asyncTest(host, optionsFilterId.result, config.logs, function(){ 166 | 167 | // remove filter 168 | uninstallFilter(host, optionsFilterId.result, done); 169 | }); 170 | }); 171 | }); 172 | 173 | it('should return a list of logs, when filtering with defining an address and using toBlock "pending"', function(done){ 174 | 175 | 176 | // INSTALL a options filter first 177 | Helpers.send(host, { 178 | id: config.rpcMessageId++, jsonrpc: "2.0", method: 'eth_newFilter', 179 | 180 | // PARAMETERS 181 | params: [{ 182 | "fromBlock": '0x0', 183 | "toBlock": 'pending', 184 | 'address': "0x"+ config.logs[0].tx.to 185 | }] 186 | 187 | }, function(optionsFilterId){ 188 | 189 | asyncTest(host, optionsFilterId.result, config.logs, function(result){ 190 | 191 | // remove filter 192 | uninstallFilter(host, optionsFilterId.result, done); 193 | }); 194 | }); 195 | }); 196 | 197 | it('should return a list of logs, when filtering by topic "0x0000000000000000000000000000000000000000000000000000000000000001"', function(done){ 198 | // INSTALL a options filter first 199 | Helpers.send(host, { 200 | id: config.rpcMessageId++, jsonrpc: "2.0", method: 'eth_newFilter', 201 | 202 | // PARAMETERS 203 | params: [{ 204 | "fromBlock": '0x0', 205 | "toBlock": 'latest', 206 | "topics": ['0x0000000000000000000000000000000000000000000000000000000000000001'] 207 | }] 208 | 209 | }, function(optionsFilterId){ 210 | 211 | // get only the logs which have true as the first index arg 212 | var newLogs = _.filter(config.logs, function(log){ 213 | return (log.anonymous && log.indexArgs[0] === true); 214 | }); 215 | 216 | asyncTest(host, optionsFilterId.result, newLogs, function(){ 217 | 218 | // remove filter 219 | uninstallFilter(host, optionsFilterId.result, done); 220 | }); 221 | }); 222 | 223 | }); 224 | 225 | it('should return a list of anonymous logs, when filtering by topic "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"', function(done){ 226 | // INSTALL a options filter first 227 | Helpers.send(host, { 228 | id: config.rpcMessageId++, jsonrpc: "2.0", method: 'eth_newFilter', 229 | 230 | // PARAMETERS 231 | params: [{ 232 | "fromBlock": '0x0', 233 | "toBlock": 'latest', 234 | "topics": [null, null, '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'] 235 | }] 236 | 237 | }, function(optionsFilterId){ 238 | 239 | // get only the logs which have true as the first index arg 240 | var newLogs = _.filter(config.logs, function(log){ 241 | return (log.anonymous && log.indexArgs[2] === '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'); 242 | }); 243 | 244 | asyncTest(host, optionsFilterId.result, newLogs, function(){ 245 | 246 | // remove filter 247 | uninstallFilter(host, optionsFilterId.result, done); 248 | 249 | }); 250 | }); 251 | 252 | }); 253 | 254 | it('should return a list of logs, when filtering by topic "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"', function(done){ 255 | // INSTALL a options filter first 256 | Helpers.send(host, { 257 | id: config.rpcMessageId++, jsonrpc: "2.0", method: 'eth_newFilter', 258 | 259 | // PARAMETERS 260 | params: [{ 261 | "fromBlock": '0x0', 262 | "toBlock": 'latest', 263 | "topics": [null, null, null, '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'] 264 | }] 265 | 266 | }, function(optionsFilterId){ 267 | 268 | // get only the logs which have true as the first index arg 269 | var newLogs = _.filter(config.logs, function(log){ 270 | return (!log.anonymous && log.indexArgs[2] === '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'); 271 | }); 272 | 273 | asyncTest(host, optionsFilterId.result, newLogs, function(){ 274 | 275 | // remove filter 276 | uninstallFilter(host, optionsFilterId.result, done); 277 | }); 278 | }); 279 | }); 280 | 281 | 282 | it('should return an error when no parameter is passed', function(done){ 283 | asyncErrorTest(host, done); 284 | }); 285 | }); 286 | }); 287 | }); 288 | -------------------------------------------------------------------------------- /test/eth_getFilterLogsEx.js_: -------------------------------------------------------------------------------- 1 | var config = require('../lib/config'), 2 | Helpers = require('../lib/helpers'), 3 | assert = require('chai').assert, 4 | _ = require('underscore'); 5 | 6 | // METHOD 7 | var method = 'eth_getFilterLogsEx', 8 | uninstallFilter = function(host, id, done) { 9 | Helpers.send(host, {id: config.rpcMessageId++, jsonrpc: "2.0", method: 'eth_uninstallFilter', params: [id] }, function() { 10 | done(); 11 | }); 12 | }; 13 | 14 | // TEST 15 | var asyncTest = function(host, filterId, logsInfo, done){ 16 | 17 | Helpers.send(host, { 18 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 19 | 20 | // PARAMETERS 21 | params: [filterId] 22 | 23 | }, function(result){ 24 | 25 | assert.property(result, 'result', (result.error) ? result.error.message : 'error'); 26 | assert.equal(result.result.length, logsInfo.length, 'logs should be '+ logsInfo.length); 27 | 28 | _.each(result.result, function(log, index){ 29 | Helpers.logExTest(log, logsInfo[index]); 30 | }); 31 | 32 | done(); 33 | }); 34 | 35 | }; 36 | 37 | var asyncErrorTest = function(host, done, param){ 38 | Helpers.send(host, { 39 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 40 | 41 | // PARAMETERS 42 | params: param ? [param] : [] 43 | 44 | }, function(result, status) { 45 | 46 | assert.equal(status, 200, 'has status code'); 47 | assert.property(result, 'error'); 48 | assert.equal(result.error.code, -32602); 49 | 50 | done(); 51 | }); 52 | }; 53 | 54 | 55 | 56 | describe(method, function(){ 57 | Helpers.eachHost(function(key, host){ 58 | 59 | // OPTIONS FILTER 60 | describe(key, function(){ 61 | 62 | _.each(config.logs, function(log){ 63 | it('should return the correct log, when filtering without defining an address', function(done){ 64 | // INSTALL a options filter first 65 | Helpers.send(host, { 66 | id: config.rpcMessageId++, jsonrpc: "2.0", method: 'eth_newFilterEx', 67 | 68 | // PARAMETERS 69 | params: [{ 70 | "fromBlock": '0x' + log.block.blockHeader.hash, 71 | "toBlock": '0x' + log.block.blockHeader.hash 72 | }] 73 | 74 | }, function(optionsFilterId){ 75 | 76 | asyncTest(host, optionsFilterId.result, [log], function(){ 77 | 78 | // remove filter 79 | uninstallFilter(host, optionsFilterId.result, done); 80 | }); 81 | 82 | }); 83 | 84 | }); 85 | 86 | it('should return the correct log, when filtering with address', function(done){ 87 | // INSTALL a options filter first 88 | Helpers.send(host, { 89 | id: config.rpcMessageId++, jsonrpc: "2.0", method: 'eth_newFilterEx', 90 | 91 | // PARAMETERS 92 | params: [{ 93 | "address": '0x'+ log.tx.to, 94 | "fromBlock": '0x' + log.block.blockHeader.hash, 95 | "toBlock": '0x' + log.block.blockHeader.hash 96 | }] 97 | 98 | }, function(optionsFilterId){ 99 | 100 | asyncTest(host, optionsFilterId.result, [log], function(){ 101 | 102 | // remove filter 103 | uninstallFilter(host, optionsFilterId.result, done); 104 | }); 105 | 106 | }); 107 | 108 | }); 109 | }); 110 | 111 | 112 | it('should return the reverted logs', function(done){ 113 | // INSTALL a options filter first 114 | Helpers.send(host, { 115 | id: config.rpcMessageId++, jsonrpc: "2.0", method: 'eth_newFilterEx', 116 | 117 | // PARAMETERS 118 | params: [config.specialLogQuery] 119 | 120 | }, function(optionsFilterId){ 121 | 122 | asyncTest(host, optionsFilterId.result, config.specialLogResult, function(){ 123 | 124 | // remove filter 125 | uninstallFilter(host, optionsFilterId.result, done); 126 | }); 127 | 128 | }); 129 | 130 | }); 131 | 132 | }); 133 | }); 134 | }); 135 | -------------------------------------------------------------------------------- /test/eth_getFilterLogs_fromExFilter.js_: -------------------------------------------------------------------------------- 1 | var config = require('../lib/config'), 2 | Helpers = require('../lib/helpers'), 3 | assert = require('chai').assert, 4 | _ = require('underscore'); 5 | 6 | // METHOD 7 | var method = 'eth_getFilterLogs', 8 | uninstallFilter = function(host, id, done) { 9 | Helpers.send(host, {id: config.rpcMessageId++, jsonrpc: "2.0", method: 'eth_uninstallFilter', params: [id] }, function(){ 10 | done(); 11 | }); 12 | }; 13 | 14 | // TEST 15 | var asyncTest = function(host, filterId, logsInfo, done){ 16 | 17 | Helpers.send(host, { 18 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 19 | 20 | // PARAMETERS 21 | params: [filterId] 22 | 23 | }, function(result, status){ 24 | 25 | assert.property(result, 'result', (result.error) ? result.error.message : 'error'); 26 | assert.equal(result.result.length, logsInfo.length, 'logs should be '+ logsInfo.length); 27 | 28 | _.each(result.result, function(log, index){ 29 | Helpers.logTest(log, logsInfo[index]); 30 | }); 31 | 32 | done(); 33 | }); 34 | 35 | }; 36 | 37 | var asyncErrorTest = function(host, done, param){ 38 | Helpers.send(host, { 39 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 40 | 41 | // PARAMETERS 42 | params: param ? [param] : [] 43 | 44 | }, function(result, status) { 45 | 46 | assert.equal(status, 200, 'has status code'); 47 | assert.property(result, 'error'); 48 | assert.equal(result.error.code, -32602); 49 | 50 | done(); 51 | }); 52 | }; 53 | 54 | 55 | 56 | describe(method, function(){ 57 | Helpers.eachHost(function(key, host){ 58 | 59 | // OPTIONS FILTER 60 | describe(key, function(){ 61 | 62 | _.each(config.logs, function(log){ 63 | it('should return the correct log, when filtering without defining an address', function(done){ 64 | // INSTALL a options filter first 65 | Helpers.send(host, { 66 | id: config.rpcMessageId++, jsonrpc: "2.0", method: 'eth_newFilterEx', 67 | 68 | // PARAMETERS 69 | params: [{ 70 | "fromBlock": '0x' + log.block.blockHeader.hash, 71 | "toBlock": '0x' + log.block.blockHeader.hash 72 | }] 73 | 74 | }, function(optionsFilterId){ 75 | 76 | asyncTest(host, optionsFilterId.result, [log], function(){ 77 | 78 | // remove filter 79 | uninstallFilter(host, optionsFilterId.result, done); 80 | }); 81 | 82 | }); 83 | 84 | }); 85 | 86 | it('should return the correct log, when filtering with address', function(done){ 87 | // INSTALL a options filter first 88 | Helpers.send(host, { 89 | id: config.rpcMessageId++, jsonrpc: "2.0", method: 'eth_newFilterEx', 90 | 91 | // PARAMETERS 92 | params: [{ 93 | "address": '0x'+ log.tx.to, 94 | "fromBlock": '0x' + log.block.blockHeader.hash, 95 | "toBlock": '0x' + log.block.blockHeader.hash 96 | }] 97 | 98 | }, function(optionsFilterId){ 99 | 100 | asyncTest(host, optionsFilterId.result, [log], function(){ 101 | 102 | // remove filter 103 | uninstallFilter(host, optionsFilterId.result, done); 104 | }); 105 | 106 | }); 107 | 108 | }); 109 | }); 110 | 111 | 112 | it('should return the reverted logs', function(done){ 113 | // INSTALL a options filter first 114 | Helpers.send(host, { 115 | id: config.rpcMessageId++, jsonrpc: "2.0", method: 'eth_newFilterEx', 116 | 117 | // PARAMETERS 118 | params: [config.specialLogQuery] 119 | 120 | }, function(optionsFilterId){ 121 | 122 | asyncTest(host, optionsFilterId.result, config.specialLogResult, function(){ 123 | 124 | // remove filter 125 | uninstallFilter(host, optionsFilterId.result, done); 126 | }); 127 | 128 | }); 129 | 130 | }); 131 | 132 | }); 133 | }); 134 | }); 135 | -------------------------------------------------------------------------------- /test/eth_getStorageAt.js: -------------------------------------------------------------------------------- 1 | var config = require('../lib/config'), 2 | Helpers = require('../lib/helpers'), 3 | assert = require('chai').assert, 4 | _ = require('underscore'); 5 | 6 | // METHOD 7 | var method = 'eth_getStorageAt'; 8 | 9 | 10 | // TEST 11 | var asyncTest = function(host, done, params, expectedResult){ 12 | Helpers.send(host, { 13 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 14 | 15 | // PARAMETERS 16 | params: params 17 | 18 | }, function(result, status) { 19 | 20 | 21 | assert.equal(status, 200, 'has status code'); 22 | assert.property(result, 'result', (result.error) ? result.error.message : 'error'); 23 | assert.isString(result.result, 'is string'); 24 | assert.match(result.result, /^0x/, 'should be HEX starting with 0x'); 25 | 26 | expectedResult = Helpers.padLeft(expectedResult, 64); 27 | 28 | assert.equal(result.result, expectedResult, 'should match '+ expectedResult); 29 | 30 | done(); 31 | }); 32 | }; 33 | 34 | 35 | var asyncErrorTest = function(host, done){ 36 | Helpers.send(host, { 37 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 38 | 39 | // PARAMETERS 40 | params: [] 41 | 42 | }, function(result, status) { 43 | 44 | assert.equal(status, 200, 'has status code'); 45 | assert.property(result, 'error'); 46 | assert.equal(result.error.code, -32602); 47 | 48 | done(); 49 | }); 50 | }; 51 | 52 | 53 | 54 | describe(method, function(){ 55 | 56 | Helpers.eachHost(function(key, host){ 57 | describe(key, function(){ 58 | 59 | _.each(config.testBlocks.postState, function(state, key){ 60 | _.each(state.storage, function(storage, index){ 61 | // fix block test file 62 | index = index.replace('0x0','0x'); 63 | it('should return '+ storage +' when the defaultBlock is "latest" for storage position '+ index +' at address 0x'+ key, function(done){ 64 | asyncTest(host, done, [ 65 | '0x'+ key, 66 | index, 67 | 'latest' 68 | ], storage); 69 | }); 70 | }); 71 | }); 72 | 73 | _.each(config.testBlocks.pre, function(state, key){ 74 | _.each(state.storage, function(storage, index){ 75 | // fix block test file 76 | index = index.replace('0x0','0x'); 77 | it('should return '+ storage +' when the defaultBlock is 0 for storage position '+ index +' at address 0x'+ key, function(done){ 78 | asyncTest(host, done, [ 79 | '0x' + key, 80 | index, 81 | '0x0' 82 | ], storage); 83 | }); 84 | }); 85 | }); 86 | 87 | it('should return an error when no parameter is passed', function(done){ 88 | asyncErrorTest(host, done); 89 | }); 90 | }); 91 | }); 92 | }); 93 | -------------------------------------------------------------------------------- /test/eth_getTransactionBy.js: -------------------------------------------------------------------------------- 1 | var config = require('../lib/config'), 2 | Helpers = require('../lib/helpers'), 3 | assert = require('chai').assert; 4 | _ = require('underscore'); 5 | 6 | 7 | 8 | // TEST 9 | var asyncTest = function(host, done, method, params, block, index){ 10 | 11 | Helpers.send(host, { 12 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 13 | 14 | // PARAMETERS 15 | params: params 16 | 17 | }, function(result){ 18 | 19 | assert.property(result, 'result', (result.error) ? result.error.message : 'error'); 20 | 21 | if(!block) 22 | assert.isNull(result.result); 23 | else if(block === 'pending') { 24 | assert.isObject(result.result, 'is object'); 25 | assert.isNull(result.transactionIndex); 26 | assert.isNull(result.blockNumber); 27 | assert.isNull(result.blockHash); 28 | } else { 29 | assert.isObject(result.result, 'expected transaction to be an object. transaction location (blockhash, index): ' + block.blockHeader.hash + ', ' + index); 30 | Helpers.transactionTest(result.result, block.transactions[index], index, block); 31 | } 32 | 33 | done(); 34 | }); 35 | 36 | }; 37 | 38 | 39 | var asyncErrorTest = function(host, done, method, params){ 40 | Helpers.send(host, { 41 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 42 | 43 | // PARAMETERS 44 | params: params 45 | 46 | }, function(result, status) { 47 | 48 | assert.equal(status, 200, 'has status code'); 49 | assert.property(result, 'error'); 50 | assert.equal(result.error.code, -32602); 51 | 52 | done(); 53 | }); 54 | }; 55 | 56 | 57 | 58 | var method1 = 'eth_getTransactionByHash'; 59 | describe(method1, function(){ 60 | 61 | Helpers.eachHost(function(key, host){ 62 | describe(key, function(){ 63 | _.each(config.testBlocks.blocks, function(bl){ 64 | _.each(bl.transactions, function(tx, index){ 65 | it('should return a transaction with the proper structure', function(done){ 66 | 67 | Helpers.send(host, { 68 | id: config.rpcMessageId++, jsonrpc: "2.0", method: 'eth_getBlockByHash', 69 | 70 | // PARAMETERS 71 | params: ['0x'+ bl.blockHeader.hash, false] 72 | }, function(givenBlock){ 73 | 74 | if(bl.reverted) 75 | asyncTest(host, done, method1, [givenBlock.result.transactions[index]], null, index); 76 | else 77 | asyncTest(host, done, method1, [givenBlock.result.transactions[index]], bl, index); 78 | }); 79 | 80 | }); 81 | }); 82 | }); 83 | 84 | it('should return null when no transaction was found', function(done){ 85 | asyncTest(host, done, method1, ['0xd2f1575105fd2272914d77355b8dab5afbdde4b012abd849e8b32111be498b0d'], null); 86 | }); 87 | it('should return an error when no parameter is passed', function(done){ 88 | asyncErrorTest(host, done, method1, []); 89 | }); 90 | }); 91 | }); 92 | }); 93 | 94 | 95 | var method2 = 'eth_getTransactionByBlockHashAndIndex'; 96 | describe(method2, function(){ 97 | 98 | Helpers.eachHost(function(key, host){ 99 | describe(key, function(){ 100 | _.each(config.testBlocks.blocks, function(bl){ 101 | _.each(bl.transactions, function(tx, index){ 102 | it('should return a transaction with the proper structure', function(done){ 103 | asyncTest(host, done, method2, ['0x'+ bl.blockHeader.hash, Helpers.fromDecimal(index)], bl, index); 104 | }); 105 | }); 106 | }); 107 | 108 | it('should return null when no transaction was found', function(done){ 109 | asyncTest(host, done, method2, ['0x'+ config.testBlocks.blocks[0].blockHeader.hash, '0xb'], null); 110 | }); 111 | 112 | it('should return an error when no parameter is passed', function(done){ 113 | asyncErrorTest(host, done, method2, []); 114 | }); 115 | }); 116 | }); 117 | }); 118 | 119 | 120 | var method3 = 'eth_getTransactionByBlockNumberAndIndex'; 121 | describe(method3, function(){ 122 | 123 | Helpers.eachHost(function(key, host){ 124 | describe(key, function(){ 125 | _.each(config.testBlocks.blocks.filter(function (block) { return block.reverted !== true }), function(bl){ 126 | _.each(bl.transactions, function(tx, index){ 127 | it('should return a transaction with the proper structure', function(done){ 128 | asyncTest(host, done, method3, [Helpers.fromDecimal(bl.blockHeader.number), Helpers.fromDecimal(index)], bl, index); 129 | }); 130 | }); 131 | }); 132 | 133 | it('should return no transactions at the genisis block when using "earliest"', function(done){ 134 | asyncTest(host, done, method3, ['earliest', '0x0'], null, 0, done); 135 | }); 136 | 137 | it('should return one transaction at 0 for the last block when using "latest"', function(done){ 138 | asyncTest(host, done, method3, ['latest', '0x0'], config.testBlocks.blocks[config.testBlocks.blocks.length-1], 0); 139 | }); 140 | 141 | it('should return transactions for the pending block when using "pending" and sending transactions before', function(done){ 142 | 143 | // send transaction 144 | Helpers.send(host, { 145 | id: config.rpcMessageId++, jsonrpc: "2.0", method: 'eth_sendTransaction', 146 | 147 | // PARAMETERS 148 | params: [{ 149 | "from": config.senderAddress, 150 | "to": config.contractAddress, 151 | "value" : 0 152 | }] 153 | 154 | }, function(res){ 155 | 156 | setTimeout(function(){ 157 | 158 | asyncTest(host, done, method3, ['pending', '0x0'], 'pending'); 159 | }, 1000); 160 | }); 161 | 162 | }); 163 | 164 | it('should return null when no transaction was found', function(done){ 165 | asyncTest(host, done, method3, ['0x2', '0xb'], null); 166 | }); 167 | it('should return an error when no parameter is passed', function(done){ 168 | asyncErrorTest(host, done, method3, []); 169 | }); 170 | }); 171 | }); 172 | }); 173 | 174 | -------------------------------------------------------------------------------- /test/eth_getTransactionCount.js: -------------------------------------------------------------------------------- 1 | var config = require('../lib/config'), 2 | Helpers = require('../lib/helpers'), 3 | assert = require('chai').assert; 4 | 5 | // METHOD 6 | var method = 'eth_getTransactionCount'; 7 | 8 | 9 | // TEST 10 | var asyncTest = function(host, done, params, expectedResult){ 11 | Helpers.send(host, { 12 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 13 | 14 | // PARAMETERS 15 | params: params 16 | 17 | }, function(result, status) { 18 | 19 | 20 | assert.equal(status, 200, 'has status code'); 21 | assert.property(result, 'result', (result.error) ? result.error.message : 'error'); 22 | assert.isString(result.result, 'is string'); 23 | assert.match(result.result, /^0x/, 'should be HEX starting with 0x'); 24 | assert.isNumber(+result.result, 'can be converted to a number'); 25 | 26 | assert.equal(+result.result, expectedResult, 'should be '+ expectedResult); 27 | 28 | done(); 29 | }); 30 | }; 31 | 32 | 33 | var asyncErrorTest = function(host, done){ 34 | Helpers.send(host, { 35 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 36 | 37 | // PARAMETERS 38 | params: [] 39 | 40 | }, function(result, status) { 41 | 42 | assert.equal(status, 200, 'has status code'); 43 | assert.property(result, 'error'); 44 | assert.equal(result.error.code, -32602); 45 | 46 | done(); 47 | }); 48 | }; 49 | 50 | 51 | 52 | describe(method, function(){ 53 | 54 | Helpers.eachHost(function(key, host){ 55 | describe(key, function(){ 56 | it('should return the current number of transactions as a hexstring when the defaultBlock is 0', function(done){ 57 | asyncTest(host, done, ['0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b', '0x0'], +config.testBlocks.pre['a94f5374fce5edbc8e2a8697c15331677e6ebf0b'].nonce); 58 | }); 59 | 60 | it('should return the current number of transactions as a hexstring when the defaultBlock is "latest"', function(done){ 61 | asyncTest(host, done, ['0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b', 'latest'], +config.testBlocks.postState['a94f5374fce5edbc8e2a8697c15331677e6ebf0b'].nonce); 62 | }); 63 | 64 | it('should return an error when no parameter is passed', function(done){ 65 | asyncErrorTest(host, done); 66 | }); 67 | }); 68 | }); 69 | }); 70 | -------------------------------------------------------------------------------- /test/eth_getTransactionReceipt.js: -------------------------------------------------------------------------------- 1 | var config = require('../lib/config'), 2 | Helpers = require('../lib/helpers'), 3 | assert = require('chai').assert; 4 | _ = require('underscore'); 5 | 6 | var method = 'eth_getTransactionReceipt'; 7 | 8 | 9 | // TEST 10 | var asyncTest = function(host, done, method, params, block, index){ 11 | 12 | Helpers.send(host, { 13 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 14 | 15 | // PARAMETERS 16 | params: params 17 | }, function(result){ 18 | 19 | assert.property(result, 'result', (result.error) ? result.error.message : 'error'); 20 | 21 | if(!block) 22 | assert.isNull(result.result); 23 | else if(block === 'pending') { 24 | assert.isObject(result.result, 'is object'); 25 | assert.isNull(result.transactionIndex); 26 | assert.isNull(result.blockNumber); 27 | assert.isNull(result.blockHash); 28 | } else { 29 | assert.isObject(result.result, 'expected transaction to be an object. transaction location: ' + block.blockHeader.hash + ', ' + index); 30 | Helpers.transactionReceiptTest(result.result, block.transactions[index], index, block); 31 | } 32 | 33 | done(); 34 | }); 35 | 36 | }; 37 | 38 | 39 | var asyncErrorTest = function(host, done, method, params){ 40 | Helpers.send(host, { 41 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 42 | 43 | // PARAMETERS 44 | params: params 45 | 46 | }, function(result, status) { 47 | 48 | assert.equal(status, 200, 'has status code'); 49 | assert.property(result, 'error'); 50 | assert.equal(result.error.code, -32602); 51 | 52 | done(); 53 | }); 54 | }; 55 | 56 | 57 | 58 | describe(method, function(){ 59 | 60 | Helpers.eachHost(function(key, host){ 61 | describe(key, function(){ 62 | _.each(config.testBlocks.blocks, function(bl){ 63 | _.each(bl.transactions, function(tx, index){ 64 | it('should return a transaction receipt with the proper structure', function(done){ 65 | 66 | Helpers.send(host, { 67 | id: config.rpcMessageId++, jsonrpc: "2.0", method: 'eth_getBlockByHash', 68 | 69 | // PARAMETERS 70 | params: ['0x'+ bl.blockHeader.hash, false] 71 | }, function(givenBlock){ 72 | 73 | if(bl.reverted) 74 | asyncTest(host, done, method, [givenBlock.result.transactions[index]], null, index); 75 | else 76 | asyncTest(host, done, method, [givenBlock.result.transactions[index]], bl, index); 77 | }); 78 | 79 | }); 80 | }); 81 | }); 82 | 83 | it('should return null when no transaction was found', function(done){ 84 | asyncTest(host, done, method, ['0xd2f1575105fd2272914d77355b8dab5afbdde4b012abd849e8b32111be498b0d'], null); 85 | }); 86 | it('should return an error when no parameter is passed', function(done){ 87 | asyncErrorTest(host, done, method, []); 88 | }); 89 | }); 90 | }); 91 | }); 92 | 93 | 94 | -------------------------------------------------------------------------------- /test/eth_getUncleBy.js: -------------------------------------------------------------------------------- 1 | var config = require('../lib/config'), 2 | Helpers = require('../lib/helpers'), 3 | assert = require('chai').assert; 4 | _ = require('underscore'); 5 | 6 | 7 | // TEST 8 | var asyncTest = function(host, done, method, params, uncle){ 9 | 10 | Helpers.send(host, { 11 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 12 | 13 | // PARAMETERS 14 | params: params 15 | }, function(result){ 16 | 17 | assert.property(result, 'result', (result.error) ? result.error.message : 'error'); 18 | 19 | if(!uncle) 20 | assert.isNull(result.result); 21 | else { 22 | assert.isObject(result.result, 'is object'); 23 | Helpers.blockTest(result.result, uncle); 24 | } 25 | 26 | done(); 27 | }); 28 | 29 | }; 30 | 31 | 32 | var asyncErrorTest = function(host, done, method, params){ 33 | Helpers.send(host, { 34 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 35 | 36 | // PARAMETERS 37 | params: params 38 | 39 | }, function(result, status) { 40 | 41 | assert.equal(status, 200, 'has status code'); 42 | assert.property(result, 'error'); 43 | assert.equal(result.error.code, -32602); 44 | 45 | done(); 46 | }); 47 | }; 48 | 49 | 50 | var method1 = 'eth_getUncleByBlockHashAndIndex'; 51 | describe(method1, function(){ 52 | 53 | Helpers.eachHost(function(key, host){ 54 | describe(key, function(){ 55 | 56 | _.each(config.testBlocks.blocks, function(block){ 57 | _.each(block.uncleHeaders, function(uncle, index){ 58 | it('should return an uncle with the proper structure', function(done){ 59 | asyncTest(host, done, method1, ['0x'+ block.blockHeader.hash, Helpers.fromDecimal(index)], uncle); 60 | }); 61 | }); 62 | }); 63 | 64 | it('should return null when no uncle was found', function(done){ 65 | asyncTest(host, done, method1, ['0x878a132155f53adb7c993ded4cfb687977397d63d873fcdbeb06c18cac907a5c', '0xb'], null); 66 | }); 67 | it('should return an error when the wrong parameters is passed', function(done){ 68 | asyncErrorTest(host, done, method1, ['0x878a132155f53adb7c993ded4cfb687977397d63d873fcdbeb06c18cac907a5c']); 69 | }); 70 | it('should return an error when no parameter is passed', function(done){ 71 | asyncErrorTest(host, done, method1, []); 72 | }); 73 | }); 74 | }); 75 | }); 76 | 77 | 78 | var method2 = 'eth_getUncleByBlockNumberAndIndex'; 79 | describe(method2, function(){ 80 | 81 | Helpers.eachHost(function(key, host){ 82 | describe(key, function(){ 83 | 84 | _.each(config.testBlocks.blocks, function(block){ 85 | _.each(block.uncleHeaders, function(uncle, index){ 86 | it('should return an uncle with the proper structure', function(done){ 87 | asyncTest(host, done, method2, [Helpers.fromDecimal(block.blockHeader.number), Helpers.fromDecimal(index)], uncle); 88 | }); 89 | }); 90 | }); 91 | 92 | it('should return null when no uncle was found', function(done){ 93 | asyncTest(host, done, method2, ['0x2', '0xbbb'], null); 94 | }); 95 | 96 | it('should return a no uncles when using "earliest"', function(done){ 97 | asyncTest(host, done, method2, ['earliest', '0x0'], null); 98 | }); 99 | 100 | it('should return a no uncles when using "latest" (as there are none)', function(done){ 101 | asyncTest(host, done, method2, ['latest', '0x0'], null); 102 | }); 103 | 104 | it('should return a no uncles when using "pending" (as there are none)', function(done){ 105 | asyncTest(host, done, method2, ['pending', '0x0'], null); 106 | }); 107 | 108 | it('should return an error when the wrong parameters is passed', function(done){ 109 | asyncErrorTest(host, done, method2, ['0x878a132155f53adb7c993ded4cfb687977397d63d873fcdbeb06c18cac907a5c']); 110 | }); 111 | it('should return an error when no parameter is passed', function(done){ 112 | asyncErrorTest(host, done, method2, []); 113 | }); 114 | }); 115 | }); 116 | }); 117 | 118 | -------------------------------------------------------------------------------- /test/eth_getUncleCountByBlockHash.js: -------------------------------------------------------------------------------- 1 | var config = require('../lib/config'), 2 | Helpers = require('../lib/helpers'), 3 | assert = require('chai').assert, 4 | _ = require('underscore'); 5 | 6 | // METHOD 7 | var method = 'eth_getUncleCountByBlockHash'; 8 | 9 | // GET test BLOCK 4 10 | var block4 = Helpers.getBlockByNumber(4); 11 | var block5 = Helpers.getBlockByNumber(5); 12 | var block6 = Helpers.getBlockByNumber(6); 13 | 14 | // TEST 15 | var asyncTest = function(host, done, params, expectedResult){ 16 | Helpers.send(host, { 17 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 18 | 19 | // PARAMETERS 20 | params: params 21 | 22 | }, function(result, status) { 23 | 24 | 25 | assert.equal(status, 200, 'has status code'); 26 | assert.property(result, 'result', (result.error) ? result.error.message : 'error'); 27 | 28 | 29 | if(!result.result) { 30 | assert.isNull(result.result); 31 | } else { 32 | assert.isString(result.result, 'is string'); 33 | assert.match(result.result, /^0x/, 'should be HEX starting with 0x'); 34 | assert.isNumber(+result.result, 'can be converted to a number'); 35 | 36 | assert.equal(+result.result, expectedResult, 'should be '+ expectedResult); 37 | } 38 | 39 | done(); 40 | }); 41 | }; 42 | 43 | 44 | var asyncErrorTest = function(host, done){ 45 | Helpers.send(host, { 46 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 47 | 48 | // PARAMETERS 49 | params: [] 50 | 51 | }, function(result, status) { 52 | 53 | assert.equal(status, 200, 'has status code'); 54 | assert.property(result, 'error'); 55 | assert.equal(result.error.code, -32602); 56 | 57 | done(); 58 | }); 59 | }; 60 | 61 | 62 | 63 | describe(method, function(){ 64 | 65 | Helpers.eachHost(function(key, host){ 66 | describe(key, function(){ 67 | 68 | _.each(config.testBlocks.blocks, function(block){ 69 | it('should return '+block.uncleHeaders.length+' as a hexstring', function(done){ 70 | asyncTest(host, done, ['0x'+ block.blockHeader.hash], block.uncleHeaders.length); 71 | }); 72 | }); 73 | 74 | 75 | it('should return null if the block doesnt exist', function(done){ 76 | asyncTest(host, done, ['0x878a132155f53adb7c993ded4cfb687977397d63d873fcdbeb06c18cac907a5c'], null); 77 | }); 78 | 79 | it('should return an error when no parameter is passed', function(done){ 80 | asyncErrorTest(host, done); 81 | }); 82 | }); 83 | }); 84 | }); 85 | -------------------------------------------------------------------------------- /test/eth_getUncleCountByBlockNumber.js: -------------------------------------------------------------------------------- 1 | var config = require('../lib/config'), 2 | Helpers = require('../lib/helpers'), 3 | assert = require('chai').assert, 4 | _ = require('underscore'); 5 | 6 | // METHOD 7 | var method = 'eth_getUncleCountByBlockNumber'; 8 | 9 | 10 | // TEST 11 | var asyncTest = function(host, done, params, expectedResult){ 12 | Helpers.send(host, { 13 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 14 | 15 | // PARAMETERS 16 | params: params 17 | 18 | }, function(result, status) { 19 | 20 | 21 | assert.equal(status, 200, 'has status code'); 22 | assert.property(result, 'result', (result.error) ? result.error.message : 'error'); 23 | 24 | 25 | if(!result.result) { 26 | assert.isNull(result.result); 27 | } else { 28 | assert.isString(result.result, 'is string'); 29 | assert.match(result.result, /^0x/, 'should be HEX starting with 0x'); 30 | assert.isNumber(+result.result, 'can be converted to a number'); 31 | 32 | assert.equal(+result.result, expectedResult, 'should be '+ expectedResult); 33 | } 34 | 35 | done(); 36 | }); 37 | }; 38 | 39 | 40 | var asyncErrorTest = function(host, done){ 41 | Helpers.send(host, { 42 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 43 | 44 | // PARAMETERS 45 | params: [] 46 | 47 | }, function(result, status) { 48 | 49 | assert.equal(status, 200, 'has status code'); 50 | assert.property(result, 'error'); 51 | assert.equal(result.error.code, -32602); 52 | 53 | done(); 54 | }); 55 | }; 56 | 57 | 58 | 59 | describe(method, function(){ 60 | 61 | Helpers.eachHost(function(key, host){ 62 | describe(key, function(){ 63 | _.each(config.testBlocks.blocks, function(block){ 64 | it('should return '+block.uncleHeaders.length+' as a hexstring', function(done){ 65 | asyncTest(host, done, [Helpers.fromDecimal(block.blockHeader.number)], block.uncleHeaders.length); 66 | }); 67 | }); 68 | 69 | it('should return '+config.testBlocks.blocks[config.testBlocks.blocks.length-1].uncleHeaders.length+' as a hexstring when "latest" (block: '+config.testBlocks.blocks[config.testBlocks.blocks.length-1].blockHeader.hash+')', function(done){ 70 | asyncTest(host, done, ['latest'], config.testBlocks.blocks[config.testBlocks.blocks.length-1].uncleHeaders.length); 71 | }); 72 | 73 | it('should return 0 as a hexstring when "pending"', function(done){ 74 | asyncTest(host, done, ['pending'], 0); 75 | }); 76 | 77 | it('should return 0 as a hexstring when "earliest" (block: '+config.testBlocks.genesisBlockHeader.hash+')', function(done){ 78 | asyncTest(host, done, ['earliest'], 0); 79 | }); 80 | 81 | it('should return null if the block doesnt exist', function(done){ 82 | asyncTest(host, done, [Helpers.fromDecimal(999999)], null); 83 | }); 84 | 85 | it('should return an error when no parameter is passed', function(done){ 86 | asyncErrorTest(host, done); 87 | }); 88 | }); 89 | }); 90 | }); 91 | -------------------------------------------------------------------------------- /test/eth_mining.js: -------------------------------------------------------------------------------- 1 | // var config = require('../lib/config'), 2 | // Helpers = require('../lib/helpers'), 3 | // assert = require('chai').assert; 4 | 5 | // // METHOD 6 | // var method = 'eth_mining'; 7 | 8 | // // TEST 9 | // var asyncTest = function(host, done){ 10 | // Helpers.send(host, { 11 | // id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 12 | 13 | // // PARAMETERS 14 | // params: [] 15 | 16 | // }, function(result, status) { 17 | 18 | // assert.equal(status, 200, 'has status code'); 19 | // assert.property(result, 'result', (result.error) ? result.error.message : 'error'); 20 | // assert.isBoolean(result.result); 21 | 22 | // done(); 23 | 24 | // }); 25 | // }; 26 | 27 | 28 | // describe(method, function(){ 29 | // Helpers.eachHost(function(key, host){ 30 | // describe(key, function(){ 31 | // it('should return a boolean', function(done){ 32 | // asyncTest(host, done); 33 | // }); 34 | // }); 35 | // }); 36 | // }); 37 | -------------------------------------------------------------------------------- /test/eth_newBlockFilter.js: -------------------------------------------------------------------------------- 1 | var config = require('../lib/config'), 2 | Helpers = require('../lib/helpers'), 3 | assert = require('chai').assert, 4 | currentFilterId = null; 5 | 6 | // METHOD 7 | var method = 'eth_newBlockFilter'; 8 | 9 | 10 | // TEST 11 | var asyncTest = function(host, done){ 12 | Helpers.send(host, { 13 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 14 | 15 | // PARAMETERS 16 | params: [] 17 | 18 | }, function(result, status) { 19 | 20 | 21 | assert.equal(status, 200, 'has status code'); 22 | assert.property(result, 'result', (result.error) ? result.error.message : 'error'); 23 | assert.isString(result.result, 'is string'); 24 | assert.match(result.result, /^0x/, 'should be HEX starting with 0x'); 25 | assert.isNumber(+result.result, 'can be converted to a number'); 26 | 27 | currentFilterId = result.result; 28 | 29 | done(); 30 | }); 31 | }; 32 | 33 | 34 | var asyncErrorTest = function(host, done, param){ 35 | Helpers.send(host, { 36 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 37 | 38 | // PARAMETERS 39 | params: param ? [param] : [] 40 | 41 | }, function(result, status) { 42 | 43 | assert.equal(status, 200, 'has status code'); 44 | assert.property(result, 'error'); 45 | assert.equal(result.error.code, -32602); 46 | 47 | done(); 48 | }); 49 | }; 50 | 51 | 52 | 53 | describe(method, function(){ 54 | 55 | Helpers.eachHost(function(key, host){ 56 | describe(key, function(){ 57 | // uninstall the filters after we are done 58 | afterEach(function(){ 59 | if(currentFilterId) { 60 | Helpers.send(host, { 61 | id: config.rpcMessageId++, jsonrpc: "2.0", method: 'eth_uninstallFilter', 62 | 63 | // PARAMETERS 64 | params: [currentFilterId] 65 | 66 | }, function(){ 67 | 68 | }); 69 | currentFilterId = null; 70 | } 71 | }); 72 | 73 | it('should return a number as hexstring', function(done){ 74 | asyncTest(host, done); 75 | }); 76 | 77 | // TODO test again? 78 | // it('should return an error when a parameter is passed', function(done){ 79 | // asyncErrorTest(host, done, 'something'); 80 | // }); 81 | }); 82 | }); 83 | }); 84 | -------------------------------------------------------------------------------- /test/eth_newFilter.js: -------------------------------------------------------------------------------- 1 | var config = require('../lib/config'), 2 | Helpers = require('../lib/helpers'), 3 | assert = require('chai').assert, 4 | currentFilterId = null; 5 | 6 | // METHOD 7 | var method = 'eth_newFilter'; 8 | 9 | 10 | // TEST 11 | var asyncTest = function(host, done, param){ 12 | Helpers.send(host, { 13 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 14 | 15 | // PARAMETERS 16 | params: [param] 17 | 18 | }, function(result, status) { 19 | 20 | assert.equal(status, 200, 'has status code'); 21 | assert.property(result, 'result', (result.error) ? result.error.message : 'error'); 22 | assert.isString(result.result, 'is string'); 23 | assert.match(result.result, /^0x/, 'should be HEX starting with 0x'); 24 | assert.isNumber(+result.result, 'can be converted to a number'); 25 | 26 | // set current filter id 27 | currentFilterId = result.result; 28 | 29 | done(); 30 | }); 31 | }; 32 | 33 | 34 | var asyncErrorTest = function(host, done, param){ 35 | Helpers.send(host, { 36 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 37 | 38 | // PARAMETERS 39 | params: param ? [param] : [] 40 | 41 | }, function(result, status) { 42 | 43 | assert.equal(status, 200, 'has status code'); 44 | assert.property(result, 'error'); 45 | assert.equal(result.error.code, -32602); 46 | 47 | done(); 48 | }); 49 | }; 50 | 51 | 52 | 53 | describe(method, function(){ 54 | 55 | Helpers.eachHost(function(key, host){ 56 | describe(key, function(){ 57 | 58 | // uninstall the filters after we are done 59 | afterEach(function(){ 60 | if(currentFilterId) { 61 | Helpers.send(host, { 62 | id: config.rpcMessageId++, jsonrpc: "2.0", method: 'eth_uninstallFilter', 63 | 64 | // PARAMETERS 65 | params: [currentFilterId] 66 | 67 | }, function(){ 68 | 69 | }); 70 | currentFilterId = null; 71 | } 72 | }); 73 | 74 | it('should return a number as hexstring when all options are passed with single address', function(done){ 75 | asyncTest(host, done, { 76 | "fromBlock": "0x1", // 1 77 | "toBlock": "0x2", // 2 78 | "address": "0xfd9801e0aa27e54970936aa910a7186fdf5549bc", 79 | "topics": ['0x01e0aa27e54970936aa910a713', '0x6aa910a7186fdf'] 80 | }); 81 | }); 82 | 83 | it('should return a number as hexstring when all options are passed with address array', function(done){ 84 | asyncTest(host, done, { 85 | "fromBlock": "0x1", // 1 86 | "toBlock": "0x2", // 2 87 | "address": ["0xfd9801e0aa27e54970936aa910a7186fdf5549bc", "0xab9801e0aa27e54970936aa910a7186fdf5549bc"], 88 | "topics": ['0x01e0aa27e54970936aa910a713', '0x6aa910a7186fdf'] 89 | }); 90 | }); 91 | 92 | it('should return a number as hexstring when all options with "latest" and "pending" for to and fromBlock', function(done){ 93 | asyncTest(host, done, { 94 | "fromBlock": "latest", 95 | "toBlock": "pending", 96 | "address": "0xfd9801e0aa27e54970936aa910a7186fdf5549bc", 97 | "topics": ['0x01e0aa27e54970936aa910a713', '0x6aa910a7186fdf'] 98 | }); 99 | }); 100 | 101 | it('should return a number as hexstring when a few options are passed', function(done){ 102 | asyncTest(host, done, { 103 | "fromBlock": "0x1", // 1 104 | "toBlock": "0x2", // 2 105 | }); 106 | }); 107 | 108 | // it('should return an error when a wrong parameter is passed', function(done){ 109 | // asyncErrorTest(host, done, { 110 | // "fromBlock": 'abc', 111 | // "toBlock": 'abc', 112 | // "address": "0xfd9801e0aa27e54970936aa910a7186fdf5549bc" 113 | // }); 114 | // }); 115 | 116 | it('should return an error when no parameter is passed', function(done){ 117 | asyncErrorTest(host, done); 118 | }); 119 | }); 120 | }); 121 | }); 122 | -------------------------------------------------------------------------------- /test/eth_newPendingTransactionFilter.js: -------------------------------------------------------------------------------- 1 | var config = require('../lib/config'), 2 | Helpers = require('../lib/helpers'), 3 | assert = require('chai').assert, 4 | currentFilterId = null; 5 | 6 | // METHOD 7 | var method = 'eth_newPendingTransactionFilter'; 8 | 9 | 10 | // TEST 11 | var asyncTest = function(host, done){ 12 | Helpers.send(host, { 13 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 14 | 15 | // PARAMETERS 16 | params: [] 17 | 18 | }, function(result, status) { 19 | 20 | 21 | assert.equal(status, 200, 'has status code'); 22 | assert.property(result, 'result', (result.error) ? result.error.message : 'error'); 23 | assert.isString(result.result, 'is string'); 24 | assert.match(result.result, /^0x/, 'should be HEX starting with 0x'); 25 | assert.isNumber(+result.result, 'can be converted to a number'); 26 | 27 | currentFilterId = result.result; 28 | 29 | done(); 30 | }); 31 | }; 32 | 33 | 34 | var asyncErrorTest = function(host, done, param){ 35 | Helpers.send(host, { 36 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 37 | 38 | // PARAMETERS 39 | params: param ? [param] : [] 40 | 41 | }, function(result, status) { 42 | 43 | assert.equal(status, 200, 'has status code'); 44 | assert.property(result, 'error'); 45 | assert.equal(result.error.code, -32602); 46 | 47 | done(); 48 | }); 49 | }; 50 | 51 | 52 | 53 | describe(method, function(){ 54 | 55 | Helpers.eachHost(function(key, host){ 56 | describe(key, function(){ 57 | // uninstall the filters after we are done 58 | afterEach(function(){ 59 | if(currentFilterId) { 60 | Helpers.send(host, { 61 | id: config.rpcMessageId++, jsonrpc: "2.0", method: 'eth_uninstallFilter', 62 | 63 | // PARAMETERS 64 | params: [currentFilterId] 65 | 66 | }, function(){ 67 | 68 | }); 69 | currentFilterId = null; 70 | } 71 | }); 72 | 73 | it('should return a number as hexstring', function(done){ 74 | asyncTest(host, done); 75 | }); 76 | 77 | // TODO test again? 78 | // it('should return an error when a parameter is passed', function(done){ 79 | // asyncErrorTest(host, done, 'something'); 80 | // }); 81 | }); 82 | }); 83 | }); 84 | -------------------------------------------------------------------------------- /test/eth_protocolVersion.js: -------------------------------------------------------------------------------- 1 | var config = require('../lib/config'), 2 | Helpers = require('../lib/helpers'), 3 | assert = require('chai').assert; 4 | 5 | // METHOD 6 | var method = 'eth_protocolVersion'; 7 | 8 | // TEST 9 | var asyncTest = function(host, done){ 10 | Helpers.send(host, { 11 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 12 | 13 | // PARAMETERS 14 | params: [] 15 | 16 | }, function(result, status) { 17 | assert.equal(status, 200, 'has status code'); 18 | assert.property(result, 'result', (result.error) ? result.error.message : 'error'); 19 | assert.isString(result.result, 'is string'); 20 | 21 | done(); 22 | }); 23 | }; 24 | 25 | 26 | describe(method, function(){ 27 | Helpers.eachHost(function(key, host){ 28 | describe(key, function(){ 29 | it('should return a version number as HEX string', function(done){ 30 | asyncTest(host, done); 31 | }); 32 | }); 33 | }); 34 | }); 35 | 36 | -------------------------------------------------------------------------------- /test/eth_uninstallFilter.js: -------------------------------------------------------------------------------- 1 | var config = require('../lib/config'), 2 | Helpers = require('../lib/helpers'), 3 | assert = require('chai').assert; 4 | 5 | // METHOD 6 | var method = 'eth_uninstallFilter'; 7 | 8 | // TEST 9 | var asyncTest = function(host, done, filterId){ 10 | 11 | Helpers.send(host, { 12 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 13 | 14 | // PARAMETERS 15 | params: [filterId] 16 | 17 | }, function(result, status) { 18 | 19 | assert.equal(status, 200, 'has status code'); 20 | assert.property(result, 'result', (result.error) ? result.error.message : 'error'); 21 | assert.isTrue(result.result); 22 | 23 | done(); 24 | 25 | }); 26 | }; 27 | 28 | var asyncErrorTest = function(host, done, param){ 29 | Helpers.send(host, { 30 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 31 | 32 | // PARAMETERS 33 | params: param ? [param] : [] 34 | 35 | }, function(result, status) { 36 | 37 | assert.equal(status, 200, 'has status code'); 38 | assert.property(result, 'error'); 39 | assert.equal(result.error.code, -32602); 40 | 41 | done(); 42 | }); 43 | }; 44 | 45 | 46 | 47 | describe(method, function(){ 48 | Helpers.eachHost(function(key, host){ 49 | 50 | describe(key, function(){ 51 | 52 | // BLOCK FILTER 53 | it('should return a boolean when uninstalling a block filter', function(done){ 54 | // INSTALL a block filter first 55 | Helpers.send(host, { 56 | id: config.rpcMessageId++, jsonrpc: "2.0", method: 'eth_newBlockFilter', 57 | 58 | // PARAMETERS 59 | params: [] 60 | 61 | }, function(blockFilterId){ 62 | 63 | asyncTest(host, done, blockFilterId.result); 64 | }); 65 | 66 | }); 67 | 68 | 69 | // OPTIONS FILTER 70 | it('should return a boolean when uninstalling a options filter', function(done){ 71 | // INSTALL a options filter first 72 | Helpers.send(host, { 73 | id: config.rpcMessageId++, jsonrpc: "2.0", method: 'eth_newFilter', 74 | 75 | // PARAMETERS 76 | params: [{ 77 | "fromBlock": "0x1", // 1 78 | "toBlock": "0x2", // 2 79 | "address": "0xfd9801e0aa27e54970936aa910a7186fdf5549bc", 80 | "topics": ['0x01e0aa27e54970936aa910a713', '0x6aa910a7186fdf'] 81 | }] 82 | 83 | }, function(optionsFilterId) { 84 | asyncTest(host, done, optionsFilterId.result); 85 | }); 86 | 87 | }); 88 | 89 | it('should return an error when no parameter is passed', function(done){ 90 | asyncErrorTest(host, done); 91 | }); 92 | }); 93 | }); 94 | }); 95 | -------------------------------------------------------------------------------- /test/mocha.opts: -------------------------------------------------------------------------------- 1 | --require chai 2 | --reporter dot 3 | --ui bdd 4 | -------------------------------------------------------------------------------- /test/net_listening.js: -------------------------------------------------------------------------------- 1 | var config = require('../lib/config'), 2 | Helpers = require('../lib/helpers'), 3 | assert = require('chai').assert; 4 | 5 | // METHOD 6 | var method = 'net_listening'; 7 | 8 | // TEST 9 | var asyncTest = function(host, done){ 10 | Helpers.send(host, { 11 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 12 | 13 | // PARAMETERS 14 | params: [] 15 | 16 | }, function(result, status) { 17 | 18 | assert.equal(status, 200, 'has status code'); 19 | assert.property(result, 'result', (result.error) ? result.error.message : 'error'); 20 | assert.isBoolean(result.result); 21 | 22 | done(); 23 | 24 | }); 25 | }; 26 | 27 | 28 | describe(method, function(){ 29 | Helpers.eachHost(function(key, host){ 30 | describe(key, function(){ 31 | it('should return a boolean', function(done){ 32 | asyncTest(host, done); 33 | }); 34 | }); 35 | }); 36 | }); 37 | -------------------------------------------------------------------------------- /test/net_peerCount.js: -------------------------------------------------------------------------------- 1 | var config = require('../lib/config'), 2 | Helpers = require('../lib/helpers'), 3 | assert = require('chai').assert; 4 | 5 | // METHOD 6 | var method = 'net_peerCount'; 7 | 8 | // TEST 9 | var asyncTest = function(host, done){ 10 | Helpers.send(host, { 11 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 12 | 13 | // PARAMETERS 14 | params: [] 15 | 16 | }, function(result, status) { 17 | 18 | assert.equal(status, 200, 'has status code'); 19 | assert.property(result, 'result', (result.error) ? result.error.message : 'error'); 20 | assert.isString(result.result, 'is string'); 21 | assert.isNumber(+result.result, 'can be converted to a number'); 22 | 23 | done(); 24 | }); 25 | }; 26 | 27 | describe(method, function(){ 28 | Helpers.eachHost(function(key, host){ 29 | describe(key, function(){ 30 | it('should return a number as hexstring', function(done){ 31 | asyncTest(host, done); 32 | }); 33 | }); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /test/net_version.js: -------------------------------------------------------------------------------- 1 | var config = require('../lib/config'), 2 | Helpers = require('../lib/helpers'), 3 | assert = require('chai').assert; 4 | 5 | // METHOD 6 | var method = 'net_version'; 7 | 8 | // TEST 9 | var asyncTest = function(host, done){ 10 | Helpers.send(host, { 11 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 12 | 13 | // PARAMETERS 14 | params: [] 15 | 16 | }, function(result, status) { 17 | assert.equal(status, 200, 'has status code'); 18 | assert.property(result, 'result', (result.error) ? result.error.message : 'error'); 19 | assert.isString(result.result, 'is string'); 20 | 21 | done(); 22 | }); 23 | }; 24 | 25 | 26 | describe(method, function(){ 27 | Helpers.eachHost(function(key, host){ 28 | describe(key, function(){ 29 | it('should return a version number as HEX string', function(done){ 30 | asyncTest(host, done); 31 | }); 32 | }); 33 | }); 34 | }); 35 | 36 | -------------------------------------------------------------------------------- /test/shh_hasIdentity.js: -------------------------------------------------------------------------------- 1 | var config = require('../lib/config'), 2 | Helpers = require('../lib/helpers'), 3 | assert = require('chai').assert; 4 | 5 | // METHOD 6 | var method = 'shh_hasIdentity'; 7 | 8 | 9 | // TEST 10 | var asyncTest = function(host, done, param, expectedResult){ 11 | Helpers.send(host, { 12 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 13 | 14 | // PARAMETERS 15 | params: [param] 16 | 17 | }, function(result){ 18 | 19 | assert.property(result, 'result', (result.error) ? result.error.message : 'error'); 20 | 21 | if(expectedResult) 22 | assert.isTrue(result.result, 'should return TRUE'); 23 | else 24 | assert.isFalse(result.result, 'should return FALSE'); 25 | 26 | done(); 27 | }); 28 | 29 | }; 30 | 31 | 32 | var asyncErrorTest = function(host, done, param){ 33 | Helpers.send(host, { 34 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 35 | 36 | // PARAMETERS 37 | params: param ? [param] : [] 38 | 39 | }, function(result, status) { 40 | 41 | assert.equal(status, 200, 'has status code'); 42 | assert.property(result, 'error'); 43 | assert.equal(result.error.code, -32602); 44 | 45 | done(); 46 | }); 47 | }; 48 | 49 | 50 | 51 | describe(method, function(){ 52 | 53 | Helpers.eachHost(function(key, host){ 54 | describe(key, function(){ 55 | it('should return TRUE if the identity already exists', function(done){ 56 | 57 | Helpers.send(host, { 58 | id: config.rpcMessageId++, jsonrpc: "2.0", method: 'shh_newIdentity', 59 | 60 | // PARAMETERS 61 | params: [] 62 | }, function(identity){ 63 | 64 | asyncTest(host, done, identity.result, true); 65 | }); 66 | 67 | }); 68 | 69 | it('should return FALSE if the identity doesn\'t exists', function(done){ 70 | asyncTest(host, done, '0x2599F5fa71695aa16e6ae0c37258ae842a90cb60f6804d2486b35dfc89adaea819e589ed904e1fb9316a11753eb44b5806af6ef7e2739eb96cf05e9bb3cc08bc', false); 71 | }); 72 | 73 | it('should return an error when no parameter is passed', function(done){ 74 | asyncErrorTest(host, done); 75 | }); 76 | }); 77 | }); 78 | }); 79 | -------------------------------------------------------------------------------- /test/shh_newFilter.js: -------------------------------------------------------------------------------- 1 | var config = require('../lib/config'), 2 | Helpers = require('../lib/helpers'), 3 | assert = require('chai').assert, 4 | currentFilterId = null; 5 | 6 | // METHOD 7 | var method = 'shh_newFilter'; 8 | 9 | 10 | // TEST 11 | var asyncTest = function(host, done, param){ 12 | Helpers.send(host, { 13 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 14 | 15 | // PARAMETERS 16 | params: [param] 17 | 18 | }, function(result, status) { 19 | 20 | assert.equal(status, 200, 'has status code'); 21 | assert.property(result, 'result', (result.error) ? result.error.message : 'error'); 22 | assert.isString(result.result, 'is string'); 23 | assert.match(result.result, /^0x/, 'should be HEX starting with 0x'); 24 | assert.isNumber(+result.result, 'can be converted to a number'); 25 | 26 | currentFilterId = result.result; 27 | 28 | done(); 29 | }); 30 | }; 31 | 32 | 33 | var asyncErrorTest = function(host, done, param){ 34 | Helpers.send(host, { 35 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 36 | 37 | // PARAMETERS 38 | params: param ? [param] : [] 39 | 40 | }, function(result, status) { 41 | 42 | assert.equal(status, 200, 'has status code'); 43 | assert.property(result, 'error'); 44 | assert.equal(result.error.code, -32602); 45 | 46 | done(); 47 | }); 48 | }; 49 | 50 | 51 | 52 | describe(method, function(){ 53 | 54 | Helpers.eachHost(function(key, host){ 55 | describe(key, function(){ 56 | // uninstall the filters after we are done 57 | afterEach(function(){ 58 | if(currentFilterId) { 59 | Helpers.send(host, { 60 | id: config.rpcMessageId++, jsonrpc: "2.0", method: 'shh_uninstallFilter', 61 | 62 | // PARAMETERS 63 | params: [currentFilterId] 64 | 65 | }); 66 | currentFilterId = null; 67 | } 68 | }); 69 | 70 | it('should return a number as hexstring when all options are passed', function(done){ 71 | asyncTest(host, done, { 72 | "topics": ['0x6aa910a7186fdf'], 73 | "to": "0xfd9801e0aa27e54970936aa910a7186fdf5549bc" 74 | }); 75 | }); 76 | 77 | it('should return a number as hexstring when a few options are passed', function(done){ 78 | asyncTest(host, done, { 79 | "topics": ['0x6aa910a7186fdf'] 80 | }); 81 | }); 82 | 83 | it('should return an error when a wrong parameter is passed', function(done){ 84 | asyncErrorTest(host, done, { 85 | "to": 2, 86 | }); 87 | }); 88 | 89 | it('should return an error when no parameter is passed', function(done){ 90 | asyncErrorTest(host, done); 91 | }); 92 | }); 93 | }); 94 | }); 95 | -------------------------------------------------------------------------------- /test/shh_newIdentity.js: -------------------------------------------------------------------------------- 1 | var config = require('../lib/config'), 2 | Helpers = require('../lib/helpers'), 3 | assert = require('chai').assert; 4 | 5 | // METHOD 6 | var method = 'shh_newIdentity'; 7 | 8 | // TEST 9 | var asyncTest = function(host, done){ 10 | Helpers.send(host, { 11 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 12 | 13 | // PARAMETERS 14 | params: [] 15 | 16 | }, function(result, status) { 17 | 18 | assert.equal(status, 200, 'has status code'); 19 | assert.property(result, 'result', (result.error) ? result.error.message : 'error'); 20 | assert.match(result.result, /0x[\da-f]+/i, 'is identity'); 21 | 22 | config.coinbase = result.result; 23 | 24 | done(); 25 | 26 | }); 27 | }; 28 | 29 | 30 | describe(method, function(){ 31 | Helpers.eachHost(function(key, host){ 32 | describe(key, function(){ 33 | it('should return an identity', function(done){ 34 | asyncTest(host, done); 35 | }); 36 | }); 37 | }); 38 | }); 39 | -------------------------------------------------------------------------------- /test/shh_uninstallFilter.js: -------------------------------------------------------------------------------- 1 | var config = require('../lib/config'), 2 | Helpers = require('../lib/helpers'), 3 | assert = require('chai').assert; 4 | 5 | // METHOD 6 | var method = 'shh_uninstallFilter'; 7 | 8 | // TEST 9 | var asyncTest = function(host, done, filterId){ 10 | 11 | Helpers.send(host, { 12 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 13 | 14 | // PARAMETERS 15 | params: [filterId] 16 | 17 | }, function(result, status) { 18 | 19 | assert.equal(status, 200, 'has status code'); 20 | assert.property(result, 'result', (result.error) ? result.error.message : 'error'); 21 | assert.isTrue(result.result); 22 | 23 | done(); 24 | 25 | }); 26 | }; 27 | 28 | var asyncErrorTest = function(host, done, param){ 29 | Helpers.send(host, { 30 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 31 | 32 | // PARAMETERS 33 | params: param ? [param] : [] 34 | 35 | }, function(result, status) { 36 | 37 | assert.equal(status, 200, 'has status code'); 38 | assert.property(result, 'error'); 39 | assert.equal(result.error.code, -32602); 40 | 41 | done(); 42 | }); 43 | }; 44 | 45 | 46 | 47 | describe(method, function(){ 48 | Helpers.eachHost(function(key, host){ 49 | 50 | // OPTIONS FILTER 51 | describe(key, function(){ 52 | 53 | it('should return a boolean when uninstalling a options filter', function(done){ 54 | // INSTALL a options filter first 55 | var optionsFilterId = Helpers.send(host, { 56 | id: config.rpcMessageId++, jsonrpc: "2.0", method: 'shh_newFilter', 57 | 58 | // PARAMETERS 59 | params: [{ 60 | "to": "0xfd9801e0aa27e54970936aa910a7186fdf5549bc", 61 | "topics": ['0x01e0aa27e54970936aa910a71', '0x6aa910a7186fdf'] 62 | }] 63 | 64 | }); 65 | asyncTest(host, done, optionsFilterId.result); 66 | }); 67 | 68 | it('should return an error when no parameter is passed', function(done){ 69 | asyncErrorTest(host, done); 70 | }); 71 | }); 72 | }); 73 | }); 74 | -------------------------------------------------------------------------------- /test/shh_version.js: -------------------------------------------------------------------------------- 1 | var config = require('../lib/config'), 2 | Helpers = require('../lib/helpers'), 3 | assert = require('chai').assert; 4 | 5 | // METHOD 6 | var method = 'shh_version'; 7 | 8 | // TEST 9 | var asyncTest = function(host, done){ 10 | Helpers.send(host, { 11 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 12 | 13 | // PARAMETERS 14 | params: [] 15 | 16 | }, function(result, status) { 17 | assert.equal(status, 200, 'has status code'); 18 | assert.property(result, 'result', (result.error) ? result.error.message : 'error'); 19 | assert.isString(result.result, 'is string'); 20 | 21 | done(); 22 | }); 23 | }; 24 | 25 | 26 | describe(method, function(){ 27 | Helpers.eachHost(function(key, host){ 28 | describe(key, function(){ 29 | it('should return a version number as HEX string', function(done){ 30 | asyncTest(host, done); 31 | }); 32 | }); 33 | }); 34 | }); 35 | 36 | -------------------------------------------------------------------------------- /test/web3_clientVersion.js: -------------------------------------------------------------------------------- 1 | var config = require('../lib/config'), 2 | Helpers = require('../lib/helpers'), 3 | assert = require('chai').assert; 4 | 5 | // METHOD 6 | var method = 'web3_clientVersion'; 7 | 8 | // TEST 9 | var asyncTest = function(host, done){ 10 | Helpers.send(host, { 11 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 12 | 13 | // PARAMETERS 14 | params: [] 15 | 16 | }, function(result, status) { 17 | assert.equal(status, 200, 'has status code'); 18 | assert.property(result, 'result', (result.error) ? result.error.message : 'error'); 19 | assert.isString(result.result, 'is string'); 20 | 21 | done(); 22 | }); 23 | }; 24 | 25 | 26 | describe(method, function(){ 27 | Helpers.eachHost(function(key, host){ 28 | describe(key, function(){ 29 | it('should return a version string', function(done){ 30 | asyncTest(host, done); 31 | }); 32 | }); 33 | }); 34 | }); 35 | 36 | -------------------------------------------------------------------------------- /test/web3_sha3.js: -------------------------------------------------------------------------------- 1 | var config = require('../lib/config'), 2 | Helpers = require('../lib/helpers'), 3 | assert = require('chai').assert; 4 | 5 | // METHOD 6 | var method = 'web3_sha3'; 7 | 8 | // TEST 9 | var asyncTest = function(host, done){ 10 | Helpers.send(host, { 11 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 12 | 13 | // PARAMETERS 14 | params: ["0x74657374"] // "test" 15 | 16 | }, function(result, status) { 17 | 18 | assert.equal(status, 200); 19 | assert.property(result, 'result', (result.error) ? result.error.message : 'error'); 20 | assert.equal(result.result, '0x9c22ff5f21f0b81b113e63f7db6da94fedef11b2119b4088b89664fb9a3cb658'); 21 | 22 | done(); 23 | }); 24 | }; 25 | 26 | var asyncErrorTest = function(host, done){ 27 | Helpers.send(host, { 28 | id: config.rpcMessageId++, jsonrpc: "2.0", method: method, 29 | 30 | // PARAMETERS 31 | params: [] 32 | 33 | }, function(result, status) { 34 | 35 | assert.equal(status, 200, 'has status code'); 36 | assert.property(result, 'error'); 37 | assert.equal(result.error.code, -32602); 38 | 39 | done(); 40 | }); 41 | }; 42 | 43 | describe(method, function(){ 44 | Helpers.eachHost(function(key, host){ 45 | describe(key, function(){ 46 | it('should return a generated hash', function(done){ 47 | asyncTest(host, done); 48 | }); 49 | 50 | it('should return an error when no parameter is passed', function(done){ 51 | asyncErrorTest(host, done); 52 | }); 53 | }); 54 | }); 55 | }); 56 | --------------------------------------------------------------------------------