From 26dc807a2d78aa70671d76860356efef8f90493f Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Mon, 28 Sep 2020 15:29:43 +0300 Subject: [PATCH] native: initialize cache in `OnPersist` If node started from non-zero height, `Initialize` is not called thus cache is empty. Thus we should initialize it before any tx is executed. --- pkg/core/native/native_neo.go | 40 ++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/pkg/core/native/native_neo.go b/pkg/core/native/native_neo.go index e69175457..636f17a61 100644 --- a/pkg/core/native/native_neo.go +++ b/pkg/core/native/native_neo.go @@ -173,13 +173,10 @@ func (n *NEO) Initialize(ic *interop.Context) error { } committee := ic.Chain.GetStandByCommittee() - n.committee.Store(committee) - script, err := smartcontract.CreateMajorityMultiSigRedeemScript(committee.Copy()) + err := n.updateCache(committee, ic.Chain) if err != nil { return err } - n.committeeHash.Store(hash.Hash160(script)) - n.updateNextValidators(committee, ic.Chain) err = ic.DAO.PutStorageItem(n.ContractID, prefixCommittee, &state.StorageItem{Value: committee.Bytes()}) if err != nil { @@ -207,10 +204,18 @@ func (n *NEO) Initialize(ic *interop.Context) error { return nil } -func (n *NEO) updateNextValidators(committee keys.PublicKeys, bc blockchainer.Blockchainer) { +func (n *NEO) updateCache(committee keys.PublicKeys, bc blockchainer.Blockchainer) error { + n.committee.Store(committee) + script, err := smartcontract.CreateMajorityMultiSigRedeemScript(committee.Copy()) + if err != nil { + return err + } + n.committeeHash.Store(hash.Hash160(script)) + nextVals := committee[:bc.GetConfig().ValidatorsCount].Copy() sort.Sort(nextVals) n.nextValidators.Store(nextVals) + return nil } func (n *NEO) updateCommittee(ic *interop.Context) error { @@ -226,13 +231,9 @@ func (n *NEO) updateCommittee(ic *interop.Context) error { if err != nil { return err } - n.committee.Store(committee) - script, err := smartcontract.CreateMajorityMultiSigRedeemScript(committee.Copy()) - if err != nil { + if err := n.updateCache(committee, ic.Chain); err != nil { return err } - n.committeeHash.Store(hash.Hash160(script)) - n.updateNextValidators(committee, ic.Chain) n.votesChanged.Store(false) si := &state.StorageItem{Value: committee.Bytes()} return ic.DAO.PutStorageItem(n.ContractID, prefixCommittee, si) @@ -246,6 +247,25 @@ func shouldUpdateCommittee(h uint32, bc blockchainer.Blockchainer) bool { // OnPersist implements Contract interface. func (n *NEO) OnPersist(ic *interop.Context) error { + gpb := n.gasPerBlockChanged.Load() + if gpb == nil { + committee := keys.PublicKeys{} + si := ic.DAO.GetStorageItem(n.ContractID, prefixCommittee) + if err := committee.DecodeBytes(si.Value); err != nil { + return err + } + if err := n.updateCache(committee, ic.Chain); err != nil { + return err + } + + var gr state.GASRecord + si = ic.DAO.GetStorageItem(n.ContractID, []byte{prefixGASPerBlock}) + if err := gr.FromBytes(si.Value); err != nil { + return err + } + n.gasPerBlock.Store(gr) + n.gasPerBlockChanged.Store(false) + } if shouldUpdateCommittee(ic.Block.Index, ic.Chain) { if err := n.updateCommittee(ic); err != nil { return err