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.
This commit is contained in:
Roman Khimov 2020-06-23 18:15:55 +03:00
parent cd2dca0259
commit e5f05790d5
9 changed files with 21 additions and 22 deletions

View file

@ -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.

View file

@ -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)

View file

@ -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")

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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)

View file

@ -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) {

View file

@ -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,