Merge pull request #2417 from nspcc-dev/interop-update

*: natives update
This commit is contained in:
Roman Khimov 2022-04-05 19:02:59 +03:00 committed by GitHub
commit 017326dca4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
34 changed files with 264 additions and 75 deletions

View file

@ -2,4 +2,4 @@ module github.com/nspcc-dev/neo-go/examples/engine
go 1.16
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220321144137-d5a9af5860af
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220405074652-16f952270c1e

View file

@ -1,2 +1,2 @@
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220321144137-d5a9af5860af h1:QO3pU/jSYyX3EHBX8BPO01oRkVhGBXPrQaQEhn+4fv8=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220321144137-d5a9af5860af/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220405074652-16f952270c1e h1:LmVuj/p99qS2gDyogAkVpurdUMGRdiJBFe7bhTDI3wY=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220405074652-16f952270c1e/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=

View file

@ -2,4 +2,4 @@ module github.com/nspcc-dev/neo-go/examples/events
go 1.16
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220321144137-d5a9af5860af
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220405074652-16f952270c1e

View file

@ -1,2 +1,2 @@
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220321144137-d5a9af5860af h1:QO3pU/jSYyX3EHBX8BPO01oRkVhGBXPrQaQEhn+4fv8=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220321144137-d5a9af5860af/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220405074652-16f952270c1e h1:LmVuj/p99qS2gDyogAkVpurdUMGRdiJBFe7bhTDI3wY=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220405074652-16f952270c1e/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=

View file

@ -2,4 +2,4 @@ module github.com/nspcc-dev/neo-go/examples/iterator
go 1.16
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220321144137-d5a9af5860af
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220405074652-16f952270c1e

View file

@ -1,2 +1,2 @@
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220321144137-d5a9af5860af h1:QO3pU/jSYyX3EHBX8BPO01oRkVhGBXPrQaQEhn+4fv8=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220321144137-d5a9af5860af/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220405074652-16f952270c1e h1:LmVuj/p99qS2gDyogAkVpurdUMGRdiJBFe7bhTDI3wY=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220405074652-16f952270c1e/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=

View file

@ -2,4 +2,4 @@ module github.com/nspcc-dev/neo-go/examples/nft
go 1.16
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220321144137-d5a9af5860af
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220405074652-16f952270c1e

View file

@ -1,2 +1,2 @@
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220321144137-d5a9af5860af h1:QO3pU/jSYyX3EHBX8BPO01oRkVhGBXPrQaQEhn+4fv8=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220321144137-d5a9af5860af/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220405074652-16f952270c1e h1:LmVuj/p99qS2gDyogAkVpurdUMGRdiJBFe7bhTDI3wY=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220405074652-16f952270c1e/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=

View file

@ -3,7 +3,7 @@ module github.com/nspcc-dev/neo-go/examples/nft-nd-nns
go 1.16
require (
github.com/nspcc-dev/neo-go v0.98.3-pre.0.20220321144433-3b639f518ebb
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220321144137-d5a9af5860af
github.com/nspcc-dev/neo-go v0.98.3-pre.0.20220405074910-7b5ff25a40a9
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220405074652-16f952270c1e
github.com/stretchr/testify v1.7.0
)

View file

