core: use raw stack items in application logs

Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
This commit is contained in:
Evgenii Stratonikov 2020-07-31 15:48:35 +03:00
parent 9cba25616d
commit e5d538ed21
7 changed files with 41 additions and 78 deletions

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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])
}

View file

@ -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)
}

View file

@ -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{},
}

View file

@ -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,
}
}