Merge pull request #804 from nodar-chkuaselidze/rpc-cleanup

Minor RPC Test updates
This commit is contained in:
Braydon Fuller 2019-06-27 12:06:04 -07:00
commit 4542ec5d18
No known key found for this signature in database
GPG Key ID: F24F232D108B3AD4
3 changed files with 277 additions and 295 deletions

63
test/node-rpc-test.js Normal file
View File

@ -0,0 +1,63 @@
/* eslint-env mocha */
/* eslint prefer-arrow-callback: "off" */
'use strict';
const assert = require('bsert');
const FullNode = require('../lib/node/fullnode');
const ports = {
p2p: 49331,
node: 49332,
wallet: 49333
};
const node = new FullNode({
network: 'regtest',
apiKey: 'foo',
walletAuth: true,
memory: true,
workers: true,
workersSize: 2,
plugins: [require('../lib/wallet/plugin')],
port: ports.p2p,
httpPort: ports.node,
env: {
'BCOIN_WALLET_HTTP_PORT': ports.wallet.toString()
}});
const {NodeClient} = require('bclient');
const nclient = new NodeClient({
port: ports.node,
apiKey: 'foo',
timeout: 15000
});
describe('RPC', function() {
this.timeout(15000);
before(async () => {
await node.open();
});
after(async () => {
await node.close();
});
it('should rpc help', async () => {
assert(await nclient.execute('help', []));
await assert.rejects(async () => {
await nclient.execute('help', ['getinfo']);
}, {
name: 'Error',
message: /^getinfo/
});
});
it('should rpc getinfo', async () => {
const info = await nclient.execute('getinfo', []);
assert.strictEqual(info.blocks, 0);
});
});

View File

