[#47] Do not read context in init with OnNEP17Payment

There is an issue with native contract callback functions
and getting storage context: nspcc-dev/neo-go#1725.

This should fix it for now.

Signed-off-by: Alex Vanin <alexey@nspcc.ru>
This commit is contained in:
Alex Vanin 2021-02-09 13:20:55 +03:00 committed by Alex Vanin
parent cff7688486
commit 76c63b7d5c
2 changed files with 43 additions and 14 deletions

View file

@ -24,16 +24,10 @@ const (
voteKey = "ballots" voteKey = "ballots"
) )
var (
ctx storage.Context
)
func init() { func init() {
if runtime.GetTrigger() != runtime.Application { if runtime.GetTrigger() != runtime.Application {
panic("contract has not been called in application node") panic("contract has not been called in application node")
} }
ctx = storage.GetContext()
} }
// OnNEP17Payment is a callback for NEP-17 compatible native GAS and NEO contracts. // OnNEP17Payment is a callback for NEP-17 compatible native GAS and NEO contracts.
@ -45,6 +39,8 @@ func OnNEP17Payment(from interop.Hash160, amount int, data interface{}) {
} }
func Init(addrNetmap []byte, name string, index, total int) { func Init(addrNetmap []byte, name string, index, total int) {
ctx := storage.GetContext()
if storage.Get(ctx, netmapKey) != nil { if storage.Get(ctx, netmapKey) != nil {
panic("contract already deployed") panic("contract already deployed")
} }
@ -79,23 +75,33 @@ func balance(hash string, addr []byte) int {
} }
func irList() []common.IRNode { func irList() []common.IRNode {
ctx := storage.GetContext()
return common.InnerRingListViaStorage(ctx, netmapKey) return common.InnerRingListViaStorage(ctx, netmapKey)
} }
func currentEpoch() int { func currentEpoch() int {
ctx := storage.GetContext()
netmapContractAddr := storage.Get(ctx, netmapKey).([]byte) netmapContractAddr := storage.Get(ctx, netmapKey).([]byte)
return contract.Call(netmapContractAddr, "epoch", contract.ReadOnly).(int) return contract.Call(netmapContractAddr, "epoch", contract.ReadOnly).(int)
} }
func name() string { func name() string {
ctx := storage.GetContext()
return storage.Get(ctx, nameKey).(string) return storage.Get(ctx, nameKey).(string)
} }
func index() int { func index() int {
ctx := storage.GetContext()
return storage.Get(ctx, indexKey).(int) return storage.Get(ctx, indexKey).(int)
} }
func total() int { func total() int {
ctx := storage.GetContext()
return storage.Get(ctx, totalKey).(int) return storage.Get(ctx, totalKey).(int)
} }
@ -141,6 +147,8 @@ func Emit() bool {
} }
func Vote(epoch int, candidates [][]byte) { func Vote(epoch int, candidates [][]byte) {
ctx := storage.GetContext()
innerRingKeys := irList() innerRingKeys := irList()
threshold := total()/3*2 + 1 threshold := total()/3*2 + 1
index := index() index := index()
@ -182,6 +190,8 @@ func Name() string {
} }
func vote(ctx storage.Context, epoch int, id, from []byte) int { func vote(ctx storage.Context, epoch int, id, from []byte) int {
ctx = storage.GetContext()
var ( var (
newCandidates []common.Ballot newCandidates []common.Ballot
candidates = getBallots(ctx) candidates = getBallots(ctx)
@ -225,6 +235,8 @@ func vote(ctx storage.Context, epoch int, id, from []byte) int {
} }
func removeVotes(ctx storage.Context, id []byte) { func removeVotes(ctx storage.Context, id []byte) {
ctx = storage.GetContext()
var ( var (
newCandidates []common.Ballot newCandidates []common.Ballot
candidates = getBallots(ctx) candidates = getBallots(ctx)

View file

@ -75,11 +75,7 @@ const (
ignoreDepositNotification = "\x57\x0b" ignoreDepositNotification = "\x57\x0b"
) )
var ( var configPrefix = []byte("config")
configPrefix = []byte("config")
ctx storage.Context
)
func init() { func init() {
// The trigger determines whether this smart-contract is being // The trigger determines whether this smart-contract is being
@ -87,13 +83,12 @@ func init() {
if runtime.GetTrigger() != runtime.Application { if runtime.GetTrigger() != runtime.Application {
panic("contract has not been called in application node") panic("contract has not been called in application node")
} }
ctx = storage.GetContext()
} }
// Init set up initial inner ring node keys. // Init set up initial inner ring node keys.
func Init(args [][]byte) bool { func Init(args [][]byte) bool {
ctx := storage.GetContext()
if storage.Get(ctx, innerRingKey) != nil { if storage.Get(ctx, innerRingKey) != nil {
panic("neofs: contract already deployed") panic("neofs: contract already deployed")
} }
@ -125,16 +120,22 @@ func Init(args [][]byte) bool {
// InnerRingList returns array of inner ring node keys. // InnerRingList returns array of inner ring node keys.
func InnerRingList() []common.IRNode { func InnerRingList() []common.IRNode {
ctx := storage.GetContext()
return getInnerRingNodes(ctx, innerRingKey) return getInnerRingNodes(ctx, innerRingKey)
} }
// InnerRingCandidates returns array of inner ring candidate node keys. // InnerRingCandidates returns array of inner ring candidate node keys.
func InnerRingCandidates() []common.IRNode { func InnerRingCandidates() []common.IRNode {
ctx := storage.GetContext()
return getInnerRingNodes(ctx, candidatesKey) return getInnerRingNodes(ctx, candidatesKey)
} }
// InnerRingCandidateRemove removes key from the list of inner ring candidates. // InnerRingCandidateRemove removes key from the list of inner ring candidates.
func InnerRingCandidateRemove(key []byte) bool { func InnerRingCandidateRemove(key []byte) bool {
ctx := storage.GetContext()
if !runtime.CheckWitness(key) { if !runtime.CheckWitness(key) {
panic("irCandidateRemove: you should be the owner of the public key") panic("irCandidateRemove: you should be the owner of the public key")
} }
@ -158,6 +159,8 @@ func InnerRingCandidateRemove(key []byte) bool {
// InnerRingCandidateAdd adds key to the list of inner ring candidates. // InnerRingCandidateAdd adds key to the list of inner ring candidates.
func InnerRingCandidateAdd(key []byte) bool { func InnerRingCandidateAdd(key []byte) bool {
ctx := storage.GetContext()
if !runtime.CheckWitness(key) { if !runtime.CheckWitness(key) {
panic("irCandidateAdd: you should be the owner of the public key") panic("irCandidateAdd: you should be the owner of the public key")
} }
@ -264,6 +267,8 @@ func Withdraw(user []byte, amount int) bool {
// Cheque sends gas assets back to the user if they were successfully // Cheque sends gas assets back to the user if they were successfully
// locked in NeoFS balance contract. // locked in NeoFS balance contract.
func Cheque(id, user []byte, amount int, lockAcc []byte) bool { func Cheque(id, user []byte, amount int, lockAcc []byte) bool {
ctx := storage.GetContext()
irList := getInnerRingNodes(ctx, innerRingKey) irList := getInnerRingNodes(ctx, innerRingKey)
threshold := len(irList)/3*2 + 1 threshold := len(irList)/3*2 + 1
@ -342,6 +347,8 @@ func Unbind(user []byte, keys [][]byte) bool {
// InnerRingUpdate updates list of inner ring nodes with provided list of // InnerRingUpdate updates list of inner ring nodes with provided list of
// public keys. // public keys.
func InnerRingUpdate(chequeID []byte, args [][]byte) bool { func InnerRingUpdate(chequeID []byte, args [][]byte) bool {
ctx := storage.GetContext()
if len(args) < minInnerRingSize { if len(args) < minInnerRingSize {
panic("irUpdate: bad arguments") panic("irUpdate: bad arguments")
} }
@ -415,6 +422,8 @@ loop:
// IsInnerRing returns 'true' if key is inside of inner ring list. // IsInnerRing returns 'true' if key is inside of inner ring list.
func IsInnerRing(key []byte) bool { func IsInnerRing(key []byte) bool {
ctx := storage.GetContext()
if len(key) != publicKeySize { if len(key) != publicKeySize {
panic("isInnerRing: incorrect public key") panic("isInnerRing: incorrect public key")
} }
@ -433,11 +442,15 @@ func IsInnerRing(key []byte) bool {
// Config returns value of NeoFS configuration with provided key. // Config returns value of NeoFS configuration with provided key.
func Config(key []byte) interface{} { func Config(key []byte) interface{} {
ctx := storage.GetContext()
return getConfig(ctx, key) return getConfig(ctx, key)
} }
// SetConfig key-value pair as a NeoFS runtime configuration value. // SetConfig key-value pair as a NeoFS runtime configuration value.
func SetConfig(id, key, val []byte) bool { func SetConfig(id, key, val []byte) bool {
ctx := storage.GetContext()
// check if it is inner ring invocation // check if it is inner ring invocation
irList := getInnerRingNodes(ctx, innerRingKey) irList := getInnerRingNodes(ctx, innerRingKey)
threshold := len(irList)/3*2 + 1 threshold := len(irList)/3*2 + 1
@ -475,6 +488,8 @@ func SetConfig(id, key, val []byte) bool {
// ListConfig returns array of all key-value pairs of NeoFS configuration. // ListConfig returns array of all key-value pairs of NeoFS configuration.
func ListConfig() []record { func ListConfig() []record {
ctx := storage.GetContext()
var config []record var config []record
it := storage.Find(ctx, configPrefix, storage.None) it := storage.Find(ctx, configPrefix, storage.None)
@ -492,6 +507,8 @@ func ListConfig() []record {
// InitConfig set up initial NeoFS key-value configuration. // InitConfig set up initial NeoFS key-value configuration.
func InitConfig(args [][]byte) bool { func InitConfig(args [][]byte) bool {
ctx := storage.GetContext()
if getConfig(ctx, candidateFeeConfigKey) != nil { if getConfig(ctx, candidateFeeConfigKey) != nil {
panic("neofs: configuration already installed") panic("neofs: configuration already installed")
} }