[NOD-163] Added BlockHeader.AcceptedIDMerkleRoot (#293)

This commit is contained in:
Evgeny Khirin 2019-05-12 11:53:47 +03:00 committed by stasatdaglabs
parent b7b41f1a94
commit 08d94c7a47
34 changed files with 329 additions and 194 deletions

View File

@ -97,12 +97,13 @@ type blockNode struct {
// reconstructing headers from memory. These must be treated as
// immutable and are intentionally ordered to avoid padding on 64-bit
// platforms.
version int32
bits uint32
nonce uint64
timestamp int64
hashMerkleRoot *daghash.Hash
idMerkleRoot *daghash.Hash
version int32
bits uint32
nonce uint64
timestamp int64
hashMerkleRoot *daghash.Hash
idMerkleRoot *daghash.Hash
acceptedIDMerkleRoot *daghash.Hash
// status is a bitfield representing the validation state of the block. The
// status field, unlike the other fields, may be written to and so should
@ -130,6 +131,7 @@ func initBlockNode(node *blockNode, blockHeader *wire.BlockHeader, parents block
node.timestamp = blockHeader.Timestamp.Unix()
node.hashMerkleRoot = blockHeader.HashMerkleRoot
node.idMerkleRoot = blockHeader.IDMerkleRoot
node.acceptedIDMerkleRoot = blockHeader.AcceptedIDMerkleRoot
} else {
node.hash = &daghash.ZeroHash
}
@ -176,13 +178,14 @@ func (node *blockNode) updateParentsChildren() {
func (node *blockNode) Header() *wire.BlockHeader {
// No lock is needed because all accessed fields are immutable.
return &wire.BlockHeader{
Version: node.version,
ParentHashes: node.ParentHashes(),
HashMerkleRoot: node.hashMerkleRoot,
IDMerkleRoot: node.idMerkleRoot,
Timestamp: time.Unix(node.timestamp, 0),
Bits: node.bits,
Nonce: node.nonce,
Version: node.version,
ParentHashes: node.ParentHashes(),
HashMerkleRoot: node.hashMerkleRoot,
IDMerkleRoot: node.idMerkleRoot,
AcceptedIDMerkleRoot: node.acceptedIDMerkleRoot,
Timestamp: time.Unix(node.timestamp, 0),
Bits: node.bits,
Nonce: node.nonce,
}
}

View File

@ -13,6 +13,7 @@ import (
"path/filepath"
"reflect"
"strings"
"testing"
"time"
"github.com/daglabs/btcd/dagconfig"
@ -81,6 +82,17 @@ func loadBlocks(filename string) (blocks []*util.Block, err error) {
return
}
func loadBlocksWithLog(t *testing.T, filename string) ([]*util.Block, error) {
blocks, err := loadBlocks(filename)
if err == nil {
t.Logf("Loaded %d blocks from file %s", len(blocks), filename)
for i, b := range blocks {
t.Logf("Block #%d: %s", i, b.Hash())
}
}
return blocks, err
}
// loadUTXOSet returns a utxo view loaded from a file.
func loadUTXOSet(filename string) (UTXOSet, error) {
// The utxostore file format is:
@ -188,12 +200,13 @@ func newTestDAG(params *dagconfig.Params) *BlockDAG {
func newTestNode(parents blockSet, blockVersion int32, bits uint32, timestamp time.Time, phantomK uint32) *blockNode {
// Make up a header and create a block node from it.
header := &wire.BlockHeader{
Version: blockVersion,
ParentHashes: parents.hashes(),
Bits: bits,
Timestamp: timestamp,
HashMerkleRoot: &daghash.ZeroHash,
IDMerkleRoot: &daghash.ZeroHash,
Version: blockVersion,
ParentHashes: parents.hashes(),
Bits: bits,
Timestamp: timestamp,
HashMerkleRoot: &daghash.ZeroHash,
IDMerkleRoot: &daghash.ZeroHash,
AcceptedIDMerkleRoot: &daghash.ZeroHash,
}
return newBlockNode(header, parents, phantomK)
}

View File

@ -192,10 +192,10 @@ func TestHaveBlock(t *testing.T) {
{hash: dagconfig.SimNetParams.GenesisHash.String(), want: true},
// Block 3b should be present (as a second child of Block 2).
{hash: "040c43ca52ded708dacef2a9fa589f41e4f7565345f7f1e61f379dbf32bb6b48", want: true},
{hash: "3a81c2f7064370dddaeaf7bc7e4d282702cefb2b6e11c84942c3791c76cdd3e8", want: true},
// Block 100000 should be present (as an orphan).
{hash: "3da8f9ec89820deee1a4d26ff0e69c53686166ea4fbc1895fa1e0b1ccb651374", want: true},
{hash: "746deb238f38dfc82ea2e1dbd85c079ceb581fc2912aae37d6c3675a12545df4", want: true},
// Random hashes should not be available.
{hash: "123", want: false},
@ -554,9 +554,10 @@ func chainedNodes(parents blockSet, numNodes int) []*blockNode {
// This is invalid, but all that is needed is enough to get the
// synthetic tests to work.
header := wire.BlockHeader{
Nonce: testNoncePrng.Uint64(),
IDMerkleRoot: &daghash.ZeroHash,
HashMerkleRoot: &daghash.ZeroHash,
Nonce: testNoncePrng.Uint64(),
IDMerkleRoot: &daghash.ZeroHash,
HashMerkleRoot: &daghash.ZeroHash,
AcceptedIDMerkleRoot: &daghash.ZeroHash,
}
header.ParentHashes = tips.hashes()
nodes[i] = newBlockNode(&header, tips, dagconfig.SimNetParams.K)
@ -902,10 +903,11 @@ func TestValidateFeeTransaction(t *testing.T) {
daghash.Sort(parentHashes)
msgBlock := &wire.MsgBlock{
Header: wire.BlockHeader{
Bits: dag.genesis.Header().Bits,
ParentHashes: parentHashes,
HashMerkleRoot: BuildHashMerkleTreeStore(utilTxs).Root(),
IDMerkleRoot: BuildIDMerkleTreeStore(utilTxs).Root(),
Bits: dag.genesis.Header().Bits,
ParentHashes: parentHashes,
HashMerkleRoot: BuildHashMerkleTreeStore(utilTxs).Root(),
IDMerkleRoot: BuildIDMerkleTreeStore(utilTxs).Root(),
AcceptedIDMerkleRoot: &daghash.ZeroHash,
},
Transactions: transactions,
}

View File

@ -617,13 +617,14 @@ func (dag *BlockDAG) deserializeBlockNode(blockRow []byte) (*blockNode, error) {
}
node := &blockNode{
hash: header.BlockHash(),
version: header.Version,
bits: header.Bits,
nonce: header.Nonce,
timestamp: header.Timestamp.Unix(),
hashMerkleRoot: header.HashMerkleRoot,
idMerkleRoot: header.IDMerkleRoot,
hash: header.BlockHash(),
version: header.Version,
bits: header.Bits,
nonce: header.Nonce,
timestamp: header.Timestamp.Unix(),
hashMerkleRoot: header.HashMerkleRoot,
idMerkleRoot: header.IDMerkleRoot,
acceptedIDMerkleRoot: header.AcceptedIDMerkleRoot,
}
node.children = newSet()

View File

@ -67,5 +67,5 @@ func ExampleBlockDAG_ProcessBlock() {
fmt.Printf("Block accepted. Is it an orphan?: %v", isOrphan)
// Output:
// Failed to process block: already have block 6477863f190fac902e556da4671c7537da4fe367022b1f00fa5270e0d073cc08
// Failed to process block: already have block 4aa46622896ef2f0c59aaff0c05f87984a3e640a8e79f9167f4c1b959fd14706
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -187,7 +187,7 @@ func TestCheckBlockSanity(t *testing.T) {
if !ok {
t.Errorf("CheckBlockSanity: wrong error returned, expect RuleError, got %T", err)
} else if ruleErr.ErrorCode != ErrTransactionsNotSorted {
t.Errorf("CheckBlockSanity: wrong error returned, expect ErrTransactionsNotSorted, got %v", ruleErr.ErrorCode)
t.Errorf("CheckBlockSanity: wrong error returned, expect ErrTransactionsNotSorted, got %v, err %s", ruleErr.ErrorCode, err)
}
// Ensure a block that has a timestamp with a precision higher than one
@ -228,9 +228,15 @@ func TestCheckBlockSanity(t *testing.T) {
0x80, 0xf7, 0x00, 0xe3, 0x16, 0x3d, 0x04, 0x95,
0x5b, 0x7e, 0xaf, 0x84, 0x7e, 0x1b, 0x6b, 0x06,
},
Timestamp: time.Unix(0x5c40613a, 0),
AcceptedIDMerkleRoot: &daghash.Hash{
0x80, 0xf7, 0x00, 0xe3, 0x16, 0x3d, 0x04, 0x95,
0x5b, 0x7e, 0xaf, 0x84, 0x7e, 0x1b, 0x6b, 0x06,
0x4e, 0x06, 0xba, 0x64, 0xd7, 0x61, 0xda, 0x25,
0x1a, 0x0e, 0x21, 0xd4, 0x64, 0x49, 0x02, 0xa2,
},
Timestamp: time.Unix(0x5cd18053, 0),
Bits: 0x207fffff,
Nonce: 0x4000000000000001,
Nonce: 0x0,
},
Transactions: []*wire.MsgTx{
{
@ -514,7 +520,7 @@ func TestCheckSerializedHeight(t *testing.T) {
msgTx := coinbaseTx.Copy()
msgTx.TxIn[0].SignatureScript = test.sigScript
msgBlock := wire.NewMsgBlock(wire.NewBlockHeader(1, []*daghash.Hash{}, &daghash.Hash{}, &daghash.Hash{}, 0, 0))
msgBlock := wire.NewMsgBlock(wire.NewBlockHeader(1, []*daghash.Hash{}, &daghash.Hash{}, &daghash.Hash{}, &daghash.Hash{}, 0, 0))
msgBlock.AddTransaction(msgTx)
block := util.NewBlock(msgBlock)
block.SetHeight(test.wantHeight)
@ -621,7 +627,7 @@ func TestValidateParents(t *testing.T) {
b := generateNode(a)
c := generateNode(genesisNode)
fakeBlockHeader := &wire.BlockHeader{IDMerkleRoot: &daghash.ZeroHash, HashMerkleRoot: &daghash.ZeroHash}
fakeBlockHeader := &wire.BlockHeader{IDMerkleRoot: &daghash.ZeroHash, HashMerkleRoot: &daghash.ZeroHash, AcceptedIDMerkleRoot: &daghash.ZeroHash}
// Check direct parents relation
err := validateParents(fakeBlockHeader, setFromSlice(a, b))
@ -759,6 +765,12 @@ var Block100000 = wire.MsgBlock{
0x8a, 0xb7, 0xd6, 0x73, 0x1b, 0xe6, 0xc5, 0xd3,
0x5d, 0x4e, 0x2c, 0xc9, 0x57, 0x88, 0x30, 0x65,
},
AcceptedIDMerkleRoot: &daghash.Hash{
0x8a, 0xb7, 0xd6, 0x73, 0x1b, 0xe6, 0xc5, 0xd3,
0x5d, 0x4e, 0x2c, 0xc9, 0x57, 0x88, 0x30, 0x65,
0x81, 0xb8, 0xa0, 0x68, 0x77, 0xc4, 0x02, 0x1e,
0x3c, 0xb1, 0x16, 0x8f, 0x5f, 0x6b, 0x45, 0x87,
},
Timestamp: time.Unix(0x5c404bc3, 0),
Bits: 0x207fffff,
Nonce: 0xdffffffffffffff9,
@ -1039,10 +1051,10 @@ var BlockWithWrongTxOrder = wire.MsgBlock{
},
},
HashMerkleRoot: &daghash.Hash{
0x0b, 0x79, 0xf5, 0x29, 0x6d, 0x1c, 0xaa, 0x90,
0x2f, 0x01, 0xd4, 0x83, 0x9b, 0x2a, 0x04, 0x5e,
0xa0, 0x69, 0x2d, 0x16, 0xb5, 0xd7, 0xe4, 0xf3,
0xcd, 0xc7, 0xc9, 0xaf, 0xfb, 0xd2, 0x1b, 0x85,
0xac, 0xa4, 0x21, 0xe1, 0xa6, 0xc3, 0xbe, 0x5d,
0x52, 0x66, 0xf3, 0x0b, 0x21, 0x87, 0xbc, 0xf3,
0xf3, 0x2d, 0xd1, 0x05, 0x64, 0xb5, 0x16, 0x76,
0xe4, 0x66, 0x7d, 0x51, 0x53, 0x18, 0x6d, 0xb1,
},
IDMerkleRoot: &daghash.Hash{
0x0b, 0x79, 0xf5, 0x29, 0x6d, 0x1c, 0xaa, 0x90,
@ -1050,9 +1062,15 @@ var BlockWithWrongTxOrder = wire.MsgBlock{
0xa0, 0x69, 0x2d, 0x16, 0xb5, 0xd7, 0xe4, 0xf3,
0xcd, 0xc7, 0xc9, 0xaf, 0xfb, 0xd2, 0x1b, 0x85,
},
Timestamp: time.Unix(0x5c22330f, 0),
AcceptedIDMerkleRoot: &daghash.Hash{
0xa0, 0x69, 0x2d, 0x16, 0xb5, 0xd7, 0xe4, 0xf3,
0xcd, 0xc7, 0xc9, 0xaf, 0xfb, 0xd2, 0x1b, 0x85,
0x0b, 0x79, 0xf5, 0x29, 0x6d, 0x1c, 0xaa, 0x90,
0x2f, 0x01, 0xd4, 0x83, 0x9b, 0x2a, 0x04, 0x5e,
},
Timestamp: time.Unix(0x5cd16eaa, 0),
Bits: 0x207fffff,
Nonce: 0xdffffffffffffffc,
Nonce: 0x2,
},
Transactions: []*wire.MsgTx{
{
@ -1188,6 +1206,8 @@ var BlockWithWrongTxOrder = wire.MsgBlock{
},
LockTime: 0,
SubnetworkID: subnetworkid.SubnetworkID{11},
Payload: []byte{},
PayloadHash: daghash.DoubleHashP([]byte{}),
},
{
Version: 1,

View File

@ -41,10 +41,10 @@ var genesisCoinbaseTx = wire.NewNativeMsgTx(1, genesisTxIns, genesisTxOuts)
// genesisHash is the hash of the first block in the block chain for the main
// network (genesis block).
var genesisHash = daghash.Hash([daghash.HashSize]byte{
0x08, 0xcc, 0x73, 0xd0, 0xe0, 0x70, 0x52, 0xfa,
0x00, 0x1f, 0x2b, 0x02, 0x67, 0xe3, 0x4f, 0xda,
0x37, 0x75, 0x1c, 0x67, 0xa4, 0x6d, 0x55, 0x2e,
0x90, 0xac, 0x0f, 0x19, 0x3f, 0x86, 0x77, 0x64,
0x06, 0x47, 0xd1, 0x9f, 0x95, 0x1b, 0x4c, 0x7f,
0x16, 0xf9, 0x79, 0x8e, 0x0a, 0x64, 0x3e, 0x4a,
0x98, 0x87, 0x5f, 0xc0, 0xf0, 0xaf, 0x9a, 0xc5,
0xf0, 0xf2, 0x6e, 0x89, 0x22, 0x66, 0xa4, 0x4a,
})
// genesisMerkleRoot is the hash of the first transaction in the genesis block
@ -60,13 +60,14 @@ var genesisMerkleRoot = daghash.Hash([daghash.HashSize]byte{
// public transaction ledger for the main network.
var genesisBlock = wire.MsgBlock{
Header: wire.BlockHeader{
Version: 1,
ParentHashes: []*daghash.Hash{},
HashMerkleRoot: &genesisMerkleRoot,
IDMerkleRoot: &genesisMerkleRoot,
Timestamp: time.Unix(0x5ca09ba1, 0),
Bits: 0x207fffff,
Nonce: 0x6,
Version: 1,
ParentHashes: []*daghash.Hash{},
HashMerkleRoot: &genesisMerkleRoot,
IDMerkleRoot: &genesisMerkleRoot,
AcceptedIDMerkleRoot: &daghash.Hash{},
Timestamp: time.Unix(0x5cd00a98, 0),
Bits: 0x207fffff,
Nonce: 0x0,
},
Transactions: []*wire.MsgTx{genesisCoinbaseTx},
}
@ -117,10 +118,10 @@ var devNetGenesisCoinbaseTx = genesisCoinbaseTx
// devGenesisHash is the hash of the first block in the block chain for the development
// network (genesis block).
var devNetGenesisHash = daghash.Hash([daghash.HashSize]byte{
0xe8, 0xf0, 0x59, 0x4b, 0x54, 0xe7, 0xa1, 0xba,
0x1b, 0xe0, 0x6c, 0x72, 0xf8, 0x3d, 0x75, 0x5d,
0xa3, 0x3c, 0xc5, 0x71, 0x43, 0x94, 0x81, 0xbf,
0x32, 0x82, 0x5e, 0xfa, 0x6a, 0x0d, 0x00, 0x00,
0x90, 0x9c, 0x51, 0x90, 0x39, 0x02, 0x5e, 0x11,
0x52, 0xa6, 0x54, 0xff, 0xc8, 0x40, 0xdf, 0x67,
0x2a, 0xe8, 0x20, 0x72, 0xed, 0x6a, 0x5e, 0x3f,
0xf4, 0x8e, 0xf8, 0xdb, 0x02, 0x02, 0x00, 0x00,
})
// devNetGenesisMerkleRoot is the hash of the first transaction in the genesis block
@ -131,13 +132,14 @@ var devNetGenesisMerkleRoot = genesisMerkleRoot
// public transaction ledger for the development network.
var devNetGenesisBlock = wire.MsgBlock{
Header: wire.BlockHeader{
Version: 1,
ParentHashes: []*daghash.Hash{},
HashMerkleRoot: &devNetGenesisMerkleRoot,
IDMerkleRoot: &devNetGenesisMerkleRoot,
Timestamp: time.Unix(0x5ca09ba1, 0),
Bits: 0x1e7fffff,
Nonce: 0x155d9,
Version: 1,
ParentHashes: []*daghash.Hash{},
HashMerkleRoot: &devNetGenesisMerkleRoot,
IDMerkleRoot: &devNetGenesisMerkleRoot,
AcceptedIDMerkleRoot: &daghash.Hash{},
Timestamp: time.Unix(0x5cd00a98, 0),
Bits: 0x1e7fffff,
Nonce: 0x2f0e8,
},
Transactions: []*wire.MsgTx{devNetGenesisCoinbaseTx},
}

View File

@ -129,9 +129,13 @@ var genesisBlockBytes = []byte{
0xb8, 0x76, 0x57, 0x9d, 0x7d, 0xe9, 0x9d, 0xae,
0xdb, 0xf8, 0x22, 0xd2, 0x0d, 0xa2, 0xe0, 0xbb,
0xbe, 0xed, 0xb0, 0xdb, 0xba, 0xeb, 0x18, 0x4d,
0x42, 0x01, 0xff, 0xed, 0x9d, 0xa1, 0x9b, 0xa0,
0x42, 0x01, 0xff, 0xed, 0x9d, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x0a, 0xd0,
0x5c, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7f,
0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

View File

@ -175,5 +175,5 @@ func Example_blockStorageAndRetrieval() {
fmt.Printf("Serialized block size: %d bytes\n", len(loadedBlockBytes))
// Output:
// Serialized block size: 193 bytes
// Serialized block size: 225 bytes
}

View File

@ -16,7 +16,7 @@ import (
func TestDeleteFile(t *testing.T) {
testBlock := util.NewBlock(wire.NewMsgBlock(
wire.NewBlockHeader(1, []*daghash.Hash{}, &daghash.Hash{}, &daghash.Hash{}, 0, 0)))
wire.NewBlockHeader(1, []*daghash.Hash{}, &daghash.Hash{}, &daghash.Hash{}, &daghash.Hash{}, 0, 0)))
tests := []struct {
fileNum uint32
@ -69,7 +69,7 @@ func TestDeleteFile(t *testing.T) {
// and makes sure no panic occurs, as well as ensures the writeCursor was updated correctly.
func TestHandleRollbackErrors(t *testing.T) {
testBlock := util.NewBlock(wire.NewMsgBlock(
wire.NewBlockHeader(1, []*daghash.Hash{}, &daghash.Hash{}, &daghash.Hash{}, 0, 0)))
wire.NewBlockHeader(1, []*daghash.Hash{}, &daghash.Hash{}, &daghash.Hash{}, &daghash.Hash{}, 0, 0)))
testBlockSize := uint32(testBlock.MsgBlock().SerializeSize())
tests := []struct {

View File

@ -553,7 +553,7 @@ func TestForEachBucket(t *testing.T) {
// TestStoreBlockErrors tests all error-cases in *tx.StoreBlock().
// The non-error-cases are tested in the more general tests.
func TestStoreBlockErrors(t *testing.T) {
testBlock := util.NewBlock(wire.NewMsgBlock(wire.NewBlockHeader(1, []*daghash.Hash{}, &daghash.Hash{}, &daghash.Hash{}, 0, 0)))
testBlock := util.NewBlock(wire.NewMsgBlock(wire.NewBlockHeader(1, []*daghash.Hash{}, &daghash.Hash{}, &daghash.Hash{}, &daghash.Hash{}, 0, 0)))
tests := []struct {
name string
@ -716,7 +716,7 @@ func TestWritePendingAndCommitErrors(t *testing.T) {
rollbackCalled = false
err = pdb.Update(func(dbTx database.Tx) error {
return dbTx.StoreBlock(util.NewBlock(wire.NewMsgBlock(
wire.NewBlockHeader(1, []*daghash.Hash{}, &daghash.Hash{}, &daghash.Hash{}, 0, 0))))
wire.NewBlockHeader(1, []*daghash.Hash{}, &daghash.Hash{}, &daghash.Hash{}, &daghash.Hash{}, 0, 0))))
})
if err == nil {
t.Errorf("No error returned when blockIdx.Put() should have returned an error")

Binary file not shown.

View File

@ -44,12 +44,14 @@ func generateBlocks(out *os.File, numBlocks int) {
func generateBlock(parent *wire.MsgBlock) *wire.MsgBlock {
return &wire.MsgBlock{
Header: wire.BlockHeader{
Version: 1,
ParentHashes: []*daghash.Hash{parent.BlockHash()},
HashMerkleRoot: genesisMerkleRoot,
Timestamp: time.Unix(0x5b28c4c8, 0), // 2018-06-19 08:54:32 +0000 UTC
Bits: 0x2e00ffff, // 503382015 [000000ffff000000000000000000000000000000000000000000000000000000]
Nonce: 0xc0192550, // 2148484547
Version: 1,
ParentHashes: []*daghash.Hash{parent.BlockHash()},
HashMerkleRoot: &genesisMerkleRoot,
IDMerkleRoot: &daghash.ZeroHash,
AcceptedIDMerkleRoot: &daghash.ZeroHash,
Timestamp: time.Unix(0x5b28c4c8, 0), // 2018-06-19 08:54:32 +0000 UTC
Bits: 0x2e00ffff, // 503382015 [000000ffff000000000000000000000000000000000000000000000000000000]
Nonce: 0xc0192550, // 2148484547
},
Transactions: []*wire.MsgTx{genesisCoinbaseTx},
}

View File

@ -186,12 +186,13 @@ func CreateBlock(parentBlock *util.Block, inclusionTxs []*util.Tx,
idMerkleTree := blockdag.BuildIDMerkleTreeStore(blockTxns)
var block wire.MsgBlock
block.Header = wire.BlockHeader{
Version: blockVersion,
ParentHashes: []*daghash.Hash{parentHash},
HashMerkleRoot: hashMerkleTree.Root(),
IDMerkleRoot: idMerkleTree.Root(),
Timestamp: ts,
Bits: net.PowLimitBits,
Version: blockVersion,
ParentHashes: []*daghash.Hash{parentHash},
HashMerkleRoot: hashMerkleTree.Root(),
IDMerkleRoot: idMerkleTree.Root(),
AcceptedIDMerkleRoot: &daghash.ZeroHash,
Timestamp: ts,
Bits: net.PowLimitBits,
}
for _, tx := range blockTxns {
block.AddTransaction(tx.MsgTx())

View File

@ -70,7 +70,7 @@ func (eft *estimateFeeTester) newBlock(txs []*wire.MsgTx) {
eft.height++
block := util.NewBlock(&wire.MsgBlock{
Header: wire.BlockHeader{IDMerkleRoot: &daghash.ZeroHash, HashMerkleRoot: &daghash.ZeroHash},
Header: wire.BlockHeader{IDMerkleRoot: &daghash.ZeroHash, HashMerkleRoot: &daghash.ZeroHash, AcceptedIDMerkleRoot: &daghash.ZeroHash},
Transactions: txs,
})
block.SetHeight(eft.height)

View File

@ -655,12 +655,13 @@ func (g *BlkTmplGenerator) NewBlockTemplate(payToAddress util.Address) (*BlockTe
idMerkleTree := blockdag.BuildIDMerkleTreeStore(blockTxns)
var msgBlock wire.MsgBlock
msgBlock.Header = wire.BlockHeader{
Version: nextBlockVersion,
ParentHashes: g.dag.TipHashes(),
HashMerkleRoot: hashMerkleTree.Root(),
IDMerkleRoot: idMerkleTree.Root(),
Timestamp: ts,
Bits: reqDifficulty,
Version: nextBlockVersion,
ParentHashes: g.dag.TipHashes(),
HashMerkleRoot: hashMerkleTree.Root(),
IDMerkleRoot: idMerkleTree.Root(),
AcceptedIDMerkleRoot: &daghash.ZeroHash,
Timestamp: ts,
Bits: reqDifficulty,
}
for _, tx := range blockTxns {
msgBlock.AddTransaction(tx.MsgTx())

View File

@ -37,7 +37,7 @@ func parseBlock(template *btcjson.GetBlockTemplateResult) (*util.Block, error) {
bits := uint32(bitsInt64)
// parse rest of block
msgBlock := wire.NewMsgBlock(wire.NewBlockHeader(template.Version, parentHashes, &daghash.Hash{}, &daghash.Hash{}, uint32(bits), 0))
msgBlock := wire.NewMsgBlock(wire.NewBlockHeader(template.Version, parentHashes, &daghash.Hash{}, &daghash.Hash{}, &daghash.Hash{}, uint32(bits), 0))
for i, txResult := range append([]btcjson.GetBlockTemplateResultTx{*template.CoinbaseTxn}, template.Transactions...) {
reader := hex.NewDecoder(strings.NewReader(txResult.Data))

View File

@ -494,7 +494,7 @@ func TestPeerListeners(t *testing.T) {
{
"OnBlock",
wire.NewMsgBlock(wire.NewBlockHeader(1,
[]*daghash.Hash{}, &daghash.Hash{}, &daghash.Hash{}, 1, 1)),
[]*daghash.Hash{}, &daghash.Hash{}, &daghash.Hash{}, &daghash.Hash{}, 1, 1)),
},
{
"OnInv",
@ -560,7 +560,7 @@ func TestPeerListeners(t *testing.T) {
{
"OnMerkleBlock",
wire.NewMsgMerkleBlock(wire.NewBlockHeader(1,
[]*daghash.Hash{}, &daghash.Hash{}, &daghash.Hash{}, 1, 1)),
[]*daghash.Hash{}, &daghash.Hash{}, &daghash.Hash{}, &daghash.Hash{}, 1, 1)),
},
// only one version message is allowed
// only one verack message is allowed

View File

@ -38,7 +38,7 @@ func TestBlock(t *testing.T) {
}
// Hash for block 100,000.
wantHashStr := "5b5168d93a5178acdf82da367f8fb85b0432874e99d5c6518adccc727fd3a012"
wantHashStr := "c4bb55d2eaae7c7505b199097ef163ab940aa41228bbdb6f8b6d8a5b71bc432c"
wantHash, err := daghash.NewHashFromStr(wantHashStr)
if err != nil {
t.Errorf("NewHashFromStr: %v", err)
@ -147,10 +147,10 @@ func TestBlock(t *testing.T) {
// Transaction offsets and length for the transaction in Block100000.
wantTxLocs := []wire.TxLoc{
{TxStart: 154, TxLen: 163},
{TxStart: 317, TxLen: 287},
{TxStart: 604, TxLen: 285},
{TxStart: 889, TxLen: 253},
{TxStart: 186, TxLen: 163},
{TxStart: 349, TxLen: 287},
{TxStart: 636, TxLen: 285},
{TxStart: 921, TxLen: 253},
}
// Ensure the transaction location information is accurate.
@ -259,7 +259,7 @@ func TestBlockErrors(t *testing.T) {
}
// Truncate the block byte buffer to force errors.
shortBytes := block100000Bytes[:154]
shortBytes := block100000Bytes[:186]
_, err = util.NewBlockFromBytes(shortBytes)
if err != io.EOF {
t.Errorf("NewBlockFromBytes: did not get expected error - "+
@ -331,6 +331,12 @@ var Block100000 = wire.MsgBlock{
0x28, 0xc3, 0x06, 0x7c, 0xc3, 0x8d, 0x48, 0x85,
0xef, 0xb5, 0xa4, 0xac, 0x42, 0x47, 0xe9, 0xf3,
}, // f3e94742aca4b5ef85488dc37c06c3282295ffec960994b2c0d5ac2a25a95766
AcceptedIDMerkleRoot: &daghash.Hash{
0x28, 0xc3, 0x06, 0x7c, 0xc3, 0x8d, 0x48, 0x85,
0xef, 0xb5, 0xa4, 0xac, 0x42, 0x47, 0xe9, 0xf3,
0x66, 0x57, 0xa9, 0x25, 0x2a, 0xac, 0xd5, 0xc0,
0xb2, 0x94, 0x09, 0x96, 0xec, 0xff, 0x95, 0x22,
},
Timestamp: time.Unix(1529483563, 0), // 2018-06-20 08:32:43 +0000 UTC
Bits: 0x1e00ffff, // 503382015
Nonce: 0x000ae53f, // 714047

View File

@ -540,6 +540,9 @@ func TestFilterInsertP2PubKeyOnly(t *testing.T) {
0x7F, 0x16, 0xC5, 0x96, 0x2E, 0x8B, 0xD9, 0x63, 0x65, 0x9C, 0x79, // Fake IDMerkleRoot. TODO: (Ori) Replace to a real IDMerkleRoot
0x3C, 0xE3, 0x70, 0xD9, 0x5F, 0x09, 0x3B, 0xC7, 0xE3, 0x67, 0x11,
0x7B, 0x3C, 0x30, 0xC1, 0xF8, 0xFD, 0xD0, 0xD9, 0x72, 0x87,
0x3C, 0xE3, 0x70, 0xD9, 0x5F, 0x09, 0x3B, 0xC7, 0xE3, 0x67, 0x11, // AcceptedIDMerkleRoot
0x7F, 0x16, 0xC5, 0x96, 0x2E, 0x8B, 0xD9, 0x63, 0x65, 0x9C, 0x79,
0x7B, 0x3C, 0x30, 0xC1, 0xF8, 0xFD, 0xD0, 0xD9, 0x72, 0x87,
0x76, 0x38, 0x1B, 0x4D, 0x00, 0x00, 0x00, 0x00, // Time
0x4C, 0x86, 0x04, 0x1B, // Bits
0x55, 0x4B, 0x85, 0x29, 0x00, 0x00, 0x00, 0x00, // Fake Nonce. TODO: (Ori) Replace to a real nonce

View File

@ -28,6 +28,9 @@ func TestMerkleBlock3(t *testing.T) {
0x7F, 0x16, 0xC5, 0x96, 0x2E, 0x8B, 0xD9, 0x63, 0x65, 0x9C, 0x79, // Fake IDMerkleRoot. TODO: (Ori) Replace to a real IDMerkleRoot
0x3C, 0xE3, 0x70, 0xD9, 0x5F, 0x09, 0x3B, 0xC7, 0xE3, 0x67, 0x11,
0x7B, 0x3C, 0x30, 0xC1, 0xF8, 0xFD, 0xD0, 0xD9, 0x72, 0x87,
0x3C, 0xE3, 0x70, 0xD9, 0x5F, 0x09, 0x3B, 0xC7, 0xE3, 0x67, 0x11, // AcceptedIDMerkleRoot
0x7F, 0x16, 0xC5, 0x96, 0x2E, 0x8B, 0xD9, 0x63, 0x65, 0x9C, 0x79,
0x7B, 0x3C, 0x30, 0xC1, 0xF8, 0xFD, 0xD0, 0xD9, 0x72, 0x87,
0x67, 0x29, 0x1B, 0x4D, 0x00, 0x00, 0x00, 0x00, //Time
0x4C, 0x86, 0x04, 0x1B, // Bits
0x8F, 0xA4, 0x5D, 0x63, 0x00, 0x00, 0x00, 0x00, // Fake Nonce. TODO: (Ori) Replace to a real nonce
@ -81,6 +84,10 @@ func TestMerkleBlock3(t *testing.T) {
0x96, 0x2e, 0x8b, 0xd9, 0x63, 0x65, 0x9c, 0x79,
0x3c, 0xe3, 0x70, 0xd9, 0x5f, 0x09, 0x3b, 0xc7,
0xe3, 0x67, 0x11, 0x7b, 0x3c, 0x30, 0xc1, 0xf8,
0xfd, 0xd0, 0xd9, 0x72, 0x87, 0x3c, 0xe3, 0x70,
0xd9, 0x5f, 0x09, 0x3b, 0xc7, 0xe3, 0x67, 0x11,
0x7f, 0x16, 0xc5, 0x96, 0x2e, 0x8b, 0xd9, 0x63,
0x65, 0x9c, 0x79, 0x7b, 0x3c, 0x30, 0xc1, 0xf8,
0xfd, 0xd0, 0xd9, 0x72, 0x87, 0x67, 0x29, 0x1b,
0x4d, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x86, 0x04,
0x1b, 0x8f, 0xa4, 0x5d, 0x63, 0x00, 0x00, 0x00,

View File

@ -426,7 +426,7 @@ func BenchmarkDecodeHeaders(b *testing.B) {
}
parentHashes[i] = hash
}
m.AddBlockHeader(NewBlockHeader(1, parentHashes, hash, hash, 0, uint64(i)))
m.AddBlockHeader(NewBlockHeader(1, parentHashes, hash, hash, hash, 0, uint64(i)))
}
// Serialize it so the bytes are available to test the decode below.
@ -572,7 +572,7 @@ func BenchmarkDecodeMerkleBlock(b *testing.B) {
if err != nil {
b.Fatalf("NewHashFromStr: unexpected error: %v", err)
}
m.Header = *NewBlockHeader(1, []*daghash.Hash{hash}, hash, hash, 0, uint64(10000))
m.Header = *NewBlockHeader(1, []*daghash.Hash{hash}, hash, hash, hash, 0, uint64(10000))
for i := 0; i < 105; i++ {
hash, err := daghash.NewHashFromStr(fmt.Sprintf("%x", i))
if err != nil {

View File

@ -15,10 +15,11 @@ import (
// BaseBlockHeaderPayload is the base number of bytes a block header can be,
// not including the list of parent block headers.
// Version 4 bytes + Timestamp 8 bytes + Bits 4 bytes + Nonce 8 bytes +
// + NumParentBlocks 1 byte + HashMerkleRoot hash + IDMerkleRoot hash.
// + NumParentBlocks 1 byte + HashMerkleRoot hash + IDMerkleRoot hash +
// + AcceptedIDMerkleRoot hash.
// To get total size of block header len(ParentHashes) * daghash.HashSize should be
// added to this value
const BaseBlockHeaderPayload = 25 + 2*(daghash.HashSize)
const BaseBlockHeaderPayload = 25 + 3*(daghash.HashSize)
// MaxNumParentBlocks is the maximum number of parent blocks a block can reference.
// Currently set to 255 as the maximum number NumParentBlocks can be due to it being a byte
@ -43,6 +44,10 @@ type BlockHeader struct {
// IDMerkleRoot is the merkle tree reference to hash of all transactions' IDs for the block.
IDMerkleRoot *daghash.Hash
// AcceptedIDMerkleRoot is merkle tree reference to hash all transactions
// accepted form the block.Blues
AcceptedIDMerkleRoot *daghash.Hash
// Time the block was created.
Timestamp time.Time
@ -121,18 +126,20 @@ func (h *BlockHeader) SerializeSize() int {
// block hash, hash merkle root, ID merkle root difficulty bits, and nonce used to generate the
// block with defaults or calclulated values for the remaining fields.
func NewBlockHeader(version int32, parentHashes []*daghash.Hash, hashMerkleRoot *daghash.Hash,
idMerkleRoot *daghash.Hash, bits uint32, nonce uint64) *BlockHeader {
idMerkleRoot *daghash.Hash, acceptedIDMerkleRoot *daghash.Hash,
bits uint32, nonce uint64) *BlockHeader {
// Limit the timestamp to one second precision since the protocol
// doesn't support better.
return &BlockHeader{
Version: version,
ParentHashes: parentHashes,
HashMerkleRoot: hashMerkleRoot,
IDMerkleRoot: idMerkleRoot,
Timestamp: time.Unix(time.Now().Unix(), 0),
Bits: bits,
Nonce: nonce,
Version: version,
ParentHashes: parentHashes,
HashMerkleRoot: hashMerkleRoot,
IDMerkleRoot: idMerkleRoot,
AcceptedIDMerkleRoot: acceptedIDMerkleRoot,
Timestamp: time.Unix(time.Now().Unix(), 0),
Bits: bits,
Nonce: nonce,
}
}
@ -157,7 +164,10 @@ func readBlockHeader(r io.Reader, pver uint32, bh *BlockHeader) error {
}
bh.HashMerkleRoot = &daghash.Hash{}
bh.IDMerkleRoot = &daghash.Hash{}
return readElements(r, bh.HashMerkleRoot, bh.IDMerkleRoot, (*int64Time)(&bh.Timestamp), &bh.Bits, &bh.Nonce)
bh.AcceptedIDMerkleRoot = &daghash.Hash{}
return readElements(r, bh.HashMerkleRoot, bh.IDMerkleRoot,
bh.AcceptedIDMerkleRoot, (*int64Time)(&bh.Timestamp),
&bh.Bits, &bh.Nonce)
}
// writeBlockHeader writes a bitcoin block header to w. See Serialize for
@ -174,5 +184,5 @@ func writeBlockHeader(w io.Writer, pver uint32, bh *BlockHeader) error {
}
}
return writeElements(w, bh.HashMerkleRoot, bh.IDMerkleRoot,
sec, bh.Bits, bh.Nonce)
bh.AcceptedIDMerkleRoot, sec, bh.Bits, bh.Nonce)
}

View File

@ -26,8 +26,10 @@ func TestBlockHeader(t *testing.T) {
merkleHash := mainNetGenesisMerkleRoot
idMerkleRoot := exampleIDMerkleRoot
acceptedIDMerkleRoot := exampleAcceptedIDMerkleRoot
bits := uint32(0x1d00ffff)
bh := NewBlockHeader(1, hashes, merkleHash, idMerkleRoot, bits, nonce)
bh := NewBlockHeader(1, hashes, merkleHash, idMerkleRoot,
acceptedIDMerkleRoot, bits, nonce)
// Ensure we get the same data back out.
if !reflect.DeepEqual(bh.ParentHashes, hashes) {
@ -57,13 +59,14 @@ func TestBlockHeaderWire(t *testing.T) {
// baseBlockHdr is used in the various tests as a baseline BlockHeader.
bits := uint32(0x1d00ffff)
baseBlockHdr := &BlockHeader{
Version: 1,
ParentHashes: []*daghash.Hash{mainNetGenesisHash, simNetGenesisHash},
HashMerkleRoot: mainNetGenesisMerkleRoot,
IDMerkleRoot: exampleIDMerkleRoot,
Timestamp: time.Unix(0x495fab29, 0), // 2009-01-03 12:15:05 -0600 CST
Bits: bits,
Nonce: nonce,
Version: 1,
ParentHashes: []*daghash.Hash{mainNetGenesisHash, simNetGenesisHash},
HashMerkleRoot: mainNetGenesisMerkleRoot,
IDMerkleRoot: exampleIDMerkleRoot,
AcceptedIDMerkleRoot: exampleAcceptedIDMerkleRoot,
Timestamp: time.Unix(0x495fab29, 0), // 2009-01-03 12:15:05 -0600 CST
Bits: bits,
Nonce: nonce,
}
// baseBlockHdrEncoded is the wire encoded bytes of baseBlockHdr.
@ -86,6 +89,10 @@ func TestBlockHeaderWire(t *testing.T) {
0x65, 0x9C, 0x79, 0x3C, 0xE3, 0x70, 0xD9, 0x5F,
0x09, 0x3B, 0xC7, 0xE3, 0x67, 0x11, 0x7B, 0x3C,
0x30, 0xC1, 0xF8, 0xFD, 0xD0, 0xD9, 0x72, 0x87,
0x09, 0x3B, 0xC7, 0xE3, 0x67, 0x11, 0x7B, 0x3C, // AcceptedIDMerkleRoot
0x30, 0xC1, 0xF8, 0xFD, 0xD0, 0xD9, 0x72, 0x87,
0x7F, 0x16, 0xC5, 0x96, 0x2E, 0x8B, 0xD9, 0x63,
0x65, 0x9C, 0x79, 0x3C, 0xE3, 0x70, 0xD9, 0x5F,
0x29, 0xab, 0x5f, 0x49, 0x00, 0x00, 0x00, 0x00, // Timestamp
0xff, 0xff, 0x00, 0x1d, // Bits
0xf3, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, // Fake Nonce. TODO: (Ori) Replace to a real nonce
@ -168,13 +175,14 @@ func TestBlockHeaderSerialize(t *testing.T) {
// baseBlockHdr is used in the various tests as a baseline BlockHeader.
bits := uint32(0x1d00ffff)
baseBlockHdr := &BlockHeader{
Version: 1,
ParentHashes: []*daghash.Hash{mainNetGenesisHash, simNetGenesisHash},
HashMerkleRoot: mainNetGenesisMerkleRoot,
IDMerkleRoot: exampleIDMerkleRoot,
Timestamp: time.Unix(0x495fab29, 0), // 2009-01-03 12:15:05 -0600 CST
Bits: bits,
Nonce: nonce,
Version: 1,
ParentHashes: []*daghash.Hash{mainNetGenesisHash, simNetGenesisHash},
HashMerkleRoot: mainNetGenesisMerkleRoot,
IDMerkleRoot: exampleIDMerkleRoot,
AcceptedIDMerkleRoot: exampleAcceptedIDMerkleRoot,
Timestamp: time.Unix(0x495fab29, 0), // 2009-01-03 12:15:05 -0600 CST
Bits: bits,
Nonce: nonce,
}
// baseBlockHdrEncoded is the wire encoded bytes of baseBlockHdr.
@ -197,6 +205,10 @@ func TestBlockHeaderSerialize(t *testing.T) {
0x65, 0x9C, 0x79, 0x3C, 0xE3, 0x70, 0xD9, 0x5F,
0x09, 0x3B, 0xC7, 0xE3, 0x67, 0x11, 0x7B, 0x3C,
0x30, 0xC1, 0xF8, 0xFD, 0xD0, 0xD9, 0x72, 0x87,
0x09, 0x3B, 0xC7, 0xE3, 0x67, 0x11, 0x7B, 0x3C, // AcceptedIDMerkleRoot
0x30, 0xC1, 0xF8, 0xFD, 0xD0, 0xD9, 0x72, 0x87,
0x7F, 0x16, 0xC5, 0x96, 0x2E, 0x8B, 0xD9, 0x63,
0x65, 0x9C, 0x79, 0x3C, 0xE3, 0x70, 0xD9, 0x5F,
0x29, 0xab, 0x5f, 0x49, 0x00, 0x00, 0x00, 0x00, // Timestamp
0xff, 0xff, 0x00, 0x1d, // Bits
0xf3, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, // Fake Nonce. TODO: (Ori) Replace to a real nonce
@ -252,33 +264,35 @@ func TestBlockHeaderSerializeSize(t *testing.T) {
bits := uint32(0x1d00ffff)
timestamp := time.Unix(0x495fab29, 0) // 2009-01-03 12:15:05 -0600 CST
baseBlockHdr := &BlockHeader{
Version: 1,
ParentHashes: []*daghash.Hash{mainNetGenesisHash, simNetGenesisHash},
HashMerkleRoot: mainNetGenesisMerkleRoot,
IDMerkleRoot: mainNetGenesisMerkleRoot,
Timestamp: timestamp,
Bits: bits,
Nonce: nonce,
Version: 1,
ParentHashes: []*daghash.Hash{mainNetGenesisHash, simNetGenesisHash},
HashMerkleRoot: mainNetGenesisMerkleRoot,
IDMerkleRoot: mainNetGenesisMerkleRoot,
AcceptedIDMerkleRoot: &daghash.ZeroHash,
Timestamp: timestamp,
Bits: bits,
Nonce: nonce,
}
genesisBlockHdr := &BlockHeader{
Version: 1,
ParentHashes: []*daghash.Hash{},
HashMerkleRoot: mainNetGenesisMerkleRoot,
IDMerkleRoot: mainNetGenesisMerkleRoot,
Timestamp: timestamp,
Bits: bits,
Nonce: nonce,
Version: 1,
ParentHashes: []*daghash.Hash{},
HashMerkleRoot: mainNetGenesisMerkleRoot,
IDMerkleRoot: mainNetGenesisMerkleRoot,
AcceptedIDMerkleRoot: &daghash.ZeroHash,
Timestamp: timestamp,
Bits: bits,
Nonce: nonce,
}
tests := []struct {
in *BlockHeader // Block header to encode
size int // Expected serialized size
}{
// Block with no transactions.
{genesisBlockHdr, 89},
{genesisBlockHdr, 121},
// First block in the mainnet block DAG.
{baseBlockHdr, 153},
{baseBlockHdr, 185},
}
t.Logf("Running %d tests", len(tests))

View File

@ -49,6 +49,13 @@ var exampleIDMerkleRoot = &daghash.Hash{
0x30, 0xC1, 0xF8, 0xFD, 0xD0, 0xD9, 0x72, 0x87,
}
var exampleAcceptedIDMerkleRoot = &daghash.Hash{
0x09, 0x3B, 0xC7, 0xE3, 0x67, 0x11, 0x7B, 0x3C,
0x30, 0xC1, 0xF8, 0xFD, 0xD0, 0xD9, 0x72, 0x87,
0x7F, 0x16, 0xC5, 0x96, 0x2E, 0x8B, 0xD9, 0x63,
0x65, 0x9C, 0x79, 0x3C, 0xE3, 0x70, 0xD9, 0x5F,
}
// TestElementWire tests wire encode and decode for various element types. This
// is mainly to test the "fast" paths in readElement and writeElement which use
// type assertions to avoid reflection when possible.

View File

@ -68,7 +68,7 @@ func TestMessage(t *testing.T) {
msgFilterAdd := NewMsgFilterAdd([]byte{0x01})
msgFilterClear := NewMsgFilterClear()
msgFilterLoad := NewMsgFilterLoad([]byte{0x01}, 10, 0, BloomUpdateNone)
bh := NewBlockHeader(1, []*daghash.Hash{mainNetGenesisHash, simNetGenesisHash}, &daghash.Hash{}, &daghash.Hash{}, 0, 0)
bh := NewBlockHeader(1, []*daghash.Hash{mainNetGenesisHash, simNetGenesisHash}, &daghash.Hash{}, &daghash.Hash{}, &daghash.Hash{}, 0, 0)
msgMerkleBlock := NewMsgMerkleBlock(bh)
msgReject := NewMsgReject("block", RejectDuplicate, "duplicate block")
msgGetCFilters := NewMsgGetCFilters(GCSFilterExtended, 0, &daghash.Hash{})
@ -91,7 +91,7 @@ func TestMessage(t *testing.T) {
{msgGetAddr, msgGetAddr, pver, MainNet, 26},
{msgAddr, msgAddr, pver, MainNet, 27},
{msgGetBlocks, msgGetBlocks, pver, MainNet, 61},
{msgBlock, msgBlock, pver, MainNet, 340},
{msgBlock, msgBlock, pver, MainNet, 372},
{msgInv, msgInv, pver, MainNet, 25},
{msgGetData, msgGetData, pver, MainNet, 25},
{msgNotFound, msgNotFound, pver, MainNet, 25},
@ -107,7 +107,7 @@ func TestMessage(t *testing.T) {
{msgFilterAdd, msgFilterAdd, pver, MainNet, 26},
{msgFilterClear, msgFilterClear, pver, MainNet, 24},
{msgFilterLoad, msgFilterLoad, pver, MainNet, 35},
{msgMerkleBlock, msgMerkleBlock, pver, MainNet, 183},
{msgMerkleBlock, msgMerkleBlock, pver, MainNet, 215},
{msgReject, msgReject, pver, MainNet, 79},
{msgGetCFilters, msgGetCFilters, pver, MainNet, 65},
{msgGetCFHeaders, msgGetCFHeaders, pver, MainNet, 65},

View File

@ -26,9 +26,11 @@ func TestBlock(t *testing.T) {
parentHashes := blockOne.Header.ParentHashes
hashMerkleRoot := blockOne.Header.HashMerkleRoot
idMerkleRoot := blockOne.Header.IDMerkleRoot
acceptedIDMerkleRoot := blockOne.Header.AcceptedIDMerkleRoot
bits := blockOne.Header.Bits
nonce := blockOne.Header.Nonce
bh := NewBlockHeader(1, parentHashes, hashMerkleRoot, idMerkleRoot, bits, nonce)
bh := NewBlockHeader(1, parentHashes, hashMerkleRoot, idMerkleRoot,
acceptedIDMerkleRoot, bits, nonce)
// Ensure the command is expected value.
wantCmd := "block"
@ -74,7 +76,7 @@ func TestBlock(t *testing.T) {
// TestBlockHash tests the ability to generate the hash of a block accurately.
func TestBlockHash(t *testing.T) {
// Block 1 hash.
hashStr := "67ec32b619b4cda3255de5318c730e2e9f696d335427adfecae884aa41156b0f"
hashStr := "d632f80af4f507bed094a424902e37cc4b1e447e4ede731f0f4b446edebaf381"
wantHash, err := daghash.NewHashFromStr(hashStr)
if err != nil {
t.Errorf("NewHashFromStr: %v", err)
@ -220,16 +222,18 @@ func TestBlockWireErrors(t *testing.T) {
{&blockOne, blockOneBytes, pver, 69, io.ErrShortWrite, io.EOF},
// Force error in ID merkle root.
{&blockOne, blockOneBytes, pver, 101, io.ErrShortWrite, io.EOF},
// Force error in timestamp.
// Force error in accepted ID merkle root.
{&blockOne, blockOneBytes, pver, 133, io.ErrShortWrite, io.EOF},
// Force error in timestamp.
{&blockOne, blockOneBytes, pver, 165, io.ErrShortWrite, io.EOF},
// Force error in difficulty bits.
{&blockOne, blockOneBytes, pver, 141, io.ErrShortWrite, io.EOF},
{&blockOne, blockOneBytes, pver, 173, io.ErrShortWrite, io.EOF},
// Force error in header nonce.
{&blockOne, blockOneBytes, pver, 145, io.ErrShortWrite, io.EOF},
{&blockOne, blockOneBytes, pver, 177, io.ErrShortWrite, io.EOF},
// Force error in transaction count.
{&blockOne, blockOneBytes, pver, 153, io.ErrShortWrite, io.EOF},
{&blockOne, blockOneBytes, pver, 185, io.ErrShortWrite, io.EOF},
// Force error in transactions.
{&blockOne, blockOneBytes, pver, 154, io.ErrShortWrite, io.EOF},
{&blockOne, blockOneBytes, pver, 186, io.ErrShortWrite, io.EOF},
}
t.Logf("Running %d tests", len(tests))
@ -344,16 +348,18 @@ func TestBlockSerializeErrors(t *testing.T) {
{&blockOne, blockOneBytes, 69, io.ErrShortWrite, io.EOF},
// Force error in ID merkle root.
{&blockOne, blockOneBytes, 101, io.ErrShortWrite, io.EOF},
// Force error in timestamp.
// Force error in accepted ID merkle root.
{&blockOne, blockOneBytes, 133, io.ErrShortWrite, io.EOF},
// Force error in timestamp.
{&blockOne, blockOneBytes, 165, io.ErrShortWrite, io.EOF},
// Force error in difficulty bits.
{&blockOne, blockOneBytes, 141, io.ErrShortWrite, io.EOF},
{&blockOne, blockOneBytes, 173, io.ErrShortWrite, io.EOF},
// Force error in header nonce.
{&blockOne, blockOneBytes, 145, io.ErrShortWrite, io.EOF},
{&blockOne, blockOneBytes, 177, io.ErrShortWrite, io.EOF},
// Force error in transaction count.
{&blockOne, blockOneBytes, 153, io.ErrShortWrite, io.EOF},
{&blockOne, blockOneBytes, 185, io.ErrShortWrite, io.EOF},
// Force error in transactions.
{&blockOne, blockOneBytes, 154, io.ErrShortWrite, io.EOF},
{&blockOne, blockOneBytes, 186, io.ErrShortWrite, io.EOF},
}
t.Logf("Running %d tests", len(tests))
@ -421,6 +427,10 @@ func TestBlockOverflowErrors(t *testing.T) {
0x65, 0x9C, 0x79, 0x3C, 0xE3, 0x70, 0xD9, 0x5F,
0x09, 0x3B, 0xC7, 0xE3, 0x67, 0x11, 0x7B, 0x3C,
0x30, 0xC1, 0xF8, 0xFD, 0xD0, 0xD9, 0x72, 0x87,
0x09, 0x3B, 0xC7, 0xE3, 0x67, 0x11, 0x7B, 0x3C, // AcceptedIDMerkleRoot
0x30, 0xC1, 0xF8, 0xFD, 0xD0, 0xD9, 0x72, 0x87,
0x7F, 0x16, 0xC5, 0x96, 0x2E, 0x8B, 0xD9, 0x63,
0x65, 0x9C, 0x79, 0x3C, 0xE3, 0x70, 0xD9, 0x5F,
0x61, 0xbc, 0x66, 0x49, 0x00, 0x00, 0x00, 0x00, // Timestamp
0xff, 0xff, 0x00, 0x1d, // Bits
0x01, 0xe3, 0x62, 0x99, 0x00, 0x00, 0x00, 0x00, // Fake Nonce. TODO: (Ori) Replace to a real nonce
@ -473,7 +483,7 @@ func TestBlockSerializeSize(t *testing.T) {
size int // Expected serialized size
}{
// Block with no transactions.
{noTxBlock, 154},
{noTxBlock, 186},
// First block in the mainnet block chain.
{&blockOne, len(blockOneBytes)},
@ -494,13 +504,14 @@ func TestBlockSerializeSize(t *testing.T) {
// blockOne is the first block in the mainnet block chain.
var blockOne = MsgBlock{
Header: BlockHeader{
Version: 1,
ParentHashes: []*daghash.Hash{mainNetGenesisHash, simNetGenesisHash},
HashMerkleRoot: mainNetGenesisMerkleRoot,
IDMerkleRoot: exampleIDMerkleRoot,
Timestamp: time.Unix(0x4966bc61, 0), // 2009-01-08 20:54:25 -0600 CST
Bits: 0x1d00ffff, // 486604799
Nonce: 0x9962e301, // 2573394689
Version: 1,
ParentHashes: []*daghash.Hash{mainNetGenesisHash, simNetGenesisHash},
HashMerkleRoot: mainNetGenesisMerkleRoot,
IDMerkleRoot: exampleIDMerkleRoot,
AcceptedIDMerkleRoot: exampleAcceptedIDMerkleRoot,
Timestamp: time.Unix(0x4966bc61, 0), // 2009-01-08 20:54:25 -0600 CST
Bits: 0x1d00ffff, // 486604799
Nonce: 0x9962e301, // 2573394689
},
Transactions: []*MsgTx{
NewNativeMsgTx(1,
@ -557,6 +568,10 @@ var blockOneBytes = []byte{
0x65, 0x9C, 0x79, 0x3C, 0xE3, 0x70, 0xD9, 0x5F,
0x09, 0x3B, 0xC7, 0xE3, 0x67, 0x11, 0x7B, 0x3C,
0x30, 0xC1, 0xF8, 0xFD, 0xD0, 0xD9, 0x72, 0x87,
0x09, 0x3B, 0xC7, 0xE3, 0x67, 0x11, 0x7B, 0x3C, // AcceptedIDMerkleRoot
0x30, 0xC1, 0xF8, 0xFD, 0xD0, 0xD9, 0x72, 0x87,
0x7F, 0x16, 0xC5, 0x96, 0x2E, 0x8B, 0xD9, 0x63,
0x65, 0x9C, 0x79, 0x3C, 0xE3, 0x70, 0xD9, 0x5F,
0x61, 0xbc, 0x66, 0x49, 0x00, 0x00, 0x00, 0x00, // Timestamp
0xff, 0xff, 0x00, 0x1d, // Bits
0x01, 0xe3, 0x62, 0x99, 0x00, 0x00, 0x00, 0x00, // Fake Nonce. TODO: (Ori) Replace to a real nonce
@ -593,5 +608,5 @@ var blockOneBytes = []byte{
// Transaction location information for block one transactions.
var blockOneTxLocs = []TxLoc{
{TxStart: 154, TxLen: 162},
{TxStart: 186, TxLen: 162},
}

View File

@ -29,7 +29,7 @@ func TestHeaders(t *testing.T) {
// Ensure max payload is expected value for latest protocol version.
// Num headers (varInt) + max allowed headers (header length + 1 byte
// for the number of transactions which is always 0).
wantPayload := uint32(16500009)
wantPayload := uint32(16564009)
maxPayload := msg.MaxPayloadLength(pver)
if maxPayload != wantPayload {
t.Errorf("MaxPayloadLength: wrong max payload length for "+
@ -64,9 +64,11 @@ func TestHeadersWire(t *testing.T) {
hashes := []*daghash.Hash{mainNetGenesisHash, simNetGenesisHash}
hashMerkleRoot := blockOne.Header.HashMerkleRoot
idMerkleRoot := blockOne.Header.IDMerkleRoot
acceptedIDMerkleRoot := blockOne.Header.AcceptedIDMerkleRoot
bits := uint32(0x1d00ffff)
nonce := uint64(0x9962e301)
bh := NewBlockHeader(1, hashes, hashMerkleRoot, idMerkleRoot, bits, nonce)
bh := NewBlockHeader(1, hashes, hashMerkleRoot, idMerkleRoot,
acceptedIDMerkleRoot, bits, nonce)
bh.Version = blockOne.Header.Version
bh.Timestamp = blockOne.Header.Timestamp
@ -99,6 +101,10 @@ func TestHeadersWire(t *testing.T) {
0x65, 0x9C, 0x79, 0x3C, 0xE3, 0x70, 0xD9, 0x5F,
0x09, 0x3B, 0xC7, 0xE3, 0x67, 0x11, 0x7B, 0x3C,
0x30, 0xC1, 0xF8, 0xFD, 0xD0, 0xD9, 0x72, 0x87,
0x09, 0x3B, 0xC7, 0xE3, 0x67, 0x11, 0x7B, 0x3C, // AcceptedIDMerkleRoot
0x30, 0xC1, 0xF8, 0xFD, 0xD0, 0xD9, 0x72, 0x87,
0x7F, 0x16, 0xC5, 0x96, 0x2E, 0x8B, 0xD9, 0x63,
0x65, 0x9C, 0x79, 0x3C, 0xE3, 0x70, 0xD9, 0x5F,
0x61, 0xbc, 0x66, 0x49, 0x00, 0x00, 0x00, 0x00, // Timestamp
0xff, 0xff, 0x00, 0x1d, // Bits
0x01, 0xe3, 0x62, 0x99, 0x00, 0x00, 0x00, 0x00, // Fake Nonce. TODO: (Ori) Replace to a real nonce
@ -168,9 +174,11 @@ func TestHeadersWireErrors(t *testing.T) {
hashes := []*daghash.Hash{mainNetGenesisHash, simNetGenesisHash}
hashMerkleRoot := blockOne.Header.HashMerkleRoot
idMerkleRoot := blockOne.Header.IDMerkleRoot
acceptedIDMerkleRoot := blockOne.Header.AcceptedIDMerkleRoot
bits := uint32(0x1d00ffff)
nonce := uint64(0x9962e301)
bh := NewBlockHeader(1, hashes, hashMerkleRoot, idMerkleRoot, bits, nonce)
bh := NewBlockHeader(1, hashes, hashMerkleRoot, idMerkleRoot,
acceptedIDMerkleRoot, bits, nonce)
bh.Version = blockOne.Header.Version
bh.Timestamp = blockOne.Header.Timestamp
@ -216,7 +224,8 @@ func TestHeadersWireErrors(t *testing.T) {
// Intentionally invalid block header that has a transaction count used
// to force errors.
bhTrans := NewBlockHeader(1, hashes, hashMerkleRoot, idMerkleRoot, bits, nonce)
bhTrans := NewBlockHeader(1, hashes, hashMerkleRoot, idMerkleRoot,
acceptedIDMerkleRoot, bits, nonce)
bhTrans.Version = blockOne.Header.Version
bhTrans.Timestamp = blockOne.Header.Timestamp
@ -242,6 +251,10 @@ func TestHeadersWireErrors(t *testing.T) {
0x65, 0x9C, 0x79, 0x3C, 0xE3, 0x70, 0xD9, 0x5F,
0x09, 0x3B, 0xC7, 0xE3, 0x67, 0x11, 0x7B, 0x3C,
0x30, 0xC1, 0xF8, 0xFD, 0xD0, 0xD9, 0x72, 0x87,
0x09, 0x3B, 0xC7, 0xE3, 0x67, 0x11, 0x7B, 0x3C, // AcceptedIDMerkleRoot
0x30, 0xC1, 0xF8, 0xFD, 0xD0, 0xD9, 0x72, 0x87,
0x7F, 0x16, 0xC5, 0x96, 0x2E, 0x8B, 0xD9, 0x63,
0x65, 0x9C, 0x79, 0x3C, 0xE3, 0x70, 0xD9, 0x5F,
0x61, 0xbc, 0x66, 0x49, 0x00, 0x00, 0x00, 0x00, // Timestamp
0xff, 0xff, 0x00, 0x1d, // Bits
0x01, 0xe3, 0x62, 0x99, 0x00, 0x00, 0x00, 0x00, // Fake Nonce. TODO: (Ori) Replace to a real nonce
@ -264,7 +277,7 @@ func TestHeadersWireErrors(t *testing.T) {
// Force error with greater than max headers.
{maxHeaders, maxHeadersEncoded, pver, 3, wireErr, wireErr},
// Force error with number of transactions.
{transHeader, transHeaderEncoded, pver, 146, io.ErrShortWrite, io.EOF},
{transHeader, transHeaderEncoded, pver, 178, io.ErrShortWrite, io.EOF},
// Force error with included transactions.
{transHeader, transHeaderEncoded, pver, len(transHeaderEncoded), nil, wireErr},
}

View File

@ -24,9 +24,11 @@ func TestMerkleBlock(t *testing.T) {
parentHashes := blockOne.Header.ParentHashes
hashMerkleRoot := blockOne.Header.HashMerkleRoot
idMerkleRoot := blockOne.Header.IDMerkleRoot
acceptedIDMerkleRoot := blockOne.Header.AcceptedIDMerkleRoot
bits := blockOne.Header.Bits
nonce := blockOne.Header.Nonce
bh := NewBlockHeader(1, parentHashes, hashMerkleRoot, idMerkleRoot, bits, nonce)
bh := NewBlockHeader(1, parentHashes, hashMerkleRoot, idMerkleRoot,
acceptedIDMerkleRoot, bits, nonce)
// Ensure the command is expected value.
wantCmd := "merkleblock"
@ -117,9 +119,11 @@ func TestMerkleBlockCrossProtocol(t *testing.T) {
parentHashes := blockOne.Header.ParentHashes
hashMerkleRoot := blockOne.Header.HashMerkleRoot
idMerkleRoot := blockOne.Header.IDMerkleRoot
acceptedIDMerkleRoot := blockOne.Header.AcceptedIDMerkleRoot
bits := blockOne.Header.Bits
nonce := blockOne.Header.Nonce
bh := NewBlockHeader(1, parentHashes, hashMerkleRoot, idMerkleRoot, bits, nonce)
bh := NewBlockHeader(1, parentHashes, hashMerkleRoot, idMerkleRoot,
acceptedIDMerkleRoot, bits, nonce)
msg := NewMsgMerkleBlock(bh)
@ -203,22 +207,24 @@ func TestMerkleBlockWireErrors(t *testing.T) {
{&merkleBlockOne, merkleBlockOneBytes, pver, 69, io.ErrShortWrite, io.EOF},
// Force error in hash merkle root.
{&merkleBlockOne, merkleBlockOneBytes, pver, 101, io.ErrShortWrite, io.EOF},
// Force error in timestamp.
// Force error in accepted ID merkle root.
{&merkleBlockOne, merkleBlockOneBytes, pver, 133, io.ErrShortWrite, io.EOF},
// Force error in timestamp.
{&merkleBlockOne, merkleBlockOneBytes, pver, 165, io.ErrShortWrite, io.EOF},
// Force error in difficulty bits.
{&merkleBlockOne, merkleBlockOneBytes, pver, 141, io.ErrShortWrite, io.EOF},
{&merkleBlockOne, merkleBlockOneBytes, pver, 173, io.ErrShortWrite, io.EOF},
// Force error in header nonce.
{&merkleBlockOne, merkleBlockOneBytes, pver, 145, io.ErrShortWrite, io.EOF},
{&merkleBlockOne, merkleBlockOneBytes, pver, 177, io.ErrShortWrite, io.EOF},
// Force error in transaction count.
{&merkleBlockOne, merkleBlockOneBytes, pver, 153, io.ErrShortWrite, io.EOF},
{&merkleBlockOne, merkleBlockOneBytes, pver, 185, io.ErrShortWrite, io.EOF},
// Force error in num hashes.
{&merkleBlockOne, merkleBlockOneBytes, pver, 157, io.ErrShortWrite, io.EOF},
{&merkleBlockOne, merkleBlockOneBytes, pver, 189, io.ErrShortWrite, io.EOF},
// Force error in hashes.
{&merkleBlockOne, merkleBlockOneBytes, pver, 158, io.ErrShortWrite, io.EOF},
// Force error in num flag bytes.
{&merkleBlockOne, merkleBlockOneBytes, pver, 190, io.ErrShortWrite, io.EOF},
// Force error in num flag bytes.
{&merkleBlockOne, merkleBlockOneBytes, pver, 222, io.ErrShortWrite, io.EOF},
// Force error in flag bytes.
{&merkleBlockOne, merkleBlockOneBytes, pver, 191, io.ErrShortWrite, io.EOF},
{&merkleBlockOne, merkleBlockOneBytes, pver, 223, io.ErrShortWrite, io.EOF},
}
t.Logf("Running %d tests", len(tests))
@ -275,7 +281,7 @@ func TestMerkleBlockOverflowErrors(t *testing.T) {
// allowed tx hashes.
var buf bytes.Buffer
WriteVarInt(&buf, maxTxPerBlock+1)
numHashesOffset := 157
numHashesOffset := 189
exceedMaxHashes := make([]byte, numHashesOffset)
copy(exceedMaxHashes, merkleBlockOneBytes[:numHashesOffset])
exceedMaxHashes = append(exceedMaxHashes, buf.Bytes()...)
@ -284,7 +290,7 @@ func TestMerkleBlockOverflowErrors(t *testing.T) {
// allowed flag bytes.
buf.Reset()
WriteVarInt(&buf, maxFlagsPerMerkleBlock+1)
numFlagBytesOffset := 190
numFlagBytesOffset := 222
exceedMaxFlagBytes := make([]byte, numFlagBytesOffset)
copy(exceedMaxFlagBytes, merkleBlockOneBytes[:numFlagBytesOffset])
exceedMaxFlagBytes = append(exceedMaxFlagBytes, buf.Bytes()...)
@ -326,10 +332,11 @@ var merkleBlockOne = MsgMerkleBlock{
0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1,
0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e,
},
IDMerkleRoot: exampleIDMerkleRoot,
Timestamp: time.Unix(0x4966bc61, 0), // 2009-01-08 20:54:25 -0600 CST
Bits: 0x1d00ffff, // 486604799
Nonce: 0x9962e301, // 2573394689
IDMerkleRoot: exampleIDMerkleRoot,
AcceptedIDMerkleRoot: exampleAcceptedIDMerkleRoot,
Timestamp: time.Unix(0x4966bc61, 0), // 2009-01-08 20:54:25 -0600 CST
Bits: 0x1d00ffff, // 486604799
Nonce: 0x9962e301, // 2573394689
},
Transactions: 1,
Hashes: []*daghash.Hash{
@ -364,6 +371,10 @@ var merkleBlockOneBytes = []byte{
0x65, 0x9C, 0x79, 0x3C, 0xE3, 0x70, 0xD9, 0x5F,
0x09, 0x3B, 0xC7, 0xE3, 0x67, 0x11, 0x7B, 0x3C,
0x30, 0xC1, 0xF8, 0xFD, 0xD0, 0xD9, 0x72, 0x87,
0x09, 0x3B, 0xC7, 0xE3, 0x67, 0x11, 0x7B, 0x3C, // AcceptedIDMerkleRoot
0x30, 0xC1, 0xF8, 0xFD, 0xD0, 0xD9, 0x72, 0x87,
0x7F, 0x16, 0xC5, 0x96, 0x2E, 0x8B, 0xD9, 0x63,
0x65, 0x9C, 0x79, 0x3C, 0xE3, 0x70, 0xD9, 0x5F,
0x61, 0xbc, 0x66, 0x49, 0x00, 0x00, 0x00, 0x00, // Timestamp
0xff, 0xff, 0x00, 0x1d, // Bits
0x01, 0xe3, 0x62, 0x99, 0x00, 0x00, 0x00, 0x00, // Fake Nonce. TODO: (Ori) Replace to a real nonce