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:
commit
8e146d19b3
4 changed files with 35 additions and 25 deletions
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -40,8 +40,8 @@ func (cs *Contracts) ByHash(h util.Uint160) interop.Contract {
|
|||
func NewContracts() *Contracts {
|
||||
cs := new(Contracts)
|
||||
|
||||
gas := NewGAS()
|
||||
neo := NewNEO()
|
||||
gas := newGAS()
|
||||
neo := newNEO()
|
||||
neo.GAS = gas
|
||||
gas.NEO = neo
|
||||
|
||||
|
|
|
@ -24,8 +24,8 @@ const gasContractID = -2
|
|||
const GASFactor = NEOTotalSupply
|
||||
const initialGAS = 30000000
|
||||
|
||||
// NewGAS returns GAS native contract.
|
||||
func NewGAS() *GAS {
|
||||
// newGAS returns GAS native contract.
|
||||
func newGAS() *GAS {
|
||||
g := &GAS{}
|
||||
nep5 := newNEP5Native(gasName)
|
||||
nep5.symbol = "gas"
|
||||
|
|
|
@ -89,8 +89,8 @@ func makeValidatorKey(key *keys.PublicKey) []byte {
|
|||
return b
|
||||
}
|
||||
|
||||
// NewNEO returns NEO native contract.
|
||||
func NewNEO() *NEO {
|
||||
// newNEO returns NEO native contract.
|
||||
func newNEO() *NEO {
|
||||
n := &NEO{}
|
||||
nep5 := newNEP5Native(neoName)
|
||||
nep5.symbol = "neo"
|
||||
|
@ -204,6 +204,30 @@ func (n *NEO) Initialize(ic *interop.Context) error {
|
|||
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 {
|
||||
n.committee.Store(committee)
|
||||
script, err := smartcontract.CreateMajorityMultiSigRedeemScript(committee.Copy())
|
||||
|
@ -247,25 +271,6 @@ 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
|
||||
|
|
Loading…
Reference in a new issue