core: add System.Runtime.CurrentSigners syscall

Port the https://github.com/neo-project/neo/pull/2827.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
This commit is contained in:
Anna Shaleva 2023-07-08 13:54:04 +03:00
parent 90b01bcea6
commit 2fba04490a
5 changed files with 69 additions and 0 deletions

View file

@ -15,6 +15,7 @@ const (
SystemIteratorValue = "System.Iterator.Value"
SystemRuntimeBurnGas = "System.Runtime.BurnGas"
SystemRuntimeCheckWitness = "System.Runtime.CheckWitness"
SystemRuntimeCurrentSigners = "System.Runtime.CurrentSigners"
SystemRuntimeGasLeft = "System.Runtime.GasLeft"
SystemRuntimeGetAddressVersion = "System.Runtime.GetAddressVersion"
SystemRuntimeGetCallingScriptHash = "System.Runtime.GetCallingScriptHash"
@ -52,6 +53,7 @@ var names = []string{
SystemIteratorValue,
SystemRuntimeBurnGas,
SystemRuntimeCheckWitness,
SystemRuntimeCurrentSigners,
SystemRuntimeGasLeft,
SystemRuntimeGetAddressVersion,
SystemRuntimeGetCallingScriptHash,

View file

@ -7,6 +7,7 @@ import (
"github.com/nspcc-dev/neo-go/pkg/config"
"github.com/nspcc-dev/neo-go/pkg/core/interop"
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
"github.com/nspcc-dev/neo-go/pkg/vm"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
@ -179,3 +180,16 @@ func BurnGas(ic *interop.Context) error {
}
return nil
}
// CurrentSigners returns signers of the currently loaded transaction or stackitem.Null
// if script container is not a transaction.
func CurrentSigners(ic *interop.Context) error {
tx, ok := ic.Container.(*transaction.Transaction)
if ok {
ic.VM.Estack().PushItem(transaction.SignersToStackItem(tx.Signers))
} else {
ic.VM.Estack().PushItem(stackitem.Null{})
}
return nil
}

View file

@ -9,6 +9,7 @@ import (
"github.com/nspcc-dev/neo-go/internal/random"
"github.com/nspcc-dev/neo-go/pkg/core/block"
"github.com/nspcc-dev/neo-go/pkg/core/interop"
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
@ -129,3 +130,45 @@ func TestLog(t *testing.T) {
require.Equal(t, h.StringLE(), logMsg["script"])
})
}
func TestCurrentSigners(t *testing.T) {
t.Run("container is block", func(t *testing.T) {
b := block.New(false)
ic := &interop.Context{VM: vm.New(), Container: b}
require.NoError(t, CurrentSigners(ic))
checkStack(t, ic.VM, stackitem.Null{})
})
t.Run("container is transaction", func(t *testing.T) {
tx := &transaction.Transaction{
Signers: []transaction.Signer{
{
Account: util.Uint160{1},
Scopes: transaction.None,
},
{
Account: util.Uint160{2},
Scopes: transaction.CalledByEntry,
},
},
}
ic := &interop.Context{VM: vm.New(), Container: tx}
require.NoError(t, CurrentSigners(ic))
checkStack(t, ic.VM, stackitem.NewArray([]stackitem.Item{
stackitem.NewArray([]stackitem.Item{
stackitem.NewByteArray(util.Uint160{1}.BytesBE()),
stackitem.NewBigInteger(big.NewInt(int64(transaction.None))),
stackitem.NewArray([]stackitem.Item{}),
stackitem.NewArray([]stackitem.Item{}),
stackitem.NewArray([]stackitem.Item{}),
}),
stackitem.NewArray([]stackitem.Item{
stackitem.NewByteArray(util.Uint160{2}.BytesBE()),
stackitem.NewBigInteger(big.NewInt(int64(transaction.CalledByEntry))),
stackitem.NewArray([]stackitem.Item{}),
stackitem.NewArray([]stackitem.Item{}),
stackitem.NewArray([]stackitem.Item{}),
}),
}))
})
}

View file

@ -46,6 +46,8 @@ var systemInterops = []interop.Function{
{Name: interopnames.SystemRuntimeBurnGas, Func: runtime.BurnGas, Price: 1 << 4, ParamCount: 1},
{Name: interopnames.SystemRuntimeCheckWitness, Func: runtime.CheckWitness, Price: 1 << 10,
RequiredFlags: callflag.NoneFlag, ParamCount: 1},
{Name: interopnames.SystemRuntimeCurrentSigners, Func: runtime.CurrentSigners, Price: 1 << 4,
RequiredFlags: callflag.NoneFlag},
{Name: interopnames.SystemRuntimeGasLeft, Func: runtime.GasLeft, Price: 1 << 4},
{Name: interopnames.SystemRuntimeGetAddressVersion, Func: runtime.GetAddressVersion, Price: 1 << 3},
{Name: interopnames.SystemRuntimeGetCallingScriptHash, Func: runtime.GetCallingScriptHash, Price: 1 << 4},

View file

@ -7,6 +7,7 @@ package runtime
import (
"github.com/nspcc-dev/neo-go/pkg/interop"
"github.com/nspcc-dev/neo-go/pkg/interop/contract"
"github.com/nspcc-dev/neo-go/pkg/interop/native/ledger"
"github.com/nspcc-dev/neo-go/pkg/interop/neogointernal"
)
@ -30,6 +31,13 @@ func CheckWitness(hashOrKey []byte) bool {
return neogointernal.Syscall1("System.Runtime.CheckWitness", hashOrKey).(bool)
}
// CurrentSigners returns signers of the currently loaded transaction or nil if
// executing script container is not a transaction. It uses
// `System.Runtime.CurrentSigners` syscall.
func CurrentSigners() []ledger.TransactionSigner {
return neogointernal.Syscall0("System.Runtime.CurrentSigners").([]ledger.TransactionSigner)
}
// LoadScript loads the given bytecode into the VM and executes it with the
// given call flags and arguments. This bytecode is executed as is from byte 0,
// it's not a deployed contract that can have methods. The execution context is