@ -176,10 +176,10 @@ github.com/nspcc-dev/hrw v1.0.9 h1:17VcAuTtrstmFppBjfRiia4K2wA/ukXZhLFS8Y8rz5Y=
github.com/nspcc-dev/hrw v1.0.9/go.mod h1:l/W2vx83vMQo6aStyx2AuZrJ+07lGv2JQGlVkPG06MU=
github.com/nspcc-dev/neo-go v0.73.1-pre.0.20200303142215-f5a1b928ce09/go.mod h1:pPYwPZ2ks+uMnlRLUyXOpLieaDQSEaf4NM3zHVbRjmg=
github.com/nspcc-dev/neo-go v0.98.0/go.mod h1:E3cc1x6RXSXrJb2nDWXTXjnXk3rIqVN8YdFyWv+FrqM=
github.com/nspcc-dev/neo-go v0.98.3-pre.0.20220321144433-3b639f518ebb h1:NBswaBUXFAjIvlA1PjbTLh/A07co24DkXvKjz3ya78I=
github.com/nspcc-dev/neo-go v0.98.3-pre.0.20220321144433-3b639f518ebb/go.mod h1:ebS1+SqgUBck6nbJzVaf92CPtLhNt4rAYPlCzH71gNU=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220321144137-d5a9af5860af h1:QO3pU/jSYyX3EHBX8BPO01oRkVhGBXPrQaQEhn+4fv8=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220321144137-d5a9af5860af/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=
github.com/nspcc-dev/neo-go v0.98.3-pre.0.20220405074910-7b5ff25a40a9 h1:vZhVfrRRghbu+EbSvnCJLMnB68ndGQEhami7Yf28IWA=
github.com/nspcc-dev/neo-go v0.98.3-pre.0.20220405074910-7b5ff25a40a9/go.mod h1:CrxyjB/HEDbnU8yaWICPxowKxv5voeh6KLNxF413+ko=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220405074652-16f952270c1e h1:LmVuj/p99qS2gDyogAkVpurdUMGRdiJBFe7bhTDI3wY=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220405074652-16f952270c1e/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=
github.com/nspcc-dev/neofs-api-go/v2 v2.11.0-pre.0.20211201134523-3604d96f3fe1/go.mod h1:oS8dycEh8PPf2Jjp6+8dlwWyEv2Dy77h/XhhcdxYEFs=
github.com/nspcc-dev/neofs-api-go/v2 v2.11.1 h1:SVqc523pZsSaS9vnPS1mm3VV6b6xY0gvdA0uYJ/GWZQ=
github.com/nspcc-dev/neofs-api-go/v2 v2.11.1/go.mod h1:oS8dycEh8PPf2Jjp6+8dlwWyEv2Dy77h/XhhcdxYEFs=
@ -207,6 +207,7 @@ github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1Cpa
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/pierrec/lz4 v2.6.1+incompatible h1:9UY3+iC23yxF0UfGaYrGplQ+79Rg+h/q9FV9ix19jjM=
github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=

View file

@ -2,4 +2,4 @@ module github.com/nspcc-dev/neo-go/examples/nft-nd
go 1.16
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220321144137-d5a9af5860af
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220405074652-16f952270c1e

View file

@ -1,2 +1,2 @@
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220321144137-d5a9af5860af h1:QO3pU/jSYyX3EHBX8BPO01oRkVhGBXPrQaQEhn+4fv8=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220321144137-d5a9af5860af/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220405074652-16f952270c1e h1:LmVuj/p99qS2gDyogAkVpurdUMGRdiJBFe7bhTDI3wY=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220405074652-16f952270c1e/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=

View file

@ -2,4 +2,4 @@ module github.com/nspcc-dev/neo-go/examples/oracle
go 1.16
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220321144137-d5a9af5860af
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220405074652-16f952270c1e

View file

@ -1,2 +1,2 @@
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220321144137-d5a9af5860af h1:QO3pU/jSYyX3EHBX8BPO01oRkVhGBXPrQaQEhn+4fv8=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220321144137-d5a9af5860af/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220405074652-16f952270c1e h1:LmVuj/p99qS2gDyogAkVpurdUMGRdiJBFe7bhTDI3wY=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220405074652-16f952270c1e/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=

View file

@ -2,4 +2,4 @@ module github.com/nspcc-dev/neo-go/examples/runtime
go 1.16
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220321144137-d5a9af5860af
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220405074652-16f952270c1e

View file

@ -1,2 +1,2 @@
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220321144137-d5a9af5860af h1:QO3pU/jSYyX3EHBX8BPO01oRkVhGBXPrQaQEhn+4fv8=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220321144137-d5a9af5860af/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220405074652-16f952270c1e h1:LmVuj/p99qS2gDyogAkVpurdUMGRdiJBFe7bhTDI3wY=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220405074652-16f952270c1e/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=

View file

@ -2,4 +2,4 @@ module github.com/nspcc-dev/neo-go/examples/storage
go 1.16
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220321144137-d5a9af5860af
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220405074652-16f952270c1e

View file

@ -1,2 +1,2 @@
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220321144137-d5a9af5860af h1:QO3pU/jSYyX3EHBX8BPO01oRkVhGBXPrQaQEhn+4fv8=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220321144137-d5a9af5860af/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220405074652-16f952270c1e h1:LmVuj/p99qS2gDyogAkVpurdUMGRdiJBFe7bhTDI3wY=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220405074652-16f952270c1e/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=

