aboutsummaryrefslogtreecommitdiffstats
path: root/packages/subproviders/test/unit
diff options
context:
space:
mode:
authorJacob Evans <jacob@dekz.net>2018-01-31 13:19:47 +0800
committerJacob Evans <jacob@dekz.net>2018-02-02 08:06:22 +0800
commitead990a734e0caf0ce0e5d0297c487756894acf2 (patch)
tree6adac8f131439c4fec897fb98c2f5626aa8c7548 /packages/subproviders/test/unit
parentd4631e14b2203bfd95b995d25819d8d9cb834336 (diff)
downloaddexon-sol-tools-ead990a734e0caf0ce0e5d0297c487756894acf2.tar.gz
dexon-sol-tools-ead990a734e0caf0ce0e5d0297c487756894acf2.tar.zst
dexon-sol-tools-ead990a734e0caf0ce0e5d0297c487756894acf2.zip
Nonce tracker subprovider
Caches the nonce when a request to getTransactionCount is made and increments the pending nonce after successful transactions
Diffstat (limited to 'packages/subproviders/test/unit')
-rw-r--r--packages/subproviders/test/unit/nonce_tracker_subprovider_test.ts195
1 files changed, 195 insertions, 0 deletions
diff --git a/packages/subproviders/test/unit/nonce_tracker_subprovider_test.ts b/packages/subproviders/test/unit/nonce_tracker_subprovider_test.ts
new file mode 100644
index 000000000..a99f1f9fb
--- /dev/null
+++ b/packages/subproviders/test/unit/nonce_tracker_subprovider_test.ts
@@ -0,0 +1,195 @@
+import * as chai from 'chai';
+import * as _ from 'lodash';
+import Web3 = require('web3');
+import Web3ProviderEngine = require('web3-provider-engine');
+import FixtureSubprovider = require('web3-provider-engine/subproviders/fixture');
+
+import promisify = require('es6-promisify');
+import EthereumTx = require('ethereumjs-tx');
+
+import { NonceTrackerSubprovider } from '../../src';
+import { DoneCallback } from '../../src/types';
+import { chaiSetup } from '../chai_setup';
+import { reportCallbackErrors } from '../utils/report_callback_errors';
+
+import { Subprovider } from '../../src/subproviders/subprovider';
+
+const expect = chai.expect;
+chaiSetup.configure();
+
+describe('NonceTrackerSubprovider', () => {
+ let provider: Web3ProviderEngine;
+ it('successfully caches the transaction count', async () => {
+ provider = new Web3ProviderEngine();
+ let called = false;
+ const nonceTrackerSubprovider = new NonceTrackerSubprovider();
+ provider.addProvider(nonceTrackerSubprovider);
+ provider.addProvider(new FixtureSubprovider({
+ 'eth_getBlockByNumber': '0x01',
+ 'eth_getTransactionCount': (data: any, next: any, end: any) => {
+ if (called) {
+ return end(null, '0x99');
+ } else {
+ called = true;
+ end(null, '0x01');
+ }
+ },
+ }));
+ provider.start();
+
+ const payload = {
+ jsonrpc: '2.0',
+ method: 'eth_getTransactionCount',
+ params: ['0x0', 'pending'],
+ id: 1,
+ };
+
+ const response = await promisify(provider.sendAsync, provider)(payload);
+ expect(response.result).to.be.eq('0x01');
+ const secondResponse = await promisify(provider.sendAsync, provider)(payload);
+ expect(secondResponse.result).to.be.eq('0x01');
+ });
+ it('does not cache the result for latest transaction count', async () => {
+ provider = new Web3ProviderEngine();
+ let called = false;
+ const nonceTrackerSubprovider = new NonceTrackerSubprovider();
+ provider.addProvider(nonceTrackerSubprovider);
+ provider.addProvider(new FixtureSubprovider({
+ 'eth_getBlockByNumber': '0x01',
+ 'eth_getTransactionCount': (data: any, next: any, end: any) => {
+ if (called) {
+ return end(null, '0x99');
+ } else {
+ called = true;
+ end(null, '0x01');
+ }
+ },
+ }));
+ provider.start();
+
+ const payload = {
+ jsonrpc: '2.0',
+ method: 'eth_getTransactionCount',
+ params: ['0x0', 'latest'],
+ id: 1,
+ };
+
+ const response = await promisify(provider.sendAsync, provider)(payload);
+ expect(response.result).to.be.eq('0x01');
+ const secondResponse = await promisify(provider.sendAsync, provider)(payload);
+ expect(secondResponse.result).to.be.eq('0x99');
+ });
+ it('clears the cache on a Nonce Too Low Error', async () => {
+ provider = new Web3ProviderEngine();
+ let called = false;
+ const nonceTrackerSubprovider = new NonceTrackerSubprovider();
+ provider.addProvider(nonceTrackerSubprovider);
+ provider.addProvider(new FixtureSubprovider({
+ 'eth_getBlockByNumber': '0x01',
+ 'eth_getTransactionCount': (data: any, next: any, end: any) => {
+ if (called) {
+ return end(null, '0x99');
+ } else {
+ called = true;
+ end(null, '0x01');
+ }
+ },
+ 'eth_sendRawTransaction': (data: any, next: any, end: any) => {
+ end(new Error('Transaction nonce is too low'));
+ },
+ }));
+ provider.start();
+
+ const noncePayload = {
+ jsonrpc: '2.0',
+ method: 'eth_getTransactionCount',
+ params: ['0x1f36f546477cda21bf2296c50976f2740247906f', 'pending'],
+ id: 1,
+ };
+ const txParams = [
+ '0x',
+ '0x09184e72a000',
+ '0x2710',
+ '0x0000000000000000000000000000000000000000',
+ '0x',
+ '0x7f7465737432000000000000000000000000000000000000000000000000000000600057',
+ '0x1c',
+ '0x5e1d3a76fbf824220eafc8c79ad578ad2b67d01b0c2425eb1f1347e8f50882ab',
+ '0x5bd428537f05f9830e93792f90ea6a3e2d1ee84952dd96edbae9f658f831ab13'
+ ];
+
+ const transaction = new EthereumTx(txParams);
+ const txPayload = {
+ jsonrpc: '2.0',
+ method: 'eth_sendRawTransaction',
+ params: [transaction.serialize()],
+ id: 1,
+ };
+
+ const response = await promisify(provider.sendAsync, provider)(noncePayload);
+ expect(response.result).to.be.eq('0x01');
+ const secondResponse = await promisify(provider.sendAsync, provider)(noncePayload);
+ expect(secondResponse.result).to.be.eq('0x01');
+ try {
+ const txResponse = await promisify(provider.sendAsync, provider)(txPayload);
+ } catch (err) {
+ const thirdResponse = await promisify(provider.sendAsync, provider)(noncePayload);
+ expect(thirdResponse.result).to.be.eq('0x99');
+ }
+ });
+ it('increments the used nonce', async () => {
+ provider = new Web3ProviderEngine();
+ let called = false;
+ const nonceTrackerSubprovider = new NonceTrackerSubprovider();
+ provider.addProvider(nonceTrackerSubprovider);
+ provider.addProvider(new FixtureSubprovider({
+ 'eth_getBlockByNumber': '0x01',
+ 'eth_getTransactionCount': (data: any, next: any, end: any) => {
+ if (called) {
+ return end(null, '0x99');
+ } else {
+ called = true;
+ end(null, '0x00');
+ }
+ },
+ 'eth_sendRawTransaction': (data: any, next: any, end: any) => {
+ end(null);
+ },
+ }));
+ provider.start();
+
+ const noncePayload = {
+ jsonrpc: '2.0',
+ method: 'eth_getTransactionCount',
+ params: ['0x1f36f546477cda21bf2296c50976f2740247906f', 'pending'],
+ id: 1,
+ };
+ const txParams = [
+ '0x',
+ '0x09184e72a000',
+ '0x2710',
+ '0x0000000000000000000000000000000000000000',
+ '0x',
+ '0x7f7465737432000000000000000000000000000000000000000000000000000000600057',
+ '0x1c',
+ '0x5e1d3a76fbf824220eafc8c79ad578ad2b67d01b0c2425eb1f1347e8f50882ab',
+ '0x5bd428537f05f9830e93792f90ea6a3e2d1ee84952dd96edbae9f658f831ab13'
+ ];
+
+ const transaction = new EthereumTx(txParams);
+ const txPayload = {
+ jsonrpc: '2.0',
+ method: 'eth_sendRawTransaction',
+ params: [transaction.serialize()],
+ id: 1,
+ };
+
+ const response = await promisify(provider.sendAsync, provider)(noncePayload);
+ expect(response.result).to.be.eq('0x00');
+ const secondResponse = await promisify(provider.sendAsync, provider)(noncePayload);
+ expect(secondResponse.result).to.be.eq('0x00');
+ const txResponse = await promisify(provider.sendAsync, provider)(txPayload);
+ const thirdResponse = await promisify(provider.sendAsync, provider)(noncePayload);
+ expect(thirdResponse.result).to.be.eq('0x01');
+ });
+});