Merge pull request #1447 from nspcc-dev/core/fix_neo_cache

core: fix cache for (NEO).nextValidators and (NEO).committee
This commit is contained in:
Roman Khimov 2020-10-02 17:09:43 +03:00 committed by GitHub
commit 8e146d19b3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 35 additions and 25 deletions

View file

@ -253,6 +253,11 @@ func (bc *Blockchain) init() error {
} }
} }
err = bc.contracts.NEO.InitializeCache(bc, bc.dao)
if err != nil {
return fmt.Errorf("can't init cache for NEO native contract: %w", err)
}
return nil return nil
} }

View file

@ -40,8 +40,8 @@ func (cs *Contracts) ByHash(h util.Uint160) interop.Contract {
func NewContracts() *Contracts { func NewContracts() *Contracts {
cs := new(Contracts) cs := new(Contracts)
gas := NewGAS() gas := newGAS()
neo := NewNEO() neo := newNEO()
neo.GAS = gas neo.GAS = gas
gas.NEO = neo gas.NEO = neo

View file

@ -24,8 +24,8 @@ const gasContractID = -2
const GASFactor = NEOTotalSupply const GASFactor = NEOTotalSupply
const initialGAS = 30000000 const initialGAS = 30000000
// NewGAS returns GAS native contract. // newGAS returns GAS native contract.
func NewGAS() *GAS { func newGAS() *GAS {
g := &GAS{} g := &GAS{}
nep5 := newNEP5Native(gasName) nep5 := newNEP5Native(gasName)
nep5.symbol = "gas" nep5.symbol = "gas"

View file

@ -89,8 +89,8 @@ func makeValidatorKey(key *keys.PublicKey) []byte {
return b return b
} }
// NewNEO returns NEO native contract. // newNEO returns NEO native contract.
func NewNEO() *NEO { func newNEO() *NEO {
n := &NEO{} n := &NEO{}
nep5 := newNEP5Native(neoName) nep5 := newNEP5Native(neoName)
nep5.symbol = "neo" nep5.symbol = "neo"
@ -204,6 +204,30 @@ func (n *NEO) Initialize(ic *interop.Context) error {
return nil return nil
} }
// InitializeCache initializes all NEO cache with the proper values from storage.
// Cache initialisation should be done apart from Initialize because Initialize is
// called only when deploying native contracts.
func (n *NEO) InitializeCache(bc blockchainer.Blockchainer, d dao.DAO) error {
committee := keys.PublicKeys{}
si := d.GetStorageItem(n.ContractID, prefixCommittee)
if err := committee.DecodeBytes(si.Value); err != nil {
return err
}
if err := n.updateCache(committee, bc); err != nil {
return err
}
var gr state.GASRecord
si = d.GetStorageItem(n.ContractID, []byte{prefixGASPerBlock})
if err := gr.FromBytes(si.Value); err != nil {
return err
}
n.gasPerBlock.Store(gr)
n.gasPerBlockChanged.Store(false)
return nil
}
func (n *NEO) updateCache(committee keys.PublicKeys, bc blockchainer.Blockchainer) error { func (n *NEO) updateCache(committee keys.PublicKeys, bc blockchainer.Blockchainer) error {
n.committee.Store(committee) n.committee.Store(committee)
script, err := smartcontract.CreateMajorityMultiSigRedeemScript(committee.Copy()) script, err := smartcontract.CreateMajorityMultiSigRedeemScript(committee.Copy())
@ -247,25 +271,6 @@ func shouldUpdateCommittee(h uint32, bc blockchainer.Blockchainer) bool {
// OnPersist implements Contract interface. // OnPersist implements Contract interface.
func (n *NEO) OnPersist(ic *interop.Context) error { 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 shouldUpdateCommittee(ic.Block.Index, ic.Chain) {
if err := n.updateCommittee(ic); err != nil { if err := n.updateCommittee(ic); err != nil {
return err return err