Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bcoin wallet pagination test: docker container and init script #167

Merged
merged 18 commits into from
Jan 23, 2019
Merged
4 changes: 2 additions & 2 deletions Dockerfile-bcoin
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ FROM base AS build
RUN pacman -Syu --noconfirm base-devel unrar git python2 \
&& ln -s /usr/bin/python2 /usr/bin/python

ARG branch=master
ARG repo=bcoin-org/bcoin

# use this to bust the build cache
ARG rebuild=0

# Install bcoin, bmultisig, blgr, bclient
RUN npm init -y &>/dev/null \
&& npm install bcoin-org/bcoin \
&& npm install $repo \
bcoin-org/bmultisig \
bcoin-org/blgr \
bcoin-org/bclient
Expand Down
5 changes: 2 additions & 3 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,13 @@ services:

bcoin:
## Use image to to pull from docker hub
image: bpanel/bcoin:dev
image: bpanel/bcoin:experimental
## Build to use local Dockerfile-bcoin
# build:
# context: .
# dockerfile: Dockerfile-bcoin
# args:
# repo: https://github.com/bcoin-org/bcoin.git
# branch: master
# repo: bpanel-org/bcoin#experimental
# rebuild: 0
restart: unless-stopped
env_file:
Expand Down
2 changes: 1 addition & 1 deletion etc/regtest.bcoin.env
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ BCOIN_NO_WALLET=true
BCOIN_INDEX_TX=true
BCOIN_INDEX_ADDRESS=true
BCOIN_NODE_HOST=0.0.0.0
BCOIN_INIT_SCRIPT=funded-dummy-wallets.js
BCOIN_INIT_SCRIPT=pagination-test-wallets.js
pinheadmz marked this conversation as resolved.
Show resolved Hide resolved
2 changes: 1 addition & 1 deletion scripts/funded-dummy-wallets.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { protocol: consensus } = require('bcoin');
const { protocol: { consensus } } = require('bcoin');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😬 whoops!


const makeWallets = async (node, config, logger, wallet) => {
const network = node.network.type;
Expand Down
167 changes: 167 additions & 0 deletions scripts/pagination-test-wallets.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
const { protocol: { consensus } } = require('bcoin');

module.exports = async (node, config, logger, wallet) => {
consensus.COINBASE_MATURITY = 0;

const miner = node.miner;
const chain = node.chain;
const network = node.network;
const feeRate = network.minRelay * 10; // for some reason bc segwit??!!
const wdb = wallet.wdb;

const numInitBlocks = 144 * 3; // Initial blocks mined to activate SegWit.
// Miner primary/default then evenly disperses
// all funds to other wallet accounts

const numTxBlocks = 10; // How many blocks to randomly fill with txs
const numTxPerBlock = 10; // How many txs to try to put in each block
// (due to the random tx-generation, some txs will fail due to lack of funds)

const maxOutputsPerTx = 4; // Each tx will have a random # of outputs
const minSend = 50000; // Each tx output will have a random value
const maxSend = 100000;

// We are going to bend time, and start our blockchain in the past!
let virtualNow = network.now() - 60 * 10 * (numInitBlocks + numTxBlocks + 1);
const blockInterval = 60 * 10; // ten minutes

const walletNames = [
tynes marked this conversation as resolved.
Show resolved Hide resolved
'Powell',
'Yellen',
'Bernanke',
'Greenspan',
'Volcker',
'Miller',
'Burns',
'Martin',
'McCabe',
'Eccles'
];

const accountNames = ['hot', 'cold'];

const wallets = [];

const mineRegtestBlock = async function(coinbaseAddr) {
const entry = await chain.getEntry(node.chain.tip.hash);
const block = await miner.mineBlock(entry, coinbaseAddr);
await node.chain.add(block);
};

const mineRegtestBlockToPast = async function(coinbaseAddr) {
tynes marked this conversation as resolved.
Show resolved Hide resolved
const entry = await chain.getEntry(node.chain.tip.hash);
const job = await miner.createJob(entry, coinbaseAddr);
job.attempt.time = virtualNow;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

very cool. Did not know about this.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah! I was playing with this testing actual time-based CSV transactions for the atomic swaps app/guide. Wrote a PR to test CSV-by-time for bcoin:
bcoin-org/bcoin#613

virtualNow += blockInterval;
job.refresh();
const block = await job.mineAsync();
await node.chain.add(block);
};

logger.info('Creating wallets and accounts...');
for (const wName of walletNames) {
try {
const newWallet = await wdb.create({
id: wName,
witness: Math.random() < 0.5
});

wallets.push(newWallet);

for (const aName of accountNames) {
await newWallet.createAccount({
name: aName,
witness: Math.random() < 0.5
});
}
} catch (e) {
logger.error(`Error creating wallet ${wName}:`, e.message);
}
}

if (!wallets.length) {
logger.info('No wallets created, likely this script has already been run');
return;
}
accountNames.push('default');

logger.info('Mining initial blocks...');
const primary = wdb.primary;
const minerReceive = await primary.receiveAddress();
await miner.addAddress(minerReceive);
for (let i = 0; i < numInitBlocks; i++) {
await mineRegtestBlockToPast(minerReceive);
}

logger.info('Ensure wallet is caught up before proceeding...');
await wdb.rescan(0);

logger.info('Air-dropping funds to the people...');
const balance = await primary.getBalance(0);

const totalAmt = balance.confirmed;
const amtPerAcct = Math.floor(
totalAmt / (walletNames.length * accountNames.length)
);
const outputs = [];
for (const wallet of wallets) {
for (const aName of accountNames) {
const recAddr = await wallet.receiveAddress(aName);
outputs.push({
value: amtPerAcct,
address: recAddr
});
}
}

await primary.send({
outputs: outputs,
rate: feeRate,
subtractFee: true
});

logger.info('Confirming airdrop...');
await mineRegtestBlockToPast(minerReceive);

logger.info('Creating a big mess!...');
for (let b = 0; b < numTxBlocks; b++) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm probably missing something really obvious, but what is numTxBlocks for?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  const numInitBlocks = 144 * 3; // blocks mined to primary/default to activate segwit and start chain
  const numTxBlocks = 10; // how many blocks to fill with transactions once wallets are all set up and initial mined funds are distributed
  const numTxPerBlock = 10; // how many txs to generate randomly between accounts before mining a block
  const maxOutputsPerTx = 4; // each random tx has ranomd # of outputs
  const minSend = 50000; // tx amounts are also random
  const maxSend = 100000;

for (let t = 0; t < numTxPerBlock; t++) {
// Randomly select recipients for this tx
const outputs = [];
const numOutputs = Math.floor(Math.random() * maxOutputsPerTx) + 1;
for (let o = 0; o < numOutputs; o++) {
const recWallet = wallets[Math.floor(Math.random() * wallets.length)];
const recAcct =
accountNames[Math.floor(Math.random() * wallets.length)];

const recAddr = await recWallet.receiveAddress(recAcct);
const value = Math.floor(
Math.random() * (maxSend - minSend) + minSend / numOutputs
);
outputs.push({
value: value,
address: recAddr
});
}

// Randomly choose a sender for this tx
const sendWallet = wallets[Math.floor(Math.random() * wallets.length)];
const sendAcct = accountNames[Math.floor(Math.random() * wallets.length)];
try {
const tx = await sendWallet.send({
account: sendAcct,
outputs: outputs,
rate: feeRate,
subtractFee: true
});
} catch (e) {
logger.error(`Problem sending tx: ${e}`);
}
}

// CONFIRM
await mineRegtestBlockToPast(minerReceive);
}

logger.info('All done! Go play.');
};