diff --git a/pkg/core/blockchain.go b/pkg/core/blockchain.go index 68d849882..cd85cb01d 100644 --- a/pkg/core/blockchain.go +++ b/pkg/core/blockchain.go @@ -591,7 +591,7 @@ func (bc *Blockchain) storeBlock(block *block.Block) error { Trigger: trigger.System, VMState: v.State(), GasConsumed: v.GasConsumed(), - Stack: v.Estack().ToContractParameters(), + Stack: v.Estack().ToArray(), Events: systemInterop.Notifications, } appExecResults = append(appExecResults, aer) @@ -632,7 +632,7 @@ func (bc *Blockchain) storeBlock(block *block.Block) error { Trigger: trigger.Application, VMState: v.State(), GasConsumed: v.GasConsumed(), - Stack: v.Estack().ToContractParameters(), + Stack: v.Estack().ToArray(), Events: systemInterop.Notifications, } appExecResults = append(appExecResults, aer) diff --git a/pkg/core/dao/dao_test.go b/pkg/core/dao/dao_test.go index a94649467..a9760b3dc 100644 --- a/pkg/core/dao/dao_test.go +++ b/pkg/core/dao/dao_test.go @@ -11,8 +11,8 @@ import ( "github.com/nspcc-dev/neo-go/pkg/core/transaction" "github.com/nspcc-dev/neo-go/pkg/internal/random" "github.com/nspcc-dev/neo-go/pkg/io" - "github.com/nspcc-dev/neo-go/pkg/smartcontract" "github.com/nspcc-dev/neo-go/pkg/vm/opcode" + "github.com/nspcc-dev/neo-go/pkg/vm/stackitem" "github.com/stretchr/testify/require" ) @@ -103,7 +103,7 @@ func TestPutGetAppExecResult(t *testing.T) { appExecResult := &state.AppExecResult{ TxHash: hash, Events: []state.NotificationEvent{}, - Stack: []smartcontract.Parameter{}, + Stack: []stackitem.Item{}, } err := dao.PutAppExecResult(appExecResult) require.NoError(t, err) diff --git a/pkg/core/native_contract_test.go b/pkg/core/native_contract_test.go index b1df21ea1..df6bad3ed 100644 --- a/pkg/core/native_contract_test.go +++ b/pkg/core/native_contract_test.go @@ -131,8 +131,7 @@ func TestNativeContract_Invoke(t *testing.T) { require.NoError(t, err) require.Equal(t, vm.HaltState, res.VMState) require.Equal(t, 1, len(res.Stack)) - require.Equal(t, smartcontract.IntegerType, res.Stack[0].Type) - require.EqualValues(t, 42, res.Stack[0].Value) + require.Equal(t, big.NewInt(42), res.Stack[0].Value()) res, err = chain.GetAppExecResult(tx2.Hash()) require.NoError(t, err) diff --git a/pkg/core/native_policy_test.go b/pkg/core/native_policy_test.go index b0fd12964..88b246335 100644 --- a/pkg/core/native_policy_test.go +++ b/pkg/core/native_policy_test.go @@ -10,10 +10,10 @@ import ( "github.com/nspcc-dev/neo-go/pkg/core/transaction" "github.com/nspcc-dev/neo-go/pkg/encoding/bigint" "github.com/nspcc-dev/neo-go/pkg/io" - "github.com/nspcc-dev/neo-go/pkg/smartcontract" "github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/vm" "github.com/nspcc-dev/neo-go/pkg/vm/emit" + "github.com/nspcc-dev/neo-go/pkg/vm/stackitem" "github.com/stretchr/testify/require" ) @@ -29,20 +29,14 @@ func TestMaxTransactionsPerBlock(t *testing.T) { t.Run("get, contract method", func(t *testing.T) { res, err := invokeNativePolicyMethod(chain, "getMaxTransactionsPerBlock") require.NoError(t, err) - checkResult(t, res, smartcontract.Parameter{ - Type: smartcontract.IntegerType, - Value: 512, - }) + checkResult(t, res, stackitem.NewBigInteger(big.NewInt(512))) require.NoError(t, chain.persist()) }) t.Run("set", func(t *testing.T) { res, err := invokeNativePolicyMethod(chain, "setMaxTransactionsPerBlock", bigint.ToBytes(big.NewInt(1024))) require.NoError(t, err) - checkResult(t, res, smartcontract.Parameter{ - Type: smartcontract.BoolType, - Value: true, - }) + checkResult(t, res, stackitem.NewBool(true)) require.NoError(t, chain.persist()) n := chain.contracts.Policy.GetMaxTransactionsPerBlockInternal(chain.dao) require.Equal(t, 1024, int(n)) @@ -56,27 +50,18 @@ func TestMaxBlockSize(t *testing.T) { t.Run("get", func(t *testing.T) { res, err := invokeNativePolicyMethod(chain, "getMaxBlockSize") require.NoError(t, err) - checkResult(t, res, smartcontract.Parameter{ - Type: smartcontract.IntegerType, - Value: 1024 * 256, - }) + checkResult(t, res, stackitem.NewBigInteger(big.NewInt(1024*256))) require.NoError(t, chain.persist()) }) t.Run("set", func(t *testing.T) { res, err := invokeNativePolicyMethod(chain, "setMaxBlockSize", bigint.ToBytes(big.NewInt(102400))) require.NoError(t, err) - checkResult(t, res, smartcontract.Parameter{ - Type: smartcontract.BoolType, - Value: true, - }) + checkResult(t, res, stackitem.NewBool(true)) require.NoError(t, chain.persist()) res, err = invokeNativePolicyMethod(chain, "getMaxBlockSize") require.NoError(t, err) - checkResult(t, res, smartcontract.Parameter{ - Type: smartcontract.IntegerType, - Value: 102400, - }) + checkResult(t, res, stackitem.NewBigInteger(big.NewInt(102400))) require.NoError(t, chain.persist()) }) } @@ -93,20 +78,14 @@ func TestFeePerByte(t *testing.T) { t.Run("get, contract method", func(t *testing.T) { res, err := invokeNativePolicyMethod(chain, "getFeePerByte") require.NoError(t, err) - checkResult(t, res, smartcontract.Parameter{ - Type: smartcontract.IntegerType, - Value: 1000, - }) + checkResult(t, res, stackitem.NewBigInteger(big.NewInt(1000))) require.NoError(t, chain.persist()) }) t.Run("set", func(t *testing.T) { res, err := invokeNativePolicyMethod(chain, "setFeePerByte", bigint.ToBytes(big.NewInt(1024))) require.NoError(t, err) - checkResult(t, res, smartcontract.Parameter{ - Type: smartcontract.BoolType, - Value: true, - }) + checkResult(t, res, stackitem.NewBool(true)) require.NoError(t, chain.persist()) n := chain.contracts.Policy.GetFeePerByteInternal(chain.dao) require.Equal(t, 1024, int(n)) @@ -127,20 +106,14 @@ func TestBlockedAccounts(t *testing.T) { t.Run("get, contract method", func(t *testing.T) { res, err := invokeNativePolicyMethod(chain, "getBlockedAccounts") require.NoError(t, err) - checkResult(t, res, smartcontract.Parameter{ - Type: smartcontract.ArrayType, - Value: []smartcontract.Parameter{}, - }) + checkResult(t, res, stackitem.NewArray([]stackitem.Item{})) require.NoError(t, chain.persist()) }) t.Run("block-unblock account", func(t *testing.T) { res, err := invokeNativePolicyMethod(chain, "blockAccount", account.BytesBE()) require.NoError(t, err) - checkResult(t, res, smartcontract.Parameter{ - Type: smartcontract.BoolType, - Value: true, - }) + checkResult(t, res, stackitem.NewBool(true)) accounts, err := chain.contracts.Policy.GetBlockedAccountsInternal(chain.dao) require.NoError(t, err) @@ -148,10 +121,7 @@ func TestBlockedAccounts(t *testing.T) { require.NoError(t, chain.persist()) res, err = invokeNativePolicyMethod(chain, "unblockAccount", account.BytesBE()) - checkResult(t, res, smartcontract.Parameter{ - Type: smartcontract.BoolType, - Value: true, - }) + checkResult(t, res, stackitem.NewBool(true)) accounts, err = chain.contracts.Policy.GetBlockedAccountsInternal(chain.dao) require.NoError(t, err) @@ -163,35 +133,23 @@ func TestBlockedAccounts(t *testing.T) { // block res, err := invokeNativePolicyMethod(chain, "blockAccount", account.BytesBE()) require.NoError(t, err) - checkResult(t, res, smartcontract.Parameter{ - Type: smartcontract.BoolType, - Value: true, - }) + checkResult(t, res, stackitem.NewBool(true)) require.NoError(t, chain.persist()) // double-block should fail res, err = invokeNativePolicyMethod(chain, "blockAccount", account.BytesBE()) require.NoError(t, err) - checkResult(t, res, smartcontract.Parameter{ - Type: smartcontract.BoolType, - Value: false, - }) + checkResult(t, res, stackitem.NewBool(false)) require.NoError(t, chain.persist()) // unblock res, err = invokeNativePolicyMethod(chain, "unblockAccount", account.BytesBE()) - checkResult(t, res, smartcontract.Parameter{ - Type: smartcontract.BoolType, - Value: true, - }) + checkResult(t, res, stackitem.NewBool(true)) require.NoError(t, chain.persist()) // unblock the same account should fail as we don't have it blocked res, err = invokeNativePolicyMethod(chain, "unblockAccount", account.BytesBE()) - checkResult(t, res, smartcontract.Parameter{ - Type: smartcontract.BoolType, - Value: false, - }) + checkResult(t, res, stackitem.NewBool(false)) require.NoError(t, chain.persist()) }) @@ -205,10 +163,7 @@ func TestBlockedAccounts(t *testing.T) { for _, acc := range accounts { res, err := invokeNativePolicyMethod(chain, "blockAccount", acc.BytesBE()) require.NoError(t, err) - checkResult(t, res, smartcontract.Parameter{ - Type: smartcontract.BoolType, - Value: true, - }) + checkResult(t, res, stackitem.NewBool(true)) require.NoError(t, chain.persist()) } @@ -253,9 +208,8 @@ func invokeNativePolicyMethod(chain *Blockchain, method string, args ...interfac return res, nil } -func checkResult(t *testing.T, result *state.AppExecResult, expected smartcontract.Parameter) { +func checkResult(t *testing.T, result *state.AppExecResult, expected stackitem.Item) { require.Equal(t, vm.HaltState, result.VMState) require.Equal(t, 1, len(result.Stack)) - require.Equal(t, expected.Type, result.Stack[0].Type) - require.EqualValues(t, expected.Value, result.Stack[0].Value) + require.Equal(t, expected, result.Stack[0]) } diff --git a/pkg/core/state/notification_event.go b/pkg/core/state/notification_event.go index 1818f4c7b..48027137d 100644 --- a/pkg/core/state/notification_event.go +++ b/pkg/core/state/notification_event.go @@ -4,7 +4,6 @@ import ( "errors" "github.com/nspcc-dev/neo-go/pkg/io" - "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" @@ -26,7 +25,7 @@ type AppExecResult struct { Trigger trigger.Type VMState vm.State GasConsumed int64 - Stack []smartcontract.Parameter + Stack []stackitem.Item Events []NotificationEvent } @@ -59,7 +58,7 @@ func (aer *AppExecResult) EncodeBinary(w *io.BinWriter) { w.WriteB(byte(aer.Trigger)) w.WriteB(byte(aer.VMState)) w.WriteU64LE(uint64(aer.GasConsumed)) - w.WriteArray(aer.Stack) + stackitem.EncodeBinaryStackItem(stackitem.NewArray(aer.Stack), w) w.WriteArray(aer.Events) } @@ -69,6 +68,14 @@ func (aer *AppExecResult) DecodeBinary(r *io.BinReader) { aer.Trigger = trigger.Type(r.ReadB()) aer.VMState = vm.State(r.ReadB()) aer.GasConsumed = int64(r.ReadU64LE()) - r.ReadArray(&aer.Stack) + item := stackitem.DecodeBinaryStackItem(r) + if r.Err == nil { + arr, ok := item.Value().([]stackitem.Item) + if !ok { + r.Err = errors.New("array expected") + return + } + aer.Stack = arr + } r.ReadArray(&aer.Events) } diff --git a/pkg/core/state/notification_event_test.go b/pkg/core/state/notification_event_test.go index 5242b8544..7a24315ce 100644 --- a/pkg/core/state/notification_event_test.go +++ b/pkg/core/state/notification_event_test.go @@ -5,7 +5,6 @@ import ( "github.com/nspcc-dev/neo-go/pkg/internal/random" "github.com/nspcc-dev/neo-go/pkg/internal/testserdes" - "github.com/nspcc-dev/neo-go/pkg/smartcontract" "github.com/nspcc-dev/neo-go/pkg/vm" "github.com/nspcc-dev/neo-go/pkg/vm/stackitem" ) @@ -26,7 +25,7 @@ func TestEncodeDecodeAppExecResult(t *testing.T) { Trigger: 1, VMState: vm.HaltState, GasConsumed: 10, - Stack: []smartcontract.Parameter{}, + Stack: []stackitem.Item{}, Events: []NotificationEvent{}, } diff --git a/pkg/rpc/response/result/application_log.go b/pkg/rpc/response/result/application_log.go index 2ae28d01f..9ecae405f 100644 --- a/pkg/rpc/response/result/application_log.go +++ b/pkg/rpc/response/result/application_log.go @@ -43,13 +43,17 @@ func NewApplicationLog(appExecRes *state.AppExecResult) ApplicationLog { for _, e := range appExecRes.Events { events = append(events, StateEventToResultNotification(e)) } - + st := make([]smartcontract.Parameter, len(appExecRes.Stack)) + seen := make(map[stackitem.Item]bool) + for i := range appExecRes.Stack { + st[i] = smartcontract.ParameterFromStackItem(appExecRes.Stack[i], seen) + } return ApplicationLog{ TxHash: appExecRes.TxHash, Trigger: appExecRes.Trigger.String(), VMState: appExecRes.VMState.String(), GasConsumed: appExecRes.GasConsumed, - Stack: appExecRes.Stack, + Stack: st, Events: events, } }