@ -1,280 +0,0 @@
/* eslint-env mocha */
/* eslint prefer-arrow-callback: "off" */
'use strict';
const assert = require('bsert');
const consensus = require('../lib/protocol/consensus');
const Address = require('../lib/primitives/address');
const FullNode = require('../lib/node/fullnode');
const ports = {
p2p: 49331,
node: 49332,
wallet: 49333
};
const node = new FullNode({
network: 'regtest',
apiKey: 'foo',
walletAuth: true,
memory: true,
workers: true,
workersSize: 2,
plugins: [require('../lib/wallet/plugin')],
port: ports.p2p,
httpPort: ports.node,
env: {
'BCOIN_WALLET_HTTP_PORT': ports.wallet.toString()
}});
const {NodeClient, WalletClient} = require('bclient');
const nclient = new NodeClient({
port: ports.node,
apiKey: 'foo',
timeout: 15000
});
const wclient = new WalletClient({
port: ports.wallet,
apiKey: 'foo'
});
const {wdb} = node.require('walletdb');
const defaultCoinbaseMaturity = consensus.COINBASE_MATURITY;
let addressHot = null;
let addressMiner = null;
let walletHot = null;
let walletMiner = null;
let blocks = null;
let txid = null;
let utxo = null;
describe('RPC', function() {
this.timeout(15000);
before(() => {
consensus.COINBASE_MATURITY = 0;
});
after(() => {
consensus.COINBASE_MATURITY = defaultCoinbaseMaturity;
});
it('should open node and create wallets', async () => {
await node.open();
await nclient.open();
await wclient.open();
const walletHotInfo = await wclient.createWallet('hot');
walletHot = wclient.wallet('hot', walletHotInfo.token);
const walletMinerInfo = await wclient.createWallet('miner');
walletMiner = wclient.wallet('miner', walletMinerInfo.token);
await walletHot.open();
await walletMiner.open();
});
it('should rpc help', async () => {
assert(await nclient.execute('help', []));
assert(await wclient.execute('help', []));
await assert.rejects(async () => {
await nclient.execute('help', ['getinfo']);
}, {
name: 'Error',
message: /^getinfo/
});
await assert.rejects(async () => {
await wclient.execute('help', ['getbalance']);
}, {
name: 'Error',
message: /^getbalance/
});
});
it('should rpc getinfo', async () => {
const info = await nclient.execute('getinfo', []);
assert.strictEqual(info.blocks, 0);
});
it('should rpc selectwallet', async () => {
const response = await wclient.execute('selectwallet', ['miner']);
assert.strictEqual(response, null);
});
it('should rpc getnewaddress from default account', async () => {
const acctAddr = await wclient.execute('getnewaddress', []);
assert(Address.fromString(acctAddr.toString()));
});
it('should fail rpc getnewaddress from nonexistent account', async () => {
await assert.rejects(async () => {
await wclient.execute('getnewaddress', ['bad-account-name']);
}, {
name: 'Error',
message: 'Account not found.'
});
});
it('should rpc getaccountaddress', async () => {
addressMiner = await wclient.execute('getaccountaddress', ['default']);
assert(Address.fromString(addressMiner.toString()));
});
it('should rpc generatetoaddress', async () => {
blocks = await nclient.execute('generatetoaddress',
[10, addressMiner]);
assert.strictEqual(blocks.length, 10);
});
it('should rpc sendtoaddress', async () => {
const acctHotDefault = await walletHot.getAccount('default');
addressHot = acctHotDefault.receiveAddress;
txid = await wclient.execute('sendtoaddress', [addressHot, 0.1234]);
assert.strictEqual(txid.length, 64);
});
it('should rpc sendmany', async () => {
const sendTo = {};
sendTo[addressHot] = 1.0;
sendTo[addressMiner] = 0.1111;
txid = await wclient.execute('sendmany', ['default', sendTo]);
assert.strictEqual(txid.length, 64);
});
it('should fail malformed rpc sendmany', async () => {
await assert.rejects(async () => {
await wclient.execute('sendmany', ['default', null]);
}, {
name: 'Error',
message: 'Invalid send-to address.'
});
const sendTo = {};
sendTo[addressHot] = null;
await assert.rejects(async () => {
await wclient.execute('sendmany', ['default', sendTo]);
}, {
name: 'Error',
message: 'Invalid amount.'
});
});
it('should rpc listreceivedbyaddress', async () => {
await wclient.execute('selectwallet', ['hot']);
const listZeroConf = await wclient.execute('listreceivedbyaddress',
[0, false, false]);
assert.deepStrictEqual(listZeroConf, [{
'involvesWatchonly': false,
'address': addressHot,
'account': 'default',
'amount': 1.1234,
'confirmations': 0,
'label': ''
}]);
blocks.push(await nclient.execute('generatetoaddress', [1, addressMiner]));
await wdb.syncChain();
const listSomeConf = await wclient.execute('listreceivedbyaddress',
[1, false, false]);
assert.deepStrictEqual(listSomeConf, [{
'involvesWatchonly': false,
'address': addressHot,
'account': 'default',
'amount': 1.1234,
'confirmations': 1,
'label': ''
}]);
const listTooManyConf = await wclient.execute('listreceivedbyaddress',
[100, false, false]);
assert.deepStrictEqual(listTooManyConf, []);
});
it('should rpc listtransactions with no args', async () => {
const txs = await wclient.execute('listtransactions', []);
assert.strictEqual(txs.length, 2);
assert.strictEqual(txs[0].amount + txs[1].amount, 1.1234);
assert.strictEqual(txs[0].account, 'default');
});
it('should rpc listtransactions from specified account', async () => {
const wallet = await wclient.wallet('hot');
await wallet.createAccount('foo');
const txs = await wclient.execute('listtransactions', ['foo']);
assert.strictEqual(txs.length, 0);
});
it('should fail rpc listtransactions from nonexistent account', async () => {
assert.rejects(async () => {
await wclient.execute('listtransactions', ['nonexistent']);
}, {
name: 'Error',
message: 'Account not found.'
});
});
it('should rpc listunspent', async () => {
utxo = await wclient.execute('listunspent', []);
assert.strictEqual(utxo.length, 2);
});
it('should rpc lockunspent and listlockunspent', async () => {
let result = await wclient.execute('listlockunspent', []);
assert.deepStrictEqual(result, []);
// lock one utxo
const output = utxo[0];
const outputsToLock = [{'txid': output.txid, 'vout': output.vout}];
result = await wclient.execute('lockunspent', [false, outputsToLock]);
assert(result);
result = await wclient.execute('listlockunspent', []);
assert.deepStrictEqual(result, outputsToLock);
// unlock all
result = await wclient.execute('lockunspent', [true]);
assert(result);
result = await wclient.execute('listlockunspent', []);
assert.deepStrictEqual(result, []);
});
it('should rpc listsinceblock', async () => {
const listNoBlock = await wclient.execute('listsinceblock', []);
assert.strictEqual(listNoBlock.transactions.length, 2);
// txs returned in unpredictable order
const txids = [
listNoBlock.transactions[0].txid,
listNoBlock.transactions[1].txid
];
assert(txids.includes(txid));
const block5 = blocks[5];
const listOldBlock = await wclient.execute('listsinceblock', [block5]);
assert.strictEqual(listOldBlock.transactions.length, 2);
const nonexistentBlock = consensus.ZERO_HASH.toString('hex');
await assert.rejects(async () => {
await wclient.execute('listsinceblock', [nonexistentBlock]);
}, {
name: 'Error',
message: 'Block not found.'
});
});
it('should cleanup', async () => {
await walletHot.close();
await walletMiner.close();
await wclient.close();
await nclient.close();
await node.close();
});
});

