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

test: added more coverage to tests #1134

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions test/coin-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,34 @@ describe('Coin', function() {
assert(fmt.includes('coinbase'));
assert(fmt.includes('script'));
});

it('should throw error for invalid input raw data', () => {
let error;
try {
Coin.fromRaw(Buffer.from([]));
} catch (e) {
error = e;
}

assert(error instanceof Error);
assert.strictEqual(error.message, 'Out of bounds read (offset=0).');
});

it('should return expected txid', () => {
const [tx] = tx1.getTX();
const coin = Coin.fromTX(tx, 0, 0);
assert.strictEqual(coin.txid(), 'ff80fe4937e2de16411c3a2bc534d661dc8b4f8aad75e6fbc4b1ec6060d9ef1c');
});

it('should return expected type', () => {
const [tx] = tx1.getTX();
const coin = Coin.fromTX(tx, 0, 0);
assert.strictEqual(coin.getType(), 'multisig');
});

it('should return expected address', () => {
const [tx] = tx1.getTX();
const coin = Coin.fromTX(tx, 0, 0);
assert.strictEqual(coin.getAddress().toString(), '3KUER9kZ693d5FQgvmr5qNDKnSpP9nXv9v');
});
});
28 changes: 28 additions & 0 deletions test/coins-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,4 +99,32 @@ describe('Coins', function() {
assert.strictEqual(coins.get(0), null);
deepCoinsEqual(coins.get(1), reserialize(coins.get(1)));
});

it('should spend multiple outputs from a single transaction', () => {
const [tx, view] = tx1.getTX();

view.addTX(tx, 1);

const hash = tx.hash();
const coins = view.get(hash);

view.spendEntry(new Outpoint(hash, 0));
view.spendEntry(new Outpoint(hash, 1));

assert.strictEqual(coins.get(0).spent, true);
assert.strictEqual(coins.get(1).spent, true);
assert.strictEqual(view.undo.items.length, 2);
});

it('should handle serialization and deserialization of the coin view', () => {
const [tx, view] = tx1.getTX();

const size = view.getSize(tx);
const bw = bio.write(size);
const raw = view.toWriter(bw, tx).render();
const br = bio.read(raw);
const res = CoinView.fromReader(br, tx);

assert.deepStrictEqual(view, res);
});
});
86 changes: 86 additions & 0 deletions test/consensus-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,90 @@ describe('Consensus', function() {
assert(consensus.hasBit(0x20000003, 1));
assert(consensus.hasBit(0x20000003, 0));
});

it('should calculate block reward properly', () => {
let height = 0;
const reward = consensus.getReward(height, 210000);
assert.strictEqual(reward, 50 * consensus.COIN);
height = 210000;
const reward2 = consensus.getReward(height, 210000);
assert.strictEqual(reward2, 25 * consensus.COIN);
});

it('should throw an error for invalid height', () => {
assert.throws(() => {
consensus.getReward(-100, 210000);
}, /Bad height for reward./);
});

it('should return false for invalid proof-of-work', () => {
const bits = 0x1900896c;
const hash = Buffer.from(
'672b3f1bb11a994267ea4171069ba0aa4448a840f38e8f340000000000000001',
'hex');
assert.strictEqual(consensus.verifyPOW(hash, bits), false);
});

it('should return correct reward amount at given height and reward interval', () => {
const height = 210000;
const rewardInterval = 210000;
const expectedReward = 25 * consensus.COIN;

const reward = consensus.getReward(height, rewardInterval);

assert.strictEqual(reward, expectedReward);
});

it('should correctly determine whether a given version number contains a specific bit', () => {
const version = 0x20000001;
const bit = 0;
const expectedResult = true;

const result = consensus.hasBit(version, bit);

assert.strictEqual(result, expectedResult);
});

it('should correctly convert target to compact representation of target', () => {
const target = new BN(
'0000000000000000896c00000000000000000000000000000000000000000000',
'hex');
const expectedCompact = 0x1900896c;

const compact = consensus.toCompact(target);

assert.strictEqual(compact, expectedCompact);
});

it('should correctly verify proof of work', () => {
const hash = Buffer.from(
'672b3f1bb11a994267ea4171069ba0aa4448a840f38e8f340000000000000000',
'hex'
);
const bits = 0x1900896c;
const expectedResult = true;

const result = consensus.verifyPOW(hash, bits);

assert.strictEqual(result, expectedResult);
});

it('should correctly return total reward for all blocks until the reward becomes zero', () => {
let height = 0;
let total = 0;

for (;;) {
const reward = consensus.getReward(height, 210000);
total += reward;
if (reward === 0)
break;
height++;
}

const expectedHeight = 6930000;
const expectedTotal = 2099999997690000;

assert.strictEqual(height, expectedHeight);
assert.strictEqual(total, expectedTotal);
});
});
10 changes: 10 additions & 0 deletions test/gcs-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -170,4 +170,14 @@ describe('GCS', function () {
match = filter2.matchAny(key, contents);
assert(match);
});

