From 3d3fe9398eff29ffc912b5d3b7024dae96683907 Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Wed, 10 Jun 2020 11:20:57 +0300 Subject: [PATCH] core: remove Neo.Header/Witness/Account.* interops They are not present in NEO3. --- pkg/compiler/syscall.go | 22 ------ pkg/core/interop_neo.go | 105 --------------------------- pkg/core/interop_neo_test.go | 70 ------------------ pkg/core/interop_system.go | 15 ---- pkg/core/interops.go | 18 ----- pkg/core/interops_test.go | 10 --- pkg/interop/account/account.go | 43 ----------- pkg/interop/blockchain/blockchain.go | 29 +------- pkg/interop/header/header.go | 61 ---------------- pkg/interop/witness/witness.go | 14 ---- 10 files changed, 2 insertions(+), 385 deletions(-) delete mode 100644 pkg/interop/account/account.go delete mode 100644 pkg/interop/header/header.go delete mode 100644 pkg/interop/witness/witness.go diff --git a/pkg/compiler/syscall.go b/pkg/compiler/syscall.go index f6bbf3ccf..b8f597736 100644 --- a/pkg/compiler/syscall.go +++ b/pkg/compiler/syscall.go @@ -1,12 +1,6 @@ package compiler var syscalls = map[string]map[string]string{ - "account": { - "GetBalance": "Neo.Account.GetBalance", - "GetScriptHash": "Neo.Account.GetScriptHash", - "GetVotes": "Neo.Account.GetVotes", - "IsStandard": "Neo.Account.IsStandard", - }, "crypto": { "ECDsaVerify": "Neo.Crypto.ECDsaVerify", }, @@ -35,25 +29,12 @@ var syscalls = map[string]map[string]string{ "Deserialize": "Neo.Runtime.Deserialize", }, "blockchain": { - "GetAccount": "Neo.Blockchain.GetAccount", "GetBlock": "System.Blockchain.GetBlock", "GetContract": "Neo.Blockchain.GetContract", - "GetHeader": "Neo.Blockchain.GetHeader", "GetHeight": "Neo.Blockchain.GetHeight", "GetTransaction": "System.Blockchain.GetTransaction", "GetTransactionFromBlock": "System.Blockchain.GetTransactionFromBlock", "GetTransactionHeight": "System.Blockchain.GetTransactionHeight", - "GetValidators": "Neo.Blockchain.GetValidators", - }, - "header": { - "GetIndex": "Neo.Header.GetIndex", - "GetHash": "Neo.Header.GetHash", - "GetPrevHash": "Neo.Header.GetPrevHash", - "GetTimestamp": "Neo.Header.GetTimestamp", - "GetVersion": "Neo.Header.GetVersion", - "GetMerkleRoot": "Neo.Header.GetMerkleRoot", - "GetConsensusData": "Neo.Header.GetConsensusData", - "GetNextConsensus": "Neo.Header.GetNextConsensus", }, "contract": { "GetScript": "Neo.Contract.GetScript", @@ -78,7 +59,4 @@ var syscalls = map[string]map[string]string{ "Value": "Neo.Iterator.Value", "Values": "Neo.Iterator.Values", }, - "witness": { - "GetVerificationScript": "Neo.Witness.GetVerificationScript", - }, } diff --git a/pkg/core/interop_neo.go b/pkg/core/interop_neo.go index d855890f8..a79757cb7 100644 --- a/pkg/core/interop_neo.go +++ b/pkg/core/interop_neo.go @@ -8,10 +8,8 @@ import ( "github.com/nspcc-dev/neo-go/pkg/core/interop" "github.com/nspcc-dev/neo-go/pkg/core/state" - "github.com/nspcc-dev/neo-go/pkg/core/transaction" "github.com/nspcc-dev/neo-go/pkg/smartcontract" "github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger" - "github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/vm" "github.com/nspcc-dev/neo-go/pkg/vm/stackitem" ) @@ -27,109 +25,6 @@ const ( MaxContractStringLen = 252 ) -// headerGetVersion returns version from the header. -func headerGetVersion(ic *interop.Context, v *vm.VM) error { - header, err := popHeaderFromVM(v) - if err != nil { - return err - } - v.Estack().PushVal(header.Version) - return nil -} - -// headerGetMerkleRoot returns version from the header. -func headerGetMerkleRoot(ic *interop.Context, v *vm.VM) error { - header, err := popHeaderFromVM(v) - if err != nil { - return err - } - v.Estack().PushVal(header.MerkleRoot.BytesBE()) - return nil -} - -// headerGetNextConsensus returns version from the header. -func headerGetNextConsensus(ic *interop.Context, v *vm.VM) error { - header, err := popHeaderFromVM(v) - if err != nil { - return err - } - v.Estack().PushVal(header.NextConsensus.BytesBE()) - return nil -} - -// witnessGetVerificationScript returns current witness' script. -func witnessGetVerificationScript(ic *interop.Context, v *vm.VM) error { - witInterface := v.Estack().Pop().Value() - wit, ok := witInterface.(*transaction.Witness) - if !ok { - return errors.New("value is not a witness") - } - // It's important not to share wit.VerificationScript slice with the code running in VM. - script := make([]byte, len(wit.VerificationScript)) - copy(script, wit.VerificationScript) - v.Estack().PushVal(script) - return nil -} - -// bcGetAccount returns or creates an account. -func bcGetAccount(ic *interop.Context, v *vm.VM) error { - accbytes := v.Estack().Pop().Bytes() - acchash, err := util.Uint160DecodeBytesBE(accbytes) - if err != nil { - return err - } - acc, err := ic.DAO.GetAccountStateOrNew(acchash) - if err != nil { - return err - } - v.Estack().PushVal(stackitem.NewInterop(acc)) - return nil -} - -// accountGetBalance returns balance for a given account. -func accountGetBalance(ic *interop.Context, v *vm.VM) error { - accInterface := v.Estack().Pop().Value() - acc, ok := accInterface.(*state.Account) - if !ok { - return fmt.Errorf("%T is not an account state", acc) - } - asbytes := v.Estack().Pop().Bytes() - ashash, err := util.Uint256DecodeBytesBE(asbytes) - if err != nil { - return err - } - balance, ok := acc.GetBalanceValues()[ashash] - if !ok { - balance = util.Fixed8(0) - } - v.Estack().PushVal(int64(balance)) - return nil -} - -// accountGetScriptHash returns script hash of a given account. -func accountGetScriptHash(ic *interop.Context, v *vm.VM) error { - accInterface := v.Estack().Pop().Value() - acc, ok := accInterface.(*state.Account) - if !ok { - return fmt.Errorf("%T is not an account state", acc) - } - v.Estack().PushVal(acc.ScriptHash.BytesBE()) - return nil -} - -// accountIsStandard checks whether given account is standard. -func accountIsStandard(ic *interop.Context, v *vm.VM) error { - accbytes := v.Estack().Pop().Bytes() - acchash, err := util.Uint160DecodeBytesBE(accbytes) - if err != nil { - return err - } - contract, err := ic.DAO.GetContractState(acchash) - res := err != nil || vm.IsStandardContract(contract.Script) - v.Estack().PushVal(res) - return nil -} - // storageFind finds stored key-value pair. func storageFind(ic *interop.Context, v *vm.VM) error { stcInterface := v.Estack().Pop().Value() diff --git a/pkg/core/interop_neo_test.go b/pkg/core/interop_neo_test.go index 626e0c5cd..853e9850d 100644 --- a/pkg/core/interop_neo_test.go +++ b/pkg/core/interop_neo_test.go @@ -2,7 +2,6 @@ package core import ( "fmt" - "math/big" "testing" "github.com/nspcc-dev/neo-go/pkg/core/block" @@ -136,64 +135,6 @@ func TestStorageFind(t *testing.T) { }) } -func TestHeaderGetVersion(t *testing.T) { - v, block, context, chain := createVMAndPushBlock(t) - defer chain.Close() - - err := headerGetVersion(context, v) - require.NoError(t, err) - value := v.Estack().Pop().Value().(*big.Int) - require.Equal(t, uint64(block.Version), value.Uint64()) -} - -func TestHeaderGetVersion_Negative(t *testing.T) { - v := vm.New() - block := newDumbBlock() - chain := newTestChain(t) - defer chain.Close() - context := chain.newInteropContext(trigger.Application, dao.NewSimple(storage.NewMemoryStore()), block, nil) - v.Estack().PushVal(stackitem.NewBool(false)) - - err := headerGetVersion(context, v) - require.Errorf(t, err, "value is not a header or block") -} - -func TestHeaderGetMerkleRoot(t *testing.T) { - v, block, context, chain := createVMAndPushBlock(t) - defer chain.Close() - - err := headerGetMerkleRoot(context, v) - require.NoError(t, err) - value := v.Estack().Pop().Value() - require.Equal(t, block.MerkleRoot.BytesBE(), value) -} - -func TestHeaderGetNextConsensus(t *testing.T) { - v, block, context, chain := createVMAndPushBlock(t) - defer chain.Close() - - err := headerGetNextConsensus(context, v) - require.NoError(t, err) - value := v.Estack().Pop().Value() - require.Equal(t, block.NextConsensus.BytesBE(), value) -} - -func TestWitnessGetVerificationScript(t *testing.T) { - v := vm.New() - script := []byte{byte(opcode.PUSHM1), byte(opcode.RET)} - witness := transaction.Witness{InvocationScript: nil, VerificationScript: script} - - chain := newTestChain(t) - defer chain.Close() - - context := chain.newInteropContext(trigger.Application, dao.NewSimple(storage.NewMemoryStore()), nil, nil) - v.Estack().PushVal(stackitem.NewInterop(&witness)) - err := witnessGetVerificationScript(context, v) - require.NoError(t, err) - value := v.Estack().Pop().Value().([]byte) - require.Equal(t, witness.VerificationScript, value) -} - func TestECDSAVerify(t *testing.T) { priv, err := keys.NewPrivateKey() require.NoError(t, err) @@ -270,17 +211,6 @@ func TestECDSAVerify(t *testing.T) { }) } -func TestAccountGetScriptHash(t *testing.T) { - v, accState, context, chain := createVMAndAccState(t) - defer chain.Close() - v.Estack().PushVal(stackitem.NewInterop(accState)) - - err := accountGetScriptHash(context, v) - require.NoError(t, err) - hash := v.Estack().Pop().Value() - require.Equal(t, accState.ScriptHash.BytesBE(), hash) -} - func TestContractGetScript(t *testing.T) { v, contractState, context, chain := createVMAndContractState(t) defer chain.Close() diff --git a/pkg/core/interop_system.go b/pkg/core/interop_system.go index 9a30fbaf8..2c4f6335e 100644 --- a/pkg/core/interop_system.go +++ b/pkg/core/interop_system.go @@ -98,21 +98,6 @@ func bcGetContract(ic *interop.Context, v *vm.VM) error { return nil } -// bcGetHeader returns block header. -func bcGetHeader(ic *interop.Context, v *vm.VM) error { - hash, err := getBlockHashFromElement(ic.Chain, v.Estack().Pop()) - if err != nil { - return err - } - header, err := ic.Chain.GetHeader(hash) - if err != nil { - v.Estack().PushVal([]byte{}) - } else { - v.Estack().PushVal(stackitem.NewInterop(header)) - } - return nil -} - // bcGetHeight returns blockchain height. func bcGetHeight(ic *interop.Context, v *vm.VM) error { v.Estack().PushVal(ic.Chain.BlockHeight()) diff --git a/pkg/core/interops.go b/pkg/core/interops.go index 889742b3a..be271a10e 100644 --- a/pkg/core/interops.go +++ b/pkg/core/interops.go @@ -64,7 +64,6 @@ func getInteropFromSlice(ic *interop.Context, slice []interop.Function) func(uin var systemInterops = []interop.Function{ {Name: "System.Blockchain.GetBlock", Func: bcGetBlock, Price: 250}, {Name: "System.Blockchain.GetContract", Func: bcGetContract, Price: 100}, - {Name: "System.Blockchain.GetHeader", Func: bcGetHeader, Price: 100}, {Name: "System.Blockchain.GetHeight", Func: bcGetHeight, Price: 1}, {Name: "System.Blockchain.GetTransaction", Func: bcGetTransaction, Price: 100}, {Name: "System.Blockchain.GetTransactionFromBlock", Func: bcGetTransactionFromBlock, Price: 100}, @@ -77,10 +76,6 @@ var systemInterops = []interop.Function{ {Name: "System.ExecutionEngine.GetEntryScriptHash", Func: engineGetEntryScriptHash, Price: 1}, {Name: "System.ExecutionEngine.GetExecutingScriptHash", Func: engineGetExecutingScriptHash, Price: 1}, {Name: "System.ExecutionEngine.GetScriptContainer", Func: engineGetScriptContainer, Price: 1}, - {Name: "System.Header.GetHash", Func: headerGetHash, Price: 1}, - {Name: "System.Header.GetIndex", Func: headerGetIndex, Price: 1}, - {Name: "System.Header.GetPrevHash", Func: headerGetPrevHash, Price: 1}, - {Name: "System.Header.GetTimestamp", Func: headerGetTimestamp, Price: 1}, {Name: "System.Runtime.CheckWitness", Func: runtime.CheckWitness, Price: 200}, {Name: "System.Runtime.Deserialize", Func: runtimeDeserialize, Price: 1}, {Name: "System.Runtime.GetTime", Func: runtimeGetTime, Price: 1}, @@ -99,12 +94,7 @@ var systemInterops = []interop.Function{ } var neoInterops = []interop.Function{ - {Name: "Neo.Account.GetBalance", Func: accountGetBalance, Price: 1}, - {Name: "Neo.Account.GetScriptHash", Func: accountGetScriptHash, Price: 1}, - {Name: "Neo.Account.IsStandard", Func: accountIsStandard, Price: 100}, - {Name: "Neo.Blockchain.GetAccount", Func: bcGetAccount, Price: 100}, {Name: "Neo.Blockchain.GetContract", Func: bcGetContract, Price: 100}, - {Name: "Neo.Blockchain.GetHeader", Func: bcGetHeader, Price: 100}, {Name: "Neo.Blockchain.GetHeight", Func: bcGetHeight, Price: 1}, {Name: "Neo.Contract.Create", Func: contractCreate, Price: 0}, {Name: "Neo.Contract.Destroy", Func: contractDestroy, Price: 1}, @@ -119,13 +109,6 @@ var neoInterops = []interop.Function{ {Name: "Neo.Enumerator.Create", Func: enumerator.Create, Price: 1}, {Name: "Neo.Enumerator.Next", Func: enumerator.Next, Price: 1}, {Name: "Neo.Enumerator.Value", Func: enumerator.Value, Price: 1}, - {Name: "Neo.Header.GetHash", Func: headerGetHash, Price: 1}, - {Name: "Neo.Header.GetIndex", Func: headerGetIndex, Price: 1}, - {Name: "Neo.Header.GetMerkleRoot", Func: headerGetMerkleRoot, Price: 1}, - {Name: "Neo.Header.GetNextConsensus", Func: headerGetNextConsensus, Price: 1}, - {Name: "Neo.Header.GetPrevHash", Func: headerGetPrevHash, Price: 1}, - {Name: "Neo.Header.GetTimestamp", Func: headerGetTimestamp, Price: 1}, - {Name: "Neo.Header.GetVersion", Func: headerGetVersion, Price: 1}, {Name: "Neo.Iterator.Concat", Func: iterator.Concat, Price: 1}, {Name: "Neo.Iterator.Create", Func: iterator.Create, Price: 1}, {Name: "Neo.Iterator.Key", Func: iterator.Key, Price: 1}, @@ -146,7 +129,6 @@ var neoInterops = []interop.Function{ {Name: "Neo.Storage.GetReadOnlyContext", Func: storageGetReadOnlyContext, Price: 1}, {Name: "Neo.Storage.Put", Func: storagePut, Price: 0}, {Name: "Neo.StorageContext.AsReadOnly", Func: storageContextAsReadOnly, Price: 1}, - {Name: "Neo.Witness.GetVerificationScript", Func: witnessGetVerificationScript, Price: 100}, // Aliases. {Name: "Neo.Iterator.Next", Func: enumerator.Next, Price: 1}, diff --git a/pkg/core/interops_test.go b/pkg/core/interops_test.go index 40d4db5ae..b346926e2 100644 --- a/pkg/core/interops_test.go +++ b/pkg/core/interops_test.go @@ -32,25 +32,15 @@ func TestUnexpectedNonInterops(t *testing.T) { // All of these functions expect an interop item on the stack. funcs := []func(*interop.Context, *vm.VM) error{ - accountGetBalance, - accountGetScriptHash, contractGetScript, contractGetStorageContext, contractIsPayable, - headerGetHash, - headerGetIndex, - headerGetMerkleRoot, - headerGetNextConsensus, - headerGetPrevHash, - headerGetTimestamp, - headerGetVersion, storageContextAsReadOnly, storageDelete, storageFind, storageGet, storagePut, storagePutEx, - witnessGetVerificationScript, } for _, f := range funcs { for k, v := range vals { diff --git a/pkg/interop/account/account.go b/pkg/interop/account/account.go deleted file mode 100644 index f0595eec0..000000000 --- a/pkg/interop/account/account.go +++ /dev/null @@ -1,43 +0,0 @@ -/* -Package account provides getter functions for Account interop structure. -To use these functions you need to get an Account first via blockchain.GetAccount -call. -*/ -package account - -// Account represents NEO account type that is used in interop functions, it's -// an opaque data structure that you can get data from only using functions from -// this package. It's similar in function to the Account class in the Neo .net -// framework. -type Account struct{} - -// GetScriptHash returns the script hash of the given Account (20 bytes in BE -// representation). It uses `Neo.Account.GetBalance` syscall internally. -func GetScriptHash(a Account) []byte { - return nil -} - -// GetVotes returns current votes of the given account represented as a slice of -// public keys. Keys are serialized into byte slices in their compressed form (33 -// bytes long each). This function uses `Neo.Account.GetVotes` syscall -// internally. -func GetVotes(a Account) [][]byte { - return nil -} - -// GetBalance returns current balance of the given asset (by its ID, 256 bit -// hash in BE form) for the given account. Only native UTXO assets can be -// queiried via this function, for NEP-5 ones use respective contract calls. -// The value returned is represented as an integer with original value multiplied -// by 10⁸ so you can work with fractional parts of the balance too. This function -// uses `Neo.Account.GetBalance` syscall internally. -func GetBalance(a Account, assetID []byte) int { - return 0 -} - -// IsStandard checks whether given account uses standard (CHECKSIG or -// CHECKMULTISIG) contract. It only works for deployed contracts and uses -// `Neo.Account.IsStandard` syscall internally. -func IsStandard(a Account) bool { - return false -} diff --git a/pkg/interop/blockchain/blockchain.go b/pkg/interop/blockchain/blockchain.go index 5afb272a5..417cd9d76 100644 --- a/pkg/interop/blockchain/blockchain.go +++ b/pkg/interop/blockchain/blockchain.go @@ -4,9 +4,7 @@ Package blockchain provides functions to access various blockchain data. package blockchain import ( - "github.com/nspcc-dev/neo-go/pkg/interop/account" "github.com/nspcc-dev/neo-go/pkg/interop/contract" - "github.com/nspcc-dev/neo-go/pkg/interop/header" ) // Transaction represents a NEO transaction. It's similar to Transaction class @@ -63,19 +61,11 @@ type Block struct { // 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 // the previous (already accepted) block. This function uses -// `Neo.Blockchain.GetHeight` syscall. +// `System.Blockchain.GetHeight` syscall. func GetHeight() int { return 0 } -// GetHeader returns header found by the given hash (256 bit hash in BE format -// represented as a slice of 32 bytes) or index (integer). Refer to the `header` -// package for possible uses of returned structure. This function uses -// `Neo.Blockchain.GetHeader` syscall. -func GetHeader(heightOrHash interface{}) header.Header { - return header.Header{} -} - // GetBlock returns block found by the given hash or index (with the same // encoding as for GetHeader). This function uses `System.Blockchain.GetBlock` // syscall. @@ -108,22 +98,7 @@ func GetTransactionHeight(hash []byte) int { // GetContract returns contract found by the given script hash (160 bit in BE // 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 -// `Neo.Blockchain.GetContract` syscall. +// `System.Blockchain.GetContract` syscall. func GetContract(scriptHash []byte) contract.Contract { return contract.Contract{} } - -// GetAccount returns account found by the given script hash (160 bit in BE -// format represented as a slice of 20 bytes). Refer to the `account` package -// for details on how to use the returned structure. This function uses -// `Neo.Blockchain.GetAccount` syscall. -func GetAccount(scriptHash []byte) account.Account { - return account.Account{} -} - -// GetValidators returns a slice of current validators public keys represented -// as a compressed serialized byte slice (33 bytes long). This function uses -// `Neo.Blockchain.GetValidators` syscall. -func GetValidators() [][]byte { - return nil -} diff --git a/pkg/interop/header/header.go b/pkg/interop/header/header.go deleted file mode 100644 index 37abe9676..000000000 --- a/pkg/interop/header/header.go +++ /dev/null @@ -1,61 +0,0 @@ -/* -Package header contains functions working with block headers. -*/ -package header - -// Header represents Neo block header type, it's an opaque data structure that -// can be used by functions from this package. You can create it with -// blockchain.GetHeader. In its function it's similar to the Header class -// of the Neo .net framework. -type Header struct{} - -// GetIndex returns the index (height) of the given header. It uses -// `Neo.Header.GetIndex` syscall. -func GetIndex(h Header) int { - return 0 -} - -// GetHash returns the hash (256-bit BE value packed into 32 byte slice) of the -// given header (which also is a hash of the block). It uses `Neo.Header.GetHash` -// syscall. -func GetHash(h Header) []byte { - return nil -} - -// GetPrevHash returns the hash (256-bit BE value packed into 32 byte slice) of -// the previous block stored in the given header. It uses `Neo.Header.GetPrevHash` -// syscall. -func GetPrevHash(h Header) []byte { - return nil -} - -// GetTimestamp returns the timestamp of the given header. It uses -// `Neo.Header.GetTimestamp` syscall. -func GetTimestamp(h Header) int { - return 0 -} - -// GetVersion returns the version of the given header. It uses -// `Neo.Header.GetVersion` syscall. -func GetVersion(h Header) int { - return 0 -} - -// GetMerkleRoot returns the Merkle root (256-bit BE value packed into 32 byte -// slice) of the given header. It uses `Neo.Header.GetMerkleRoot` syscall. -func GetMerkleRoot(h Header) []byte { - return nil -} - -// GetConsensusData returns the consensus data (nonce) of the given header. -// It uses `Neo.Header.GetConsensusData` syscall. -func GetConsensusData(h Header) int { - return 0 -} - -// GetNextConsensus returns the next consensus field (verification script hash, -// 160-bit BE value packed into 20 byte slice) of the given header. It uses -// `Neo.Header.GetNextConsensus` syscall. -func GetNextConsensus(h Header) []byte { - return nil -} diff --git a/pkg/interop/witness/witness.go b/pkg/interop/witness/witness.go deleted file mode 100644 index 5bf742f83..000000000 --- a/pkg/interop/witness/witness.go +++ /dev/null @@ -1,14 +0,0 @@ -/* -Package witness provides functions dealing with transaction's witnesses. -*/ -package witness - -// Witness is an opaque data structure that can only be created by -// transaction.GetWitnesses and representing transaction's witness. -type Witness struct{} - -// GetVerificationScript returns verification script stored in the given -// witness. It uses `Neo.Witness.GetVerificationScript` syscall. -func GetVerificationScript(w Witness) []byte { - return nil -}