From d7b1ba95878363ec96b019d155e829c44b8772df Mon Sep 17 00:00:00 2001 From: hh Date: Mon, 5 Feb 2024 22:11:09 +0800 Subject: [PATCH] use ctc parameter --- src/blockchain.ts | 24 +++++++++++++++++------- src/merklePath.ts | 16 ++++++++-------- tests/contracts/blockchainTest.ts | 6 +++--- tests/contracts/merklePath.ts | 4 ++-- tests/specs/blockchain.test.ts | 5 +---- 5 files changed, 31 insertions(+), 24 deletions(-) diff --git a/src/blockchain.ts b/src/blockchain.ts index 298c4f2..b2e0988 100644 --- a/src/blockchain.ts +++ b/src/blockchain.ts @@ -33,9 +33,12 @@ export class Blockchain extends SmartContractLib { static txInBlock( txid: Sha256, bh: BlockHeader, - merkleProof: MerkleProof + merkleProof: MerkleProof, + depth: number ): boolean { - return MerklePath.calcMerkleRoot(txid, merkleProof) == bh.merkleRoot + return ( + MerklePath.calcMerkleRoot(txid, merkleProof, depth) == bh.merkleRoot + ) } // Is txid the last transaction in a block @@ -43,12 +46,13 @@ export class Blockchain extends SmartContractLib { static lastTxInBlock( txid: Sha256, bh: BlockHeader, - merkleProof: MerkleProof + merkleProof: MerkleProof, + depth: number ): boolean { let last = true let root = txid - for (let i = 0; i < MerklePath.DEPTH; i++) { + for (let i = 0; i < depth; i++) { const node = merkleProof[i] if (node.pos != MerklePath.INVALID_NODE) { @@ -139,15 +143,21 @@ export class Blockchain extends SmartContractLib { static blockHeight( bh: BlockHeader, coinbaseTx: ByteString, - merkleProof: MerkleProof + merkleProof: MerkleProof, + depth: number ): bigint { // Ensure coinbase it's in the block. assert( - Blockchain.txInBlock(Sha256(hash256(coinbaseTx)), bh, merkleProof) + Blockchain.txInBlock( + Sha256(hash256(coinbaseTx)), + bh, + merkleProof, + depth + ) ) // Ensure it's the coinbase. - assert(MerklePath.isCoinbase(merkleProof)) + assert(MerklePath.isCoinbase(merkleProof, depth)) return Blockchain.readBlockHeight(coinbaseTx) } diff --git a/src/merklePath.ts b/src/merklePath.ts index 350ef71..00aaad2 100644 --- a/src/merklePath.ts +++ b/src/merklePath.ts @@ -21,10 +21,6 @@ export type Node = { export type MerkleProof = FixedArray // If shorter than 32, pad with invalid nodes. export class MerklePath extends SmartContractLib { - // Maximal depth of a Merkle tree/path, which can support a block with 2^32 transactions. - @prop() - static readonly DEPTH: bigint = 32n // TODO: Make configurable by lib user. - @prop() static readonly INVALID_NODE: bigint = 0n @@ -36,10 +32,14 @@ export class MerklePath extends SmartContractLib { // According to the given leaf node and merkle path, calculate the hash of the root node of the merkle tree. @method() - static calcMerkleRoot(leaf: Sha256, merkleProof: MerkleProof): Sha256 { + static calcMerkleRoot( + leaf: Sha256, + merkleProof: MerkleProof, + depth: number + ): Sha256 { let root = leaf - for (let i = 0; i < MerklePath.DEPTH; i++) { + for (let i = 0; i < depth; i++) { const node = merkleProof[i] if (node.pos != MerklePath.INVALID_NODE) { // s is valid @@ -55,9 +55,9 @@ export class MerklePath extends SmartContractLib { // A tx is the blocks coinbase if all nodes on its Merkle path are on the right branch. @method() - static isCoinbase(merkleproof: MerkleProof): boolean { + static isCoinbase(merkleproof: MerkleProof, depth: number): boolean { let res = true - for (let i = 0; i < MerklePath.DEPTH; i++) { + for (let i = 0; i < depth; i++) { const node = merkleproof[i] if (node.pos != MerklePath.INVALID_NODE) { // node on the right diff --git a/tests/contracts/blockchainTest.ts b/tests/contracts/blockchainTest.ts index d470cca..fec3878 100644 --- a/tests/contracts/blockchainTest.ts +++ b/tests/contracts/blockchainTest.ts @@ -9,7 +9,7 @@ export class BlockchainTest extends SmartContract { merkleProof: MerkleProof, res: boolean ) { - assert(Blockchain.txInBlock(txid, bh, merkleProof) == res) + assert(Blockchain.txInBlock(txid, bh, merkleProof, 32) == res) } @method() @@ -24,7 +24,7 @@ export class BlockchainTest extends SmartContract { merkleProof: MerkleProof, res: boolean ) { - assert(Blockchain.lastTxInBlock(txid, bh, merkleProof) == res) + assert(Blockchain.lastTxInBlock(txid, bh, merkleProof, 32) == res) } @method() @@ -48,7 +48,7 @@ export class BlockchainTest extends SmartContract { merkleProof: MerkleProof, res: bigint ) { - assert(Blockchain.blockHeight(bh, coinbaseTx, merkleProof) == res) + assert(Blockchain.blockHeight(bh, coinbaseTx, merkleProof, 32) == res) } //@method() diff --git a/tests/contracts/merklePath.ts b/tests/contracts/merklePath.ts index 2af69a4..6341c33 100644 --- a/tests/contracts/merklePath.ts +++ b/tests/contracts/merklePath.ts @@ -4,11 +4,11 @@ import { method, assert, SmartContract, Sha256 } from 'scrypt-ts' export class MerklePathTest extends SmartContract { @method() public calcMerkleRoot(leaf: Sha256, merkleProof: MerkleProof, res: Sha256) { - assert(MerklePath.calcMerkleRoot(leaf, merkleProof) == res) + assert(MerklePath.calcMerkleRoot(leaf, merkleProof, 32) == res) } @method() public isCoinbase(merkleProof: MerkleProof, res: boolean) { - assert(MerklePath.isCoinbase(merkleProof) == res) + assert(MerklePath.isCoinbase(merkleProof, 32) == res) } } diff --git a/tests/specs/blockchain.test.ts b/tests/specs/blockchain.test.ts index cfaea85..5ad05e0 100644 --- a/tests/specs/blockchain.test.ts +++ b/tests/specs/blockchain.test.ts @@ -1281,10 +1281,7 @@ function prepProofFromWoc(proof: any): MerkleProof { ), pos: MerklePath.INVALID_NODE, } - return [ - ...res, - ...Array(Number(MerklePath.DEPTH) - res.length).fill(invalidNode), - ] as MerkleProof + return [...res, ...Array(32 - res.length).fill(invalidNode)] as MerkleProof } /**