From 9de82712092d7ca145a7f3fc8bdd72da5c00071f Mon Sep 17 00:00:00 2001 From: Hussam Date: Tue, 19 Nov 2024 16:35:52 -0600 Subject: [PATCH 1/4] Commit to MixHash in header, update tests --- core/types/block.go | 6 +++++- core/types/wo.go | 14 +++++++++----- core/types/wo_test.go | 22 ++++++++++++++++++---- params/config.go | 20 ++++++++++---------- 4 files changed, 42 insertions(+), 20 deletions(-) diff --git a/core/types/block.go b/core/types/block.go index 4a3172481b..cb4ffc43c5 100644 --- a/core/types/block.go +++ b/core/types/block.go @@ -35,6 +35,10 @@ import ( "github.com/dominant-strategies/go-quai/rlp" ) +const ( + NonceLength = 8 +) + var ( EmptyRootHash = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421") EmptyUncleHash = RlpHash([]*Header(nil)) @@ -48,7 +52,7 @@ var ( // A BlockNonce is a 64-bit hash which proves (combined with the // mix-hash) that a sufficient amount of computation has been carried // out on a block. -type BlockNonce [8]byte +type BlockNonce [NonceLength]byte // EncodeNonce converts the given integer to a block nonce. func EncodeNonce(i uint64) BlockNonce { diff --git a/core/types/wo.go b/core/types/wo.go index 1f8ee03429..ea38e5fd68 100644 --- a/core/types/wo.go +++ b/core/types/wo.go @@ -794,6 +794,7 @@ func (wo *WorkObject) WithBody(header *Header, txs []*Transaction, etxs []*Trans func EmptyWorkObjectBody() *WorkObjectBody { woBody := &WorkObjectBody{} + woBody.SetHeader(EmptyHeader()) woBody.SetTransactions([]*Transaction{}) woBody.SetOutboundEtxs([]*Transaction{}) return woBody @@ -1079,12 +1080,15 @@ func (wh *WorkObjectHeader) RPCMarshalWorkObjectHeader() map[string]interface{} func (wh *WorkObjectHeader) Hash() (hash common.Hash) { sealHash := wh.SealHash().Bytes() + mixHash := wh.MixHash().Bytes() + nonce := wh.Nonce().Bytes() hasherMu.Lock() defer hasherMu.Unlock() hasher.Reset() - var hData [40]byte - copy(hData[:], wh.Nonce().Bytes()) - copy(hData[len(wh.nonce):], sealHash) + var hData [common.HashLength + common.HashLength + NonceLength]byte + copy(hData[:], mixHash) + copy(hData[common.HashLength:], sealHash) + copy(hData[common.HashLength+common.HashLength:], nonce) sum := blake3.Sum256(hData[:]) hash.SetBytes(sum[:]) return hash @@ -1106,7 +1110,7 @@ func (wh *WorkObjectHeader) SealHash() (hash common.Hash) { func (wh *WorkObjectHeader) SealEncode() *ProtoWorkObjectHeader { // Omit MixHash and PowHash - hash := common.ProtoHash{Value: wh.HeaderHash().Bytes()} + headerHash := common.ProtoHash{Value: wh.HeaderHash().Bytes()} parentHash := common.ProtoHash{Value: wh.ParentHash().Bytes()} txHash := common.ProtoHash{Value: wh.TxHash().Bytes()} number := wh.Number().Bytes() @@ -1118,7 +1122,7 @@ func (wh *WorkObjectHeader) SealEncode() *ProtoWorkObjectHeader { coinbase := common.ProtoAddress{Value: wh.PrimaryCoinbase().Bytes()} return &ProtoWorkObjectHeader{ - HeaderHash: &hash, + HeaderHash: &headerHash, ParentHash: &parentHash, Number: number, Difficulty: difficulty, diff --git a/core/types/wo_test.go b/core/types/wo_test.go index 6884814957..39618ba4ef 100644 --- a/core/types/wo_test.go +++ b/core/types/wo_test.go @@ -12,7 +12,7 @@ func woTestData() (*WorkObject, common.Hash) { wo := &WorkObject{ woHeader: &WorkObjectHeader{ headerHash: common.HexToHash("0x123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0"), - parentHash: common.HexToHash("0x23456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef1"), + parentHash: common.HexToHash("0x23456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef12"), number: big.NewInt(1), difficulty: big.NewInt(123456789), primeTerminusNumber: big.NewInt(42), @@ -24,16 +24,24 @@ func woTestData() (*WorkObject, common.Hash) { nonce: EncodeNonce(uint64(1)), lock: 0, }, + woBody: EmptyWorkObjectBody(), } return wo, wo.Hash() } func TestWoHash(t *testing.T) { _, actualHash := woTestData() - expectedHash := common.HexToHash("0x572273f26629ca2a02c329cd21dc3def6e1d1934465ea11fca393c7a9ce3c89b") + expectedHash := common.HexToHash("0x5699348bb74873668408253dc3c518e1570eec73516dced58cbddcf294d2f477") require.Equal(t, expectedHash, actualHash, "Hash not equal to expected hash") } +func TestWoSealHash(t *testing.T) { + testWo, _ := woTestData() + actualHash := testWo.SealHash() + expectedHash := common.HexToHash("0x8ea659d6d9e1da464ae1a505cc19b1fe5f3df1e7013168227be1c290b3edaf01") + require.Equal(t, expectedHash, actualHash, "Seal hash not equal to expected hash") +} + func FuzzHeaderHash(f *testing.F) { fuzzHash(f, func(woh *WorkObjectHeader) common.Hash { return woh.headerHash }, @@ -60,8 +68,14 @@ func FuzzNumberHash(f *testing.F) { func FuzzTxHash(f *testing.F) { fuzzHash(f, - func(woh *WorkObjectHeader) common.Hash { return woh.txHash }, - func(woh *WorkObjectHeader, hash common.Hash) { woh.txHash = hash }) + func(woh *WorkObjectHeader) common.Hash { return woh.TxHash() }, + func(woh *WorkObjectHeader, hash common.Hash) { woh.SetTxHash(hash)}) +} + +func FuzzMixHash(f *testing.F) { + fuzzHash(f, + func(woh *WorkObjectHeader) common.Hash { return woh.MixHash() }, + func(woh *WorkObjectHeader, hash common.Hash) { woh.SetMixHash(hash) }) } func TestLocationHash(t *testing.T) { diff --git a/params/config.go b/params/config.go index dbb147558d..ffee14b4b0 100644 --- a/params/config.go +++ b/params/config.go @@ -26,18 +26,18 @@ import ( // Genesis hashes to enforce below configs on. var ( // Progpow GenesisHashes - ProgpowColosseumGenesisHash = common.HexToHash("0xba33a6807db85d5de6f51ff95c4805feaa9b81951a57e43254117d489031e96f") - ProgpowGardenGenesisHash = common.HexToHash("0xb610af2eef9d854d01510785b0171247cb221912124c74fcef888bbed42448bb") - ProgpowOrchardGenesisHash = common.HexToHash("0x863406b0b535b316d4ae5a4d97336c0a015a36c0e5c055aa2e4461e9048b62c9") - ProgpowLighthouseGenesisHash = common.HexToHash("0xf60de17f1ae6cbae820d14599eb95581f5c18799f84904520c264be9cfff64c4") - ProgpowLocalGenesisHash = common.HexToHash("0x175e643b5fe6158daca4742959f33ac2a8e9e6fe06cfd7233582827558f934f9") + ProgpowColosseumGenesisHash = common.HexToHash("0x34e8df195cc7f2b3092c938ecafc984572a3b1e6d3b83033ff4fc842d4ae7791") + ProgpowGardenGenesisHash = common.HexToHash("0x826e9735d06b9d280057735b7f27b48f275a5a6fc2554e2b645801a4d453edfb") + ProgpowOrchardGenesisHash = common.HexToHash("0x00b474af48e9786747a6517f2fc249a3a688ec815852982c0d5a34cbba531df3") + ProgpowLighthouseGenesisHash = common.HexToHash("0xe6f93265416217ec71dca5791a4c98e442814151f078fc5daa95e459e2e54516") + ProgpowLocalGenesisHash = common.HexToHash("0xdee631c2caea3e795327f3563c24f7b3f7709115eef9a191b94964680ecee70b") // Blake3GenesisHashes - Blake3PowColosseumGenesisHash = common.HexToHash("0xee89c5f775980556c2bf8dc988e477f16005da57f84f2a1000dbe4693ad5f53d") - Blake3PowGardenGenesisHash = common.HexToHash("0x46dfa6724020658b3e03cfdf894bd8e990f46d1e9b1b66b49598788e43eaf50f") - Blake3PowOrchardGenesisHash = common.HexToHash("0xf60de17f1ae6cbae820d14599eb95581f5c18799f84904520c264be9cfff64c4") - Blake3PowLighthouseGenesisHash = common.HexToHash("0xf60de17f1ae6cbae820d14599eb95581f5c18799f84904520c264be9cfff64c4") - Blake3PowLocalGenesisHash = common.HexToHash("0x36872ac4bc745d9bb86ace9859fd4d12f97b92c6ae32535eb122274ccf9df29c") + Blake3PowColosseumGenesisHash = common.HexToHash("0x4a6d4cb9f95f7ac25687b4e64cd582d2663753e724fd7ed7670e225319d7bb04") + Blake3PowGardenGenesisHash = common.HexToHash("0x2544dc1a9448ac384b963513d8e91cd30d45da57828e6514a42b38025f9b49b5") + Blake3PowOrchardGenesisHash = common.HexToHash("0xe6f93265416217ec71dca5791a4c98e442814151f078fc5daa95e459e2e54516") + Blake3PowLighthouseGenesisHash = common.HexToHash("0xe6f93265416217ec71dca5791a4c98e442814151f078fc5daa95e459e2e54516") + Blake3PowLocalGenesisHash = common.HexToHash("0x2544dc1a9448ac384b963513d8e91cd30d45da57828e6514a42b38025f9b49b5") ) // Different Network names From d3ec57e68f3c6d049c84247253f0504eae47d351 Mon Sep 17 00:00:00 2001 From: Hussam Date: Wed, 20 Nov 2024 12:17:51 -0600 Subject: [PATCH 2/4] Set missing fields in EmptyWorkObjectBody, use setters for WoTestData --- core/types/wo.go | 3 +++ core/types/wo_test.go | 35 +++++++++++++++++------------------ 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/core/types/wo.go b/core/types/wo.go index ea38e5fd68..825953252e 100644 --- a/core/types/wo.go +++ b/core/types/wo.go @@ -797,6 +797,9 @@ func EmptyWorkObjectBody() *WorkObjectBody { woBody.SetHeader(EmptyHeader()) woBody.SetTransactions([]*Transaction{}) woBody.SetOutboundEtxs([]*Transaction{}) + woBody.SetUncles([]*WorkObjectHeader{}) + woBody.SetManifest(BlockManifest{}) + woBody.SetInterlinkHashes(common.Hashes{}) return woBody } diff --git a/core/types/wo_test.go b/core/types/wo_test.go index 39618ba4ef..f72533ae24 100644 --- a/core/types/wo_test.go +++ b/core/types/wo_test.go @@ -9,29 +9,28 @@ import ( ) func woTestData() (*WorkObject, common.Hash) { - wo := &WorkObject{ - woHeader: &WorkObjectHeader{ - headerHash: common.HexToHash("0x123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0"), - parentHash: common.HexToHash("0x23456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef12"), - number: big.NewInt(1), - difficulty: big.NewInt(123456789), - primeTerminusNumber: big.NewInt(42), - txHash: common.HexToHash("0x456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef3"), - location: common.Location{0, 0}, - mixHash: common.HexToHash("0x56789abcdef0123456789abcdef0123456789abcdef0123456789abcdef4"), - primaryCoinbase: common.HexToAddress("0x123456789abcdef0123456789abcdef0123456789", common.Location{0, 0}), - time: uint64(1), - nonce: EncodeNonce(uint64(1)), - lock: 0, - }, - woBody: EmptyWorkObjectBody(), - } + wo := &WorkObject{} + wo.SetWorkObjectHeader(&WorkObjectHeader{}) + wo.woHeader.SetHeaderHash(common.HexToHash("0x123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0")) + wo.woHeader.SetParentHash(common.HexToHash("0x23456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef12")) + wo.woHeader.SetNumber(big.NewInt(1)) + wo.woHeader.SetDifficulty(big.NewInt(123456789)) + wo.woHeader.SetPrimeTerminusNumber(big.NewInt(42)) + wo.woHeader.SetTxHash(common.HexToHash("0x456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef3")) + wo.woHeader.SetLocation(common.Location{0, 0}) + wo.woHeader.SetMixHash(common.HexToHash("0x56789abcdef0123456789abcdef0123456789abcdef0123456789abcdef4")) + wo.woHeader.SetPrimaryCoinbase(common.HexToAddress("0x123456789abcdef0123456789abcdef0123456789", common.Location{0, 0})) + wo.woHeader.SetTime(uint64(1)) + wo.woHeader.SetNonce(EncodeNonce(uint64(1))) + wo.woHeader.SetLock(0) + + wo.woBody = EmptyWorkObjectBody() return wo, wo.Hash() } func TestWoHash(t *testing.T) { _, actualHash := woTestData() - expectedHash := common.HexToHash("0x5699348bb74873668408253dc3c518e1570eec73516dced58cbddcf294d2f477") + expectedHash := common.HexToHash("0x1bfdf14daa1844a372da6f2a2024d2fcc2bf92feb01d11b4e02f88d17ee9e9f8") require.Equal(t, expectedHash, actualHash, "Hash not equal to expected hash") } From e50d6e7c40b8e0711bba1b5fe7854a7d52722f53 Mon Sep 17 00:00:00 2001 From: Hussam Date: Wed, 20 Nov 2024 16:08:52 -0600 Subject: [PATCH 3/4] Add UncleHash tests, fill in empty fields for woTestData --- core/types/wo_test.go | 72 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 66 insertions(+), 6 deletions(-) diff --git a/core/types/wo_test.go b/core/types/wo_test.go index f72533ae24..83c77bcb6f 100644 --- a/core/types/wo_test.go +++ b/core/types/wo_test.go @@ -1,6 +1,7 @@ package types import ( + "fmt" "math/big" "testing" @@ -11,8 +12,8 @@ import ( func woTestData() (*WorkObject, common.Hash) { wo := &WorkObject{} wo.SetWorkObjectHeader(&WorkObjectHeader{}) - wo.woHeader.SetHeaderHash(common.HexToHash("0x123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0")) - wo.woHeader.SetParentHash(common.HexToHash("0x23456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef12")) + wo.woHeader.SetHeaderHash(EmptyHeader().Hash()) + wo.woHeader.SetParentHash(EmptyHeader().Hash()) wo.woHeader.SetNumber(big.NewInt(1)) wo.woHeader.SetDifficulty(big.NewInt(123456789)) wo.woHeader.SetPrimeTerminusNumber(big.NewInt(42)) @@ -28,16 +29,20 @@ func woTestData() (*WorkObject, common.Hash) { return wo, wo.Hash() } +var ( + expectedWoHash = common.HexToHash("0xd8e3ef0d1804c06495b219308535844169ccfdbd8565770077ea12f928fc8000") + expectedUncleHash = common.HexToHash("0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347") +) + func TestWoHash(t *testing.T) { _, actualHash := woTestData() - expectedHash := common.HexToHash("0x1bfdf14daa1844a372da6f2a2024d2fcc2bf92feb01d11b4e02f88d17ee9e9f8") - require.Equal(t, expectedHash, actualHash, "Hash not equal to expected hash") + require.Equal(t, expectedWoHash, actualHash, "Hash not equal to expected hash") } func TestWoSealHash(t *testing.T) { testWo, _ := woTestData() actualHash := testWo.SealHash() - expectedHash := common.HexToHash("0x8ea659d6d9e1da464ae1a505cc19b1fe5f3df1e7013168227be1c290b3edaf01") + expectedHash := common.HexToHash("0x83fd7f1dbd2f62d320c2dd974e2d1b3ce8108594a7c9e3aa99dfd993ca106090") require.Equal(t, expectedHash, actualHash, "Seal hash not equal to expected hash") } @@ -68,7 +73,7 @@ func FuzzNumberHash(f *testing.F) { func FuzzTxHash(f *testing.F) { fuzzHash(f, func(woh *WorkObjectHeader) common.Hash { return woh.TxHash() }, - func(woh *WorkObjectHeader, hash common.Hash) { woh.SetTxHash(hash)}) + func(woh *WorkObjectHeader, hash common.Hash) { woh.SetTxHash(hash) }) } func FuzzMixHash(f *testing.F) { @@ -117,6 +122,61 @@ func FuzzNonceHash(f *testing.F) { func(woh *WorkObjectHeader, nonce uint64) { woh.nonce = EncodeNonce(nonce) }) } +func TestCalcUncleHash(t *testing.T) { + tests := []struct { + uncleNum int + expectedUncleHash common.Hash + expectedWoHash common.Hash + shouldPass bool + }{ + { + uncleNum: 0, + expectedUncleHash: expectedUncleHash, + expectedWoHash: expectedWoHash, + shouldPass: true, + }, + { + uncleNum: 1, + expectedUncleHash: expectedUncleHash, + expectedWoHash: expectedWoHash, + shouldPass: false, + }, + { + uncleNum: 5, + expectedUncleHash: common.HexToHash("0x3c9dd26495f9a6ddf36e1443bee2ff0a3bb59b0722a765b145d01ab1f78ccd44"), + expectedWoHash: common.HexToHash("0x67c4f50242b43f752a32574a28633ac08d316fdbd786ccdc675e90887643adc2"), + shouldPass: true, + }, + } + + // Run test cases + for _, tt := range tests { + t.Run(fmt.Sprintf("uncleNum=%d", tt.uncleNum), func(t *testing.T) { + assertUncleHash(t, tt.uncleNum, tt.expectedUncleHash, tt.expectedWoHash, tt.shouldPass) + }) + } +} + +func assertUncleHash(t *testing.T, uncleNum int, expectedUncleHash common.Hash, expectedWoHash common.Hash, shouldPass bool) { + wo, _ := woTestData() + wo.Body().uncles = make([]*WorkObjectHeader, uncleNum) + for i := 0; i < uncleNum; i++ { + uncle, _ := woTestData() + wo.Body().uncles[i] = CopyWorkObjectHeader(uncle.WorkObjectHeader()) + } + + wo.Body().Header().SetUncleHash(CalcUncleHash(wo.Body().uncles)) + wo.woHeader.SetHeaderHash(wo.Body().header.Hash()) + + if shouldPass { + require.Equal(t, expectedUncleHash, wo.Header().UncleHash(), "Uncle hashes do not create the expected root hash") + require.Equal(t, expectedWoHash, wo.Hash(), "Uncle hashes do not create the expected WorkObject hash") + } else { + require.NotEqual(t, expectedUncleHash, wo.Header().UncleHash(), "Uncle hashes do not create the expected root hash") + require.NotEqual(t, expectedWoHash, wo.Hash(), "Uncle hashes do not create the expected WorkObject hash") + } +} + func fuzzHash(f *testing.F, getField func(*WorkObjectHeader) common.Hash, setField func(*WorkObjectHeader, common.Hash)) { wo, _ := woTestData() f.Add(testByte) From b62ad991ab76b61ad13da03332de9dfdbaa6c486 Mon Sep 17 00:00:00 2001 From: Hussam Date: Wed, 20 Nov 2024 17:21:39 -0600 Subject: [PATCH 4/4] Fix nil pointer panics for decoding WorkObjects --- core/types/block.go | 10 +- core/types/transaction.go | 16 +-- core/types/wo_test.go | 217 +++++++++++++++++++++++++++++++++++++- 3 files changed, 230 insertions(+), 13 deletions(-) diff --git a/core/types/block.go b/core/types/block.go index cb4ffc43c5..70457e654e 100644 --- a/core/types/block.go +++ b/core/types/block.go @@ -1234,10 +1234,12 @@ func (m BlockManifest) ProtoEncode() (*ProtoManifest, error) { // ProtoDecode deserializes th ProtoManifest into the BlockManifest format func (m *BlockManifest) ProtoDecode(protoManifest *ProtoManifest) error { - for _, protoHash := range protoManifest.Manifest { - hash := &common.Hash{} - hash.ProtoDecode(protoHash) - *m = append(*m, *hash) + if protoManifest != nil { + for _, protoHash := range protoManifest.Manifest { + hash := &common.Hash{} + hash.ProtoDecode(protoHash) + *m = append(*m, *hash) + } } return nil } diff --git a/core/types/transaction.go b/core/types/transaction.go index a857889871..ed93ae672a 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -799,14 +799,16 @@ func (s Transactions) ProtoEncode() (*ProtoTransactions, error) { // ProtoDecode decodes the ProtoTransactions into the Transactions format func (s *Transactions) ProtoDecode(transactions *ProtoTransactions, location common.Location) error { - *s = make(Transactions, 0, len(transactions.Transactions)) - for _, protoTx := range transactions.Transactions { - tx := &Transaction{} - err := tx.ProtoDecode(protoTx, location) - if err != nil { - return err + if transactions != nil { + *s = make(Transactions, 0, len(transactions.Transactions)) + for _, protoTx := range transactions.Transactions { + tx := &Transaction{} + err := tx.ProtoDecode(protoTx, location) + if err != nil { + return err + } + *s = append(*s, tx) } - *s = append(*s, tx) } return nil } diff --git a/core/types/wo_test.go b/core/types/wo_test.go index 83c77bcb6f..31d8bd6349 100644 --- a/core/types/wo_test.go +++ b/core/types/wo_test.go @@ -7,6 +7,7 @@ import ( "github.com/dominant-strategies/go-quai/common" "github.com/stretchr/testify/require" + "google.golang.org/protobuf/proto" ) func woTestData() (*WorkObject, common.Hash) { @@ -30,8 +31,119 @@ func woTestData() (*WorkObject, common.Hash) { } var ( - expectedWoHash = common.HexToHash("0xd8e3ef0d1804c06495b219308535844169ccfdbd8565770077ea12f928fc8000") - expectedUncleHash = common.HexToHash("0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347") + expectedWoHash = common.HexToHash("0xd8e3ef0d1804c06495b219308535844169ccfdbd8565770077ea12f928fc8000") + expectedUncleHash = common.HexToHash("0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347") + expectedPETXProtoBytes = []byte{ + 0x0a, 0xc0, 0x01, 0x0a, 0x22, 0x0a, 0x20, 0x97, 0xb8, 0xd8, 0x2d, 0x3f, 0x97, 0x82, 0x7d, 0x2f, + 0x95, 0x8f, 0x53, 0xa5, 0x31, 0x4a, 0x3c, 0x36, 0xe5, 0x1c, 0x57, 0xb9, 0xbb, 0x77, 0x08, 0x80, + 0xb2, 0x48, 0x79, 0x5d, 0x40, 0xa0, 0x1e, 0x12, 0x22, 0x0a, 0x20, 0x97, 0xb8, 0xd8, 0x2d, 0x3f, + 0x97, 0x82, 0x7d, 0x2f, 0x95, 0x8f, 0x53, 0xa5, 0x31, 0x4a, 0x3c, 0x36, 0xe5, 0x1c, 0x57, 0xb9, + 0xbb, 0x77, 0x08, 0x80, 0xb2, 0x48, 0x79, 0x5d, 0x40, 0xa0, 0x1e, 0x1a, 0x01, 0x01, 0x22, 0x04, + 0x07, 0x5b, 0xcd, 0x15, 0x2a, 0x22, 0x0a, 0x20, 0x00, 0x04, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, + 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, + 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf3, 0x30, 0x01, 0x3a, 0x04, 0x0a, 0x02, 0x00, 0x00, + 0x42, 0x22, 0x0a, 0x20, 0x00, 0x00, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56, 0x78, + 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56, 0x78, + 0x9a, 0xbc, 0xde, 0xf4, 0x48, 0x01, 0x52, 0x01, 0x2a, 0x58, 0x00, 0x62, 0x16, 0x0a, 0x14, 0x23, + 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, + 0x45, 0x67, 0x89, 0x12, 0x89, 0x05, 0x0a, 0x86, 0x05, 0x0a, 0x22, 0x0a, 0x20, 0x56, 0xe8, 0x1f, + 0x17, 0x1b, 0xcc, 0x55, 0xa6, 0xff, 0x83, 0x45, 0xe6, 0x92, 0xc0, 0xf8, 0x6e, 0x5b, 0x48, 0xe0, + 0x1b, 0x99, 0x6c, 0xad, 0xc0, 0x01, 0x62, 0x2f, 0xb5, 0xe3, 0x63, 0xb4, 0x21, 0x0a, 0x22, 0x0a, + 0x20, 0x56, 0xe8, 0x1f, 0x17, 0x1b, 0xcc, 0x55, 0xa6, 0xff, 0x83, 0x45, 0xe6, 0x92, 0xc0, 0xf8, + 0x6e, 0x5b, 0x48, 0xe0, 0x1b, 0x99, 0x6c, 0xad, 0xc0, 0x01, 0x62, 0x2f, 0xb5, 0xe3, 0x63, 0xb4, + 0x21, 0x12, 0x22, 0x0a, 0x20, 0x1d, 0xcc, 0x4d, 0xe8, 0xde, 0xc7, 0x5d, 0x7a, 0xab, 0x85, 0xb5, + 0x67, 0xb6, 0xcc, 0xd4, 0x1a, 0xd3, 0x12, 0x45, 0x1b, 0x94, 0x8a, 0x74, 0x13, 0xf0, 0xa1, 0x42, + 0xfd, 0x40, 0xd4, 0x93, 0x47, 0x1a, 0x22, 0x0a, 0x20, 0x56, 0xe8, 0x1f, 0x17, 0x1b, 0xcc, 0x55, + 0xa6, 0xff, 0x83, 0x45, 0xe6, 0x92, 0xc0, 0xf8, 0x6e, 0x5b, 0x48, 0xe0, 0x1b, 0x99, 0x6c, 0xad, + 0xc0, 0x01, 0x62, 0x2f, 0xb5, 0xe3, 0x63, 0xb4, 0x21, 0x22, 0x22, 0x0a, 0x20, 0x56, 0xe8, 0x1f, + 0x17, 0x1b, 0xcc, 0x55, 0xa6, 0xff, 0x83, 0x45, 0xe6, 0x92, 0xc0, 0xf8, 0x6e, 0x5b, 0x48, 0xe0, + 0x1b, 0x99, 0x6c, 0xad, 0xc0, 0x01, 0x62, 0x2f, 0xb5, 0xe3, 0x63, 0xb4, 0x21, 0x2a, 0x22, 0x0a, + 0x20, 0x56, 0xe8, 0x1f, 0x17, 0x1b, 0xcc, 0x55, 0xa6, 0xff, 0x83, 0x45, 0xe6, 0x92, 0xc0, 0xf8, + 0x6e, 0x5b, 0x48, 0xe0, 0x1b, 0x99, 0x6c, 0xad, 0xc0, 0x01, 0x62, 0x2f, 0xb5, 0xe3, 0x63, 0xb4, + 0x21, 0x32, 0x22, 0x0a, 0x20, 0x56, 0xe8, 0x1f, 0x17, 0x1b, 0xcc, 0x55, 0xa6, 0xff, 0x83, 0x45, + 0xe6, 0x92, 0xc0, 0xf8, 0x6e, 0x5b, 0x48, 0xe0, 0x1b, 0x99, 0x6c, 0xad, 0xc0, 0x01, 0x62, 0x2f, + 0xb5, 0xe3, 0x63, 0xb4, 0x21, 0x3a, 0x22, 0x0a, 0x20, 0x56, 0xe8, 0x1f, 0x17, 0x1b, 0xcc, 0x55, + 0xa6, 0xff, 0x83, 0x45, 0xe6, 0x92, 0xc0, 0xf8, 0x6e, 0x5b, 0x48, 0xe0, 0x1b, 0x99, 0x6c, 0xad, + 0xc0, 0x01, 0x62, 0x2f, 0xb5, 0xe3, 0x63, 0xb4, 0x21, 0x3a, 0x22, 0x0a, 0x20, 0x56, 0xe8, 0x1f, + 0x17, 0x1b, 0xcc, 0x55, 0xa6, 0xff, 0x83, 0x45, 0xe6, 0x92, 0xc0, 0xf8, 0x6e, 0x5b, 0x48, 0xe0, + 0x1b, 0x99, 0x6c, 0xad, 0xc0, 0x01, 0x62, 0x2f, 0xb5, 0xe3, 0x63, 0xb4, 0x21, 0x3a, 0x22, 0x0a, + 0x20, 0x56, 0xe8, 0x1f, 0x17, 0x1b, 0xcc, 0x55, 0xa6, 0xff, 0x83, 0x45, 0xe6, 0x92, 0xc0, 0xf8, + 0x6e, 0x5b, 0x48, 0xe0, 0x1b, 0x99, 0x6c, 0xad, 0xc0, 0x01, 0x62, 0x2f, 0xb5, 0xe3, 0x63, 0xb4, + 0x21, 0x42, 0x22, 0x0a, 0x20, 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, 0x52, 0x00, 0x52, 0x00, 0x52, 0x00, 0x5a, 0x00, 0x5a, 0x00, 0x5a, + 0x00, 0x62, 0x00, 0x62, 0x00, 0x62, 0x00, 0x6a, 0x00, 0x72, 0x00, 0x72, 0x00, 0x78, 0x00, 0x80, + 0x01, 0x00, 0x8a, 0x01, 0x00, 0x9a, 0x01, 0x00, 0xb2, 0x01, 0x22, 0x0a, 0x20, 0x56, 0xe8, 0x1f, + 0x17, 0x1b, 0xcc, 0x55, 0xa6, 0xff, 0x83, 0x45, 0xe6, 0x92, 0xc0, 0xf8, 0x6e, 0x5b, 0x48, 0xe0, + 0x1b, 0x99, 0x6c, 0xad, 0xc0, 0x01, 0x62, 0x2f, 0xb5, 0xe3, 0x63, 0xb4, 0x21, 0xba, 0x01, 0x22, + 0x0a, 0x20, 0x56, 0xe8, 0x1f, 0x17, 0x1b, 0xcc, 0x55, 0xa6, 0xff, 0x83, 0x45, 0xe6, 0x92, 0xc0, + 0xf8, 0x6e, 0x5b, 0x48, 0xe0, 0x1b, 0x99, 0x6c, 0xad, 0xc0, 0x01, 0x62, 0x2f, 0xb5, 0xe3, 0x63, + 0xb4, 0x21, 0xc0, 0x01, 0x00, 0xc8, 0x01, 0x00, 0xd0, 0x01, 0x00, 0xda, 0x01, 0x22, 0x0a, 0x20, + 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, + 0xe2, 0x01, 0x22, 0x0a, 0x20, 0x56, 0xe8, 0x1f, 0x17, 0x1b, 0xcc, 0x55, 0xa6, 0xff, 0x83, 0x45, + 0xe6, 0x92, 0xc0, 0xf8, 0x6e, 0x5b, 0x48, 0xe0, 0x1b, 0x99, 0x6c, 0xad, 0xc0, 0x01, 0x62, 0x2f, + 0xb5, 0xe3, 0x63, 0xb4, 0x21, 0xea, 0x01, 0x22, 0x0a, 0x20, 0x56, 0xe8, 0x1f, 0x17, 0x1b, 0xcc, + 0x55, 0xa6, 0xff, 0x83, 0x45, 0xe6, 0x92, 0xc0, 0xf8, 0x6e, 0x5b, 0x48, 0xe0, 0x1b, 0x99, 0x6c, + 0xad, 0xc0, 0x01, 0x62, 0x2f, 0xb5, 0xe3, 0x63, 0xb4, 0x21, 0xf0, 0x01, 0x00, 0xf8, 0x01, 0x00, + 0x82, 0x02, 0x00, 0x8a, 0x02, 0x00, 0x92, 0x02, 0x00, 0x9a, 0x02, 0x00, 0xa2, 0x02, 0x00, + } + expectedBlockProtoBytes = []byte{ + 0x0a, 0xc0, 0x01, 0x0a, 0x22, 0x0a, 0x20, 0x97, 0xb8, 0xd8, 0x2d, 0x3f, 0x97, 0x82, 0x7d, 0x2f, + 0x95, 0x8f, 0x53, 0xa5, 0x31, 0x4a, 0x3c, 0x36, 0xe5, 0x1c, 0x57, 0xb9, 0xbb, 0x77, 0x08, 0x80, + 0xb2, 0x48, 0x79, 0x5d, 0x40, 0xa0, 0x1e, 0x12, 0x22, 0x0a, 0x20, 0x97, 0xb8, 0xd8, 0x2d, 0x3f, + 0x97, 0x82, 0x7d, 0x2f, 0x95, 0x8f, 0x53, 0xa5, 0x31, 0x4a, 0x3c, 0x36, 0xe5, 0x1c, 0x57, 0xb9, + 0xbb, 0x77, 0x08, 0x80, 0xb2, 0x48, 0x79, 0x5d, 0x40, 0xa0, 0x1e, 0x1a, 0x01, 0x01, 0x22, 0x04, + 0x07, 0x5b, 0xcd, 0x15, 0x2a, 0x22, 0x0a, 0x20, 0x00, 0x04, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, + 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, + 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf3, 0x30, 0x01, 0x3a, 0x04, 0x0a, 0x02, 0x00, 0x00, + 0x42, 0x22, 0x0a, 0x20, 0x00, 0x00, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56, 0x78, + 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56, 0x78, + 0x9a, 0xbc, 0xde, 0xf4, 0x48, 0x01, 0x52, 0x01, 0x2a, 0x58, 0x00, 0x62, 0x16, 0x0a, 0x14, 0x23, + 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, + 0x45, 0x67, 0x89, 0x12, 0x93, 0x05, 0x0a, 0x86, 0x05, 0x0a, 0x22, 0x0a, 0x20, 0x56, 0xe8, 0x1f, + 0x17, 0x1b, 0xcc, 0x55, 0xa6, 0xff, 0x83, 0x45, 0xe6, 0x92, 0xc0, 0xf8, 0x6e, 0x5b, 0x48, 0xe0, + 0x1b, 0x99, 0x6c, 0xad, 0xc0, 0x01, 0x62, 0x2f, 0xb5, 0xe3, 0x63, 0xb4, 0x21, 0x0a, 0x22, 0x0a, + 0x20, 0x56, 0xe8, 0x1f, 0x17, 0x1b, 0xcc, 0x55, 0xa6, 0xff, 0x83, 0x45, 0xe6, 0x92, 0xc0, 0xf8, + 0x6e, 0x5b, 0x48, 0xe0, 0x1b, 0x99, 0x6c, 0xad, 0xc0, 0x01, 0x62, 0x2f, 0xb5, 0xe3, 0x63, 0xb4, + 0x21, 0x12, 0x22, 0x0a, 0x20, 0x1d, 0xcc, 0x4d, 0xe8, 0xde, 0xc7, 0x5d, 0x7a, 0xab, 0x85, 0xb5, + 0x67, 0xb6, 0xcc, 0xd4, 0x1a, 0xd3, 0x12, 0x45, 0x1b, 0x94, 0x8a, 0x74, 0x13, 0xf0, 0xa1, 0x42, + 0xfd, 0x40, 0xd4, 0x93, 0x47, 0x1a, 0x22, 0x0a, 0x20, 0x56, 0xe8, 0x1f, 0x17, 0x1b, 0xcc, 0x55, + 0xa6, 0xff, 0x83, 0x45, 0xe6, 0x92, 0xc0, 0xf8, 0x6e, 0x5b, 0x48, 0xe0, 0x1b, 0x99, 0x6c, 0xad, + 0xc0, 0x01, 0x62, 0x2f, 0xb5, 0xe3, 0x63, 0xb4, 0x21, 0x22, 0x22, 0x0a, 0x20, 0x56, 0xe8, 0x1f, + 0x17, 0x1b, 0xcc, 0x55, 0xa6, 0xff, 0x83, 0x45, 0xe6, 0x92, 0xc0, 0xf8, 0x6e, 0x5b, 0x48, 0xe0, + 0x1b, 0x99, 0x6c, 0xad, 0xc0, 0x01, 0x62, 0x2f, 0xb5, 0xe3, 0x63, 0xb4, 0x21, 0x2a, 0x22, 0x0a, + 0x20, 0x56, 0xe8, 0x1f, 0x17, 0x1b, 0xcc, 0x55, 0xa6, 0xff, 0x83, 0x45, 0xe6, 0x92, 0xc0, 0xf8, + 0x6e, 0x5b, 0x48, 0xe0, 0x1b, 0x99, 0x6c, 0xad, 0xc0, 0x01, 0x62, 0x2f, 0xb5, 0xe3, 0x63, 0xb4, + 0x21, 0x32, 0x22, 0x0a, 0x20, 0x56, 0xe8, 0x1f, 0x17, 0x1b, 0xcc, 0x55, 0xa6, 0xff, 0x83, 0x45, + 0xe6, 0x92, 0xc0, 0xf8, 0x6e, 0x5b, 0x48, 0xe0, 0x1b, 0x99, 0x6c, 0xad, 0xc0, 0x01, 0x62, 0x2f, + 0xb5, 0xe3, 0x63, 0xb4, 0x21, 0x3a, 0x22, 0x0a, 0x20, 0x56, 0xe8, 0x1f, 0x17, 0x1b, 0xcc, 0x55, + 0xa6, 0xff, 0x83, 0x45, 0xe6, 0x92, 0xc0, 0xf8, 0x6e, 0x5b, 0x48, 0xe0, 0x1b, 0x99, 0x6c, 0xad, + 0xc0, 0x01, 0x62, 0x2f, 0xb5, 0xe3, 0x63, 0xb4, 0x21, 0x3a, 0x22, 0x0a, 0x20, 0x56, 0xe8, 0x1f, + 0x17, 0x1b, 0xcc, 0x55, 0xa6, 0xff, 0x83, 0x45, 0xe6, 0x92, 0xc0, 0xf8, 0x6e, 0x5b, 0x48, 0xe0, + 0x1b, 0x99, 0x6c, 0xad, 0xc0, 0x01, 0x62, 0x2f, 0xb5, 0xe3, 0x63, 0xb4, 0x21, 0x3a, 0x22, 0x0a, + 0x20, 0x56, 0xe8, 0x1f, 0x17, 0x1b, 0xcc, 0x55, 0xa6, 0xff, 0x83, 0x45, 0xe6, 0x92, 0xc0, 0xf8, + 0x6e, 0x5b, 0x48, 0xe0, 0x1b, 0x99, 0x6c, 0xad, 0xc0, 0x01, 0x62, 0x2f, 0xb5, 0xe3, 0x63, 0xb4, + 0x21, 0x42, 0x22, 0x0a, 0x20, 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, 0x52, 0x00, 0x52, 0x00, 0x52, 0x00, 0x5a, 0x00, 0x5a, 0x00, 0x5a, + 0x00, 0x62, 0x00, 0x62, 0x00, 0x62, 0x00, 0x6a, 0x00, 0x72, 0x00, 0x72, 0x00, 0x78, 0x00, 0x80, + 0x01, 0x00, 0x8a, 0x01, 0x00, 0x9a, 0x01, 0x00, 0xb2, 0x01, 0x22, 0x0a, 0x20, 0x56, 0xe8, 0x1f, + 0x17, 0x1b, 0xcc, 0x55, 0xa6, 0xff, 0x83, 0x45, 0xe6, 0x92, 0xc0, 0xf8, 0x6e, 0x5b, 0x48, 0xe0, + 0x1b, 0x99, 0x6c, 0xad, 0xc0, 0x01, 0x62, 0x2f, 0xb5, 0xe3, 0x63, 0xb4, 0x21, 0xba, 0x01, 0x22, + 0x0a, 0x20, 0x56, 0xe8, 0x1f, 0x17, 0x1b, 0xcc, 0x55, 0xa6, 0xff, 0x83, 0x45, 0xe6, 0x92, 0xc0, + 0xf8, 0x6e, 0x5b, 0x48, 0xe0, 0x1b, 0x99, 0x6c, 0xad, 0xc0, 0x01, 0x62, 0x2f, 0xb5, 0xe3, 0x63, + 0xb4, 0x21, 0xc0, 0x01, 0x00, 0xc8, 0x01, 0x00, 0xd0, 0x01, 0x00, 0xda, 0x01, 0x22, 0x0a, 0x20, + 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, + 0xe2, 0x01, 0x22, 0x0a, 0x20, 0x56, 0xe8, 0x1f, 0x17, 0x1b, 0xcc, 0x55, 0xa6, 0xff, 0x83, 0x45, + 0xe6, 0x92, 0xc0, 0xf8, 0x6e, 0x5b, 0x48, 0xe0, 0x1b, 0x99, 0x6c, 0xad, 0xc0, 0x01, 0x62, 0x2f, + 0xb5, 0xe3, 0x63, 0xb4, 0x21, 0xea, 0x01, 0x22, 0x0a, 0x20, 0x56, 0xe8, 0x1f, 0x17, 0x1b, 0xcc, + 0x55, 0xa6, 0xff, 0x83, 0x45, 0xe6, 0x92, 0xc0, 0xf8, 0x6e, 0x5b, 0x48, 0xe0, 0x1b, 0x99, 0x6c, + 0xad, 0xc0, 0x01, 0x62, 0x2f, 0xb5, 0xe3, 0x63, 0xb4, 0x21, 0xf0, 0x01, 0x00, 0xf8, 0x01, 0x00, + 0x82, 0x02, 0x00, 0x8a, 0x02, 0x00, 0x92, 0x02, 0x00, 0x9a, 0x02, 0x00, 0xa2, 0x02, 0x00, 0x12, + 0x00, 0x1a, 0x00, 0x22, 0x00, 0x2a, 0x00, 0x32, 0x00, + } ) func TestWoHash(t *testing.T) { @@ -157,6 +269,107 @@ func TestCalcUncleHash(t *testing.T) { } } +func TestProtoEncode(t *testing.T) { + // Test data + testWo, _ := woTestData() + + // Define test cases + tests := []struct { + name string + objectType WorkObjectView + expectedBytes []byte + }{ + { + name: "PEtxObject", + objectType: PEtxObject, + expectedBytes: expectedPETXProtoBytes, + }, + { + name: "BlockObject", + objectType: BlockObject, + expectedBytes: expectedBlockProtoBytes, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // ProtoEncode the test WorkObject + protoTestWo, err := testWo.ProtoEncode(tt.objectType) + require.NoError(t, err) + + // Marshal to bytes + protoTestWoBytes, err := proto.Marshal(protoTestWo) + require.NoError(t, err) + + // Compare with expected bytes + require.Equal(t, tt.expectedBytes, protoTestWoBytes) + }) + } +} + +func TestProtoDecode(t *testing.T) { + _, testWoHash := woTestData() + + tests := []struct { + name string + objectType WorkObjectView + testBytes []byte + expectedHash common.Hash + }{ + { + "PETX", + PEtxObject, + expectedPETXProtoBytes, + testWoHash, + }, + { + "BlockObject", + BlockObject, + expectedBlockProtoBytes, + testWoHash, + }, + { + "WorkShareObject", + WorkShareObject, + expectedBlockProtoBytes, + testWoHash, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + protoWo := &ProtoWorkObject{} + err := proto.Unmarshal(tt.testBytes, protoWo) + require.NoError(t, err) + + decoded := &WorkObject{} + decoded.ProtoDecode(protoWo, common.Location{0, 0}, tt.objectType) + require.Equal(t, decoded.Hash(), tt.expectedHash) + }) + } +} + +func TestCopyWorkObject(t *testing.T) { + originalWo, expectedHash := woTestData() + + newWo := CopyWorkObject(originalWo) + + require.Equal(t, expectedHash, newWo.Hash(), "Copied work object is different from new work object") + + // Test to make sure the copy doesn't modify original. + newWo.WorkObjectHeader().SetLocation(common.Location{2, 2}) + require.NotEqual(t, expectedHash, newWo.Hash(), "WorkObject hash didn't change with a new location") + require.Equal(t, originalWo.Hash(), expectedHash, "Copied WorkObject changed values from the original") +} + +func TestNewWorkObject(t *testing.T) { + // Verify that copy is same as original. + originalWo, expectedHash := woTestData() + newWo := NewWorkObject(originalWo.WorkObjectHeader(), originalWo.Body(), originalWo.Tx()) + + require.Equal(t, expectedHash, newWo.Hash(), "NewWorkObject created a different WorkObject than the original") +} + func assertUncleHash(t *testing.T, uncleNum int, expectedUncleHash common.Hash, expectedWoHash common.Hash, shouldPass bool) { wo, _ := woTestData() wo.Body().uncles = make([]*WorkObjectHeader, uncleNum)