diff --git a/consensus/blake3pow/consensus.go b/consensus/blake3pow/consensus.go index f3943f3722..d2ec24ab8a 100644 --- a/consensus/blake3pow/consensus.go +++ b/consensus/blake3pow/consensus.go @@ -212,7 +212,7 @@ func (blake3pow *Blake3pow) VerifyUncles(chain consensus.ChainReader, block *typ // If the ancestor doesn't have any uncles, we don't have to iterate them if ancestorHeader.UncleHash() != types.EmptyUncleHash { // Need to add those uncles to the banned list too - ancestor := chain.GetWorkObject(parent) + ancestor := chain.GetWorkObjectWithWorkShares(parent) if ancestor == nil { break } diff --git a/consensus/consensus.go b/consensus/consensus.go index 7a07165e10..2d6c71fc7c 100644 --- a/consensus/consensus.go +++ b/consensus/consensus.go @@ -70,6 +70,10 @@ type ChainReader interface { // GetBlock retrieves a block from the database by hash and number. GetWorkObject(hash common.Hash) *types.WorkObject + + // GetWorkObjectWithWorkShares retrieves a block from the database by hash + // but only has header and workshares populated in the body + GetWorkObjectWithWorkShares(hash common.Hash) *types.WorkObject } type GenesisReader interface { diff --git a/consensus/progpow/consensus.go b/consensus/progpow/consensus.go index 2255b00eb8..88274d2a04 100644 --- a/consensus/progpow/consensus.go +++ b/consensus/progpow/consensus.go @@ -215,7 +215,7 @@ func (progpow *Progpow) VerifyUncles(chain consensus.ChainReader, block *types.W // If the ancestor doesn't have any uncles, we don't have to iterate them if ancestorHeader.UncleHash() != types.EmptyUncleHash { // Need to add those uncles to the banned list too - ancestor := chain.GetWorkObject(parent) + ancestor := chain.GetWorkObjectWithWorkShares(parent) if ancestor == nil { break } diff --git a/core/bodydb.go b/core/bodydb.go index cda919e8df..0e6749d524 100644 --- a/core/bodydb.go +++ b/core/bodydb.go @@ -195,6 +195,20 @@ func (bc *BodyDb) GetWorkObject(hash common.Hash) *types.WorkObject { return wo } +// GetWorkObjectWithWorkShares retrieves a workObject with workshares from the database by hash, +// caching it if found. +func (bc *BodyDb) GetWorkObjectWithWorkShares(hash common.Hash) *types.WorkObject { + termini := rawdb.ReadTermini(bc.db, hash) + if termini == nil { + return nil + } + wo := rawdb.ReadWorkObjectWithWorkShares(bc.db, hash) + if wo == nil { + return nil + } + return wo +} + // GetBlockOrCandidate retrieves any known block from the database by hash and number, // caching it if found. func (bc *BodyDb) GetBlockOrCandidate(hash common.Hash, number uint64) *types.WorkObject { diff --git a/core/headerchain.go b/core/headerchain.go index 27e8a145ef..82c4b6ac37 100644 --- a/core/headerchain.go +++ b/core/headerchain.go @@ -816,6 +816,10 @@ func (hc *HeaderChain) GetWorkObject(hash common.Hash) *types.WorkObject { return hc.bc.GetWorkObject(hash) } +func (hc *HeaderChain) GetWorkObjectWithWorkShares(hash common.Hash) *types.WorkObject { + return hc.bc.GetWorkObjectWithWorkShares(hash) +} + // CheckContext checks to make sure the range of a context or order is valid func (hc *HeaderChain) CheckContext(context int) error { if context < 0 || context > common.HierarchyDepth { diff --git a/core/rawdb/accessors_chain.go b/core/rawdb/accessors_chain.go index e63ec7232d..330f80b460 100644 --- a/core/rawdb/accessors_chain.go +++ b/core/rawdb/accessors_chain.go @@ -640,7 +640,20 @@ func ReadWorkObject(db ethdb.Reader, hash common.Hash, woType types.WorkObjectVi if workObjectHeader == nil { return nil } - workObjectBody := ReadWorkObjectBody(db, hash) + workObjectBody := ReadWorkObjectBody(db, hash, types.BlockObject) + if workObjectBody == nil { + return nil + } + return types.NewWorkObject(workObjectHeader, workObjectBody, nil) //TODO: mmtx transaction +} + +// ReadWorkObjectWithWorkShares retreive's the work object stored in hash. +func ReadWorkObjectWithWorkShares(db ethdb.Reader, hash common.Hash) *types.WorkObject { + workObjectHeader := ReadWorkObjectHeader(db, hash, types.BlockObject) + if workObjectHeader == nil { + return nil + } + workObjectBody := ReadWorkObjectBody(db, hash, types.WorkShareObject) if workObjectBody == nil { return nil } @@ -683,7 +696,7 @@ func DeleteBlockWithoutNumber(db ethdb.KeyValueWriter, hash common.Hash, number } // ReadWorkObjectBody retreive's the work object body stored in hash. -func ReadWorkObjectBody(db ethdb.Reader, hash common.Hash) *types.WorkObjectBody { +func ReadWorkObjectBody(db ethdb.Reader, hash common.Hash, woType types.WorkObjectView) *types.WorkObjectBody { key := workObjectBodyKey(hash) data, _ := db.Get(key) if len(data) == 0 { @@ -696,7 +709,7 @@ func ReadWorkObjectBody(db ethdb.Reader, hash common.Hash) *types.WorkObjectBody return nil } workObjectBody := new(types.WorkObjectBody) - err = workObjectBody.ProtoDecode(protoWorkObjectBody, db.Location()) + err = workObjectBody.ProtoDecode(protoWorkObjectBody, db.Location(), woType) if err != nil { db.Logger().WithFields(log.Fields{ "hash": hash, @@ -1049,7 +1062,7 @@ func (b *badWorkObject) ProtoDecode(pb *ProtoBadWorkObject) error { } b.woHeader = woHeader woBody := new(types.WorkObjectBody) - if err := woBody.ProtoDecode(pb.WoBody, b.woHeader.Location()); err != nil { + if err := woBody.ProtoDecode(pb.WoBody, b.woHeader.Location(), types.BlockObject); err != nil { return err } b.woBody = woBody diff --git a/core/types/wo.go b/core/types/wo.go index 61a2aa98e3..0ea3420b8e 100644 --- a/core/types/wo.go +++ b/core/types/wo.go @@ -54,6 +54,7 @@ const ( PEtxObject HeaderObject PhObject + WorkShareObject ) func (wo *WorkObject) Hash() common.Hash { @@ -795,7 +796,7 @@ func (wo *WorkObjectHeaderView) ProtoDecode(data *ProtoWorkObjectHeaderView, loc return err } wo.woBody = new(WorkObjectBody) - err = wo.woBody.ProtoDecode(data.GetWoBody(), location) + err = wo.woBody.ProtoDecode(data.GetWoBody(), location, BlockObject) if err != nil { return err } @@ -809,7 +810,7 @@ func (wob *WorkObjectBlockView) ProtoDecode(data *ProtoWorkObjectBlockView, loca return err } wob.woBody = new(WorkObjectBody) - err = wob.woBody.ProtoDecode(data.GetWoBody(), location) + err = wob.woBody.ProtoDecode(data.GetWoBody(), location, BlockObject) if err != nil { return err } @@ -835,7 +836,7 @@ func (wo *WorkObject) ProtoDecode(data *ProtoWorkObject, location common.Locatio return err } wo.woBody = new(WorkObjectBody) - err = wo.woBody.ProtoDecode(data.GetWoBody(), location) + err = wo.woBody.ProtoDecode(data.GetWoBody(), location, BlockObject) if err != nil { return err } @@ -1033,38 +1034,56 @@ func (wb *WorkObjectBody) ProtoEncode() (*ProtoWorkObjectBody, error) { }, nil } -func (wb *WorkObjectBody) ProtoDecode(data *ProtoWorkObjectBody, location common.Location) error { - wb.header = &Header{} - err := wb.header.ProtoDecode(data.GetHeader(), location) - if err != nil { - return err - } - wb.transactions = Transactions{} - err = wb.transactions.ProtoDecode(data.GetTransactions(), location) - if err != nil { - return err - } - wb.extTransactions = Transactions{} - err = wb.extTransactions.ProtoDecode(data.GetExtTransactions(), location) - if err != nil { - return err - } - wb.uncles = make([]*WorkObjectHeader, len(data.GetUncles().GetWoHeaders())) - for i, protoUncle := range data.GetUncles().GetWoHeaders() { - uncle := &WorkObjectHeader{} - err = uncle.ProtoDecode(protoUncle) +func (wb *WorkObjectBody) ProtoDecode(data *ProtoWorkObjectBody, location common.Location, woType WorkObjectView) error { + switch woType { + case WorkShareObject: + wb.header = &Header{} + err := wb.header.ProtoDecode(data.GetHeader(), location) if err != nil { return err } - wb.uncles[i] = uncle - } - wb.manifest = BlockManifest{} - err = wb.manifest.ProtoDecode(data.GetManifest()) - if err != nil { - return err + wb.uncles = make([]*WorkObjectHeader, len(data.GetUncles().GetWoHeaders())) + for i, protoUncle := range data.GetUncles().GetWoHeaders() { + uncle := &WorkObjectHeader{} + err = uncle.ProtoDecode(protoUncle) + if err != nil { + return err + } + wb.uncles[i] = uncle + } + default: + wb.header = &Header{} + err := wb.header.ProtoDecode(data.GetHeader(), location) + if err != nil { + return err + } + wb.transactions = Transactions{} + err = wb.transactions.ProtoDecode(data.GetTransactions(), location) + if err != nil { + return err + } + wb.extTransactions = Transactions{} + err = wb.extTransactions.ProtoDecode(data.GetExtTransactions(), location) + if err != nil { + return err + } + wb.uncles = make([]*WorkObjectHeader, len(data.GetUncles().GetWoHeaders())) + for i, protoUncle := range data.GetUncles().GetWoHeaders() { + uncle := &WorkObjectHeader{} + err = uncle.ProtoDecode(protoUncle) + if err != nil { + return err + } + wb.uncles[i] = uncle + } + wb.manifest = BlockManifest{} + err = wb.manifest.ProtoDecode(data.GetManifest()) + if err != nil { + return err + } + wb.interlinkHashes = common.Hashes{} + wb.interlinkHashes.ProtoDecode(data.GetInterlinkHashes()) } - wb.interlinkHashes = common.Hashes{} - wb.interlinkHashes.ProtoDecode(data.GetInterlinkHashes()) return nil }