From e5f05790d5a329874a0b7cdfac97b3c724081964 Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Tue, 23 Jun 2020 18:15:55 +0300 Subject: [PATCH] core: cache standby validators in the Blockchain They never change, so it makes no sense parsing the keys over and over again. It also simplifies the interface a little. --- pkg/core/blockchain.go | 13 +++++++++++-- pkg/core/blockchainer/blockchainer.go | 2 +- pkg/core/helper_test.go | 7 ++----- pkg/core/native/native_gas.go | 5 +---- pkg/core/native/native_neo.go | 5 +---- pkg/core/util.go | 4 ++-- pkg/core/util_test.go | 2 +- pkg/network/helper_test.go | 2 +- pkg/rpc/server/server_test.go | 3 +-- 9 files changed, 21 insertions(+), 22 deletions(-) diff --git a/pkg/core/blockchain.go b/pkg/core/blockchain.go index 5824a0649..56123da5e 100644 --- a/pkg/core/blockchain.go +++ b/pkg/core/blockchain.go @@ -117,6 +117,8 @@ type Blockchain struct { // cache for block verification keys. keyCache map[util.Uint160]map[string]*keys.PublicKey + sbValidators keys.PublicKeys + log *zap.Logger lastBatch *storage.MemBatch @@ -152,6 +154,10 @@ func NewBlockchain(s storage.Store, cfg config.ProtocolConfiguration, log *zap.L cfg.MemPoolSize = defaultMemPoolSize log.Info("mempool size is not set or wrong, setting default value", zap.Int("MemPoolSize", cfg.MemPoolSize)) } + validators, err := validatorsFromConfig(cfg) + if err != nil { + return nil, err + } bc := &Blockchain{ config: cfg, dao: dao.NewSimple(s, cfg.Magic), @@ -161,6 +167,7 @@ func NewBlockchain(s storage.Store, cfg config.ProtocolConfiguration, log *zap.L runToExitCh: make(chan struct{}), memPool: mempool.NewMemPool(cfg.MemPoolSize), keyCache: make(map[util.Uint160]map[string]*keys.PublicKey), + sbValidators: validators, log: log, events: make(chan bcEvent), subCh: make(chan interface{}), @@ -1235,8 +1242,10 @@ func (bc *Blockchain) PoolTx(t *transaction.Transaction) error { } //GetStandByValidators returns validators from the configuration. -func (bc *Blockchain) GetStandByValidators() (keys.PublicKeys, error) { - return getValidators(bc.config) +func (bc *Blockchain) GetStandByValidators() keys.PublicKeys { + res := make(keys.PublicKeys, len(bc.sbValidators)) + copy(res, bc.sbValidators) + return res } // GetValidators returns next block validators. diff --git a/pkg/core/blockchainer/blockchainer.go b/pkg/core/blockchainer/blockchainer.go index bbe30a972..ef667c51e 100644 --- a/pkg/core/blockchainer/blockchainer.go +++ b/pkg/core/blockchainer/blockchainer.go @@ -37,7 +37,7 @@ type Blockchainer interface { GetNEP5TransferLog(util.Uint160) *state.NEP5TransferLog GetNEP5Balances(util.Uint160) *state.NEP5Balances GetValidators() ([]*keys.PublicKey, error) - GetStandByValidators() (keys.PublicKeys, error) + GetStandByValidators() keys.PublicKeys GetScriptHashesForVerifying(*transaction.Transaction) ([]util.Uint160, error) GetStorageItem(id int32, key []byte) *state.StorageItem GetStorageItems(id int32) (map[string]*state.StorageItem, error) diff --git a/pkg/core/helper_test.go b/pkg/core/helper_test.go index c27c1ec10..fb16b2f43 100644 --- a/pkg/core/helper_test.go +++ b/pkg/core/helper_test.go @@ -48,7 +48,7 @@ func (bc *Blockchain) newBlock(txs ...*transaction.Transaction) *block.Block { } func newBlock(cfg config.ProtocolConfiguration, index uint32, prev util.Uint256, txs ...*transaction.Transaction) *block.Block { - validators, _ := getValidators(cfg) + validators, _ := validatorsFromConfig(cfg) vlen := len(validators) valScript, _ := smartcontract.CreateMultiSigRedeemScript( vlen-(vlen-1)/3, @@ -399,10 +399,7 @@ func addCosigners(txs ...*transaction.Transaction) { } func signTx(bc *Blockchain, txs ...*transaction.Transaction) error { - validators, err := getValidators(bc.config) - if err != nil { - return errors.Wrap(err, "fail to sign tx") - } + validators := bc.GetStandByValidators() rawScript, err := smartcontract.CreateMultiSigRedeemScript(len(bc.config.StandbyValidators)/2+1, validators) if err != nil { return errors.Wrap(err, "fail to sign tx") diff --git a/pkg/core/native/native_gas.go b/pkg/core/native/native_gas.go index 2e1e57ada..d5eef961c 100644 --- a/pkg/core/native/native_gas.go +++ b/pkg/core/native/native_gas.go @@ -101,10 +101,7 @@ func (g *GAS) OnPersist(ic *interop.Context) error { } func getStandbyValidatorsHash(ic *interop.Context) (util.Uint160, []*keys.PublicKey, error) { - vs, err := ic.Chain.GetStandByValidators() - if err != nil { - return util.Uint160{}, nil, err - } + vs := ic.Chain.GetStandByValidators() s, err := smartcontract.CreateMultiSigRedeemScript(len(vs)/2+1, vs) if err != nil { return util.Uint160{}, nil, err diff --git a/pkg/core/native/native_neo.go b/pkg/core/native/native_neo.go index 7a9c7513c..eed219825 100644 --- a/pkg/core/native/native_neo.go +++ b/pkg/core/native/native_neo.go @@ -384,10 +384,7 @@ func (n *NEO) getRegisteredValidatorsCall(ic *interop.Context, _ []stackitem.Ite // GetValidatorsInternal returns a list of current validators. func (n *NEO) GetValidatorsInternal(bc blockchainer.Blockchainer, d dao.DAO) (keys.PublicKeys, error) { - standByValidators, err := bc.GetStandByValidators() - if err != nil { - return nil, err - } + standByValidators := bc.GetStandByValidators() si := d.GetStorageItem(n.ContractID, validatorsCountKey) if si == nil { return standByValidators, nil diff --git a/pkg/core/util.go b/pkg/core/util.go index de081004f..339422900 100644 --- a/pkg/core/util.go +++ b/pkg/core/util.go @@ -34,7 +34,7 @@ var ( // createGenesisBlock creates a genesis block based on the given configuration. func createGenesisBlock(cfg config.ProtocolConfiguration) (*block.Block, error) { - validators, err := getValidators(cfg) + validators, err := validatorsFromConfig(cfg) if err != nil { return nil, err } @@ -91,7 +91,7 @@ func deployNativeContracts(magic netmode.Magic) *transaction.Transaction { return tx } -func getValidators(cfg config.ProtocolConfiguration) ([]*keys.PublicKey, error) { +func validatorsFromConfig(cfg config.ProtocolConfiguration) ([]*keys.PublicKey, error) { validators := make([]*keys.PublicKey, len(cfg.StandbyValidators)) for i, pubKeyStr := range cfg.StandbyValidators { pubKey, err := keys.NewPublicKeyFromString(pubKeyStr) diff --git a/pkg/core/util_test.go b/pkg/core/util_test.go index 9d5002742..de438e42c 100644 --- a/pkg/core/util_test.go +++ b/pkg/core/util_test.go @@ -34,7 +34,7 @@ func TestGetConsensusAddressMainNet(t *testing.T) { cfg, err := config.Load("../../config", netmode.MainNet) require.NoError(t, err) - validators, err := getValidators(cfg.ProtocolConfiguration) + validators, err := validatorsFromConfig(cfg.ProtocolConfiguration) require.NoError(t, err) script, err := getNextConsensusAddress(validators) diff --git a/pkg/network/helper_test.go b/pkg/network/helper_test.go index cf7f39e2a..e09ae2727 100644 --- a/pkg/network/helper_test.go +++ b/pkg/network/helper_test.go @@ -85,7 +85,7 @@ func (chain testChain) GetNEP5Balances(util.Uint160) *state.NEP5Balances { func (chain testChain) GetValidators() ([]*keys.PublicKey, error) { panic("TODO") } -func (chain testChain) GetStandByValidators() (keys.PublicKeys, error) { +func (chain testChain) GetStandByValidators() keys.PublicKeys { panic("TODO") } func (chain testChain) GetEnrollments() ([]state.Validator, error) { diff --git a/pkg/rpc/server/server_test.go b/pkg/rpc/server/server_test.go index f4b38862c..4ab2361e4 100644 --- a/pkg/rpc/server/server_test.go +++ b/pkg/rpc/server/server_test.go @@ -577,8 +577,7 @@ var rpcTestCases = map[string][]rpcTestCase{ }, check: func(t *testing.T, e *executor, validators interface{}) { var expected []result.Validator - sBValidators, err := e.chain.GetStandByValidators() - require.NoError(t, err) + sBValidators := e.chain.GetStandByValidators() for _, sbValidator := range sBValidators { expected = append(expected, result.Validator{ PublicKey: *sbValidator,