264 lines
7.5 KiB
JavaScript
264 lines
7.5 KiB
JavaScript
/* eslint-env mocha */
|
|
/* eslint prefer-arrow-callback: "off" */
|
|
|
|
'use strict';
|
|
|
|
const assert = require('assert');
|
|
const BN = require('../lib/crypto/bn');
|
|
const base58 = require('../lib/utils/base58');
|
|
const encoding = require('../lib/utils/encoding');
|
|
const Amount = require('../lib/btc/amount');
|
|
const consensus = require('../lib/protocol/consensus');
|
|
const Validator = require('../lib/utils/validator');
|
|
const util = require('../lib/utils/util');
|
|
|
|
const base58Tests = [
|
|
['', ''],
|
|
['61', '2g'],
|
|
['626262', 'a3gV'],
|
|
['636363', 'aPEr'],
|
|
[
|
|
'73696d706c792061206c6f6e6720737472696e67',
|
|
'2cFupjhnEsSn59qHXstmK2ffpLv2'
|
|
],
|
|
[
|
|
'00eb15231dfceb60925886b67d065299925915aeb172c06647',
|
|
'1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L'
|
|
],
|
|
['516b6fcd0f', 'ABnLTmg'],
|
|
['bf4f89001e670274dd', '3SEo3LWLoPntC'],
|
|
['572e4794', '3EFU7m'],
|
|
['ecac89cad93923c02321', 'EJDM8drfXA6uyA'],
|
|
['10c8511e', 'Rt5zm'],
|
|
['00000000000000000000', '1111111111']
|
|
];
|
|
|
|
describe('Utils', function() {
|
|
it('should encode/decode base58', () => {
|
|
const buf = Buffer.from('000000deadbeef', 'hex');
|
|
const str = base58.encode(buf);
|
|
|
|
assert.equal(str, '1116h8cQN');
|
|
assert.deepEqual(base58.decode(str), buf);
|
|
|
|
for (const [hex, b58] of base58Tests) {
|
|
const data = Buffer.from(hex, 'hex');
|
|
assert.equal(base58.encode(data), b58);
|
|
assert.deepEqual(base58.decode(b58), data);
|
|
}
|
|
});
|
|
|
|
it('should verify proof-of-work', () => {
|
|
const bits = 0x1900896c;
|
|
|
|
const hash = Buffer.from(
|
|
'672b3f1bb11a994267ea4171069ba0aa4448a840f38e8f340000000000000000',
|
|
'hex'
|
|
);
|
|
|
|
assert(consensus.verifyPOW(hash, bits));
|
|
});
|
|
|
|
it('should convert satoshi to btc', () => {
|
|
let btc = Amount.btc(5460);
|
|
assert.equal(btc, '0.0000546');
|
|
btc = Amount.btc(54678 * 1000000);
|
|
assert.equal(btc, '546.78');
|
|
btc = Amount.btc(5460 * 10000000);
|
|
assert.equal(btc, '546.0');
|
|
});
|
|
|
|
it('should convert btc to satoshi', () => {
|
|
let btc = Amount.value('0.0000546');
|
|
assert(btc === 5460);
|
|
btc = Amount.value('546.78');
|
|
assert(btc === 54678 * 1000000);
|
|
btc = Amount.value('546');
|
|
assert(btc === 5460 * 10000000);
|
|
btc = Amount.value('546.0');
|
|
assert(btc === 5460 * 10000000);
|
|
btc = Amount.value('546.0000');
|
|
assert(btc === 5460 * 10000000);
|
|
|
|
assert.doesNotThrow(() => {
|
|
Amount.value('546.00000000000000000');
|
|
});
|
|
|
|
assert.throws(() => {
|
|
Amount.value('546.00000000000000001');
|
|
});
|
|
|
|
assert.doesNotThrow(() => {
|
|
Amount.value('90071992.54740991');
|
|
});
|
|
|
|
assert.doesNotThrow(() => {
|
|
Amount.value('090071992.547409910');
|
|
});
|
|
|
|
assert.throws(() => {
|
|
Amount.value('90071992.54740992');
|
|
});
|
|
|
|
assert.throws(() => {
|
|
Amount.value('190071992.54740991');
|
|
});
|
|
|
|
assert.strictEqual(parseFloat('0.15645647') * 1e8, 15645646.999999998);
|
|
assert.strictEqual(util.fromFixed('0.15645647', 8), 15645647);
|
|
assert.strictEqual(util.toFixed(15645647, 8), '0.15645647');
|
|
});
|
|
|
|
it('should write/read new varints', () => {
|
|
/*
|
|
* 0: [0x00] 256: [0x81 0x00]
|
|
* 1: [0x01] 16383: [0xFE 0x7F]
|
|
* 127: [0x7F] 16384: [0xFF 0x00]
|
|
* 128: [0x80 0x00] 16511: [0x80 0xFF 0x7F]
|
|
* 255: [0x80 0x7F] 65535: [0x82 0xFD 0x7F]
|
|
* 2^32: [0x8E 0xFE 0xFE 0xFF 0x00]
|
|
*/
|
|
|
|
let b = Buffer.allocUnsafe(1);
|
|
b.fill(0x00);
|
|
encoding.writeVarint2(b, 0, 0);
|
|
assert.equal(encoding.readVarint2(b, 0).value, 0);
|
|
assert.deepEqual(b, [0]);
|
|
|
|
b = Buffer.allocUnsafe(1);
|
|
b.fill(0x00);
|
|
encoding.writeVarint2(b, 1, 0);
|
|
assert.equal(encoding.readVarint2(b, 0).value, 1);
|
|
assert.deepEqual(b, [1]);
|
|
|
|
b = Buffer.allocUnsafe(1);
|
|
b.fill(0x00);
|
|
encoding.writeVarint2(b, 127, 0);
|
|
assert.equal(encoding.readVarint2(b, 0).value, 127);
|
|
assert.deepEqual(b, [0x7f]);
|
|
|
|
b = Buffer.allocUnsafe(2);
|
|
b.fill(0x00);
|
|
encoding.writeVarint2(b, 128, 0);
|
|
assert.equal(encoding.readVarint2(b, 0).value, 128);
|
|
assert.deepEqual(b, [0x80, 0x00]);
|
|
|
|
b = Buffer.allocUnsafe(2);
|
|
b.fill(0x00);
|
|
encoding.writeVarint2(b, 255, 0);
|
|
assert.equal(encoding.readVarint2(b, 0).value, 255);
|
|
assert.deepEqual(b, [0x80, 0x7f]);
|
|
|
|
b = Buffer.allocUnsafe(2);
|
|
b.fill(0x00);
|
|
encoding.writeVarint2(b, 16383, 0);
|
|
assert.equal(encoding.readVarint2(b, 0).value, 16383);
|
|
assert.deepEqual(b, [0xfe, 0x7f]);
|
|
|
|
b = Buffer.allocUnsafe(2);
|
|
b.fill(0x00);
|
|
encoding.writeVarint2(b, 16384, 0);
|
|
assert.equal(encoding.readVarint2(b, 0).value, 16384);
|
|
assert.deepEqual(b, [0xff, 0x00]);
|
|
|
|
b = Buffer.allocUnsafe(3);
|
|
b.fill(0x00);
|
|
encoding.writeVarint2(b, 16511, 0);
|
|
assert.equal(encoding.readVarint2(b, 0).value, 16511);
|
|
// assert.deepEqual(b, [0x80, 0xff, 0x7f]);
|
|
assert.deepEqual(b, [0xff, 0x7f, 0x00]);
|
|
|
|
b = Buffer.allocUnsafe(3);
|
|
b.fill(0x00);
|
|
encoding.writeVarint2(b, 65535, 0);
|
|
assert.equal(encoding.readVarint2(b, 0).value, 65535);
|
|
// assert.deepEqual(b, [0x82, 0xfd, 0x7f]);
|
|
assert.deepEqual(b, [0x82, 0xfe, 0x7f]);
|
|
|
|
b = Buffer.allocUnsafe(5);
|
|
b.fill(0x00);
|
|
encoding.writeVarint2(b, Math.pow(2, 32), 0);
|
|
assert.equal(encoding.readVarint2(b, 0).value, Math.pow(2, 32));
|
|
assert.deepEqual(b, [0x8e, 0xfe, 0xfe, 0xff, 0x00]);
|
|
});
|
|
|
|
const unsigned = [
|
|
new BN('ffeeffee'),
|
|
new BN('001fffeeffeeffee'),
|
|
new BN('eeffeeff'),
|
|
new BN('001feeffeeffeeff'),
|
|
new BN(0),
|
|
new BN(1)
|
|
];
|
|
|
|
const signed = [
|
|
new BN('ffeeffee'),
|
|
new BN('001fffeeffeeffee'),
|
|
new BN('eeffeeff'),
|
|
new BN('001feeffeeffeeff'),
|
|
new BN(0),
|
|
new BN(1),
|
|
new BN('ffeeffee').ineg(),
|
|
new BN('001fffeeffeeffee').ineg(),
|
|
new BN('eeffeeff').ineg(),
|
|
new BN('001feeffeeffeeff').ineg(),
|
|
new BN(0).ineg(),
|
|
new BN(1).ineg()
|
|
];
|
|
|
|
for (const num of unsigned) {
|
|
const bits = num.bitLength();
|
|
|
|
it(`should write+read a ${bits} bit unsigned int`, () => {
|
|
const buf1 = Buffer.allocUnsafe(8);
|
|
const buf2 = Buffer.allocUnsafe(8);
|
|
encoding.writeU64BN(buf1, num, 0);
|
|
encoding.writeU64(buf2, num.toNumber(), 0);
|
|
assert.deepEqual(buf1, buf2);
|
|
|
|
const n1 = encoding.readU64BN(buf1, 0);
|
|
const n2 = encoding.readU64(buf2, 0);
|
|
assert.equal(n1.toNumber(), n2);
|
|
});
|
|
}
|
|
|
|
for (const num of signed) {
|
|
const bits = num.bitLength();
|
|
const sign = num.isNeg() ? 'negative' : 'positive';
|
|
|
|
it(`should write+read a ${bits} bit ${sign} int`, () => {
|
|
const buf1 = Buffer.allocUnsafe(8);
|
|
const buf2 = Buffer.allocUnsafe(8);
|
|
encoding.writeI64BN(buf1, num, 0);
|
|
encoding.writeI64(buf2, num.toNumber(), 0);
|
|
assert.deepEqual(buf1, buf2);
|
|
|
|
const n1 = encoding.readI64BN(buf1, 0);
|
|
const n2 = encoding.readI64(buf2, 0);
|
|
assert.equal(n1.toNumber(), n2);
|
|
});
|
|
|
|
it(`should write+read a ${bits} bit ${sign} int as unsigned`, () => {
|
|
const buf1 = Buffer.allocUnsafe(8);
|
|
const buf2 = Buffer.allocUnsafe(8);
|
|
encoding.writeU64BN(buf1, num, 0);
|
|
encoding.writeU64(buf2, num.toNumber(), 0);
|
|
assert.deepEqual(buf1, buf2);
|
|
|
|
const n1 = encoding.readU64BN(buf1, 0);
|
|
if (num.isNeg()) {
|
|
assert.throws(() => encoding.readU64(buf2, 0));
|
|
} else {
|
|
const n2 = encoding.readU64(buf2, 0);
|
|
assert.equal(n1.toNumber(), n2);
|
|
}
|
|
});
|
|
}
|
|
|
|
it('should validate integers 0 and 1 as booleans', () => {
|
|
const validator = new Validator({shouldBeTrue: 1, shouldBeFalse: 0});
|
|
assert(validator.bool('shouldBeTrue') === true);
|
|
assert(validator.bool('shouldBeFalse') === false);
|
|
});
|
|
});
|