contract: block calls to contracts via Policy contract
See neo-project/neo#2567.
This commit is contained in:
parent
11351b9702
commit
f477a48758
2 changed files with 34 additions and 0 deletions
|
@ -5,7 +5,9 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
|
||||
"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/core/state"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
||||
|
@ -15,6 +17,10 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||
)
|
||||
|
||||
type policyChecker interface {
|
||||
IsBlockedInternal(dao.DAO, util.Uint160) bool
|
||||
}
|
||||
|
||||
// LoadToken calls method specified by token id.
|
||||
func LoadToken(ic *interop.Context) func(id int32) error {
|
||||
return func(id int32) error {
|
||||
|
@ -88,6 +94,15 @@ func callInternal(ic *interop.Context, cs *state.Contract, name string, f callfl
|
|||
// callExFromNative calls a contract with flags using provided calling hash.
|
||||
func callExFromNative(ic *interop.Context, caller util.Uint160, cs *state.Contract,
|
||||
name string, args []stackitem.Item, f callflag.CallFlag, hasReturn bool) error {
|
||||
for _, nc := range ic.Natives {
|
||||
if nc.Metadata().Name == nativenames.Policy {
|
||||
var pch = nc.(policyChecker)
|
||||
if pch.IsBlockedInternal(ic.DAO, cs.Hash) {
|
||||
return fmt.Errorf("contract %s is blocked", cs.Hash.StringLE())
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
md := cs.Manifest.ABI.GetMethod(name, len(args))
|
||||
if md == nil {
|
||||
return fmt.Errorf("method '%s' not found", name)
|
||||
|
|
|
@ -196,4 +196,23 @@ func TestBlockedAccounts(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
checkFAULTState(t, invokeRes)
|
||||
})
|
||||
|
||||
t.Run("block-unblock contract", func(t *testing.T) {
|
||||
neoHash := chain.contracts.NEO.Metadata().Hash
|
||||
res, err := invokeContractMethodGeneric(chain, 100000000, policyHash, "blockAccount", true, neoHash.BytesBE())
|
||||
require.NoError(t, err)
|
||||
checkResult(t, res, stackitem.NewBool(true))
|
||||
|
||||
res, err = invokeContractMethodGeneric(chain, 100000000, neoHash, "balanceOf", true, account.BytesBE())
|
||||
require.NoError(t, err)
|
||||
checkFAULTState(t, res)
|
||||
|
||||
res, err = invokeContractMethodGeneric(chain, 100000000, policyHash, "unblockAccount", true, neoHash.BytesBE())
|
||||
require.NoError(t, err)
|
||||
checkResult(t, res, stackitem.NewBool(true))
|
||||
|
||||
res, err = invokeContractMethodGeneric(chain, 100000000, neoHash, "balanceOf", true, account.BytesBE())
|
||||
require.NoError(t, err)
|
||||
checkResult(t, res, stackitem.Make(0))
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue