From b1d3ca020642af3f4911c58093ae9ca25cf580f0 Mon Sep 17 00:00:00 2001 From: stasatdaglabs <39559713+stasatdaglabs@users.noreply.github.com> Date: Wed, 15 May 2019 16:16:57 +0300 Subject: [PATCH] [NOD-177] Remove idMerkleRoot (#299) * [NOD-177] Removed references to idMerkleRoot. * [NOD-177] Generated new genesis hashes. * [NOD-177] Generated new blk_ blocks. * [NOD-177] Fixed TestHaveBlock. * [NOD-177] Fixed The rest of the tests. * [NOD-177] Fixed a couple of comments and a duplicate test. * [NOD-177] Fixed blocks1-256.bz2. --- blockdag/blocknode.go | 3 -- blockdag/common_test.go | 1 - blockdag/dag_test.go | 9 ++--- blockdag/dagio.go | 1 - blockdag/example_test.go | 2 +- blockdag/merkle_test.go | 8 +++- blockdag/testdata/blk_0_to_4.dat | Bin 2108 -> 1948 bytes blockdag/testdata/blk_3A.dat | Bin 489 -> 457 bytes blockdag/testdata/blk_3B.dat | Bin 376 -> 344 bytes blockdag/testdata/blk_3C.dat | Bin 408 -> 376 bytes blockdag/testdata/blk_3D.dat | Bin 534 -> 502 bytes blockdag/validate.go | 9 ----- blockdag/validate_test.go | 25 ++---------- btcjson/dagsvrresults.go | 2 - dagconfig/genesis.go | 26 ++++++------- dagconfig/genesis_test.go | 62 ++++++++++++++---------------- database/example_test.go | 2 +- database/ffldb/blockio_test.go | 4 +- database/ffldb/db_test.go | 4 +- database/testdata/blocks1-256.bz2 | Bin 9972 -> 9938 bytes database/testdata/generator.go | 1 - integration/rpctest/blockgen.go | 2 - mempool/estimatefee_test.go | 1 - mining/mining.go | 4 -- mining/simulator/mineloop.go | 3 +- mining/test_utils.go | 1 - peer/peer_test.go | 4 +- server/rpc/rpcserver.go | 4 -- server/rpc/rpcserverhelp.go | 2 - util/block_test.go | 18 +++------ util/bloom/filter_test.go | 3 -- util/bloom/merkleblock_test.go | 9 +---- util/daghash/hash_test.go | 12 +++--- wire/bench_test.go | 4 +- wire/blockheader.go | 23 ++++------- wire/blockheader_test.go | 36 ++++++----------- wire/common_test.go | 15 ++------ wire/message_test.go | 6 +-- wire/msgblock_test.go | 59 +++++++++++----------------- wire/msgheaders_test.go | 35 +++++------------ wire/msgmerkleblock_test.go | 47 +++++++++------------- wire/msgreject_test.go | 8 ++-- 42 files changed, 155 insertions(+), 300 deletions(-) diff --git a/blockdag/blocknode.go b/blockdag/blocknode.go index 0f233941f..f28e024c2 100644 --- a/blockdag/blocknode.go +++ b/blockdag/blocknode.go @@ -102,7 +102,6 @@ type blockNode struct { nonce uint64 timestamp int64 hashMerkleRoot *daghash.Hash - idMerkleRoot *daghash.Hash acceptedIDMerkleRoot *daghash.Hash utxoCommitment *daghash.Hash @@ -131,7 +130,6 @@ func initBlockNode(node *blockNode, blockHeader *wire.BlockHeader, parents block node.nonce = blockHeader.Nonce node.timestamp = blockHeader.Timestamp.Unix() node.hashMerkleRoot = blockHeader.HashMerkleRoot - node.idMerkleRoot = blockHeader.IDMerkleRoot node.acceptedIDMerkleRoot = blockHeader.AcceptedIDMerkleRoot node.utxoCommitment = blockHeader.UTXOCommitment } else { @@ -183,7 +181,6 @@ func (node *blockNode) Header() *wire.BlockHeader { Version: node.version, ParentHashes: node.ParentHashes(), HashMerkleRoot: node.hashMerkleRoot, - IDMerkleRoot: node.idMerkleRoot, AcceptedIDMerkleRoot: node.acceptedIDMerkleRoot, UTXOCommitment: node.utxoCommitment, Timestamp: time.Unix(node.timestamp, 0), diff --git a/blockdag/common_test.go b/blockdag/common_test.go index 7384ed9ae..1a661523d 100644 --- a/blockdag/common_test.go +++ b/blockdag/common_test.go @@ -205,7 +205,6 @@ func newTestNode(parents blockSet, blockVersion int32, bits uint32, timestamp ti Bits: bits, Timestamp: timestamp, HashMerkleRoot: &daghash.ZeroHash, - IDMerkleRoot: &daghash.ZeroHash, AcceptedIDMerkleRoot: &daghash.ZeroHash, UTXOCommitment: &daghash.ZeroHash, } diff --git a/blockdag/dag_test.go b/blockdag/dag_test.go index 731974a91..d9a19cf76 100644 --- a/blockdag/dag_test.go +++ b/blockdag/dag_test.go @@ -174,8 +174,7 @@ func TestHaveBlock(t *testing.T) { } // Insert an orphan block. - isOrphan, err = dag.ProcessBlock(util.NewBlock(&Block100000), - BFNoPoWCheck) + isOrphan, err = dag.ProcessBlock(util.NewBlock(&Block100000), BFNoPoWCheck) if err != nil { t.Fatalf("Unable to process block: %v", err) } @@ -192,10 +191,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: "6733a86f4e3a46c0d4df76d6fbfab88eacadf8e44f54eb544a18d6b95570510c", want: true}, + {hash: "3f2ded16b7115e69a48cee5f4be743ff23ad8d41da16d059c38cc83d14459863", want: true}, // Block 100000 should be present (as an orphan). - {hash: "18bcf45b8c0dbccd7690a728f3486c6d5fc84971688f89f4554297b6a278e554", want: true}, + {hash: "4e530ee9f967de3b2cd47ac5cd00109bb9ed7b0e30a60485c94badad29ecb4ce", want: true}, // Random hashes should not be available. {hash: "123", want: false}, @@ -555,7 +554,6 @@ func chainedNodes(parents blockSet, numNodes int) []*blockNode { // synthetic tests to work. header := wire.BlockHeader{ Nonce: testNoncePrng.Uint64(), - IDMerkleRoot: &daghash.ZeroHash, HashMerkleRoot: &daghash.ZeroHash, AcceptedIDMerkleRoot: &daghash.ZeroHash, UTXOCommitment: &daghash.ZeroHash, @@ -919,7 +917,6 @@ func TestValidateFeeTransaction(t *testing.T) { Bits: dag.genesis.Header().Bits, ParentHashes: parentHashes, HashMerkleRoot: BuildHashMerkleTreeStore(utilTxs).Root(), - IDMerkleRoot: BuildIDMerkleTreeStore(utilTxs).Root(), AcceptedIDMerkleRoot: acceptedIDMerkleRoot, UTXOCommitment: &daghash.ZeroHash, }, diff --git a/blockdag/dagio.go b/blockdag/dagio.go index 06d2bab73..edf78eca9 100644 --- a/blockdag/dagio.go +++ b/blockdag/dagio.go @@ -623,7 +623,6 @@ func (dag *BlockDAG) deserializeBlockNode(blockRow []byte) (*blockNode, error) { nonce: header.Nonce, timestamp: header.Timestamp.Unix(), hashMerkleRoot: header.HashMerkleRoot, - idMerkleRoot: header.IDMerkleRoot, acceptedIDMerkleRoot: header.AcceptedIDMerkleRoot, utxoCommitment: header.UTXOCommitment, } diff --git a/blockdag/example_test.go b/blockdag/example_test.go index 994c12071..a3f797e50 100644 --- a/blockdag/example_test.go +++ b/blockdag/example_test.go @@ -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 5804d0207bdbfd88dd035271fab95944585eb57017b0709d5a0a10a7edb37795 + // Failed to process block: already have block 63bbcfdd699ffd8cb19878564b14d3af8ba4d7ee4d1dd54925a7c21d5b5b5fdc } diff --git a/blockdag/merkle_test.go b/blockdag/merkle_test.go index 573a33da4..4fc09a8d7 100644 --- a/blockdag/merkle_test.go +++ b/blockdag/merkle_test.go @@ -5,6 +5,7 @@ package blockdag import ( + "github.com/daglabs/btcd/util/daghash" "testing" "github.com/daglabs/btcd/util" @@ -24,8 +25,11 @@ func TestMerkle(t *testing.T) { idMerkleTree := BuildIDMerkleTreeStore(block.Transactions()) calculatedIDMerkleRoot := idMerkleTree.Root() - wantIDMerkleRoot := Block100000.Header.IDMerkleRoot - if !wantIDMerkleRoot.IsEqual(calculatedIDMerkleRoot) { + wantIDMerkleRoot, err := daghash.NewHashFromStr("65308857c92c4e5dd3c5e61b73d6b78a87456b5f8f16b13c1e02c47768a0b881") + if err != nil { + t.Errorf("BuildIDMerkleTreeStore: unexpected error: %s", err) + } + if !calculatedIDMerkleRoot.IsEqual(wantIDMerkleRoot) { t.Errorf("BuildIDMerkleTreeStore: ID merkle root mismatch - "+ "got %v, want %v", calculatedIDMerkleRoot, wantIDMerkleRoot) } diff --git a/blockdag/testdata/blk_0_to_4.dat b/blockdag/testdata/blk_0_to_4.dat index 67e4e30771d29f496d5f524c0114a7ec17922dbc..10a82ca25783a0f298b7bb2d41c480050521ec9b 100644 GIT binary patch delta 664 zcmdlZFo&P_=e{jBA2Kj7Faj~dMBN154M%RpfY|^4*DEkgoK@@@0G479V7wC_9W8rk zxvJ+?S>JcpmvpbcEaDwjF=J!T-}#w$&+ksI{LdZdI8E!4QcT%0oo~gD3X{J({yP+| z(V)L}qOrZV@I+k)(Tzx^GlQ%F0;b72tXh-5GCC;`vSIQ>8NB?c-7tB@Pm9oXoD6HI!;roVr zUl;!tJrTNt^iM8~=edTNZ6!{IKHYt#vd1?DZ`cTx`EEN3Oo? z@1z^*&zHCtXRos^*tFtPZ^xGx5obUApCG&b*EfYuK4$TZb$Oy2^1bHwEV4bcsNQ&< zrOKp?&1^aCm!IYod))=OZZptz%9{{`R!LI_bB?QL#f<~m+8{sqNdix>l`k9&suEy?ORU7MotOlqWCkdhnSXK-_@O^ z>7Ab|xZ>NIcbh7_@;&c&?9-3*UL>e8~s7a0@v6Y$n^YJ1G#d59q?# E0Bk`x;{X5v literal 2108 zcmeylZ_7&CN(SzOl-fp

$QZh6XXB4a|y|V z%%B7;u)Prj(*OT|y#m-lKsLy65Z8fZaDo3oz{kMAtsh_%?4h4jlANLs5&{86hEJ?o zU_%0N=?01a1O`L_#8LsqspXsBE*Id6np?0zykKiwgiGYkUxh);cRT*xu2#6f5-~Z= zX8qR8TQ?_cj61gCP@Axv=Ksadwn?npWpMTA(iQo!gybm=$c0D&1@jaW@c|VWNI^h> ztsxXZpnwNPBLu))h?NF~`$Jf`TO~z(GuZ37N9)b2=dXq2Cb&i&Q|$lu%v$pO?M!+Wh1C_TTj`(Ezd=QyB6B3>773rRQrB=c`%$&@BiQTESVUwb$+DFqw(r~v^K5>F z-**)>DPCr%w{P8N!HzXZL50CYiRcSc4xacC-v8QjjmLu1yv1cEs}-0pKX~~3+q;~% z#>ccJE~})(&Nn@~(n$NcE9mU@!Vjv(e5{1z9U|<7_QiGJ#k#jT)Qo5V9#E75 diff --git a/blockdag/testdata/blk_3A.dat b/blockdag/testdata/blk_3A.dat index 77b98c2ffc5ead12a3a307395a1f7d064fbce410..8bdda0902cacc36548462adf9025e6e3873187c1 100644 GIT binary patch delta 174 zcmaFKe3Ci$=e{jB4>B@UYrKL~W#24TA53Jd;X#3)a6*q6KoB3z2Z?WKF`-M4j z^(pVx|4u9wE!sQhzUqrF&RRcjXP&*j-uhI##aqUU`EM(k#WU9BiEhaEn%}d?_Rykw z<9U`UlQK55<+NXZnp5m`cj82ui3?bGHy^nb1G4b{|9S=HiMvV^2-!Q?k8w5tYvWcr delta 207 zcmX@f{F1r;=e{jBA2Kq4fB@r#DF;vd2=9OGxyEC`Y2M;8lhq2$mmfTQ{_S1PTjOKe z67~_ceyjCY&Iot?^z&GpNQee|ZHnf0^R3ErqL#=o8Z#4;cZjeT+7}~YTkrm*-&cZP z`d})by?My)B8PR+jQ=k^x)L$5P-bES3-4mv8!;dk{r_LDz%+4Ii2@;qP1a+a4FJSp BTM7UG diff --git a/blockdag/testdata/blk_3B.dat b/blockdag/testdata/blk_3B.dat index eaf5ff6c340ffae635ba93e48293ab94fbf9ef31..ac21c81088aadab41aa564ac4127e073a997357b 100644 GIT binary patch delta 174 zcmeytbb~4P=e{jB0~i@VK!DMy($Xhw;)`$m2i9y^w0-fzikr9A&HS_1w^(qo{lXl% z`n>uT&$dmwc*AdlputyJ_Y6m2-6sbPBNP+NBp17Mto_I=p0O@ZbVI(^{GLU&hZfZv y&$CpSl(CsDr~UHNoMNxL6DP_{T)@J+`N*vpkcI#M*DEki+*P7L$ll3*j9LJhiBX3D literal 376 zcmeylZ_CXBMg|ZNV7xHp;E5mM{jWXOcq};0TU=(cT7miUgNM(*y~}xPd`w$nUb#u^ z%immv0d@u+VzKRw7?AY;|MdzmWlSK)Lp%Tz!b1NC0>0odZv6nGU=RJI mlH?S9kPrwkGJImy0vi&DMI&4Ytb$Mgfy@KC4g%m>u`vKu9Cc^_ diff --git a/blockdag/testdata/blk_3C.dat b/blockdag/testdata/blk_3C.dat index a33cd826751acb768ffacf3395c1c932a6f0d02a..57ef5b56efc7087b5f074ac0a95db064cfd150d5 100644 GIT binary patch delta 197 zcmbQi{DZ0f=e{jB3m6$dK!7Pme@FBS_peTS%`Serp?ABmK`rX(Kk*0u|E-o_414*l z+NsjgCvD=3Z~O<=Y+1B@@xzLnx7N-4v)8v+aIyWu9J%`XoTODB-_*>u{N>A5yT|g$ z!t)9$|9*X}-=ePeY>(C}+5F^bm7EQE_vJ$iBH#v_{3jj6+VyFNB literal 408 zcmeylZ_CXIj0_+kz;t2C!4p5i`(Jym@mO%0x46t?wF2|y2M?crdzbUp_?WhYRZ`S9 zgT0=6wBEdW{#rUYrKL~W#24TA53Jd;X#3)a6*q6KoB3z2Z?WKF`-M4j z_5Iv#t;T9>VF@kOT~i;nUEW@}ej>A6>4h`bBC~Vf*XQRaPpjl?$h%*ES?-#ejlfAa p+cWdD=Shou`E|FNaJW61I8kQe0v6`YM{Z5rP^Uo1w#j~sCjh$*PGbN7 delta 197 zcmeyyJdLIP=e{jB`Is0$K!EYWl!GUJg!jMpT;s9eG;eX4$!Z1W%MTtt|Mo8Dt?@B! ziDY(7-{N<>^t{%3E!cnP(HaLk#|bSS(iM!ygD=g$CjFa`y#LZ_(IszLYi|g*?KPOv uyKUK4KF2$~6BllM%lEAL`@iteiG?x~8(5eZ+uoQsp-zF2b0+ICo&W%i>|u-m diff --git a/blockdag/validate.go b/blockdag/validate.go index 02eeaf625..e3fb94a9f 100644 --- a/blockdag/validate.go +++ b/blockdag/validate.go @@ -563,15 +563,6 @@ func (dag *BlockDAG) checkBlockSanity(block *util.Block, flags BehaviorFlags) er return ruleError(ErrBadMerkleRoot, str) } - idMerkleTree := BuildIDMerkleTreeStore(block.Transactions()) - calculatedIDMerkleRoot := idMerkleTree.Root() - if !header.IDMerkleRoot.IsEqual(calculatedIDMerkleRoot) { - str := fmt.Sprintf("block ID merkle root is invalid - block "+ - "header indicates %s, but calculated value is %s", - header.IDMerkleRoot, calculatedIDMerkleRoot) - return ruleError(ErrBadMerkleRoot, str) - } - // Check for duplicate transactions. This check will be fairly quick // since the transaction IDs are already cached due to building the // merkle tree above. diff --git a/blockdag/validate_test.go b/blockdag/validate_test.go index 01b2a31bd..3f95599cf 100644 --- a/blockdag/validate_test.go +++ b/blockdag/validate_test.go @@ -222,12 +222,6 @@ func TestCheckBlockSanity(t *testing.T) { 0x48, 0x3e, 0x8b, 0xe1, 0xcf, 0xdc, 0x20, 0xba, 0xae, 0xec, 0x0a, 0x2f, 0xe4, 0x85, 0x31, 0x30, }, - IDMerkleRoot: &daghash.Hash{ - 0x4e, 0x06, 0xba, 0x64, 0xd7, 0x61, 0xda, 0x25, - 0x1a, 0x0e, 0x21, 0xd4, 0x64, 0x49, 0x02, 0xa2, - 0x80, 0xf7, 0x00, 0xe3, 0x16, 0x3d, 0x04, 0x95, - 0x5b, 0x7e, 0xaf, 0x84, 0x7e, 0x1b, 0x6b, 0x06, - }, AcceptedIDMerkleRoot: &daghash.Hash{ 0x80, 0xf7, 0x00, 0xe3, 0x16, 0x3d, 0x04, 0x95, 0x5b, 0x7e, 0xaf, 0x84, 0x7e, 0x1b, 0x6b, 0x06, @@ -242,7 +236,7 @@ func TestCheckBlockSanity(t *testing.T) { }, Timestamp: time.Unix(0x5cd18053, 0), Bits: 0x207fffff, - Nonce: 0x0, + Nonce: 0x1, }, Transactions: []*wire.MsgTx{ { @@ -526,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{}, &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) @@ -634,7 +628,6 @@ func TestValidateParents(t *testing.T) { c := generateNode(genesisNode) fakeBlockHeader := &wire.BlockHeader{ - IDMerkleRoot: &daghash.ZeroHash, HashMerkleRoot: &daghash.ZeroHash, AcceptedIDMerkleRoot: &daghash.ZeroHash, UTXOCommitment: &daghash.ZeroHash, @@ -770,12 +763,6 @@ var Block100000 = wire.MsgBlock{ 0x6f, 0x22, 0xfa, 0x60, 0x36, 0x80, 0x99, 0xc3, 0x6e, 0x39, 0x14, 0x9b, 0xcc, 0x1f, 0x31, 0xa9, }, - IDMerkleRoot: &daghash.Hash{ - 0x81, 0xb8, 0xa0, 0x68, 0x77, 0xc4, 0x02, 0x1e, - 0x3c, 0xb1, 0x16, 0x8f, 0x5f, 0x6b, 0x45, 0x87, - 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, @@ -1068,12 +1055,6 @@ var BlockWithWrongTxOrder = wire.MsgBlock{ 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, - 0x2f, 0x01, 0xd4, 0x83, 0x9b, 0x2a, 0x04, 0x5e, - 0xa0, 0x69, 0x2d, 0x16, 0xb5, 0xd7, 0xe4, 0xf3, - 0xcd, 0xc7, 0xc9, 0xaf, 0xfb, 0xd2, 0x1b, 0x85, - }, AcceptedIDMerkleRoot: &daghash.Hash{ 0xa0, 0x69, 0x2d, 0x16, 0xb5, 0xd7, 0xe4, 0xf3, 0xcd, 0xc7, 0xc9, 0xaf, 0xfb, 0xd2, 0x1b, 0x85, @@ -1088,7 +1069,7 @@ var BlockWithWrongTxOrder = wire.MsgBlock{ }, Timestamp: time.Unix(0x5cd16eaa, 0), Bits: 0x207fffff, - Nonce: 0x2, + Nonce: 0x0, }, Transactions: []*wire.MsgTx{ { diff --git a/btcjson/dagsvrresults.go b/btcjson/dagsvrresults.go index d4e84c5d4..48336fb5c 100644 --- a/btcjson/dagsvrresults.go +++ b/btcjson/dagsvrresults.go @@ -16,7 +16,6 @@ type GetBlockHeaderVerboseResult struct { Version int32 `json:"version"` VersionHex string `json:"versionHex"` HashMerkleRoot string `json:"hashMerkleRoot"` - IDMerkleRoot string `json:"idMerkleRoot"` AcceptedIDMerkleRoot string `json:"acceptedIdMerkleRoot"` Time int64 `json:"time"` Nonce uint64 `json:"nonce"` @@ -37,7 +36,6 @@ type GetBlockVerboseResult struct { Version int32 `json:"version"` VersionHex string `json:"versionHex"` HashMerkleRoot string `json:"hashMerkleRoot"` - IDMerkleRoot string `json:"idMerkleRoot"` AcceptedIDMerkleRoot string `json:"acceptedIdMerkleRoot"` Tx []string `json:"tx,omitempty"` RawTx []TxRawResult `json:"rawRx,omitempty"` diff --git a/dagconfig/genesis.go b/dagconfig/genesis.go index fb0910ced..2d90e2def 100644 --- a/dagconfig/genesis.go +++ b/dagconfig/genesis.go @@ -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{ - 0x95, 0x77, 0xb3, 0xed, 0xa7, 0x10, 0x0a, 0x5a, - 0x9d, 0x70, 0xb0, 0x17, 0x70, 0xb5, 0x5e, 0x58, - 0x44, 0x59, 0xb9, 0xfa, 0x71, 0x52, 0x03, 0xdd, - 0x88, 0xfd, 0xdb, 0x7b, 0x20, 0xd0, 0x04, 0x58, + 0xdc, 0x5f, 0x5b, 0x5b, 0x1d, 0xc2, 0xa7, 0x25, + 0x49, 0xd5, 0x1d, 0x4d, 0xee, 0xd7, 0xa4, 0x8b, + 0xaf, 0xd3, 0x14, 0x4b, 0x56, 0x78, 0x98, 0xb1, + 0x8c, 0xfd, 0x9f, 0x69, 0xdd, 0xcf, 0xbb, 0x63, }) // genesisMerkleRoot is the hash of the first transaction in the genesis block @@ -63,12 +63,11 @@ var genesisBlock = wire.MsgBlock{ Version: 1, ParentHashes: []*daghash.Hash{}, HashMerkleRoot: &genesisMerkleRoot, - IDMerkleRoot: &genesisMerkleRoot, AcceptedIDMerkleRoot: &daghash.Hash{}, UTXOCommitment: &daghash.Hash{}, - Timestamp: time.Unix(0x5cd83da0, 0), + Timestamp: time.Unix(0x5cdac4b0, 0), Bits: 0x207fffff, - Nonce: 0x1, + Nonce: 0x0, }, Transactions: []*wire.MsgTx{genesisCoinbaseTx}, } @@ -119,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{ - 0x53, 0x68, 0x95, 0xd4, 0xf7, 0xc7, 0x3b, 0x94, - 0x64, 0xfa, 0x98, 0xc7, 0xcb, 0x92, 0x53, 0x71, - 0x5e, 0x14, 0xd1, 0x83, 0x01, 0xd4, 0x1e, 0x17, - 0xd4, 0xc4, 0xd3, 0x50, 0xa7, 0x64, 0x00, 0x00, + 0xab, 0x03, 0xe2, 0x8e, 0xd4, 0x66, 0xf9, 0x75, + 0x21, 0xd8, 0x8b, 0x49, 0xb2, 0xb4, 0xeb, 0xc6, + 0x4a, 0x03, 0xbf, 0x9b, 0x41, 0xcb, 0x36, 0x79, + 0x33, 0x03, 0xc4, 0x4d, 0x37, 0x17, 0x00, 0x00, }) // devNetGenesisMerkleRoot is the hash of the first transaction in the genesis block @@ -136,12 +135,11 @@ var devNetGenesisBlock = wire.MsgBlock{ Version: 1, ParentHashes: []*daghash.Hash{}, HashMerkleRoot: &devNetGenesisMerkleRoot, - IDMerkleRoot: &devNetGenesisMerkleRoot, AcceptedIDMerkleRoot: &daghash.Hash{}, UTXOCommitment: &daghash.Hash{}, - Timestamp: time.Unix(0x5cd83da0, 0), + Timestamp: time.Unix(0x5cdac4b0, 0), Bits: 0x1e7fffff, - Nonce: 0xfe2a, + Nonce: 0xc79c, }, Transactions: []*wire.MsgTx{devNetGenesisCoinbaseTx}, } diff --git a/dagconfig/genesis_test.go b/dagconfig/genesis_test.go index b3eddfff0..b98fb2c12 100644 --- a/dagconfig/genesis_test.go +++ b/dagconfig/genesis_test.go @@ -121,39 +121,35 @@ func TestSimNetGenesisBlock(t *testing.T) { // genesisBlockBytes are the wire encoded bytes for the genesis block of the // main network as of protocol version 60002. var genesisBlockBytes = []byte{ - 0x01, 0x00, 0x00, 0x00, 0x00, 0xd4, 0xdc, 0x8b, - 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, 0xd4, 0xdc, 0x8b, - 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, 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, 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, 0xa0, 0x3d, 0xd8, - 0x5c, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7f, - 0x20, 0x01, 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, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, - 0xff, 0xff, 0xff, 0x0e, 0x00, 0x00, 0x0b, 0x2f, - 0x50, 0x32, 0x53, 0x48, 0x2f, 0x62, 0x74, 0x63, - 0x64, 0x2f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x01, 0x00, 0xf2, 0x05, 0x2a, 0x01, - 0x00, 0x00, 0x00, 0x01, 0x51, 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, + 0x01, 0x00, 0x00, 0x00, 0x00, 0xd4, 0xdc, 0x8b, /* |........| */ + 0xb8, 0x76, 0x57, 0x9d, 0x7d, 0xe9, 0x9d, 0xae, /* |.vW.}...| */ + 0xdb, 0xf8, 0x22, 0xd2, 0x0d, 0xa2, 0xe0, 0xbb, /* |..".....| */ + 0xbe, 0xed, 0xb0, 0xdb, 0xba, 0xeb, 0x18, 0x4d, /* |.......M| */ + 0x42, 0x01, 0xff, 0xed, 0x9d, 0x00, 0x00, 0x00, /* |B.......| */ + 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, /* |........| */ + 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, 0xb0, 0xc4, 0xda, /* |........| */ + 0x5c, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7f, /* |\.......| */ + 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, /* |........| */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, /* |........| */ + 0xff, 0xff, 0xff, 0x0e, 0x00, 0x00, 0x0b, 0x2f, /* |......./| */ + 0x50, 0x32, 0x53, 0x48, 0x2f, 0x62, 0x74, 0x63, /* |P2SH/btc| */ + 0x64, 0x2f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* |d/......| */ + 0xff, 0xff, 0x01, 0x00, 0xf2, 0x05, 0x2a, 0x01, /* |......*.| */ + 0x00, 0x00, 0x00, 0x01, 0x51, 0x00, 0x00, 0x00, /* |....Q...| */ + 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, /* |.| */ } // regTestGenesisBlockBytes are the wire encoded bytes for the genesis block of diff --git a/database/example_test.go b/database/example_test.go index b5cc906af..93b1afcd1 100644 --- a/database/example_test.go +++ b/database/example_test.go @@ -175,5 +175,5 @@ func Example_blockStorageAndRetrieval() { fmt.Printf("Serialized block size: %d bytes\n", len(loadedBlockBytes)) // Output: - // Serialized block size: 257 bytes + // Serialized block size: 225 bytes } diff --git a/database/ffldb/blockio_test.go b/database/ffldb/blockio_test.go index 6fd57063b..3d380501c 100644 --- a/database/ffldb/blockio_test.go +++ b/database/ffldb/blockio_test.go @@ -16,7 +16,7 @@ import ( func TestDeleteFile(t *testing.T) { testBlock := util.NewBlock(wire.NewMsgBlock( - wire.NewBlockHeader(1, []*daghash.Hash{}, &daghash.Hash{}, &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{}, &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 { diff --git a/database/ffldb/db_test.go b/database/ffldb/db_test.go index 021e9e10f..9086f7857 100644 --- a/database/ffldb/db_test.go +++ b/database/ffldb/db_test.go @@ -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{}, &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{}, &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") diff --git a/database/testdata/blocks1-256.bz2 b/database/testdata/blocks1-256.bz2 index ad970d81368e50f39171f7b364868dad7dfd6ee3..41874ec34080c052c3b69dc8765fc55ce9cdac01 100644 GIT binary patch literal 9938 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