forked from TrueCloudLab/neoneo-go
parent
4254407a9b
commit
b431e47d2a
3 changed files with 68 additions and 2 deletions
|
@ -14,6 +14,7 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"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"
|
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -62,6 +63,11 @@ func newLedger() *Ledger {
|
||||||
md = newMethodAndPrice(l.getTransactionFromBlock, 1<<16, callflag.ReadStates)
|
md = newMethodAndPrice(l.getTransactionFromBlock, 1<<16, callflag.ReadStates)
|
||||||
l.AddMethod(md, desc)
|
l.AddMethod(md, desc)
|
||||||
|
|
||||||
|
desc = newDescriptor("getTransactionVMState", smartcontract.IntegerType,
|
||||||
|
manifest.NewParameter("hash", smartcontract.Hash256Type))
|
||||||
|
md = newMethodAndPrice(l.getTransactionVMState, 1<<15, callflag.ReadStates)
|
||||||
|
l.AddMethod(md, desc)
|
||||||
|
|
||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,6 +148,19 @@ func (l *Ledger) getTransactionFromBlock(ic *interop.Context, params []stackitem
|
||||||
return TransactionToStackItem(block.Transactions[index])
|
return TransactionToStackItem(block.Transactions[index])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getTransactionVMState returns VM state got after transaction invocation.
|
||||||
|
func (l *Ledger) getTransactionVMState(ic *interop.Context, params []stackitem.Item) stackitem.Item {
|
||||||
|
hash, err := getUint256FromItem(params[0])
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
h, _, aer, err := ic.DAO.GetTxExecResult(hash)
|
||||||
|
if err != nil || !isTraceableBlock(ic.Chain, h) {
|
||||||
|
return stackitem.Make(vm.NoneState)
|
||||||
|
}
|
||||||
|
return stackitem.Make(aer.VMState)
|
||||||
|
}
|
||||||
|
|
||||||
// isTraceableBlock defines whether we're able to give information about
|
// isTraceableBlock defines whether we're able to give information about
|
||||||
// the block with index specified.
|
// the block with index specified.
|
||||||
func isTraceableBlock(bc interop.Ledger, index uint32) bool {
|
func isTraceableBlock(bc interop.Ledger, index uint32) bool {
|
||||||
|
|
|
@ -5,11 +5,11 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/config"
|
"github.com/nspcc-dev/neo-go/pkg/config"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/neotest/chain"
|
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/native/nativenames"
|
"github.com/nspcc-dev/neo-go/pkg/core/native/nativenames"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/neotest"
|
"github.com/nspcc-dev/neo-go/pkg/neotest"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/neotest/chain"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
@ -44,6 +44,33 @@ func TestLedger_GetTransactionHeight(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestLedger_GetTransactionState(t *testing.T) {
|
||||||
|
c := newLedgerClient(t)
|
||||||
|
e := c.Executor
|
||||||
|
ledgerInvoker := c.WithSigners(c.Committee)
|
||||||
|
|
||||||
|
hash := e.InvokeScript(t, []byte{byte(opcode.RET)}, []neotest.Signer{c.Committee})
|
||||||
|
|
||||||
|
t.Run("unknown transaction", func(t *testing.T) {
|
||||||
|
ledgerInvoker.Invoke(t, vm.NoneState, "getTransactionVMState", util.Uint256{1, 2, 3})
|
||||||
|
})
|
||||||
|
t.Run("not a hash", func(t *testing.T) {
|
||||||
|
ledgerInvoker.InvokeFail(t, "expected []byte of size 32", "getTransactionVMState", []byte{1, 2, 3})
|
||||||
|
})
|
||||||
|
t.Run("good: HALT", func(t *testing.T) {
|
||||||
|
ledgerInvoker.Invoke(t, vm.HaltState, "getTransactionVMState", hash)
|
||||||
|
})
|
||||||
|
t.Run("isn't traceable", func(t *testing.T) {
|
||||||
|
// Add more blocks so that tx becomes untraceable.
|
||||||
|
e.GenerateNewBlocks(t, int(e.Chain.GetConfig().MaxTraceableBlocks))
|
||||||
|
ledgerInvoker.Invoke(t, vm.NoneState, "getTransactionVMState", hash)
|
||||||
|
})
|
||||||
|
t.Run("good: FAULT", func(t *testing.T) {
|
||||||
|
faultedH := e.InvokeScript(t, []byte{byte(opcode.ABORT)}, []neotest.Signer{c.Committee})
|
||||||
|
ledgerInvoker.Invoke(t, vm.FaultState, "getTransactionVMState", faultedH)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestLedger_GetTransaction(t *testing.T) {
|
func TestLedger_GetTransaction(t *testing.T) {
|
||||||
c := newLedgerClient(t)
|
c := newLedgerClient(t)
|
||||||
e := c.Executor
|
e := c.Executor
|
||||||
|
|
|
@ -13,6 +13,21 @@ import (
|
||||||
// Hash represents Ledger contract hash.
|
// Hash represents Ledger contract hash.
|
||||||
const Hash = "\xbe\xf2\x04\x31\x40\x36\x2a\x77\xc1\x50\x99\xc7\xe6\x4c\x12\xf7\x00\xb6\x65\xda"
|
const Hash = "\xbe\xf2\x04\x31\x40\x36\x2a\x77\xc1\x50\x99\xc7\xe6\x4c\x12\xf7\x00\xb6\x65\xda"
|
||||||
|
|
||||||
|
// VMState represents VM execution state.
|
||||||
|
type VMState uint8
|
||||||
|
|
||||||
|
// Various VM execution states.
|
||||||
|
const (
|
||||||
|
// NoneState represents NONE VM state.
|
||||||
|
NoneState VMState = 0
|
||||||
|
// HaltState represents HALT VM state.
|
||||||
|
HaltState VMState = 1
|
||||||
|
// FaultState represents FAULT VM state.
|
||||||
|
FaultState VMState = 2
|
||||||
|
// BreakState represents BREAK VM state.
|
||||||
|
BreakState VMState = 4
|
||||||
|
)
|
||||||
|
|
||||||
// CurrentHash represents `currentHash` method of Ledger native contract.
|
// CurrentHash represents `currentHash` method of Ledger native contract.
|
||||||
func CurrentHash() interop.Hash256 {
|
func CurrentHash() interop.Hash256 {
|
||||||
return neogointernal.CallWithToken(Hash, "currentHash", int(contract.ReadStates)).(interop.Hash256)
|
return neogointernal.CallWithToken(Hash, "currentHash", int(contract.ReadStates)).(interop.Hash256)
|
||||||
|
@ -43,3 +58,8 @@ func GetTransactionFromBlock(indexOrHash interface{}, txIndex int) *Transaction
|
||||||
return neogointernal.CallWithToken(Hash, "getTransactionFromBlock", int(contract.ReadStates),
|
return neogointernal.CallWithToken(Hash, "getTransactionFromBlock", int(contract.ReadStates),
|
||||||
indexOrHash, txIndex).(*Transaction)
|
indexOrHash, txIndex).(*Transaction)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetTransactionVMState represents `getTransactionVMState` method of Ledger native contract.
|
||||||
|
func GetTransactionVMState(hash interop.Hash256) VMState {
|
||||||
|
return neogointernal.CallWithToken(Hash, "getTransactionVMState", int(contract.ReadStates), hash).(VMState)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue