forked from TrueCloudLab/neoneo-go
core: adjust System.Blockchain.GetContract interop
Part of #1055. It should put on stack an array instead of interop interface.
This commit is contained in:
parent
1a5fb01e61
commit
d2ec0fed3d
4 changed files with 59 additions and 9 deletions
|
@ -14,7 +14,7 @@ var syscalls = map[string]map[string]Syscall{
|
||||||
},
|
},
|
||||||
"blockchain": {
|
"blockchain": {
|
||||||
"GetBlock": {"System.Blockchain.GetBlock", true},
|
"GetBlock": {"System.Blockchain.GetBlock", true},
|
||||||
"GetContract": {"System.Blockchain.GetContract", false},
|
"GetContract": {"System.Blockchain.GetContract", true},
|
||||||
"GetHeight": {"System.Blockchain.GetHeight", false},
|
"GetHeight": {"System.Blockchain.GetHeight", false},
|
||||||
"GetTransaction": {"System.Blockchain.GetTransaction", true},
|
"GetTransaction": {"System.Blockchain.GetTransaction", true},
|
||||||
"GetTransactionFromBlock": {"System.Blockchain.GetTransactionFromBlock", false},
|
"GetTransactionFromBlock": {"System.Blockchain.GetTransactionFromBlock", false},
|
||||||
|
|
|
@ -83,6 +83,20 @@ func bcGetBlock(ic *interop.Context, v *vm.VM) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// contractToStackItem converts state.Contract to stackitem.Item
|
||||||
|
func contractToStackItem(cs *state.Contract) (stackitem.Item, error) {
|
||||||
|
manifest, err := cs.Manifest.MarshalJSON()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return stackitem.NewArray([]stackitem.Item{
|
||||||
|
stackitem.NewByteArray(cs.Script),
|
||||||
|
stackitem.NewByteArray(manifest),
|
||||||
|
stackitem.NewBool(cs.HasStorage()),
|
||||||
|
stackitem.NewBool(cs.IsPayable()),
|
||||||
|
}), nil
|
||||||
|
}
|
||||||
|
|
||||||
// bcGetContract returns contract.
|
// bcGetContract returns contract.
|
||||||
func bcGetContract(ic *interop.Context, v *vm.VM) error {
|
func bcGetContract(ic *interop.Context, v *vm.VM) error {
|
||||||
hashbytes := v.Estack().Pop().Bytes()
|
hashbytes := v.Estack().Pop().Bytes()
|
||||||
|
@ -92,9 +106,13 @@ func bcGetContract(ic *interop.Context, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
cs, err := ic.DAO.GetContractState(hash)
|
cs, err := ic.DAO.GetContractState(hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
v.Estack().PushVal([]byte{})
|
v.Estack().PushVal(stackitem.Null{})
|
||||||
} else {
|
} else {
|
||||||
v.Estack().PushVal(stackitem.NewInterop(cs))
|
item, err := contractToStackItem(cs)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.Estack().PushVal(item)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -292,3 +292,31 @@ func TestRuntimeGetInvocationCounter(t *testing.T) {
|
||||||
require.EqualValues(t, 42, v.Estack().Pop().BigInt().Int64())
|
require.EqualValues(t, 42, v.Estack().Pop().BigInt().Int64())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBlockchainGetContractState(t *testing.T) {
|
||||||
|
v, cs, ic, bc := createVMAndContractState(t)
|
||||||
|
defer bc.Close()
|
||||||
|
require.NoError(t, ic.DAO.PutContractState(cs))
|
||||||
|
|
||||||
|
t.Run("positive", func(t *testing.T) {
|
||||||
|
v.Estack().PushVal(cs.ScriptHash().BytesBE())
|
||||||
|
require.NoError(t, bcGetContract(ic, v))
|
||||||
|
|
||||||
|
expectedManifest, err := cs.Manifest.MarshalJSON()
|
||||||
|
require.NoError(t, err)
|
||||||
|
actual := v.Estack().Pop().Array()
|
||||||
|
require.Equal(t, 4, len(actual))
|
||||||
|
require.Equal(t, cs.Script, actual[0].Value().([]byte))
|
||||||
|
require.Equal(t, expectedManifest, actual[1].Value().([]byte))
|
||||||
|
require.Equal(t, cs.HasStorage(), actual[2].Bool())
|
||||||
|
require.Equal(t, cs.IsPayable(), actual[3].Bool())
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("uncknown contract state", func(t *testing.T) {
|
||||||
|
v.Estack().PushVal(util.Uint160{1, 2, 3}.BytesBE())
|
||||||
|
require.NoError(t, bcGetContract(ic, v))
|
||||||
|
|
||||||
|
actual := v.Estack().Pop().Item()
|
||||||
|
require.Equal(t, stackitem.Null{}, actual)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -3,10 +3,6 @@ Package blockchain provides functions to access various blockchain data.
|
||||||
*/
|
*/
|
||||||
package blockchain
|
package blockchain
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/contract"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Transaction represents a NEO transaction. It's similar to Transaction class
|
// Transaction represents a NEO transaction. It's similar to Transaction class
|
||||||
// in Neo .net framework.
|
// in Neo .net framework.
|
||||||
type Transaction struct {
|
type Transaction struct {
|
||||||
|
@ -57,6 +53,14 @@ type Block struct {
|
||||||
TransactionsLength int
|
TransactionsLength int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Contract represents a Neo contract and is used in interop functions.
|
||||||
|
type Contract struct {
|
||||||
|
Script []byte
|
||||||
|
Manifest []byte
|
||||||
|
HasStorage bool
|
||||||
|
IsPayable bool
|
||||||
|
}
|
||||||
|
|
||||||
// GetHeight returns current block height (index of the last accepted block).
|
// GetHeight returns current block height (index of the last accepted block).
|
||||||
// Note that when transaction is being run as a part of new block this block is
|
// Note that when transaction is being run as a part of new block this block is
|
||||||
// considered as not yet accepted (persisted) and thus you'll get an index of
|
// considered as not yet accepted (persisted) and thus you'll get an index of
|
||||||
|
@ -99,6 +103,6 @@ func GetTransactionHeight(hash []byte) int {
|
||||||
// format represented as a slice of 20 bytes). Refer to the `contract` package
|
// format represented as a slice of 20 bytes). Refer to the `contract` package
|
||||||
// for details on how to use the returned structure. This function uses
|
// for details on how to use the returned structure. This function uses
|
||||||
// `System.Blockchain.GetContract` syscall.
|
// `System.Blockchain.GetContract` syscall.
|
||||||
func GetContract(scriptHash []byte) contract.Contract {
|
func GetContract(scriptHash []byte) Contract {
|
||||||
return contract.Contract{}
|
return Contract{}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue