From eedba260ce2def0b7112a3e5cb60ebd727ded609 Mon Sep 17 00:00:00 2001 From: jiangzehua <1092431698@qq.com> Date: Tue, 19 Apr 2022 18:40:18 +0800 Subject: [PATCH] refactor(dpos2.0): transaction storage refactored --- benchmark/tools/generator/chain/datagen.go | 7 +++- blockchain/blockchain.go | 17 +++++--- blockchain/chainio.go | 21 +++++++++- blockchain/chainstore.go | 23 ++++++++++- blockchain/chainstoreffldb.go | 40 +++---------------- blockchain/indexers/tx3index.go | 1 + blockchain/ledgerstore.go | 2 +- core/transaction/bucketname.go | 8 ++++ .../crcproposalreviewtransaction.go | 9 +++++ .../crcproposaltrackingtransaction.go | 25 +++++++++--- core/transaction/crcproposaltransaction.go | 9 +++++ core/transaction/transaction.go | 1 + core/transaction/transactionprocesser.go | 20 ++++++++++ core/types/interfaces/basetransaction.go | 1 + .../transactionprocessorinterface.go | 15 +++++++ cr/state/committee.go | 4 +- database/ffldb/db.go | 14 +------ database/interface.go | 5 ++- elanet/netsync/manager.go | 4 +- test/unit/dposstate_test.go | 6 +-- 20 files changed, 161 insertions(+), 71 deletions(-) create mode 100644 core/transaction/bucketname.go create mode 100644 core/transaction/transactionprocesser.go create mode 100644 core/types/interfaces/transactionprocessorinterface.go diff --git a/benchmark/tools/generator/chain/datagen.go b/benchmark/tools/generator/chain/datagen.go index c7de381ae..f31d3c797 100644 --- a/benchmark/tools/generator/chain/datagen.go +++ b/benchmark/tools/generator/chain/datagen.go @@ -205,8 +205,13 @@ func (g *DataGen) generateBlock( func (g *DataGen) storeData(block *types.Block) error { blockHash := block.Hash() newNode := blockchain.NewBlockNode(&block.Header, &blockHash) + + ps, err := blockchain.GetProcessorsFromBlock(block) + if err != nil { + return err + } if err := g.chain.GetDB().GetFFLDB().SaveBlock(block, newNode, - nil, time.Unix(int64(block.Timestamp), 0)); err != nil { + nil, time.Unix(int64(block.Timestamp), 0), ps); err != nil { return err } diff --git a/blockchain/blockchain.go b/blockchain/blockchain.go index fe2c65bdc..8c81a6cb1 100644 --- a/blockchain/blockchain.go +++ b/blockchain/blockchain.go @@ -201,14 +201,14 @@ func (b *BlockChain) MigrateOldDB( if start >= params.CRCOnlyDPOSHeight { confirm, err = b.db.GetConfirm(hash) if err != nil { - done <- fmt.Errorf("GetConfirm err: %s", err) + done <- fmt.Errorf("get confirm err: %s", err) break } } node, err := b.LoadBlockNode(&block.Header, &hash) if err != nil { - done <- fmt.Errorf("LoadBlockNode err: %s", err) + done <- fmt.Errorf("load block node err: %s", err) break } b.SetTip(node) @@ -216,20 +216,25 @@ func (b *BlockChain) MigrateOldDB( b.index.SetFlags(&block.Header, statusDataStored) err = b.index.flushToDB() if err != nil { - done <- fmt.Errorf("flushToDB err: %s", err) + done <- fmt.Errorf("flusht to DB err: %s", err) break } - err = b.db.GetFFLDB().SaveBlock(block, node, confirm, CalcPastMedianTime(node)) + ps, err := GetProcessorsFromBlock(block) if err != nil { - done <- fmt.Errorf("SaveBlock err: %s", err) + done <- fmt.Errorf("get processors err: %s", err) + break + } + err = b.db.GetFFLDB().SaveBlock(block, node, confirm, CalcPastMedianTime(node), ps) + if err != nil { + done <- fmt.Errorf("save block err: %s", err) break } b.index.SetFlags(&block.Header, statusDataStored|statusValid) err = b.index.flushToDB() if err != nil { - done <- fmt.Errorf("flushToDB err: %s", err) + done <- fmt.Errorf("flush to DB err: %s", err) break } diff --git a/blockchain/chainio.go b/blockchain/chainio.go index a2d837b33..f8d585a34 100644 --- a/blockchain/chainio.go +++ b/blockchain/chainio.go @@ -14,6 +14,7 @@ package blockchain import ( "bytes" "encoding/binary" + "errors" "fmt" common2 "github.com/elastos/Elastos.ELA/core/types/common" "math/big" @@ -233,7 +234,16 @@ func dbStoreBlock(dbTx database.Tx, block *types.DposBlock) error { if hasBlock { return nil } - return dbTx.StoreBlock(block) + + buf := new(bytes.Buffer) + err = block.Serialize(buf) + if err != nil { + str := fmt.Sprintf("failed to get serialized bytes for block %s", + blockHash) + return errors.New(str) + } + + return dbTx.StoreBlock(blockHash, buf.Bytes()) } // ----------------------------------------------------------------------------- @@ -283,6 +293,15 @@ func dbPutProposalDraftData(dbTx database.Tx, hash *common.Uint256, draftData [] return draftDataBucket.Put(hash[:], draftData) } +// dbPutData store data to ffldb. +func DBPutData(dbTx database.Tx, name []byte, key []byte, value []byte) error { + // Add the block hash to height mapping to the index. + meta := dbTx.Metadata() + // Add the block height to hash mapping to the index. + dataBucket := meta.Bucket(name) + return dataBucket.Put(key, value) +} + // dbFetchProposalDraftData get the proposal draft data by draft hash. func dbFetchProposalDraftData(dbTx database.Tx, hash *common.Uint256) ([]byte, error) { meta := dbTx.Metadata() diff --git a/blockchain/chainstore.go b/blockchain/chainstore.go index 809ea8701..bcdc49b37 100644 --- a/blockchain/chainstore.go +++ b/blockchain/chainstore.go @@ -9,7 +9,7 @@ import ( "bytes" "encoding/hex" "errors" - "github.com/elastos/Elastos.ELA/core/types/functions" + "github.com/elastos/Elastos.ELA/database" "path/filepath" "sync" "sync/atomic" @@ -20,6 +20,7 @@ import ( "github.com/elastos/Elastos.ELA/common/log" . "github.com/elastos/Elastos.ELA/core/types" "github.com/elastos/Elastos.ELA/core/types/common" + "github.com/elastos/Elastos.ELA/core/types/functions" "github.com/elastos/Elastos.ELA/core/types/interfaces" "github.com/elastos/Elastos.ELA/core/types/payload" _ "github.com/elastos/Elastos.ELA/database/ffldb" @@ -215,12 +216,30 @@ func (c *ChainStore) rollback(b *Block, node *BlockNode, return nil } +func GetProcessorsFromBlock(b *Block) ([]database.TXProcessor, error) { + ps := make([]database.TXProcessor, 0) + for _, t := range b.Transactions { + processor, err := t.GetProcessor() + if err != nil { + return nil, err + } + if processor != nil { + ps = append(ps, processor) + } + } + return ps, nil +} + func (c *ChainStore) persist(b *Block, node *BlockNode, confirm *payload.Confirm, medianTimePast time.Time) error { c.persistMutex.Lock() defer c.persistMutex.Unlock() - if err := c.fflDB.SaveBlock(b, node, confirm, medianTimePast); err != nil { + ps, err := GetProcessorsFromBlock(b) + if err != nil { + return err + } + if err := c.fflDB.SaveBlock(b, node, confirm, medianTimePast, ps); err != nil { return err } return nil diff --git a/blockchain/chainstoreffldb.go b/blockchain/chainstoreffldb.go index 8516004d1..9a2407e45 100644 --- a/blockchain/chainstoreffldb.go +++ b/blockchain/chainstoreffldb.go @@ -133,37 +133,6 @@ func (c *ChainStoreFFLDB) Close() error { return c.db.Close() } -func ProcessProposalDraftData(dbTx database.Tx, Transactions []interfaces.Transaction) (err error) { - for _, tx := range Transactions { - switch tx.TxType() { - case common.CRCProposal: - proposal := tx.Payload().(*payload.CRCProposal) - err = dbPutProposalDraftData(dbTx, &proposal.DraftHash, proposal.DraftData) - if err != nil { - return err - } - case common.CRCProposalTracking: - proposalTracking := tx.Payload().(*payload.CRCProposalTracking) - err = dbPutProposalDraftData(dbTx, &proposalTracking.SecretaryGeneralOpinionHash, - proposalTracking.SecretaryGeneralOpinionData) - if err != nil { - return err - } - err = dbPutProposalDraftData(dbTx, &proposalTracking.MessageHash, proposalTracking.MessageData) - if err != nil { - return err - } - case common.CRCProposalReview: - proposalReview := tx.Payload().(*payload.CRCProposalReview) - err = dbPutProposalDraftData(dbTx, &proposalReview.OpinionHash, proposalReview.OpinionData) - if err != nil { - return err - } - } - } - return err -} - func RollbackProcessProposalDraftData(dbTx database.Tx, Transactions []interfaces.Transaction) (err error) { for _, tx := range Transactions { switch tx.TxType() { @@ -195,7 +164,7 @@ func RollbackProcessProposalDraftData(dbTx database.Tx, Transactions []interface } func (c *ChainStoreFFLDB) SaveBlock(b *Block, node *BlockNode, - confirm *payload.Confirm, medianTimePast time.Time) error { + confirm *payload.Confirm, medianTimePast time.Time, ps []database.TXProcessor) error { err := c.db.Update(func(dbTx database.Tx) error { return dbStoreBlock(dbTx, &DposBlock{ @@ -231,8 +200,11 @@ func (c *ChainStoreFFLDB) SaveBlock(b *Block, node *BlockNode, return err } - if b.Height >= c.params.ChangeCommitteeNewCRHeight { - ProcessProposalDraftData(dbTx, b.Transactions) + for _, processor := range ps { + err = processor(dbTx) + if err != nil { + return err + } } // Allow the index manager to call each of the currently active diff --git a/blockchain/indexers/tx3index.go b/blockchain/indexers/tx3index.go index a52730070..e8d3e26cb 100644 --- a/blockchain/indexers/tx3index.go +++ b/blockchain/indexers/tx3index.go @@ -135,6 +135,7 @@ func (idx *Tx3Index) ConnectBlock(dbTx database.Tx, block *types.Block) error { } } } + return nil } diff --git a/blockchain/ledgerstore.go b/blockchain/ledgerstore.go index 9df91959e..0ba1cc0aa 100644 --- a/blockchain/ledgerstore.go +++ b/blockchain/ledgerstore.go @@ -57,7 +57,7 @@ type IFFLDBChainStore interface { // SaveBlock will write block into file DB. SaveBlock(b *Block, node *BlockNode, confirm *payload.Confirm, - medianTimePast time.Time) error + medianTimePast time.Time, ps []database.TXProcessor) error // RollbackBlock only remove block state and block index. RollbackBlock(b *Block, node *BlockNode, diff --git a/core/transaction/bucketname.go b/core/transaction/bucketname.go new file mode 100644 index 000000000..97f26b347 --- /dev/null +++ b/core/transaction/bucketname.go @@ -0,0 +1,8 @@ +package transaction + +var ( + + // proposalDraftDataBucketName is the name of the DB bucket used to house the + // proposal releated draft data and draft hash. + proposalDraftDataBucketName = []byte("proposaldraftdata") +) \ No newline at end of file diff --git a/core/transaction/crcproposalreviewtransaction.go b/core/transaction/crcproposalreviewtransaction.go index f9d10440d..937cb68c0 100644 --- a/core/transaction/crcproposalreviewtransaction.go +++ b/core/transaction/crcproposalreviewtransaction.go @@ -9,6 +9,7 @@ import ( "bytes" "errors" "fmt" + "github.com/elastos/Elastos.ELA/database" "github.com/elastos/Elastos.ELA/blockchain" "github.com/elastos/Elastos.ELA/common" @@ -109,3 +110,11 @@ func (t *CRCProposalReviewTransaction) SpecialContextCheck() (result elaerr.ELAE } return nil, false } + +func (t *CRCProposalReviewTransaction) Process() (database.TXProcessor, elaerr.ELAError) { + proposalReview := t.Payload().(*payload.CRCProposalReview) + return func(tx database.Tx) error { + return blockchain.DBPutData(tx, proposalDraftDataBucketName, + proposalReview.OpinionHash[:], proposalReview.OpinionData) + }, nil +} diff --git a/core/transaction/crcproposaltrackingtransaction.go b/core/transaction/crcproposaltrackingtransaction.go index b2c2cdf21..74742caca 100644 --- a/core/transaction/crcproposaltrackingtransaction.go +++ b/core/transaction/crcproposaltrackingtransaction.go @@ -10,6 +10,7 @@ import ( "encoding/hex" "errors" "fmt" + "github.com/elastos/Elastos.ELA/database" "github.com/elastos/Elastos.ELA/blockchain" "github.com/elastos/Elastos.ELA/common" @@ -82,7 +83,7 @@ func (t *CRCProposalTrackingTransaction) SpecialContextCheck() (result elaerr.EL } tempMessageHash := common.Hash(cptPayload.MessageData) if !cptPayload.MessageHash.IsEqual(tempMessageHash) { - return elaerr.Simple(elaerr.ErrTxPayload, errors.New("the message data and message hash of" + + return elaerr.Simple(elaerr.ErrTxPayload, errors.New("the message data and message hash of"+ " proposal tracking are inconsistent")), true } if len(cptPayload.SecretaryGeneralOpinionData) >= payload.MaxSecretaryGeneralOpinionDataSize { @@ -90,7 +91,7 @@ func (t *CRCProposalTrackingTransaction) SpecialContextCheck() (result elaerr.EL } tempOpinionHash := common.Hash(cptPayload.SecretaryGeneralOpinionData) if !cptPayload.SecretaryGeneralOpinionHash.IsEqual(tempOpinionHash) { - return elaerr.Simple(elaerr.ErrTxPayload, errors.New("the opinion data and opinion hash of" + + return elaerr.Simple(elaerr.ErrTxPayload, errors.New("the opinion data and opinion hash of"+ " proposal tracking are inconsistent")), true } } @@ -151,7 +152,6 @@ func (t *CRCProposalTrackingTransaction) checkCRCProposalCommonTracking( return t.normalCheckCRCProposalTrackingSignature(t.parameters, cptPayload, pState, payloadVersion) } - func (t *CRCProposalTrackingTransaction) normalCheckCRCProposalTrackingSignature( params *TransactionParameters, cptPayload *payload.CRCProposalTracking, pState *crstate.ProposalState, payloadVersion byte) error { @@ -285,7 +285,6 @@ func (t *CRCProposalTrackingTransaction) checkCRCProposalProgressTracking( return t.normalCheckCRCProposalTrackingSignature(t.parameters, cptPayload, pState, payloadVersion) } - func (t *CRCProposalTrackingTransaction) checkCRCProposalRejectedTracking( params *TransactionParameters, cptPayload *payload.CRCProposalTracking, pState *crstate.ProposalState, blockHeight uint32, payloadVersion byte) error { @@ -373,4 +372,20 @@ func (t *CRCProposalTrackingTransaction) checkCRCProposalFinalizedTracking( // Check signature. return t.normalCheckCRCProposalTrackingSignature(t.parameters, cptPayload, pState, payloadVersion) -} \ No newline at end of file +} + +func (t *CRCProposalTrackingTransaction) Process() (database.TXProcessor, elaerr.ELAError) { + proposalTracking := t.Payload().(*payload.CRCProposalTracking) + + return func(tx database.Tx) error { + err := blockchain.DBPutData(tx, proposalDraftDataBucketName, + proposalTracking.SecretaryGeneralOpinionHash[:], + proposalTracking.SecretaryGeneralOpinionData) + if err != nil { + return err + } + + return blockchain.DBPutData(tx, proposalDraftDataBucketName, + proposalTracking.MessageHash[:], proposalTracking.MessageData) + }, nil +} diff --git a/core/transaction/crcproposaltransaction.go b/core/transaction/crcproposaltransaction.go index 827ad9ee1..e9a4bed08 100644 --- a/core/transaction/crcproposaltransaction.go +++ b/core/transaction/crcproposaltransaction.go @@ -9,6 +9,7 @@ import ( "bytes" "errors" "fmt" + "github.com/elastos/Elastos.ELA/database" "sort" "github.com/elastos/Elastos.ELA/blockchain" @@ -669,3 +670,11 @@ func (t *CRCProposalTransaction) checkNormalOrELIPProposal(params *TransactionPa crCouncilMember := t.parameters.BlockChain.GetCRCommittee().GetMember(proposal.CRCouncilMemberDID) return t.checkOwnerAndCRCouncilMemberSign(proposal, crCouncilMember.Info.Code, PayloadVersion) } + +func (t *CRCProposalTransaction) Process() (database.TXProcessor, elaerr.ELAError) { + proposal := t.Payload().(*payload.CRCProposal) + return func(tx database.Tx) error { + return blockchain.DBPutData(tx, proposalDraftDataBucketName, + proposal.DraftHash[:], proposal.DraftData) + }, nil +} diff --git a/core/transaction/transaction.go b/core/transaction/transaction.go index c4e5f2129..fcbc6efca 100644 --- a/core/transaction/transaction.go +++ b/core/transaction/transaction.go @@ -25,6 +25,7 @@ const ( type BaseTransaction struct { DefaultChecker + DefaultProcessor version common2.TransactionVersion // New field added in TxVersion09 txType common2.TxType diff --git a/core/transaction/transactionprocesser.go b/core/transaction/transactionprocesser.go new file mode 100644 index 000000000..aa6ba8005 --- /dev/null +++ b/core/transaction/transactionprocesser.go @@ -0,0 +1,20 @@ +// Copyright (c) 2017-2021 The Elastos Foundation +// Use of this source code is governed by an MIT +// license that can be found in the LICENSE file. +// + +package transaction + +import ( + "github.com/elastos/Elastos.ELA/database" + elaerr "github.com/elastos/Elastos.ELA/errors" +) + +type DefaultProcessor struct { +} + +func (t *DefaultProcessor) GetProcessor() (database.TXProcessor, elaerr.ELAError) { + + // todo process transaction + return nil, nil +} diff --git a/core/types/interfaces/basetransaction.go b/core/types/interfaces/basetransaction.go index 572afa903..2b54aec4b 100644 --- a/core/types/interfaces/basetransaction.go +++ b/core/types/interfaces/basetransaction.go @@ -15,6 +15,7 @@ import ( type Transaction interface { TransactionChecker + TransactionProcessor // get data Version() common2.TransactionVersion diff --git a/core/types/interfaces/transactionprocessorinterface.go b/core/types/interfaces/transactionprocessorinterface.go new file mode 100644 index 000000000..0e906e3c8 --- /dev/null +++ b/core/types/interfaces/transactionprocessorinterface.go @@ -0,0 +1,15 @@ +// Copyright (c) 2017-2021 The Elastos Foundation +// Use of this source code is governed by an MIT +// license that can be found in the LICENSE file. +// + +package interfaces + +import ( + "github.com/elastos/Elastos.ELA/database" + elaerr "github.com/elastos/Elastos.ELA/errors" +) + +type TransactionProcessor interface { + GetProcessor() (database.TXProcessor, elaerr.ELAError) +} diff --git a/cr/state/committee.go b/cr/state/committee.go index 20127a2ac..2ca8d1b43 100644 --- a/cr/state/committee.go +++ b/cr/state/committee.go @@ -1430,10 +1430,10 @@ func (c *Committee) changeCommitteeMembers(height uint32) error { }) return errors.New("candidates count less than required count Height" + strconv.Itoa(int(height))) } - // Process current members. + // GetProcessor current members. newMembers := c.processCurrentMembersHistory(height, candidates) - // Process current candidates. + // GetProcessor current candidates. c.processCurrentCandidates(height, candidates, newMembers) oriLastCommitteeHeight := c.LastCommitteeHeight diff --git a/database/ffldb/db.go b/database/ffldb/db.go index 0b7cb6e3b..fa696868e 100644 --- a/database/ffldb/db.go +++ b/database/ffldb/db.go @@ -18,7 +18,6 @@ import ( "sync" "github.com/elastos/Elastos.ELA/common" - "github.com/elastos/Elastos.ELA/core/types" "github.com/elastos/Elastos.ELA/database" "github.com/elastos/Elastos.ELA/database/internal/treap" @@ -1148,7 +1147,7 @@ func (tx *transaction) hasBlock(hash common.Uint256) bool { // - ErrTxClosed if the transaction has already been closed // // This function is part of the database.Tx interface implementation. -func (tx *transaction) StoreBlock(block *types.DposBlock) error { +func (tx *transaction) StoreBlock(blockHash common.Uint256, data []byte) error { // Ensure transaction state is valid. if err := tx.checkClosed(); err != nil { return err @@ -1161,20 +1160,11 @@ func (tx *transaction) StoreBlock(block *types.DposBlock) error { } // Reject the block if it already exists. - blockHash := block.Hash() if tx.hasBlock(blockHash) { str := fmt.Sprintf("block %s already exists", blockHash) return makeDbErr(database.ErrBlockExists, str, nil) } - buf := new(bytes.Buffer) - err := block.Serialize(buf) - if err != nil { - str := fmt.Sprintf("failed to get serialized bytes for block %s", - blockHash) - return makeDbErr(database.ErrDriverSpecific, str, err) - } - // Add the block to be stored to the list of pending blocks to store // when the transaction is committed. Also, add it to pending blocks // map so it is easy to determine the block is pending based on the @@ -1185,7 +1175,7 @@ func (tx *transaction) StoreBlock(block *types.DposBlock) error { tx.pendingBlocks[blockHash] = len(tx.pendingBlockData) tx.pendingBlockData = append(tx.pendingBlockData, pendingBlock{ hash: &blockHash, - bytes: buf.Bytes(), + bytes: data, }) log.Debugf("Added block %s to pending blocks", blockHash) diff --git a/database/interface.go b/database/interface.go index 3613f287f..fa7c05a00 100644 --- a/database/interface.go +++ b/database/interface.go @@ -12,7 +12,6 @@ package database import ( "github.com/elastos/Elastos.ELA/common" - "github.com/elastos/Elastos.ELA/core/types" ) // Cursor represents a cursor over key/value pairs and nested buckets of a @@ -206,6 +205,8 @@ type BlockRegion struct { Len uint32 } +type TXProcessor func(tx Tx) error + // Tx represents a database transaction. It can either by read-only or // read-write. The transaction provides a metadata bucket against which all // read and writes occur. @@ -230,7 +231,7 @@ type Tx interface { // - ErrTxClosed if the transaction has already been closed // // Other errors are possible depending on the implementation. - StoreBlock(block *types.DposBlock) error + StoreBlock(blockHash common.Uint256, data []byte) error // HasBlock returns whether or not a block with the given hash exists // in the database. diff --git a/elanet/netsync/manager.go b/elanet/netsync/manager.go index 576683963..a5deb1bc4 100644 --- a/elanet/netsync/manager.go +++ b/elanet/netsync/manager.go @@ -317,7 +317,7 @@ func (sm *SyncManager) handleTxMsg(tmsg *txMsg) { delete(state.requestedTxns, txHash) delete(sm.requestedTxns, txHash) - // Process the transaction to include validation, insertion in the + // GetProcessor the transaction to include validation, insertion in the // memory pool, orphan handling, etc. err := sm.txMemPool.AppendToTxPool(tmsg.tx) if err != nil { @@ -413,7 +413,7 @@ func (sm *SyncManager) handleBlockMsg(bmsg *blockMsg) { } } - // Process the block to include validation, best chain selection, orphan + // GetProcessor the block to include validation, best chain selection, orphan // handling, etc. log.Debugf("Receive block %s at height %d", blockHash, bmsg.block.Block.Height) diff --git a/test/unit/dposstate_test.go b/test/unit/dposstate_test.go index 0731bb46c..108088b2e 100644 --- a/test/unit/dposstate_test.go +++ b/test/unit/dposstate_test.go @@ -583,7 +583,7 @@ func TestState_ProcessIllegalBlockEvidence(t *testing.T) { t.FailNow() } - // Process next height, state will rollback illegal producer. + // GetProcessor next height, state will rollback illegal producer. state.ProcessBlock(mockBlock(11), nil) // At this point, we have 4 pending, 6 active and 10 in total producers. if !assert.Equal(t, 4, len(state.GetPendingProducers())) { @@ -642,7 +642,7 @@ func TestState_ProcessEmergencyInactiveArbitrators(t *testing.T) { t.FailNow() } - // Process next height, state will rollback illegal producer. + // GetProcessor next height, state will rollback illegal producer. state.ProcessBlock(mockBlock(11), nil) // At this point, we have 4 pending, 6 active and 10 in total producers. if !assert.Equal(t, 4, len(state.GetPendingProducers())) { @@ -835,7 +835,7 @@ func TestState_GetHistory(t *testing.T) { t.FailNow() } - // Process a new height see if state go to best height. + // GetProcessor a new height see if state go to best height. state.ProcessBlock(mockBlock(15, tx), nil) // At this point, we have 1 canceled, 0 pending, 8 active, 1 illegal and 8 in total producers. if !assert.Equal(t, 1, len(state.GetCanceledProducers())) {