View File

@ -4,6 +4,7 @@
const {NodeClient, WalletClient} = require('bclient');
const assert = require('bsert');
const consensus = require('../lib/protocol/consensus');
const FullNode = require('../lib/node/fullnode');
const Network = require('../lib/protocol/network');
const Mnemonic = require('../lib/hd/mnemonic');
@ -12,6 +13,7 @@ const Script = require('../lib/script/script');
const Address = require('../lib/primitives/address');
const network = Network.get('regtest');
const mnemonics = require('./data/mnemonic-english.json');
const {forValue} = require('./util/common');
// Commonly used test mnemonic
const phrase = mnemonics[0][1];
@ -27,6 +29,7 @@ const node = new FullNode({
walletAuth: true,
memory: true,
workers: true,
workersSize: 2,
plugins: [require('../lib/wallet/plugin')],
port: ports.p2p,
httpPort: ports.node,
@ -35,9 +38,12 @@ const node = new FullNode({
}
});
const {wdb} = node.require('walletdb');
const nclient = new NodeClient({
port: ports.node,
apiKey: 'bar'
apiKey: 'bar',
timeout: 15000
});
const wclient = new WalletClient({
@ -52,10 +58,14 @@ describe('Wallet RPC Methods', function() {
// used to derive addresses throughout the test suite
let xpub;
let walletHot = null;
let walletMiner = null;
let addressHot = null;
let addressMiner = null;
let utxo = null;
before(async () => {
await node.open();
await nclient.open();
await wclient.open();
// Derive the xpub using the well known
// mnemonic and network's coin type
@ -73,17 +83,214 @@ describe('Wallet RPC Methods', function() {
'abandon', 'abandon', 'abandon', 'abandon',
'abandon', 'abandon', 'abandon', 'about'
].join(' '));
// Create wallets.
{
const walletInfo = await wclient.createWallet('hot');
walletHot = wclient.wallet('hot', walletInfo.token);
const account = await walletHot.getAccount('default');
addressHot = account.receiveAddress;
}
{
const walletInfo = await wclient.createWallet('miner');
walletMiner = wclient.wallet('miner', walletInfo.token);
const account = await walletMiner.getAccount('default');
addressMiner = account.receiveAddress;
}
await nclient.execute('generatetoaddress', [102, addressMiner]);
await forValue(wdb, 'height', 102);
});
after(async () => {
await nclient.close();
await wclient.close();
await node.close();
});
it('should rpc help', async () => {
assert(await wclient.execute('help', []));
await assert.rejects(async () => {
await wclient.execute('help', ['getbalance']);
}, {
name: 'Error',
message: /^getbalance/
});
});
it('should rpc selectwallet', async () => {
for (const wname of ['hot', 'miner']) {
const response = await wclient.execute('selectwallet', [wname]);
assert.strictEqual(response, null);
const info = await wclient.execute('getwalletinfo');
assert.strictEqual(info.walletid, wname);
}
});
it('should rpc getnewaddress from default account', async () => {
const acctAddr = await wclient.execute('getnewaddress', []);
assert(Address.fromString(acctAddr.toString()));
});
it('should rpc sendtoaddress', async () => {
await wclient.execute('selectwallet', ['miner']);
const txid = await wclient.execute('sendtoaddress', [addressHot, 0.1234]);
assert.strictEqual(txid.length, 64);
});
it('should rpc getaccountaddress', async () => {
addressMiner = await wclient.execute('getaccountaddress', ['default']);
assert(Address.fromString(addressMiner.toString()));
});
it('should fail rpc getnewaddress from nonexistent account', async () => {
await assert.rejects(async () => {
await wclient.execute('getnewaddress', ['bad-account-name']);
}, {
name: 'Error',
message: 'Account not found.'
});
});
it('should rpc sendmany', async () => {
const sendTo = {};
sendTo[addressHot] = 1.0;
sendTo[addressMiner] = 0.1111;
const txid = await wclient.execute('sendmany', ['default', sendTo]);
assert.strictEqual(txid.length, 64);
});
it('should fail malformed rpc sendmany', async () => {
await assert.rejects(async () => {
await wclient.execute('sendmany', ['default', null]);
}, {
name: 'Error',
message: 'Invalid send-to address.'
});
const sendTo = {};
sendTo[addressHot] = null;
await assert.rejects(async () => {
await wclient.execute('sendmany', ['default', sendTo]);
}, {
name: 'Error',
message: 'Invalid amount.'
});
});
it('should rpc listreceivedbyaddress', async () => {
await wclient.execute('selectwallet', ['hot']);
const listZeroConf = await wclient.execute('listreceivedbyaddress',
[0, false, false]);
assert.deepStrictEqual(listZeroConf, [{
'involvesWatchonly': false,
'address': addressHot,
'account': 'default',
'amount': 1.1234,
'confirmations': 0,
'label': ''
}]);
await nclient.execute('generatetoaddress', [1, addressMiner]);
await wdb.syncChain();
const listSomeConf = await wclient.execute('listreceivedbyaddress',
[1, false, false]);
assert.deepStrictEqual(listSomeConf, [{
'involvesWatchonly': false,
'address': addressHot,
'account': 'default',
'amount': 1.1234,
'confirmations': 1,
'label': ''
}]);
const listTooManyConf = await wclient.execute('listreceivedbyaddress',
[100, false, false]);
assert.deepStrictEqual(listTooManyConf, []);
});
it('should rpc listtransactions with no args', async () => {
const txs = await wclient.execute('listtransactions', []);
assert.strictEqual(txs.length, 2);
assert.strictEqual(txs[0].amount + txs[1].amount, 1.1234);
assert.strictEqual(txs[0].account, 'default');
});
it('should rpc listtransactions from specified account', async () => {
const wallet = await wclient.wallet('hot');
await wallet.createAccount('foo');
const txs = await wclient.execute('listtransactions', ['foo']);
assert.strictEqual(txs.length, 0);
});
it('should fail rpc listtransactions from nonexistent account', async () => {
assert.rejects(async () => {
await wclient.execute('listtransactions', ['nonexistent']);
}, {
name: 'Error',
message: 'Account not found.'
});
});
it('should rpc listunspent', async () => {
utxo = await wclient.execute('listunspent', []);
assert.strictEqual(utxo.length, 2);
});
it('should rpc lockunspent and listlockunspent', async () => {
let result = await wclient.execute('listlockunspent', []);
assert.deepStrictEqual(result, []);
// lock one utxo
const output = utxo[0];
const outputsToLock = [{'txid': output.txid, 'vout': output.vout}];
result = await wclient.execute('lockunspent', [false, outputsToLock]);
assert(result);
result = await wclient.execute('listlockunspent', []);
assert.deepStrictEqual(result, outputsToLock);
// unlock all
result = await wclient.execute('lockunspent', [true]);
assert(result);
result = await wclient.execute('listlockunspent', []);
assert.deepStrictEqual(result, []);
});
it('should rpc listsinceblock', async () => {
const listNoBlock = await wclient.execute('listsinceblock', []);
assert.strictEqual(listNoBlock.transactions.length, 2);
const txs = listNoBlock.transactions;
// Sort transactions by blockheight
txs.sort((a, b) => a.blockheight - b.blockheight);
// get lowest block hash.
const bhash = txs[0].blockhash;
const listOldBlock = await wclient.execute('listsinceblock', [bhash]);
assert.strictEqual(listOldBlock.transactions.length, 2);
const nonexistentBlock = consensus.ZERO_HASH.toString('hex');
await assert.rejects(async () => {
await wclient.execute('listsinceblock', [nonexistentBlock]);
}, {
name: 'Error',
message: 'Block not found.'
});
});
describe('getaddressinfo', () => {
const watchOnlyWalletId = 'foo';
const standardWalletId = 'bar';
const watchOnlyWalletId = 'getaddressinfo-foo';
const standardWalletId = 'getaddressinfo-bar';
// m/44'/1'/0'/0/{0,1}
const pubkeys = [
@ -95,14 +302,6 @@ describe('Wallet RPC Methods', function() {
// set up the initial testing state
before(async () => {
{
// Set up the testing environment
// by creating a wallet and a watch
// only wallet
const info = await nclient.getInfo();
assert.equal(info.chain.height, 0);
}
{
// Create a watch only wallet using the path
// m/44'/1'/0' and assert that the wallet