it('should test toBytes', () => {
const filterBytes = filter1.toBytes();
assert(filterBytes instanceof Buffer);
});

it('should test toNBytes', () => {
const filterNBytes = filter1.toNBytes();
assert(filterNBytes instanceof Buffer);
});
});
16 changes: 16 additions & 0 deletions test/headers-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,20 @@ describe('Headers', function() {
assert(headers.verifyBody());
assert(headers.verifyPOW());
});

it('should match raw headers from headers', () => {
const headers = new Headers();
headers.time = 1231469665;
headers.bits = 486604799;
headers.nonce = 2573394689;
headers.version = 1;
headers.prevBlock = Buffer.from(
'6fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000',
'hex');
headers.merkleRoot = Buffer.from(
'982051fd1e4ba744bbbe680e1fee14677ba1a3c3540bf7b1cdb606e857233e0e',
'hex');

assert.bufferEqual(headers.toRaw(), headers1);
});
});
18 changes: 18 additions & 0 deletions test/mnemonic-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,22 @@ describe('Mnemonic', function() {
assert.strictEqual(m2.language, m1.language);
assert.bufferEqual(m2.toSeed(), m1.toSeed());
});

it('should create different seed with different passphrase', () => {
const mnemonic = new Mnemonic();
const seed1 = mnemonic.toSeed();
const seed2 = mnemonic.toSeed('different passphrase');
assert.notDeepEqual(seed1, seed2);
});

it('should create a mnemonic in French', () => {
const mnemonic = new Mnemonic({language: 'french'});
assert.strictEqual(mnemonic.language, 'french');
});

it('should create an HD Private Key from a mnemonic with no passphrase', () => {
const mnemonic = new Mnemonic();
const key = HDPrivateKey.fromMnemonic(mnemonic);
assert.strictEqual(key.depth, 0);
});
});
50 changes: 50 additions & 0 deletions test/mtx-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,54 @@ describe('MTX', function () {
const mtx2 = MTX.fromRaw(mtx1.toRaw());
assert.deepStrictEqual(mtx1, mtx2);
});

it('should encode and decode mtx with multiple inputs and outputs', () => {
const input1 = new Input({
prevout: {
hash: Buffer.alloc(32),
index: 0
}
});
const input2 = new Input({
prevout: {
hash: Buffer.alloc(32),
index: 1
}
});
const output1 = new Output({
value: 1e8,
address: new Address()
});
const output2 = new Output({
value: 2e8,
address: new Address()
});
const mtx1 = new MTX({
inputs: [input1, input2],
outputs: [output1, output2]
});
const mtx2 = MTX.fromRaw(mtx1.toRaw());
assert.deepStrictEqual(mtx1, mtx2);
});

it('should encode and decode mtx with segwit inputs and outputs', () => {
const input = new Input({
prevout: {
hash: Buffer.alloc(32),
index: 0
},
witness: [Buffer.alloc(4)]
});
const output = new Output({
value: 1e8,
address: new Address(),
script: Buffer.alloc(4)
});
const mtx1 = new MTX({
inputs: [input],
outputs: [output]
});
const mtx2 = MTX.fromRaw(mtx1.toRaw());
assert.deepStrictEqual(mtx1, mtx2);
});
});
21 changes: 21 additions & 0 deletions test/pow-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,27 @@ describe('Difficulty', function() {
assert.strictEqual(chain.retarget(prev, first), 0x1d00e1fd);
});

it('should test retarget with a range of inputs', async () => {
// Create an array of test cases
const testCases = [
{ prevTime: 1262152739, prevBits: 0x1d00ffff, firstTime: 1261130161, expected: 0x1d00d86a },
{ prevTime: 1233061996, prevBits: 0x1d00ffff, firstTime: 1231006505, expected: 0x1d00ffff },
{ prevTime: 1279297671, prevBits: 0x1c05a3f4, firstTime: 1279008237, expected: 0x1c0168fd },
{ prevTime: 1269211443, prevBits: 0x1c387f6f, firstTime: 1263163443, expected: 0x1d00e1fd }
];

// Iterate through the test cases and check the output of the retarget function
for (const testCase of testCases) {
const prev = new ChainEntry();
prev.time = testCase.prevTime;
prev.bits = testCase.prevBits;
prev.height = 32255;
const first = new ChainEntry();
first.time = testCase.firstTime;
assert.strictEqual(chain.retarget(prev, first), testCase.expected);
}
});

it('should get block proof equivalent time', async () => {
const blocks = [];
for (let i = 0; i < 10000; i++) {
Expand Down