View file

@ -2,4 +2,4 @@ module github.com/nspcc-dev/neo-go/examples/timer
go 1.16
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220321144137-d5a9af5860af
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220405074652-16f952270c1e

View file

@ -1,2 +1,2 @@
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220321144137-d5a9af5860af h1:QO3pU/jSYyX3EHBX8BPO01oRkVhGBXPrQaQEhn+4fv8=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220321144137-d5a9af5860af/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220405074652-16f952270c1e h1:LmVuj/p99qS2gDyogAkVpurdUMGRdiJBFe7bhTDI3wY=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220405074652-16f952270c1e/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=

View file

@ -2,4 +2,4 @@ module github.com/nspcc-dev/neo-go/examples/token
go 1.16
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220321144137-d5a9af5860af
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220405074652-16f952270c1e

View file

@ -1,2 +1,2 @@
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220321144137-d5a9af5860af h1:QO3pU/jSYyX3EHBX8BPO01oRkVhGBXPrQaQEhn+4fv8=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220321144137-d5a9af5860af/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220405074652-16f952270c1e h1:LmVuj/p99qS2gDyogAkVpurdUMGRdiJBFe7bhTDI3wY=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220405074652-16f952270c1e/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=

2
go.mod
View file

@ -11,7 +11,7 @@ require (
github.com/mr-tron/base58 v1.2.0
github.com/nspcc-dev/dbft v0.0.0-20210721160347-1b03241391ac
github.com/nspcc-dev/go-ordered-json v0.0.0-20220111165707-25110be27d22
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220321144137-d5a9af5860af
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220405074652-16f952270c1e
github.com/nspcc-dev/neofs-sdk-go v0.0.0-20220113123743-7f3162110659
github.com/nspcc-dev/rfc6979 v0.2.0
github.com/pierrec/lz4 v2.6.1+incompatible

4
go.sum
View file

@ -182,8 +182,8 @@ github.com/nspcc-dev/hrw v1.0.9 h1:17VcAuTtrstmFppBjfRiia4K2wA/ukXZhLFS8Y8rz5Y=
github.com/nspcc-dev/hrw v1.0.9/go.mod h1:l/W2vx83vMQo6aStyx2AuZrJ+07lGv2JQGlVkPG06MU=
github.com/nspcc-dev/neo-go v0.73.1-pre.0.20200303142215-f5a1b928ce09/go.mod h1:pPYwPZ2ks+uMnlRLUyXOpLieaDQSEaf4NM3zHVbRjmg=
github.com/nspcc-dev/neo-go v0.98.0/go.mod h1:E3cc1x6RXSXrJb2nDWXTXjnXk3rIqVN8YdFyWv+FrqM=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220321144137-d5a9af5860af h1:QO3pU/jSYyX3EHBX8BPO01oRkVhGBXPrQaQEhn+4fv8=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220321144137-d5a9af5860af/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220405074652-16f952270c1e h1:LmVuj/p99qS2gDyogAkVpurdUMGRdiJBFe7bhTDI3wY=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220405074652-16f952270c1e/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=
github.com/nspcc-dev/neofs-api-go/v2 v2.11.0-pre.0.20211201134523-3604d96f3fe1/go.mod h1:oS8dycEh8PPf2Jjp6+8dlwWyEv2Dy77h/XhhcdxYEFs=
github.com/nspcc-dev/neofs-api-go/v2 v2.11.1 h1:SVqc523pZsSaS9vnPS1mm3VV6b6xY0gvdA0uYJ/GWZQ=
github.com/nspcc-dev/neofs-api-go/v2 v2.11.1/go.mod h1:oS8dycEh8PPf2Jjp6+8dlwWyEv2Dy77h/XhhcdxYEFs=

View file

@ -89,6 +89,13 @@ func TestOracleContractValues(t *testing.T) {
require.EqualValues(t, oracle.MinimumResponseGas, native.MinimumResponseGas)
}
func TestLedgerVMStates(t *testing.T) {
require.EqualValues(t, ledger.NoneState, vm.NoneState)
require.EqualValues(t, ledger.HaltState, vm.HaltState)
require.EqualValues(t, ledger.FaultState, vm.FaultState)
require.EqualValues(t, ledger.BreakState, vm.BreakState)
}
type nativeTestCase struct {
method string
params []string
@ -151,6 +158,7 @@ func TestNativeHelpersCompile(t *testing.T) {
{"getTransaction", []string{u256}},
{"getTransactionFromBlock", []string{u256, "1"}},
{"getTransactionHeight", []string{u256}},
{"getTransactionVMState", []string{u256}},
})
runNativeTestCases(t, cs.Notary.ContractMD, "notary", []nativeTestCase{
{"lockDepositUntil", []string{u160, "123"}},
@ -175,6 +183,7 @@ func TestNativeHelpersCompile(t *testing.T) {
runNativeTestCases(t, cs.Crypto.ContractMD, "crypto", []nativeTestCase{
{"sha256", []string{"[]byte{1, 2, 3}"}},
{"ripemd160", []string{"[]byte{1, 2, 3}"}},
{"murmur32", []string{"[]byte{1, 2, 3}", "123"}},
{"verifyWithECDsa", []string{"[]byte{1, 2, 3}", pub, sig, "crypto.Secp256k1"}},
})
runNativeTestCases(t, cs.Std.ContractMD, "std", []nativeTestCase{

View file

@ -25,6 +25,9 @@ var (
// ErrHasConflicts is returned when transaction is in the list of conflicting
// transactions which are already in dao.
ErrHasConflicts = errors.New("transaction has conflicts")
// ErrInternalDBInconsistency is returned when the format of retrieved DAO
// record is unexpected.
ErrInternalDBInconsistency = errors.New("internal DB inconsistency")
)
// Simple is memCached wrapper around DB, simple DAO implementation.
@ -251,21 +254,17 @@ func (dao *Simple) GetAppExecResults(hash util.Uint256, trig trigger.Type) ([]st
if err != nil {
return nil, err
}
r := io.NewBinReaderFromBuf(bs)
switch r.ReadB() {
if len(bs) == 0 {
return nil, fmt.Errorf("%w: empty execution log", ErrInternalDBInconsistency)
}
switch bs[0] {
case storage.ExecBlock:
r := io.NewBinReaderFromBuf(bs)
_ = r.ReadB()
_, err = block.NewTrimmedFromReader(dao.Version.StateRootInHeader, r)
if err != nil {
return nil, err
}
case storage.ExecTransaction:
_ = r.ReadU32LE()
tx := &transaction.Transaction{}
tx.DecodeBinary(r)
}
if r.Err != nil {
return nil, r.Err
}
result := make([]state.AppExecResult, 0, 2)
for {
aer := new(state.AppExecResult)
@ -281,6 +280,58 @@ func (dao *Simple) GetAppExecResults(hash util.Uint256, trig trigger.Type) ([]st
}
}
return result, nil
case storage.ExecTransaction:
_, _, aer, err := decodeTxAndExecResult(bs)
if err != nil {
return nil, err
}
if aer.Trigger&trig != 0 {
return []state.AppExecResult{*aer}, nil
}
return nil, nil
default:
return nil, fmt.Errorf("%w: unexpected executable prefix %d", ErrInternalDBInconsistency, bs[0])
}
}
// GetTxExecResult gets application execution result of the specified transaction
// and returns the transaction itself, its height and its AppExecResult.
func (dao *Simple) GetTxExecResult(hash util.Uint256) (uint32, *transaction.Transaction, *state.AppExecResult, error) {
key := dao.makeExecutableKey(hash)
bs, err := dao.Store.Get(key)
if err != nil {
return 0, nil, nil, err
}
if len(bs) == 0 {
return 0, nil, nil, fmt.Errorf("%w: empty execution log", ErrInternalDBInconsistency)
}
if bs[0] != storage.ExecTransaction {
return 0, nil, nil, storage.ErrKeyNotFound
}
return decodeTxAndExecResult(bs)
}
// decodeTxAndExecResult decodes transaction, its height and execution result from
// the given executable bytes. It performs no executable prefix check.
func decodeTxAndExecResult(buf []byte) (uint32, *transaction.Transaction, *state.AppExecResult, error) {
if len(buf) >= 6 && buf[5] == transaction.DummyVersion {
return 0, nil, nil, storage.ErrKeyNotFound
}
r := io.NewBinReaderFromBuf(buf)
_ = r.ReadB()
h := r.ReadU32LE()
tx := &transaction.Transaction{}
tx.DecodeBinary(r)
if r.Err != nil {
return 0, nil, nil, r.Err
}
aer := new(state.AppExecResult)
aer.DecodeBinary(r)
if r.Err != nil {
return 0, nil, nil, r.Err
}
return h, tx, aer, nil
}
// -- end notification event.
@ -355,7 +406,8 @@ func (dao *Simple) getBlock(key []byte) (*block.Block, error) {
r := io.NewBinReaderFromBuf(b)
if r.ReadB() != storage.ExecBlock {
return nil, errors.New("internal DB inconsistency")
// It may be a transaction.
return nil, storage.ErrKeyNotFound
}
block, err := block.NewTrimmedFromReader(dao.Version.StateRootInHeader, r)
if err != nil {
@ -519,7 +571,8 @@ func (dao *Simple) GetTransaction(hash util.Uint256) (*transaction.Transaction,
return nil, 0, errors.New("bad transaction bytes")
}
if b[0] != storage.ExecTransaction {
return nil, 0, errors.New("internal DB inconsistency")
// It may be a block.
return nil, 0, storage.ErrKeyNotFound
}
if b[5] == transaction.DummyVersion {
return nil, 0, storage.ErrKeyNotFound

View file

@ -2,6 +2,7 @@ package native
import (
"crypto/elliptic"
"encoding/binary"
"errors"
"fmt"
@ -14,6 +15,7 @@ import (
"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/vm/stackitem"
"github.com/twmb/murmur3"
)
// Crypto represents CryptoLib contract.
@ -46,6 +48,12 @@ func newCrypto() *Crypto {
md = newMethodAndPrice(c.ripemd160, 1<<15, callflag.NoneFlag)
c.AddMethod(md, desc)
desc = newDescriptor("murmur32", smartcontract.ByteArrayType,
manifest.NewParameter("data", smartcontract.ByteArrayType),
manifest.NewParameter("seed", smartcontract.IntegerType))
md = newMethodAndPrice(c.murmur32, 1<<13, callflag.NoneFlag)
c.AddMethod(md, desc)
desc = newDescriptor("verifyWithECDsa", smartcontract.BoolType,
manifest.NewParameter("message", smartcontract.ByteArrayType),
manifest.NewParameter("pubkey", smartcontract.ByteArrayType),
@ -72,6 +80,18 @@ func (c *Crypto) ripemd160(_ *interop.Context, args []stackitem.Item) stackitem.
return stackitem.NewByteArray(hash.RipeMD160(bs).BytesBE())
}
func (c *Crypto) murmur32(_ *interop.Context, args []stackitem.Item) stackitem.Item {
bs, err := args[0].TryBytes()
if err != nil {
panic(err)
}
seed := toUint32(args[1])
h := murmur3.SeedSum32(seed, bs)
result := make([]byte, 4)
binary.LittleEndian.PutUint32(result, h)
return stackitem.NewByteArray(result)
}
func (c *Crypto) verifyWithECDsa(_ *interop.Context, args []stackitem.Item) stackitem.Item {
msg, err := args[0].TryBytes()
if err != nil {

View file

@ -1,6 +1,7 @@
package native
import (
"encoding/binary"
"encoding/hex"
"math"
"math/big"
@ -43,6 +44,26 @@ func TestRIPEMD160(t *testing.T) {
})
}
func TestMurmur32(t *testing.T) {
c := newCrypto()
ic := &interop.Context{VM: vm.New()}
t.Run("bad arg type", func(t *testing.T) {
require.Panics(t, func() {
c.murmur32(ic, []stackitem.Item{stackitem.NewInterop(nil), stackitem.Make(5)})
})
})
t.Run("good", func(t *testing.T) {
// Example from the C# node:
// https://github.com/neo-project/neo/blob/2a64c1cc809d1ff4b3a573c7c22bffbbf69a738b/tests/neo.UnitTests/Cryptography/UT_Murmur32.cs#L18
data := []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1}
seed := 10
expected := make([]byte, 4)
binary.LittleEndian.PutUint32(expected, 378574820)
require.Equal(t, expected, c.murmur32(ic, []stackitem.Item{stackitem.NewByteArray(data), stackitem.Make(seed)}).Value().([]byte))
})
}
func TestCryptoLibVerifyWithECDsa(t *testing.T) {
t.Run("R1", func(t *testing.T) {
testECDSAVerify(t, Secp256r1)

View file

@ -14,6 +14,7 @@ import (
"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/util"
"github.com/nspcc-dev/neo-go/pkg/vm"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
)
@ -62,6 +63,11 @@ func newLedger() *Ledger {
md = newMethodAndPrice(l.getTransactionFromBlock, 1<<16, callflag.ReadStates)
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
}
@ -142,6 +148,19 @@ func (l *Ledger) getTransactionFromBlock(ic *interop.Context, params []stackitem
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
// the block with index specified.
func isTraceableBlock(bc interop.Ledger, index uint32) bool {
@ -166,25 +185,29 @@ func getBlockHashFromItem(bc interop.Ledger, item stackitem.Item) util.Uint256 {
}
return bc.GetHeaderHash(int(index))
}
bytes, err := item.TryBytes()
if err != nil {
panic(err)
}
hash, err := util.Uint256DecodeBytesBE(bytes)
hash, err := getUint256FromItem(item)
if err != nil {
panic(err)
}
return hash
}
func getUint256FromItem(item stackitem.Item) (util.Uint256, error) {
hashbytes, err := item.TryBytes()
if err != nil {
return util.Uint256{}, fmt.Errorf("failed to get hash bytes: %w", err)
}
hash, err := util.Uint256DecodeBytesBE(hashbytes)
if err != nil {
return util.Uint256{}, fmt.Errorf("failed to decode hash: %w", err)
}
return hash, nil
}
// getTransactionAndHeight returns transaction and its height if it's present
// on the chain. It panics if anything goes wrong.
func getTransactionAndHeight(d *dao.Simple, item stackitem.Item) (*transaction.Transaction, uint32, error) {
hashbytes, err := item.TryBytes()
if err != nil {
panic(err)
}
hash, err := util.Uint256DecodeBytesBE(hashbytes)
hash, err := getUint256FromItem(item)
if err != nil {
panic(err)
}

View file

@ -5,11 +5,11 @@ import (
"testing"
"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/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/vm"
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
"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) {
c := newLedgerClient(t)
e := c.Executor

View file

@ -32,6 +32,12 @@ func Ripemd160(b []byte) interop.Hash160 {
return neogointernal.CallWithToken(Hash, "ripemd160", int(contract.NoneFlag), b).(interop.Hash160)
}
// Murmur32 calls `murmur32` method of native CryptoLib contract and computes Murmur32 hash of b
// using the given seed.
func Murmur32(b []byte, seed int) []byte {
return neogointernal.CallWithToken(Hash, "murmur32", int(contract.NoneFlag), b, seed).([]byte)
}
// VerifyWithECDsa calls `verifyWithECDsa` method of native CryptoLib contract and checks that sig is
// correct msg's signature for a given pub (serialized public key on a given curve).
func VerifyWithECDsa(msg []byte, pub interop.PublicKey, sig interop.Signature, curve NamedCurve) bool {

View file

@ -13,6 +13,21 @@ import (
// 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"
// 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.
func CurrentHash() 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),
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)
}

View file

@ -10,14 +10,14 @@ type State uint8
// Available States.
const (
// NoneState represents NONE VM state.
NoneState State = 0
// HaltState represents HALT VM state.
HaltState State = 1 << iota
// FaultState represents FAULT VM state.
FaultState
// BreakState represents BREAK VM state.
BreakState
// NoneState represents NONE VM state.
NoneState State = 0
)
// HasFlag checks for State flag presence.

View file

@ -86,3 +86,12 @@ func TestState_UnmarshalJSON(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, NoneState, s)
}
// TestState_EnumCompat tests that byte value of State matches the C#'s one got from
// https://github.com/neo-project/neo-vm/blob/0028d862e253bda3c12eb8bb007a2d95822d3922/src/neo-vm/VMState.cs#L16.
func TestState_EnumCompat(t *testing.T) {
assert.Equal(t, byte(0), byte(NoneState))
assert.Equal(t, byte(1<<0), byte(HaltState))
assert.Equal(t, byte(1<<1), byte(FaultState))
assert.Equal(t, byte(1<<2), byte(BreakState))
}