core: add InitializeCache method to Contract interface
Make the contracts cache initialization unified. The order of cache iniitialization is not important and Nottary contract is added to the bc.contracts.Contracts wrt P2PSigExtensions setting, thus no functional changes, just refactoring for future applications. Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
This commit is contained in:
parent
29b3df10b6
commit
33c971b0e4
13 changed files with 40 additions and 28 deletions
|
@ -1011,29 +1011,12 @@ func (bc *Blockchain) resetStateInternal(height uint32, stage stateChangeStage)
|
|||
}
|
||||
|
||||
func (bc *Blockchain) initializeNativeCache(blockHeight uint32, d *dao.Simple) error {
|
||||
err := bc.contracts.NEO.InitializeCache(blockHeight, d)
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't init cache for NEO native contract: %w", err)
|
||||
}
|
||||
err = bc.contracts.Management.InitializeCache(d)
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't init cache for Management native contract: %w", err)
|
||||
}
|
||||
err = bc.contracts.Designate.InitializeCache(d)
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't init cache for Designation native contract: %w", err)
|
||||
}
|
||||
bc.contracts.Oracle.InitializeCache(d)
|
||||
if bc.P2PSigExtensionsEnabled() {
|
||||
err = bc.contracts.Notary.InitializeCache(d)
|
||||
for _, c := range bc.contracts.Contracts {
|
||||
err := c.InitializeCache(blockHeight, d)
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't init cache for Notary native contract: %w", err)
|
||||
return fmt.Errorf("failed to initialize cache for %s: %w", c.Metadata().Name, err)
|
||||
}
|
||||
}
|
||||
err = bc.contracts.Policy.InitializeCache(d)
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't init cache for Policy native contract: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -153,6 +153,11 @@ type MethodAndPrice struct {
|
|||
// Contract is an interface for all native contracts.
|
||||
type Contract interface {
|
||||
Initialize(*Context) error
|
||||
// InitializeCache aimed to initialize contract's cache when the contract has
|
||||
// been deployed, but in-memory cached data were lost due to the node reset.
|
||||
// It should be called each time after node restart iff the contract was
|
||||
// deployed and no Initialize method was called.
|
||||
InitializeCache(blockHeight uint32, d *dao.Simple) error
|
||||
Metadata() *ContractMD
|
||||
OnPersist(*Context) error
|
||||
PostPersist(*Context) error
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
bls12381 "github.com/consensys/gnark-crypto/ecc/bls12-381"
|
||||
"github.com/consensys/gnark-crypto/ecc/bls12-381/fr"
|
||||
"github.com/decred/dcrd/dcrec/secp256k1/v4"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/dao"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/native/nativenames"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
||||
|
@ -467,6 +468,11 @@ func (c *Crypto) Initialize(ic *interop.Context) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// InitializeCache implements the Contract interface.
|
||||
func (c *Crypto) InitializeCache(blockHeight uint32, d *dao.Simple) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// OnPersist implements the Contract interface.
|
||||
func (c *Crypto) OnPersist(ic *interop.Context) error {
|
||||
return nil
|
||||
|
|
|
@ -132,7 +132,7 @@ func (s *Designate) Initialize(ic *interop.Context) error {
|
|||
|
||||
// InitializeCache fills native Designate cache from DAO. It is called at non-zero height, thus
|
||||
// we can fetch the roles data right from the storage.
|
||||
func (s *Designate) InitializeCache(d *dao.Simple) error {
|
||||
func (s *Designate) InitializeCache(blockHeight uint32, d *dao.Simple) error {
|
||||
cache := &DesignationCache{}
|
||||
roles := []noderoles.Role{noderoles.Oracle, noderoles.NeoFSAlphabet, noderoles.StateValidator}
|
||||
if s.p2pSigExtensionsEnabled {
|
||||
|
|
|
@ -85,6 +85,11 @@ func (l *Ledger) Initialize(ic *interop.Context) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// InitializeCache implements the Contract interface.
|
||||
func (l *Ledger) InitializeCache(blockHeight uint32, d *dao.Simple) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// OnPersist implements the Contract interface.
|
||||
func (l *Ledger) OnPersist(ic *interop.Context) error {
|
||||
// Actual block/tx processing is done in Blockchain.storeBlock().
|
||||
|
|
|
@ -610,7 +610,7 @@ func (m *Management) OnPersist(ic *interop.Context) error {
|
|||
// InitializeCache initializes contract cache with the proper values from storage.
|
||||
// Cache initialization should be done apart from Initialize because Initialize is
|
||||
// called only when deploying native contracts.
|
||||
func (m *Management) InitializeCache(d *dao.Simple) error {
|
||||
func (m *Management) InitializeCache(blockHeight uint32, d *dao.Simple) error {
|
||||
cache := &ManagementCache{
|
||||
contracts: make(map[util.Uint160]*state.Contract),
|
||||
nep11: make(map[util.Uint160]struct{}),
|
||||
|
|
|
@ -82,7 +82,7 @@ func TestManagement_Initialize(t *testing.T) {
|
|||
t.Run("good", func(t *testing.T) {
|
||||
d := dao.NewSimple(storage.NewMemoryStore(), false, false)
|
||||
mgmt := newManagement()
|
||||
require.NoError(t, mgmt.InitializeCache(d))
|
||||
require.NoError(t, mgmt.InitializeCache(0, d))
|
||||
})
|
||||
/* See #2801
|
||||
t.Run("invalid contract state", func(t *testing.T) {
|
||||
|
@ -101,7 +101,7 @@ func TestManagement_GetNEP17Contracts(t *testing.T) {
|
|||
err := mgmt.Initialize(&interop.Context{DAO: d})
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, mgmt.Policy.Initialize(&interop.Context{DAO: d}))
|
||||
err = mgmt.InitializeCache(d)
|
||||
err = mgmt.InitializeCache(0, d)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Empty(t, mgmt.GetNEP17Contracts(d))
|
||||
|
|
|
@ -99,6 +99,11 @@ func (g *GAS) Initialize(ic *interop.Context) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// InitializeCache implements the Contract interface.
|
||||
func (g *GAS) InitializeCache(blockHeight uint32, d *dao.Simple) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// OnPersist implements the Contract interface.
|
||||
func (g *GAS) OnPersist(ic *interop.Context) error {
|
||||
if len(ic.Block.Transactions) == 0 {
|
||||
|
|
|
@ -305,7 +305,8 @@ func (n *NEO) Initialize(ic *interop.Context) error {
|
|||
|
||||
// InitializeCache initializes all NEO cache with the proper values from the storage.
|
||||
// Cache initialization should be done apart from Initialize because Initialize is
|
||||
// called only when deploying native contracts.
|
||||
// called only when deploying native contracts. InitializeCache implements the Contract
|
||||
// interface.
|
||||
func (n *NEO) InitializeCache(blockHeight uint32, d *dao.Simple) error {
|
||||
cache := &NeoCache{
|
||||
gasPerVoteCache: make(map[string]big.Int),
|
||||
|
|
|
@ -152,7 +152,7 @@ func (n *Notary) Initialize(ic *interop.Context) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (n *Notary) InitializeCache(d *dao.Simple) error {
|
||||
func (n *Notary) InitializeCache(blockHeight uint32, d *dao.Simple) error {
|
||||
cache := &NotaryCache{
|
||||
maxNotValidBeforeDelta: uint32(getIntWithKey(n.ID, d, maxNotValidBeforeDeltaKey)),
|
||||
notaryServiceFeePerKey: getIntWithKey(n.ID, d, notaryServiceFeeKey),
|
||||
|
|
|
@ -251,10 +251,11 @@ func (o *Oracle) Initialize(ic *interop.Context) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (o *Oracle) InitializeCache(d *dao.Simple) {
|
||||
func (o *Oracle) InitializeCache(blockHeight uint32, d *dao.Simple) error {
|
||||
cache := &OracleCache{}
|
||||
cache.requestPrice = getIntWithKey(o.ID, d, prefixRequestPrice)
|
||||
d.SetCache(o.ID, cache)
|
||||
return nil
|
||||
}
|
||||
|
||||
func getResponse(tx *transaction.Transaction) *transaction.OracleResponse {
|
||||
|
|
|
@ -153,7 +153,7 @@ func (p *Policy) Initialize(ic *interop.Context) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (p *Policy) InitializeCache(d *dao.Simple) error {
|
||||
func (p *Policy) InitializeCache(blockHeight uint32, d *dao.Simple) error {
|
||||
cache := &PolicyCache{}
|
||||
err := p.fillCacheFromDAO(cache, d)
|
||||
if err != nil {
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/mr-tron/base58"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/dao"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/native/nativenames"
|
||||
base58neogo "github.com/nspcc-dev/neo-go/pkg/encoding/base58"
|
||||
|
@ -429,6 +430,11 @@ func (s *Std) Initialize(ic *interop.Context) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// InitializeCache implements the Contract interface.
|
||||
func (s *Std) InitializeCache(blockHeight uint32, d *dao.Simple) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// OnPersist implements the Contract interface.
|
||||
func (s *Std) OnPersist(ic *interop.Context) error {
|
||||
return nil
|
||||
|
|
Loading…
Reference in a new issue