diff --git a/lib/period.js b/lib/period.js index f4c99b7..d9c25c2 100644 --- a/lib/period.js +++ b/lib/period.js @@ -64,6 +64,10 @@ export default class Period { } } + usePrevPeriod() { + this.usePrev = true; + } + // helpful: https://docs.google.com/drawings/d/13oFjua-v_E_yaFYUbralluI-EysgtTaZb_sSgGbxG_A periodData() { if (typeof this.slotId === 'undefined' || !this.ownerAddr) { @@ -85,7 +89,7 @@ export default class Period { // make metaRoot let metaRoot = Buffer.alloc(32, 0); - if (this.prevHash) { + if (this.usePrev) { rootBuf = Buffer.alloc(64, 0); toBuffer(this.prevHash).copy(rootBuf, 32); metaRoot = keccak256(rootBuf); @@ -115,6 +119,44 @@ export default class Period { return periodRoot; } + prevPeriodProof() { + if (!this.usePrev) { + throw Error('not set to use prev period in proofs'); + } + + const { casRoot, metaRoot } = this.periodData(); + + const proof = []; + + // fees hash + proof.push(bufferToHex(Buffer.alloc(32, 0))); + proof.push(this.prevHash); + proof.push(this.merkleRoot()); + proof.push(bufferToHex(casRoot)); + + return proof; + } + + // returns current period + static verifyPrevPeriodProof(proof) { + let result; + result = Buffer.alloc(64, 0); + // fees hash + toBuffer(proof[0]).copy(result); + // prevPeriod + toBuffer(proof[1]).copy(result, 32); + const metaRoot = keccak256(result); + result = Buffer.alloc(64, 0); + //blocks root + toBuffer(proof[2]).copy(result); + metaRoot.copy(result, 32); + const consensusRoot = keccak256(result); + result = Buffer.alloc(64, 0); + toBuffer(consensusRoot).copy(result); + toBuffer(proof[3]).copy(result, 32); + return bufferToHex(keccak256(result)); + } + proof(tx) { let periodPos = -1; for (let i = 0; i < this.blockList.length; i++) { diff --git a/lib/period.spec.js b/lib/period.spec.js index 826e89b..b6c26e0 100644 --- a/lib/period.spec.js +++ b/lib/period.spec.js @@ -255,38 +255,21 @@ describe('periods', () => { const blocks = []; let block; - for (let i = 0; i < 31; i++) { - if (i % 2) { - block = new Block(i).addTx(Tx.deposit(i, value, ADDR, color)); - blocks.push(block); - } else { - blocks.push(new Block(i)); - } + for (let i = 0; i < 30; i++) { + block = new Block(i).addTx(Tx.deposit(i, value, ADDR, color)); + blocks.push(block); } block = new Block(31).addTx(transfer); blocks.push(block); - const period = new Period("'0x8b04de057fe524a3118eb7c8e14a2e55323c67fd7b6080583d1047b700b2d674'", blocks); + const period = new Period("0x8b04de057fe524a3118eb7c8e14a2e55323c67fd7b6080583d1047b700b2d674", blocks); period.setValidatorData(slotId, ADDR); - const proof = period.proof(transfer); - expect(proof).to.eql([ - '0xec7034f5cf812842edc14044fa453c60958c90063a31b623cf44f50402c14938', - '0x300800d0000000000000003e0000000003127777777777777777777777777777', - '0x77777777777777777777777777777777777700c2b5d5b0953f40dd9bbc5e534f', - '0x2db3d4847d897b6615103a157bd69c640490c07945dc613cd500f12a009aad63', - '0x1c530264507c1f5a8591ddc053bd5dc87bcf291b000000000000000000000000', - '0x0000000000000000000000000000000002f34f60053982e8c6cf42c8d1ff9594', - '0xb17a3f50e94a12cc860f00000000000000000000000000000000000000000000', - '0x00000000000002f34f60053982e8c6cf42c8d1ff9594b17a3f50e94a12cc860f', - '0x0000000000000000000000000000000000000000000000000000000000000000', - '0x0000000000000000000000000000000000000000000000000000000000000000', - '0x7d63e2113d90d4316fd6fd3f25837061858b8401ac1331295e922a21fe5e9579', - '0x04fc4e57a69f3fc7b76e12212f843a49837b36dd7280539e52b12f303d1355c4', - '0x3d5087be87669128a31314d9a3cf9d52af2e6dc96132eef574f84ed4ba260b2c', - '0x7e85398f3d5b052c378cc3d2a15209a7e8fbaf2a2b65349f80f5faf033ddf172', - '0x4f23fef08ddaf966bed1b1a57541da6c5a6779fbb51c2d70e4674397ae33712f', - '0x03bfe7f7bc5ba5d5119009b30c5eb918b6ab5050af363b4c3844ec5565e4a604' - ]); + const periodAfter = new Period(period.periodRoot(), blocks); + periodAfter.setValidatorData(slotId, ADDR); + periodAfter.usePrevPeriod(); + + const proof = periodAfter.prevPeriodProof(); + expect(Period.verifyPrevPeriodProof(proof)).to.eql(periodAfter.periodRoot()); done(); });