From 8553320e1c611d0462339f48fbd5b36358f33b83 Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Tue, 26 Oct 2021 14:28:14 +0300 Subject: [PATCH] [#161] tests: reuse neo-go testing framework Signed-off-by: Evgenii Stratonikov --- go.mod | 3 +- go.sum | 31 +--- tests/balance_test.go | 18 ++- tests/basic.go | 282 ---------------------------------- tests/compile.go | 69 --------- tests/container_test.go | 267 ++++++++++++++------------------- tests/helpers.go | 11 ++ tests/netmap_test.go | 84 +++++------ tests/nns_test.go | 325 ++++++++++++++++------------------------ tests/util.go | 13 ++ 10 files changed, 324 insertions(+), 779 deletions(-) delete mode 100644 tests/basic.go delete mode 100644 tests/compile.go create mode 100644 tests/helpers.go create mode 100644 tests/util.go diff --git a/go.mod b/go.mod index dc88759..490162d 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,6 @@ go 1.14 require ( github.com/mr-tron/base58 v1.2.0 - github.com/nspcc-dev/neo-go v0.97.2 + github.com/nspcc-dev/neo-go v0.97.4-pre.0.20211115125313-0e1fe2f58b1a github.com/stretchr/testify v1.7.0 - go.uber.org/zap v1.18.1 ) diff --git a/go.sum b/go.sum index b777ebf..6109474 100644 --- a/go.sum +++ b/go.sum @@ -5,13 +5,9 @@ github.com/CityOfZion/neo-go v0.62.1-pre.0.20191114145240-e740fbe708f8/go.mod h1 github.com/CityOfZion/neo-go v0.70.1-pre.0.20191209120015-fccb0085941e/go.mod h1:0enZl0az8xA6PVkwzEOwPWVJGqlt/GO4hA4kmQ5Xzig= github.com/CityOfZion/neo-go v0.70.1-pre.0.20191212173117-32ac01130d4c/go.mod h1:JtlHfeqLywZLswKIKFnAp+yzezY4Dji9qlfQKB2OD/I= github.com/CityOfZion/neo-go v0.71.1-pre.0.20200129171427-f773ec69fb84/go.mod h1:FLI526IrRWHmcsO+mHsCbj64pJZhwQFTLJZu+A4PGOA= -github.com/DataDog/zstd v1.4.1 h1:3oxKN3wbHibqx897utPC2LTQU4J+IHWWJO+glkAkpFM= github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= -github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/Workiva/go-datastructures v1.0.50/go.mod h1:Z+F2Rca0qCsVYDS8z7bAGm8f3UkzuWYS/oBZz5a7VVA= -github.com/Workiva/go-datastructures v1.0.53 h1:J6Y/52yX10Xc5JjXmGtWoSSxs3mZnGSaq37xZZh7Yig= -github.com/Workiva/go-datastructures v1.0.53/go.mod h1:1yZL+zfsztete+ePzZz/Zb1/t5BnDuE2Ya2MMGhzP6A= github.com/abiosoft/ishell v2.0.0+incompatible/go.mod h1:HQR9AqF2R3P4XXpMpI0NAzgHf/aS6+zVXRj14cVk9qg= github.com/abiosoft/ishell/v2 v2.0.2/go.mod h1:E4oTCXfo6QjoCart0QYa5m9w4S+deXs/P/9jA77A9Bs= github.com/abiosoft/readline v0.0.0-20180607040430-155bce2042db/go.mod h1:rB3B4rKii8V21ydCbIzH5hZiCQE7f5E9SzUb/ZZx530= @@ -22,12 +18,7 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/alicebob/gopher-json v0.0.0-20180125190556-5a6b3ba71ee6/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc= -github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a h1:HbKu58rmZpUGpz5+4FfNmIU+FmZg2P3Xaj2v2bfNWmk= -github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc= -github.com/alicebob/miniredis v2.5.0+incompatible h1:yBHoLpsyjupjz3NL3MhKMVkR41j82Yjf3KFv7ApYzUI= github.com/alicebob/miniredis v2.5.0+incompatible/go.mod h1:8HZjEj4yU0dwhYHky+DxYx+6BMjkBbe5ONFIF1MXffk= -github.com/alicebob/miniredis/v2 v2.15.1 h1:Fw+ixAJPmKhCLBqDwHlTDqxUxp0xjEwXczEpt1B6r7k= -github.com/alicebob/miniredis/v2 v2.15.1/go.mod h1:gquAfGbzn92jvtrSC69+6zZnwSODVXVpYDRaGhWaL6I= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= @@ -71,13 +62,9 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= -github.com/dgraph-io/badger/v2 v2.0.3 h1:inzdf6VF/NZ+tJ8RwwYMjJMvsOALTHYdozn0qSl6XJI= github.com/dgraph-io/badger/v2 v2.0.3/go.mod h1:3KY8+bsP8wI0OEnQJAKpd4wIJW/Mm32yw2j/9FUVnIM= -github.com/dgraph-io/ristretto v0.0.2-0.20200115201040-8f368f2f2ab3 h1:MQLRM35Pp0yAyBYksjbj1nZI/w6eyRY/mWoM1sFf4kU= github.com/dgraph-io/ristretto v0.0.2-0.20200115201040-8f368f2f2ab3/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= -github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= -github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -97,8 +84,6 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9 github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-redis/redis v6.10.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= -github.com/go-redis/redis v6.15.9+incompatible h1:K0pv1D7EQUjfyoMql+r/jZqCLizCGKFlFgcHWWmHQjg= -github.com/go-redis/redis v6.15.9+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= @@ -185,13 +170,17 @@ github.com/nspcc-dev/dbft v0.0.0-20200219114139-199d286ed6c1/go.mod h1:O0qtn62pr github.com/nspcc-dev/dbft v0.0.0-20200711144034-c526ccc6f570/go.mod h1:1FYQXSbb6/9HQIkoF8XO7W/S8N7AZRkBsgwbcXRvk0E= github.com/nspcc-dev/dbft v0.0.0-20210302103605-cc75991b7cfb/go.mod h1:U8MSnEShH+o5hexfWJdze6uMFJteP0ko7J2frO7Yu1Y= github.com/nspcc-dev/dbft v0.0.0-20210721160347-1b03241391ac/go.mod h1:U8MSnEShH+o5hexfWJdze6uMFJteP0ko7J2frO7Yu1Y= +github.com/nspcc-dev/go-ordered-json v0.0.0-20210915112629-e1b6cce73d02 h1:JgRx27vfGw5WV5QbaNDy0iy2WD1XJO964wwAapaYKLg= +github.com/nspcc-dev/go-ordered-json v0.0.0-20210915112629-e1b6cce73d02/go.mod h1:79bEUDEviBHJMFV6Iq6in57FEOCMcRhfQnfaf0ETA5U= 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.91.0/go.mod h1:G6HdOWvzQ6tlvFdvFSN/PgCzLPN/X/X4d5hTjFRUDcc= github.com/nspcc-dev/neo-go v0.95.1/go.mod h1:bW07ge1WFXsBgqrcPpLUr6OcyQxHqM26MZNesWMdH0c= -github.com/nspcc-dev/neo-go v0.97.2 h1:oENXAc0ORjfYfFVyHy6aMyMLTosZsmSGeKgOvYGN3Eg= -github.com/nspcc-dev/neo-go v0.97.2/go.mod h1:yguwQBpWMTHx07INKoElJT8Gga1LUdTSi0gT75ywJ68= +github.com/nspcc-dev/neo-go v0.97.4-pre.0.20211111084655-0a7f8afcea5d h1:h3duQCMpHn0Vq1qeKYVdK5RQyNPu8JfpUrC9S9EsLZU= +github.com/nspcc-dev/neo-go v0.97.4-pre.0.20211111084655-0a7f8afcea5d/go.mod h1:i6TJVL2vwddNlP1CftD0b8qZ2mcTi9DzYxOlxkXxgg0= +github.com/nspcc-dev/neo-go v0.97.4-pre.0.20211115125313-0e1fe2f58b1a h1:H8BHO5syx7qT6LrRwLPbWunQCeaaveAnjunBiK1XGzg= +github.com/nspcc-dev/neo-go v0.97.4-pre.0.20211115125313-0e1fe2f58b1a/go.mod h1:i6TJVL2vwddNlP1CftD0b8qZ2mcTi9DzYxOlxkXxgg0= github.com/nspcc-dev/neofs-api-go v1.24.0/go.mod h1:G7dqincfdjBrAbL5nxVp82emF05fSVEqe59ICsoRDI8= github.com/nspcc-dev/neofs-api-go v1.27.1 h1:ONdKOnm0/hK6m38VTUliCHY6RTxg+IpAzY4G+BeOZG4= github.com/nspcc-dev/neofs-api-go v1.27.1/go.mod h1:i0Cwgvcu9A4M4e58pydbXFisUhSxpfljmuWFPIp2btE= @@ -217,7 +206,6 @@ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7J 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/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/philhofer/fwd v1.1.1/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= github.com/pierrec/lz4 v2.5.2+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= 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= @@ -277,8 +265,6 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/syndtr/goleveldb v0.0.0-20180307113352-169b1b37be73/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0= github.com/syndtr/goleveldb v1.0.1-0.20210305035536-64b5b1c73954 h1:xQdMZ1WLrgkkvOZ/LDQxjVxMLdby7osSh4ZEVa5sIjs= github.com/syndtr/goleveldb v1.0.1-0.20210305035536-64b5b1c73954/go.mod h1:u2MKkTVTVJWe5D1rCvame8WqhBd88EuIwODJZ1VHCPM= -github.com/tinylib/msgp v1.1.5/go.mod h1:eQsjooMTnV42mHu917E26IogZ2930nFyBQdofk10Udg= -github.com/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31/go.mod h1:onvgF043R+lC5RZ8IT9rBXDaEDnpnw/Cl+HFiw+v/7Q= github.com/twmb/murmur3 v1.1.5 h1:i9OLS9fkuLzBXjt6dptlAEyk58fJsSTXbRg3SgVyqgk= github.com/twmb/murmur3 v1.1.5/go.mod h1:Qq/R7NUyOfr65zD+6Q5IHKsJLwP7exErjN6lyyq3OSQ= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= @@ -291,8 +277,6 @@ github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1: github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/gopher-lua v0.0.0-20190514113301-1cd887cd7036/go.mod h1:gqRgreBUhTSL0GeU64rtZ3Uq3wtjOa/TB2YfrtkCbVQ= github.com/yuin/gopher-lua v0.0.0-20191128022950-c6266f4fe8d7/go.mod h1:gqRgreBUhTSL0GeU64rtZ3Uq3wtjOa/TB2YfrtkCbVQ= -github.com/yuin/gopher-lua v0.0.0-20200816102855-ee81675732da h1:NimzV1aGyq29m5ukMK0AMWEhFaL/lrEOaephfuoiARg= -github.com/yuin/gopher-lua v0.0.0-20200816102855-ee81675732da/go.mod h1:E1AXubJBdNmFERAOucpDIxNzeGfLzg0mYh+UfMWdChA= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU= @@ -353,8 +337,9 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a h1:DcqTD9SDLc+1P/r1EmRBwnVsrOwW+kk2vWf9n+1sGhs= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= diff --git a/tests/balance_test.go b/tests/balance_test.go index 7bf564c..03b076e 100644 --- a/tests/balance_test.go +++ b/tests/balance_test.go @@ -1,24 +1,28 @@ package tests import ( + "path" "testing" - "github.com/nspcc-dev/neo-go/pkg/core" + "github.com/nspcc-dev/neo-go/pkg/neotest" "github.com/nspcc-dev/neo-go/pkg/util" - "github.com/nspcc-dev/neo-go/pkg/wallet" + "github.com/nspcc-dev/neo-go/pkg/vm/stackitem" ) const balancePath = "../balance" -func deployBalanceContract(t *testing.T, bc *core.Blockchain, addrNetmap, addrContainer util.Uint160) util.Uint160 { +func deployBalanceContract(t *testing.T, e *neotest.Executor, addrNetmap, addrContainer util.Uint160) util.Uint160 { + c := neotest.CompileFile(t, e.CommitteeHash, balancePath, path.Join(balancePath, "config.yml")) + args := make([]interface{}, 3) args[0] = false args[1] = addrNetmap args[2] = addrContainer - return DeployContract(t, bc, balancePath, args) + + e.DeployContract(t, c, args) + return c.Hash } -func balanceMint(t *testing.T, bc *core.Blockchain, acc *wallet.Account, h util.Uint160, amount int64, details []byte) { - tx := PrepareInvoke(t, bc, CommitteeAcc, h, "mint", acc.Contract.ScriptHash(), amount, details) - AddBlockCheckHalt(t, bc, tx) +func balanceMint(t *testing.T, c *neotest.ContractInvoker, acc neotest.Signer, amount int64, details []byte) { + c.Invoke(t, stackitem.Null{}, "mint", acc.ScriptHash(), amount, details) } diff --git a/tests/basic.go b/tests/basic.go deleted file mode 100644 index 5fac96d..0000000 --- a/tests/basic.go +++ /dev/null @@ -1,282 +0,0 @@ -package tests - -import ( - "encoding/hex" - "encoding/json" - "math/rand" - "strings" - "testing" - - "github.com/nspcc-dev/neo-go/pkg/config" - "github.com/nspcc-dev/neo-go/pkg/config/netmode" - "github.com/nspcc-dev/neo-go/pkg/core" - "github.com/nspcc-dev/neo-go/pkg/core/block" - "github.com/nspcc-dev/neo-go/pkg/core/fee" - "github.com/nspcc-dev/neo-go/pkg/core/native" - "github.com/nspcc-dev/neo-go/pkg/core/state" - "github.com/nspcc-dev/neo-go/pkg/core/storage" - "github.com/nspcc-dev/neo-go/pkg/core/transaction" - "github.com/nspcc-dev/neo-go/pkg/crypto/keys" - "github.com/nspcc-dev/neo-go/pkg/io" - "github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag" - "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/emit" - "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/wallet" - "github.com/stretchr/testify/require" - "go.uber.org/zap/zaptest" -) - -const validatorWIF = "KxyjQ8eUa4FHt3Gvioyt1Wz29cTUrE4eTqX3yFSk1YFCsPL8uNsY" - -// CommitteeAcc is an account used to sign tx as a committee. -var CommitteeAcc *wallet.Account - -func init() { - CommitteeAcc, _ = wallet.NewAccountFromWIF(validatorWIF) - pubs := keys.PublicKeys{CommitteeAcc.PrivateKey().PublicKey()} - err := CommitteeAcc.ConvertMultisig(1, pubs) - if err != nil { - panic(err) - } -} - -var _nonce uint32 - -func nonce() uint32 { - _nonce++ - return _nonce -} - -// NewChain creates new blockchain instance with a single validator and -// setups cleanup functions. -func NewChain(t *testing.T) *core.Blockchain { - protoCfg := config.ProtocolConfiguration{ - Magic: netmode.UnitTestNet, - P2PSigExtensions: true, - SecondsPerBlock: 1, - StandbyCommittee: []string{hex.EncodeToString(CommitteeAcc.PrivateKey().PublicKey().Bytes())}, - ValidatorsCount: 1, - VerifyBlocks: true, - VerifyTransactions: true, - } - - st := storage.NewMemoryStore() - log := zaptest.NewLogger(t) - bc, err := core.NewBlockchain(st, protoCfg, log) - require.NoError(t, err) - go bc.Run() - t.Cleanup(bc.Close) - return bc -} - -// PrepareInvoke creates new invocation transaction. -// Signer can be either bool or *wallet.Account. -// In the first case `true` means sign by committee, `false` means sign by validators. -func PrepareInvoke(t *testing.T, bc *core.Blockchain, signer interface{}, - hash util.Uint160, method string, args ...interface{}) *transaction.Transaction { - w := io.NewBufBinWriter() - emit.AppCall(w.BinWriter, hash, method, callflag.All, args...) - require.NoError(t, w.Err) - - script := w.Bytes() - tx := transaction.New(script, 0) - tx.Nonce = nonce() - tx.ValidUntilBlock = bc.BlockHeight() + 1 - - switch s := signer.(type) { - case *wallet.Account: - tx.Signers = append(tx.Signers, transaction.Signer{ - Account: s.Contract.ScriptHash(), - Scopes: transaction.Global, - }) - require.NoError(t, addNetworkFee(bc, tx, s)) - require.NoError(t, addSystemFee(bc, tx)) - require.NoError(t, s.SignTx(netmode.UnitTestNet, tx)) - case []*wallet.Account: - for _, acc := range s { - tx.Signers = append(tx.Signers, transaction.Signer{ - Account: acc.Contract.ScriptHash(), - Scopes: transaction.Global, - }) - require.NoError(t, addNetworkFee(bc, tx, acc)) - } - require.NoError(t, addSystemFee(bc, tx)) - for _, acc := range s { - require.NoError(t, acc.SignTx(netmode.UnitTestNet, tx)) - } - default: - panic("invalid signer") - } - - return tx -} - -// NewAccount creates new account and transfers 100.0 GAS to it. -func NewAccount(t *testing.T, bc *core.Blockchain) *wallet.Account { - acc, err := wallet.NewAccount() - require.NoError(t, err) - - tx := PrepareInvoke(t, bc, CommitteeAcc, - bc.UtilityTokenHash(), "transfer", - CommitteeAcc.Contract.ScriptHash(), acc.Contract.ScriptHash(), int64(100_0000_0000), nil) - AddBlock(t, bc, tx) - CheckHalt(t, bc, tx.Hash()) - return acc -} - -// DeployContract compiles and deploys contract to bc. -// path should contain Go source files. -// data is an optional argument to `_deploy`. -func DeployContract(t *testing.T, bc *core.Blockchain, path string, data interface{}) util.Uint160 { - tx, h := newDeployTx(t, bc, path, data) - AddBlock(t, bc, tx) - CheckHalt(t, bc, tx.Hash()) - return h -} - -// CheckHalt checks that transaction persisted with HALT state. -func CheckHalt(t *testing.T, bc *core.Blockchain, h util.Uint256, stack ...stackitem.Item) *state.AppExecResult { - aer, err := bc.GetAppExecResults(h, trigger.Application) - require.NoError(t, err) - require.Equal(t, vm.HaltState, aer[0].VMState, aer[0].FaultException) - if len(stack) != 0 { - require.Equal(t, stack, aer[0].Stack) - } - return &aer[0] -} - -// CheckFault checks that transaction persisted with FAULT state. -// Raised exception is also checked to contain s as a substring. -func CheckFault(t *testing.T, bc *core.Blockchain, h util.Uint256, s string) { - aer, err := bc.GetAppExecResults(h, trigger.Application) - require.NoError(t, err) - require.Equal(t, vm.FaultState, aer[0].VMState) - require.True(t, strings.Contains(aer[0].FaultException, s), - "expected: %s, got: %s", s, aer[0].FaultException) -} - -// newDeployTx returns new deployment tx for contract. -func newDeployTx(t *testing.T, bc *core.Blockchain, ctrPath string, data interface{}) (*transaction.Transaction, util.Uint160) { - c, err := ContractInfo(CommitteeAcc.Contract.ScriptHash(), ctrPath) - require.NoError(t, err) - - rawManifest, err := json.Marshal(c.Manifest) - require.NoError(t, err) - - neb, err := c.NEF.Bytes() - require.NoError(t, err) - - buf := io.NewBufBinWriter() - emit.AppCall(buf.BinWriter, bc.ManagementContractHash(), "deploy", callflag.All, neb, rawManifest, data) - require.NoError(t, buf.Err) - - tx := transaction.New(buf.Bytes(), 100*native.GASFactor) - tx.Nonce = nonce() - tx.ValidUntilBlock = bc.BlockHeight() + 1 - tx.Signers = []transaction.Signer{{ - Account: CommitteeAcc.Contract.ScriptHash(), - Scopes: transaction.Global, - }} - require.NoError(t, addNetworkFee(bc, tx, CommitteeAcc)) - require.NoError(t, CommitteeAcc.SignTx(netmode.UnitTestNet, tx)) - return tx, c.Hash -} - -func addSystemFee(bc *core.Blockchain, tx *transaction.Transaction) error { - v, _ := TestInvoke(bc, tx) // ignore error to support failing transactions - tx.SystemFee = v.GasConsumed() - return nil -} - -func addNetworkFee(bc *core.Blockchain, tx *transaction.Transaction, sender *wallet.Account) error { - size := io.GetVarSize(tx) - netFee, sizeDelta := fee.Calculate(bc.GetBaseExecFee(), sender.Contract.Script) - tx.NetworkFee += netFee - size += sizeDelta - for _, cosigner := range tx.Signers { - contract := bc.GetContractState(cosigner.Account) - if contract != nil { - netFee, sizeDelta = fee.Calculate(bc.GetBaseExecFee(), contract.NEF.Script) - tx.NetworkFee += netFee - size += sizeDelta - } - } - tx.NetworkFee += int64(size) * bc.FeePerByte() - return nil -} - -// AddBlock creates a new block from provided transactions and adds it on bc. -func AddBlock(t *testing.T, bc *core.Blockchain, txs ...*transaction.Transaction) *block.Block { - return addCustomBlock(t, bc, nil, txs...) -} - -func addCustomBlock(t *testing.T, bc *core.Blockchain, blockFunc func(*block.Block), txs ...*transaction.Transaction) *block.Block { - lastBlock, err := bc.GetBlock(bc.GetHeaderHash(int(bc.BlockHeight()))) - require.NoError(t, err) - b := &block.Block{ - Header: block.Header{ - NextConsensus: CommitteeAcc.Contract.ScriptHash(), - Script: transaction.Witness{ - VerificationScript: CommitteeAcc.Contract.Script, - }, - Timestamp: lastBlock.Timestamp + 1, - }, - Transactions: txs, - } - b.PrevHash = lastBlock.Hash() - b.Index = bc.BlockHeight() + 1 - b.RebuildMerkleRoot() - if blockFunc != nil { - blockFunc(b) - } - - sign := CommitteeAcc.PrivateKey().SignHashable(uint32(netmode.UnitTestNet), b) - b.Script.InvocationScript = append([]byte{byte(opcode.PUSHDATA1), 64}, sign...) - require.NoError(t, bc.AddBlock(b)) - - return b -} - -// AddBlockCheckHalt is a convenient wrapper over AddBlock and CheckHalt. -func AddBlockCheckHalt(t *testing.T, bc *core.Blockchain, txs ...*transaction.Transaction) *block.Block { - b := AddBlock(t, bc, txs...) - for _, tx := range txs { - CheckHalt(t, bc, tx.Hash()) - } - return b -} - -// CheckTestInvoke executes transaction without persisting it's state and -// compares the result with the expected. -func CheckTestInvoke(t *testing.T, bc *core.Blockchain, tx *transaction.Transaction, expected interface{}) { - v, err := TestInvoke(bc, tx) - require.NoError(t, err) - require.Equal(t, 1, v.Estack().Len()) - require.Equal(t, stackitem.Make(expected), v.Estack().Pop().Item()) -} - -// TestInvoke creates a test VM with dummy block and executes transaction in it. -func TestInvoke(bc *core.Blockchain, tx *transaction.Transaction) (*vm.VM, error) { - lastBlock, err := bc.GetBlock(bc.GetHeaderHash(int(bc.BlockHeight()))) - if err != nil { - return nil, err - } - b := &block.Block{Header: block.Header{ - Index: bc.BlockHeight() + 1, - Timestamp: lastBlock.Timestamp + 1, - }} - v := bc.GetTestVM(trigger.Application, tx, b) - v.LoadWithFlags(tx.Script, callflag.All) - err = v.Run() - return v, err -} - -func randomBytes(n int) []byte { - a := make([]byte, n) - rand.Read(a) - return a -} diff --git a/tests/compile.go b/tests/compile.go deleted file mode 100644 index 8f4aa8a..0000000 --- a/tests/compile.go +++ /dev/null @@ -1,69 +0,0 @@ -package tests - -import ( - "path" - - "github.com/nspcc-dev/neo-go/cli/smartcontract" - "github.com/nspcc-dev/neo-go/pkg/compiler" - "github.com/nspcc-dev/neo-go/pkg/config" - "github.com/nspcc-dev/neo-go/pkg/core/state" - "github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest" - "github.com/nspcc-dev/neo-go/pkg/smartcontract/nef" - "github.com/nspcc-dev/neo-go/pkg/util" -) - -// Contract contains contract info for deployment. -type Contract struct { - Hash util.Uint160 - NEF *nef.File - Manifest *manifest.Manifest -} - -var contracts = map[string]*Contract{} - -// ContractInfo compiles contract and returns it's NEF, manifest and hash. -func ContractInfo(sender util.Uint160, ctrPath string) (*Contract, error) { - if c, ok := contracts[ctrPath]; ok { - return c, nil - } - - // nef.NewFile() cares about version a lot. - config.Version = "0.90.0-test" - - avm, di, err := compiler.CompileWithDebugInfo(ctrPath, nil) - if err != nil { - return nil, err - } - - ne, err := nef.NewFile(avm) - if err != nil { - return nil, err - } - - conf, err := smartcontract.ParseContractConfig(path.Join(ctrPath, "config.yml")) - if err != nil { - return nil, err - } - - o := &compiler.Options{} - o.Name = conf.Name - o.ContractEvents = conf.Events - o.ContractSupportedStandards = conf.SupportedStandards - o.Permissions = make([]manifest.Permission, len(conf.Permissions)) - for i := range conf.Permissions { - o.Permissions[i] = manifest.Permission(conf.Permissions[i]) - } - o.SafeMethods = conf.SafeMethods - m, err := compiler.CreateManifest(di, o) - if err != nil { - return nil, err - } - - c := &Contract{ - Hash: state.CreateContractHash(sender, ne.Checksum, m.Name), - NEF: ne, - Manifest: m, - } - contracts[ctrPath] = c - return c, nil -} diff --git a/tests/container_test.go b/tests/container_test.go index 2c323d9..a22f008 100644 --- a/tests/container_test.go +++ b/tests/container_test.go @@ -2,17 +2,16 @@ package tests import ( "crypto/sha256" - "strings" + "path" "testing" "github.com/mr-tron/base58" - "github.com/nspcc-dev/neo-go/pkg/core" + "github.com/nspcc-dev/neo-go/pkg/encoding/address" + "github.com/nspcc-dev/neo-go/pkg/neotest" "github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/vm/stackitem" - "github.com/nspcc-dev/neo-go/pkg/wallet" "github.com/nspcc-dev/neofs-contract/container" "github.com/nspcc-dev/neofs-contract/nns" - "github.com/stretchr/testify/require" ) const containerPath = "../container" @@ -22,7 +21,7 @@ const ( containerAliasFee = 0_0050_0000 ) -func deployContainerContract(t *testing.T, bc *core.Blockchain, addrNetmap, addrBalance, addrNNS util.Uint160) util.Uint160 { +func deployContainerContract(t *testing.T, e *neotest.Executor, addrNetmap, addrBalance, addrNNS util.Uint160) util.Uint160 { args := make([]interface{}, 6) args[0] = int64(0) args[1] = addrNetmap @@ -30,30 +29,31 @@ func deployContainerContract(t *testing.T, bc *core.Blockchain, addrNetmap, addr args[3] = util.Uint160{} // not needed for now args[4] = addrNNS args[5] = "neofs" - return DeployContract(t, bc, containerPath, args) + + c := neotest.CompileFile(t, e.CommitteeHash, containerPath, path.Join(containerPath, "config.yml")) + e.DeployContract(t, c, args) + return c.Hash } -func prepareContainerContract(t *testing.T, bc *core.Blockchain) (util.Uint160, util.Uint160) { - addrNNS := DeployContract(t, bc, nnsPath, nil) +func newContainerInvoker(t *testing.T) (*neotest.ContractInvoker, *neotest.ContractInvoker) { + e := newExecutor(t) - ctrNetmap, err := ContractInfo(CommitteeAcc.Contract.ScriptHash(), netmapPath) - require.NoError(t, err) + ctrNNS := neotest.CompileFile(t, e.CommitteeHash, nnsPath, path.Join(nnsPath, "config.yml")) + ctrNetmap := neotest.CompileFile(t, e.CommitteeHash, netmapPath, path.Join(netmapPath, "config.yml")) + ctrBalance := neotest.CompileFile(t, e.CommitteeHash, balancePath, path.Join(balancePath, "config.yml")) + ctrContainer := neotest.CompileFile(t, e.CommitteeHash, containerPath, path.Join(containerPath, "config.yml")) - ctrBalance, err := ContractInfo(CommitteeAcc.Contract.ScriptHash(), balancePath) - require.NoError(t, err) - - ctrContainer, err := ContractInfo(CommitteeAcc.Contract.ScriptHash(), containerPath) - require.NoError(t, err) - - deployNetmapContract(t, bc, ctrBalance.Hash, ctrContainer.Hash, + e.DeployContract(t, ctrNNS, nil) + deployNetmapContract(t, e, ctrBalance.Hash, ctrContainer.Hash, container.RegistrationFeeKey, int64(containerFee), container.AliasFeeKey, int64(containerAliasFee)) - balHash := deployBalanceContract(t, bc, ctrNetmap.Hash, ctrContainer.Hash) - return deployContainerContract(t, bc, ctrNetmap.Hash, ctrBalance.Hash, addrNNS), balHash + deployBalanceContract(t, e, ctrNetmap.Hash, ctrContainer.Hash) + deployContainerContract(t, e, ctrNetmap.Hash, ctrBalance.Hash, ctrNNS.Hash) + return e.CommitteeInvoker(ctrContainer.Hash), e.CommitteeInvoker(ctrBalance.Hash) } -func setContainerOwner(c []byte, acc *wallet.Account) { - owner, _ := base58.Decode(acc.Address) +func setContainerOwner(c []byte, acc neotest.Signer) { + owner, _ := base58.Decode(address.Uint160ToString(acc.ScriptHash())) copy(c[6:], owner) } @@ -62,7 +62,7 @@ type testContainer struct { value, sig, pub, token []byte } -func dummyContainer(owner *wallet.Account) testContainer { +func dummyContainer(owner neotest.Signer) testContainer { value := randomBytes(100) value[1] = 0 // zero offset setContainerOwner(value, owner) @@ -77,179 +77,146 @@ func dummyContainer(owner *wallet.Account) testContainer { } func TestContainerPut(t *testing.T) { - bc := NewChain(t) - h, balanceHash := prepareContainerContract(t, bc) + c, cBal := newContainerInvoker(t) - acc := NewAccount(t, bc) - c := dummyContainer(acc) + acc := c.NewAccount(t) + cnt := dummyContainer(acc) - putArgs := []interface{}{c.value, c.sig, c.pub, c.token} - tx := PrepareInvoke(t, bc, CommitteeAcc, h, "put", putArgs...) - AddBlock(t, bc, tx) - CheckFault(t, bc, tx.Hash(), "insufficient balance to create container") + putArgs := []interface{}{cnt.value, cnt.sig, cnt.pub, cnt.token} + c.InvokeFail(t, "insufficient balance to create container", "put", putArgs...) - balanceMint(t, bc, acc, balanceHash, containerFee*1, []byte{}) + balanceMint(t, cBal, acc, containerFee*1, []byte{}) - tx = PrepareInvoke(t, bc, acc, h, "put", putArgs...) - AddBlock(t, bc, tx) - CheckFault(t, bc, tx.Hash(), "alphabet witness check failed") + cAcc := c.WithSigners(acc) + cAcc.InvokeFail(t, "alphabet witness check failed", "put", putArgs...) - tx = PrepareInvoke(t, bc, CommitteeAcc, h, "put", putArgs...) - AddBlockCheckHalt(t, bc, tx) + c.Invoke(t, stackitem.Null{}, "put", putArgs...) t.Run("with nice names", func(t *testing.T) { - nnsHash := contracts[nnsPath].Hash + ctrNNS := neotest.CompileFile(t, c.CommitteeHash, nnsPath, path.Join(nnsPath, "config.yml")) + nnsHash := ctrNNS.Hash - balanceMint(t, bc, acc, balanceHash, containerFee*1, []byte{}) + balanceMint(t, cBal, acc, containerFee*1, []byte{}) - putArgs := []interface{}{c.value, c.sig, c.pub, c.token, "mycnt", ""} + putArgs := []interface{}{cnt.value, cnt.sig, cnt.pub, cnt.token, "mycnt", ""} t.Run("no fee for alias", func(t *testing.T) { - tx = PrepareInvoke(t, bc, acc, h, "putNamed", putArgs...) - AddBlock(t, bc, tx) - CheckFault(t, bc, tx.Hash(), "insufficient balance to create container") + c.InvokeFail(t, "insufficient balance to create container", "putNamed", putArgs...) }) - balanceMint(t, bc, acc, balanceHash, containerAliasFee*1, []byte{}) + balanceMint(t, cBal, acc, containerAliasFee*1, []byte{}) + c.Invoke(t, stackitem.Null{}, "putNamed", putArgs...) - tx = PrepareInvoke(t, bc, CommitteeAcc, h, "putNamed", putArgs...) - AddBlockCheckHalt(t, bc, tx) - - tx = PrepareInvoke(t, bc, acc, nnsHash, "resolve", "mycnt.neofs", int64(nns.TXT)) - CheckTestInvoke(t, bc, tx, stackitem.NewArray([]stackitem.Item{ - stackitem.NewByteArray([]byte(base58.Encode(c.id[:]))), - })) + expected := stackitem.NewArray([]stackitem.Item{ + stackitem.NewByteArray([]byte(base58.Encode(cnt.id[:]))), + }) + cNNS := c.CommitteeInvoker(nnsHash) + cNNS.Invoke(t, expected, "resolve", "mycnt.neofs", int64(nns.TXT)) t.Run("name is already taken", func(t *testing.T) { - tx = PrepareInvoke(t, bc, CommitteeAcc, h, "putNamed", putArgs...) - AddBlock(t, bc, tx) - CheckFault(t, bc, tx.Hash(), "name is already taken") + c.InvokeFail(t, "name is already taken", "putNamed", putArgs...) }) - tx = PrepareInvoke(t, bc, CommitteeAcc, h, "delete", c.id[:], c.sig, c.token) - AddBlockCheckHalt(t, bc, tx) - - tx = PrepareInvoke(t, bc, CommitteeAcc, nnsHash, "resolve", "mycnt.neofs", int64(nns.TXT)) - CheckTestInvoke(t, bc, tx, stackitem.Null{}) + c.Invoke(t, stackitem.Null{}, "delete", cnt.id[:], cnt.sig, cnt.token) + cNNS.Invoke(t, stackitem.Null{}, "resolve", "mycnt.neofs", int64(nns.TXT)) t.Run("register in advance", func(t *testing.T) { - c.value[len(c.value)-1] = 10 - c.id = sha256.Sum256(c.value) + cnt.value[len(cnt.value)-1] = 10 + cnt.id = sha256.Sum256(cnt.value) t.Run("bad domain owner", func(t *testing.T) { - tx = PrepareInvoke(t, bc, []*wallet.Account{acc, CommitteeAcc}, nnsHash, "register", - "baddomain.neofs", acc.Contract.ScriptHash(), + c1 := cNNS.WithSigners(acc, c.Committee) + c1.Invoke(t, true, "register", + "baddomain.neofs", acc.ScriptHash(), "whateveriwant@world.com", int64(0), int64(0), int64(0), int64(0)) - AddBlockCheckHalt(t, bc, tx) - tx = PrepareInvoke(t, bc, acc, h, "putNamed", - c.value, c.sig, c.pub, c.token, "baddomain", "neofs") - AddBlock(t, bc, tx) - CheckFault(t, bc, tx.Hash(), "committee or container contract must own registered domain") + cAcc.InvokeFail(t, "committee or container contract must own registered domain", + "putNamed", + cnt.value, cnt.sig, cnt.pub, cnt.token, "baddomain", "neofs") }) - tx = PrepareInvoke(t, bc, CommitteeAcc, nnsHash, "register", - "second.neofs", CommitteeAcc.Contract.ScriptHash(), + cNNS.Invoke(t, true, "register", + "second.neofs", c.CommitteeHash, "whateveriwant@world.com", int64(0), int64(0), int64(0), int64(0)) - AddBlockCheckHalt(t, bc, tx) - balanceMint(t, bc, acc, balanceHash, (containerFee+containerAliasFee)*1, []byte{}) + balanceMint(t, cBal, acc, (containerFee+containerAliasFee)*1, []byte{}) - putArgs := []interface{}{c.value, c.sig, c.pub, c.token, "second", "neofs"} - tx = PrepareInvoke(t, bc, []*wallet.Account{CommitteeAcc, acc}, h, "putNamed", putArgs...) - AddBlockCheckHalt(t, bc, tx) + putArgs := []interface{}{cnt.value, cnt.sig, cnt.pub, cnt.token, "second", "neofs"} + c2 := c.WithSigners(c.Committee, acc) + c2.Invoke(t, stackitem.Null{}, "putNamed", putArgs...) - tx = PrepareInvoke(t, bc, CommitteeAcc, nnsHash, "resolve", "second.neofs", int64(nns.TXT)) - CheckTestInvoke(t, bc, tx, stackitem.NewArray([]stackitem.Item{ - stackitem.NewByteArray([]byte(base58.Encode(c.id[:]))), - })) + expected = stackitem.NewArray([]stackitem.Item{ + stackitem.NewByteArray([]byte(base58.Encode(cnt.id[:])))}) + cNNS.Invoke(t, expected, "resolve", "second.neofs", int64(nns.TXT)) }) }) } func TestContainerDelete(t *testing.T) { - bc := NewChain(t) - h, balanceHash := prepareContainerContract(t, bc) + c, cBal := newContainerInvoker(t) - acc := NewAccount(t, bc) - c := dummyContainer(acc) + acc := c.NewAccount(t) + cnt := dummyContainer(acc) - balanceMint(t, bc, acc, balanceHash, containerFee*1, []byte{}) - tx := PrepareInvoke(t, bc, CommitteeAcc, h, "put", - c.value, c.sig, c.pub, c.token) - AddBlockCheckHalt(t, bc, tx) + balanceMint(t, cBal, acc, containerFee*1, []byte{}) + c.Invoke(t, stackitem.Null{}, "put", cnt.value, cnt.sig, cnt.pub, cnt.token) - tx = PrepareInvoke(t, bc, acc, h, "delete", c.id[:], c.sig, c.token) - AddBlock(t, bc, tx) - CheckFault(t, bc, tx.Hash(), "delete: alphabet witness check failed") + cAcc := c.WithSigners(acc) + cAcc.InvokeFail(t, "delete: alphabet witness check failed", "delete", + cnt.id[:], cnt.sig, cnt.token) - tx = PrepareInvoke(t, bc, CommitteeAcc, h, "delete", c.id[:], c.sig, c.token) - AddBlockCheckHalt(t, bc, tx) + c.Invoke(t, stackitem.Null{}, "delete", cnt.id[:], cnt.sig, cnt.token) t.Run("missing container", func(t *testing.T) { - id := c.id + id := cnt.id id[0] ^= 0xFF - tx = PrepareInvoke(t, bc, CommitteeAcc, h, "delete", id[:], c.sig, c.token) - AddBlockCheckHalt(t, bc, tx) + c.Invoke(t, stackitem.Null{}, "delete", cnt.id[:], cnt.sig, cnt.token) }) - tx = PrepareInvoke(t, bc, acc, h, "get", c.id[:]) - _, err := TestInvoke(bc, tx) - require.Error(t, err) - require.True(t, strings.Contains(err.Error(), container.NotFoundError)) + c.InvokeFail(t, container.NotFoundError, "get", cnt.id[:]) } func TestContainerOwner(t *testing.T) { - bc := NewChain(t) - h, balanceHash := prepareContainerContract(t, bc) + c, cBal := newContainerInvoker(t) - acc := NewAccount(t, bc) - balanceMint(t, bc, acc, balanceHash, containerFee*1, []byte{}) + acc := c.NewAccount(t) + cnt := dummyContainer(acc) - c := dummyContainer(acc) - tx := PrepareInvoke(t, bc, CommitteeAcc, h, "put", c.value, c.sig, c.pub, c.token) - AddBlockCheckHalt(t, bc, tx) + balanceMint(t, cBal, acc, containerFee*1, []byte{}) + c.Invoke(t, stackitem.Null{}, "put", cnt.value, cnt.sig, cnt.pub, cnt.token) t.Run("missing container", func(t *testing.T) { - id := c.id + id := cnt.id id[0] ^= 0xFF - tx = PrepareInvoke(t, bc, CommitteeAcc, h, "owner", id[:]) - _, err := TestInvoke(bc, tx) - require.Error(t, err) - require.True(t, strings.Contains(err.Error(), container.NotFoundError)) + c.InvokeFail(t, container.NotFoundError, "owner", id[:]) }) - tx = PrepareInvoke(t, bc, CommitteeAcc, h, "owner", c.id[:]) - owner, _ := base58.Decode(acc.Address) - CheckTestInvoke(t, bc, tx, stackitem.NewBuffer(owner)) + owner, _ := base58.Decode(address.Uint160ToString(acc.ScriptHash())) + c.Invoke(t, stackitem.NewBuffer(owner), "owner", cnt.id[:]) } func TestContainerGet(t *testing.T) { - bc := NewChain(t) - h, balanceHash := prepareContainerContract(t, bc) + c, cBal := newContainerInvoker(t) - acc := NewAccount(t, bc) - balanceMint(t, bc, acc, balanceHash, containerFee*1, []byte{}) + acc := c.NewAccount(t) + cnt := dummyContainer(acc) - c := dummyContainer(acc) - tx := PrepareInvoke(t, bc, CommitteeAcc, h, "put", c.value, c.sig, c.pub, c.token) - AddBlockCheckHalt(t, bc, tx) + balanceMint(t, cBal, acc, containerFee*1, []byte{}) + + c.Invoke(t, stackitem.Null{}, "put", cnt.value, cnt.sig, cnt.pub, cnt.token) t.Run("missing container", func(t *testing.T) { - id := c.id + id := cnt.id id[0] ^= 0xFF - tx = PrepareInvoke(t, bc, CommitteeAcc, h, "get", id[:]) - _, err := TestInvoke(bc, tx) - require.Error(t, err) - require.True(t, strings.Contains(err.Error(), container.NotFoundError)) + c.InvokeFail(t, container.NotFoundError, "get", id[:]) }) - tx = PrepareInvoke(t, bc, CommitteeAcc, h, "get", c.id[:]) - CheckTestInvoke(t, bc, tx, stackitem.NewStruct([]stackitem.Item{ - stackitem.NewByteArray(c.value), - stackitem.NewByteArray(c.sig), - stackitem.NewByteArray(c.pub), - stackitem.NewByteArray(c.token), - })) + expected := stackitem.NewStruct([]stackitem.Item{ + stackitem.NewByteArray(cnt.value), + stackitem.NewByteArray(cnt.sig), + stackitem.NewByteArray(cnt.pub), + stackitem.NewByteArray(cnt.token), + }) + c.Invoke(t, expected, "get", cnt.id[:]) } type eacl struct { @@ -271,39 +238,33 @@ func dummyEACL(containerID [32]byte) eacl { } func TestContainerSetEACL(t *testing.T) { - bc := NewChain(t) - h, balanceHash := prepareContainerContract(t, bc) + c, cBal := newContainerInvoker(t) - acc := NewAccount(t, bc) - balanceMint(t, bc, acc, balanceHash, containerFee*1, []byte{}) + acc := c.NewAccount(t) + cnt := dummyContainer(acc) + balanceMint(t, cBal, acc, containerFee*1, []byte{}) - c := dummyContainer(acc) - tx := PrepareInvoke(t, bc, CommitteeAcc, h, "put", c.value, c.sig, c.pub, c.token) - AddBlockCheckHalt(t, bc, tx) + c.Invoke(t, stackitem.Null{}, "put", cnt.value, cnt.sig, cnt.pub, cnt.token) t.Run("missing container", func(t *testing.T) { - id := c.id + id := cnt.id id[0] ^= 0xFF e := dummyEACL(id) - tx = PrepareInvoke(t, bc, CommitteeAcc, h, "setEACL", e.value, e.sig, e.pub, e.token) - _, err := TestInvoke(bc, tx) - require.Error(t, err) - require.True(t, strings.Contains(err.Error(), container.NotFoundError)) + c.InvokeFail(t, container.NotFoundError, "setEACL", e.value, e.sig, e.pub, e.token) }) - e := dummyEACL(c.id) - tx = PrepareInvoke(t, bc, acc, h, "setEACL", e.value, e.sig, e.pub, e.token) - AddBlock(t, bc, tx) - CheckFault(t, bc, tx.Hash(), "setEACL: alphabet witness check failed") + e := dummyEACL(cnt.id) + setArgs := []interface{}{e.value, e.sig, e.pub, e.token} + cAcc := c.WithSigners(acc) + cAcc.InvokeFail(t, "alphabet witness check failed", "setEACL", setArgs...) - tx = PrepareInvoke(t, bc, CommitteeAcc, h, "setEACL", e.value, e.sig, e.pub, e.token) - AddBlockCheckHalt(t, bc, tx) + c.Invoke(t, stackitem.Null{}, "setEACL", setArgs...) - tx = PrepareInvoke(t, bc, CommitteeAcc, h, "eACL", c.id[:]) - CheckTestInvoke(t, bc, tx, stackitem.NewStruct([]stackitem.Item{ + expected := stackitem.NewStruct([]stackitem.Item{ stackitem.NewByteArray(e.value), stackitem.NewByteArray(e.sig), stackitem.NewByteArray(e.pub), stackitem.NewByteArray(e.token), - })) + }) + c.Invoke(t, expected, "eACL", cnt.id[:]) } diff --git a/tests/helpers.go b/tests/helpers.go new file mode 100644 index 0000000..248f9c6 --- /dev/null +++ b/tests/helpers.go @@ -0,0 +1,11 @@ +package tests + +import ( + "math/rand" +) + +func randomBytes(n int) []byte { + a := make([]byte, n) + rand.Read(a) + return a +} diff --git a/tests/netmap_test.go b/tests/netmap_test.go index 98bf190..522f44f 100644 --- a/tests/netmap_test.go +++ b/tests/netmap_test.go @@ -3,90 +3,88 @@ package tests import ( "math/big" "math/rand" + "path" "testing" - "github.com/nspcc-dev/neo-go/pkg/core" "github.com/nspcc-dev/neo-go/pkg/encoding/bigint" + "github.com/nspcc-dev/neo-go/pkg/neotest" "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/wallet" "github.com/nspcc-dev/neofs-contract/container" "github.com/stretchr/testify/require" ) const netmapPath = "../netmap" -func deployNetmapContract(t *testing.T, bc *core.Blockchain, addrBalance, addrContainer util.Uint160, config ...interface{}) util.Uint160 { +func deployNetmapContract(t *testing.T, e *neotest.Executor, addrBalance, addrContainer util.Uint160, config ...interface{}) util.Uint160 { + _, pubs, ok := vm.ParseMultiSigContract(e.Committee.Script()) + require.True(t, ok) + args := make([]interface{}, 5) args[0] = false args[1] = addrBalance args[2] = addrContainer - args[3] = []interface{}{CommitteeAcc.PrivateKey().PublicKey().Bytes()} + args[3] = []interface{}{pubs[0]} args[4] = append([]interface{}{}, config...) - return DeployContract(t, bc, netmapPath, args) + + c := neotest.CompileFile(t, e.CommitteeHash, netmapPath, path.Join(netmapPath, "config.yml")) + e.DeployContract(t, c, args) + return c.Hash } -func prepareNetmapContract(t *testing.T, bc *core.Blockchain, config ...interface{}) util.Uint160 { - addrNNS := DeployContract(t, bc, nnsPath, nil) +func newNetmapInvoker(t *testing.T, config ...interface{}) *neotest.ContractInvoker { + e := newExecutor(t) - ctrNetmap, err := ContractInfo(CommitteeAcc.Contract.ScriptHash(), netmapPath) - require.NoError(t, err) + ctrNNS := neotest.CompileFile(t, e.CommitteeHash, nnsPath, path.Join(nnsPath, "config.yml")) + ctrNetmap := neotest.CompileFile(t, e.CommitteeHash, netmapPath, path.Join(netmapPath, "config.yml")) + ctrBalance := neotest.CompileFile(t, e.CommitteeHash, balancePath, path.Join(balancePath, "config.yml")) + ctrContainer := neotest.CompileFile(t, e.CommitteeHash, containerPath, path.Join(containerPath, "config.yml")) - ctrBalance, err := ContractInfo(CommitteeAcc.Contract.ScriptHash(), balancePath) - require.NoError(t, err) - - ctrContainer, err := ContractInfo(CommitteeAcc.Contract.ScriptHash(), containerPath) - require.NoError(t, err) - - deployContainerContract(t, bc, ctrNetmap.Hash, ctrBalance.Hash, addrNNS) - deployBalanceContract(t, bc, ctrNetmap.Hash, ctrContainer.Hash) - return deployNetmapContract(t, bc, ctrBalance.Hash, ctrContainer.Hash, config...) + e.DeployContract(t, ctrNNS, nil) + deployContainerContract(t, e, ctrNetmap.Hash, ctrBalance.Hash, ctrNNS.Hash) + deployBalanceContract(t, e, ctrNetmap.Hash, ctrContainer.Hash) + deployNetmapContract(t, e, ctrBalance.Hash, ctrContainer.Hash, config...) + return e.CommitteeInvoker(ctrNetmap.Hash) } func TestDeploySetConfig(t *testing.T) { - bc := NewChain(t) - h := prepareNetmapContract(t, bc, "SomeKey", "TheValue", container.AliasFeeKey, int64(123)) - - tx := PrepareInvoke(t, bc, CommitteeAcc, h, "config", "SomeKey") - CheckTestInvoke(t, bc, tx, "TheValue") - - tx = PrepareInvoke(t, bc, CommitteeAcc, h, "config", container.AliasFeeKey) - CheckTestInvoke(t, bc, tx, bigint.ToBytes(big.NewInt(123))) + c := newNetmapInvoker(t, "SomeKey", "TheValue", container.AliasFeeKey, int64(123)) + c.Invoke(t, "TheValue", "config", "SomeKey") + c.Invoke(t, stackitem.NewByteArray(bigint.ToBytes(big.NewInt(123))), + "config", container.AliasFeeKey) } -func dummyNodeInfo(acc *wallet.Account) []byte { +func dummyNodeInfo(acc neotest.Signer) []byte { ni := make([]byte, 66) rand.Read(ni) - copy(ni[2:], acc.PrivateKey().PublicKey().Bytes()) + + pub, _ := vm.ParseSignatureContract(acc.Script()) + copy(ni[2:], pub) return ni } func TestAddPeer(t *testing.T) { - bc := NewChain(t) - h := prepareNetmapContract(t, bc) + c := newNetmapInvoker(t) - acc := NewAccount(t, bc) + acc := c.NewAccount(t) + cAcc := c.WithSigners(acc) dummyInfo := dummyNodeInfo(acc) - acc1 := NewAccount(t, bc) - tx := PrepareInvoke(t, bc, acc1, h, "addPeer", dummyInfo) - AddBlock(t, bc, tx) - CheckFault(t, bc, tx.Hash(), "witness check failed") + acc1 := c.NewAccount(t) + cAcc1 := c.WithSigners(acc1) + cAcc1.InvokeFail(t, "witness check failed", "addPeer", dummyInfo) - tx = PrepareInvoke(t, bc, acc, h, "addPeer", dummyInfo) - AddBlock(t, bc, tx) - - aer := CheckHalt(t, bc, tx.Hash()) + h := cAcc.Invoke(t, stackitem.Null{}, "addPeer", dummyInfo) + aer := cAcc.CheckHalt(t, h) require.Equal(t, 1, len(aer.Events)) require.Equal(t, "AddPeer", aer.Events[0].Name) require.Equal(t, stackitem.NewArray([]stackitem.Item{stackitem.NewByteArray(dummyInfo)}), aer.Events[0].Item) dummyInfo[0] ^= 0xFF - tx = PrepareInvoke(t, bc, acc, h, "addPeer", dummyInfo) - AddBlock(t, bc, tx) - - aer = CheckHalt(t, bc, tx.Hash()) + h = cAcc.Invoke(t, stackitem.Null{}, "addPeer", dummyInfo) + aer = cAcc.CheckHalt(t, h) require.Equal(t, 1, len(aer.Events)) require.Equal(t, "AddPeer", aer.Events[0].Name) require.Equal(t, stackitem.NewArray([]stackitem.Item{stackitem.NewByteArray(dummyInfo)}), diff --git a/tests/nns_test.go b/tests/nns_test.go index 7c699b7..fe3d62f 100644 --- a/tests/nns_test.go +++ b/tests/nns_test.go @@ -3,14 +3,13 @@ package tests import ( "fmt" "math/big" - "strings" + "path" "testing" "time" - "github.com/nspcc-dev/neo-go/pkg/core/block" "github.com/nspcc-dev/neo-go/pkg/core/interop/storage" + "github.com/nspcc-dev/neo-go/pkg/neotest" "github.com/nspcc-dev/neo-go/pkg/vm/stackitem" - "github.com/nspcc-dev/neo-go/pkg/wallet" "github.com/nspcc-dev/neofs-contract/nns" "github.com/stretchr/testify/require" ) @@ -19,161 +18,141 @@ const nnsPath = "../nns" const msPerYear = 365 * 24 * time.Hour / time.Millisecond +func newNNSInvoker(t *testing.T, addRoot bool) *neotest.ContractInvoker { + e := newExecutor(t) + ctr := neotest.CompileFile(t, e.CommitteeHash, nnsPath, path.Join(nnsPath, "config.yml")) + e.DeployContract(t, ctr, nil) + + c := e.CommitteeInvoker(ctr.Hash) + if addRoot { + refresh, retry, expire, ttl := int64(101), int64(102), int64(103), int64(104) + c.Invoke(t, true, "register", + "com", c.CommitteeHash, + "myemail@nspcc.ru", refresh, retry, expire, ttl) + } + return c +} + func TestNNSGeneric(t *testing.T) { - bc := NewChain(t) - h := DeployContract(t, bc, nnsPath, nil) + c := newNNSInvoker(t, false) - tx := PrepareInvoke(t, bc, CommitteeAcc, h, "symbol") - CheckTestInvoke(t, bc, tx, "NNS") - - tx = PrepareInvoke(t, bc, CommitteeAcc, h, "decimals") - CheckTestInvoke(t, bc, tx, 0) - - tx = PrepareInvoke(t, bc, CommitteeAcc, h, "totalSupply") - CheckTestInvoke(t, bc, tx, 0) + c.Invoke(t, "NNS", "symbol") + c.Invoke(t, 0, "decimals") + c.Invoke(t, 0, "totalSupply") } func TestNNSRegisterTLD(t *testing.T) { - bc := NewChain(t) - h := DeployContract(t, bc, nnsPath, nil) + c := newNNSInvoker(t, false) refresh, retry, expire, ttl := int64(101), int64(102), int64(103), int64(104) - tx := PrepareInvoke(t, bc, CommitteeAcc, h, "register", - "0com", CommitteeAcc.Contract.ScriptHash(), - "email@nspcc.ru", refresh, retry, expire, ttl) - AddBlock(t, bc, tx) - CheckFault(t, bc, tx.Hash(), "invalid domain name format") - acc := NewAccount(t, bc) - tx = PrepareInvoke(t, bc, acc, h, "register", - "com", acc.Contract.ScriptHash(), + c.InvokeFail(t, "invalid domain name format", "register", + "0com", c.CommitteeHash, "email@nspcc.ru", refresh, retry, expire, ttl) - AddBlock(t, bc, tx) - CheckFault(t, bc, tx.Hash(), "not witnessed by committee") - tx = PrepareInvoke(t, bc, CommitteeAcc, h, "register", - "com", CommitteeAcc.Contract.ScriptHash(), + acc := c.NewAccount(t) + cAcc := c.WithSigners(acc) + cAcc.InvokeFail(t, "not witnessed by committee", "register", + "com", acc.ScriptHash(), "email@nspcc.ru", refresh, retry, expire, ttl) - AddBlock(t, bc, tx) - CheckHalt(t, bc, tx.Hash()) - tx = PrepareInvoke(t, bc, CommitteeAcc, h, "register", - "com", CommitteeAcc.Contract.ScriptHash(), + c.Invoke(t, true, "register", + "com", c.CommitteeHash, + "email@nspcc.ru", refresh, retry, expire, ttl) + + c.InvokeFail(t, "TLD already exists", "register", + "com", c.CommitteeHash, "email@nspcc.ru", refresh, retry, expire, ttl) - AddBlock(t, bc, tx) - CheckFault(t, bc, tx.Hash(), "TLD already exists") } func TestNNSRegister(t *testing.T) { - bc := NewChain(t) - h := DeployContract(t, bc, nnsPath, nil) + c := newNNSInvoker(t, false) - accTop := NewAccount(t, bc) + accTop := c.NewAccount(t) refresh, retry, expire, ttl := int64(101), int64(102), int64(103), int64(104) - tx := PrepareInvoke(t, bc, []*wallet.Account{CommitteeAcc, accTop}, h, "register", - "com", accTop.Contract.ScriptHash(), + c1 := c.WithSigners(c.Committee, accTop) + c1.Invoke(t, true, "register", + "com", accTop.ScriptHash(), "myemail@nspcc.ru", refresh, retry, expire, ttl) - AddBlockCheckHalt(t, bc, tx) - acc := NewAccount(t, bc) - tx = PrepareInvoke(t, bc, []*wallet.Account{CommitteeAcc, acc}, h, "register", - "testdomain.com", acc.Contract.ScriptHash(), + acc := c.NewAccount(t) + c2 := c.WithSigners(c.Committee, acc) + c2.InvokeFail(t, "not witnessed by admin", "register", + "testdomain.com", acc.ScriptHash(), "myemail@nspcc.ru", refresh, retry, expire, ttl) - AddBlock(t, bc, tx) - CheckFault(t, bc, tx.Hash(), "not witnessed by admin") - tx = PrepareInvoke(t, bc, []*wallet.Account{accTop, acc}, h, "register", - "testdomain.com", acc.Contract.ScriptHash(), + c3 := c.WithSigners(accTop, acc) + c3.Invoke(t, true, "register", + "testdomain.com", acc.ScriptHash(), "myemail@nspcc.ru", refresh, retry, expire, ttl) - b := AddBlockCheckHalt(t, bc, tx) - tx = PrepareInvoke(t, bc, acc, h, "getRecords", "testdomain.com", int64(nns.SOA)) - CheckTestInvoke(t, bc, tx, stackitem.NewArray([]stackitem.Item{stackitem.NewBuffer( + b := c.TopBlock(t) + expected := stackitem.NewArray([]stackitem.Item{stackitem.NewBuffer( []byte(fmt.Sprintf("testdomain.com myemail@nspcc.ru %d %d %d %d %d", - b.Timestamp, refresh, retry, expire, ttl)))})) + b.Timestamp, refresh, retry, expire, ttl)))}) + c.Invoke(t, expected, "getRecords", "testdomain.com", int64(nns.SOA)) - tx = PrepareInvoke(t, bc, acc, h, "addRecord", + cAcc := c.WithSigners(acc) + cAcc.Invoke(t, stackitem.Null{}, "addRecord", "testdomain.com", int64(nns.TXT), "first TXT record") - AddBlockCheckHalt(t, bc, tx) - - tx = PrepareInvoke(t, bc, acc, h, "addRecord", + cAcc.Invoke(t, stackitem.Null{}, "addRecord", "testdomain.com", int64(nns.TXT), "second TXT record") - AddBlockCheckHalt(t, bc, tx) - tx = PrepareInvoke(t, bc, acc, h, "getRecords", "testdomain.com", int64(nns.TXT)) - CheckTestInvoke(t, bc, tx, stackitem.NewArray([]stackitem.Item{ + expected = stackitem.NewArray([]stackitem.Item{ stackitem.NewByteArray([]byte("first TXT record")), - stackitem.NewByteArray([]byte("second TXT record"))})) + stackitem.NewByteArray([]byte("second TXT record"))}) + c.Invoke(t, expected, "getRecords", "testdomain.com", int64(nns.TXT)) - tx = PrepareInvoke(t, bc, acc, h, "setRecord", + cAcc.Invoke(t, stackitem.Null{}, "setRecord", "testdomain.com", int64(nns.TXT), int64(0), "replaced first") - AddBlockCheckHalt(t, bc, tx) - tx = PrepareInvoke(t, bc, acc, h, "getRecords", "testdomain.com", int64(nns.TXT)) - CheckTestInvoke(t, bc, tx, stackitem.NewArray([]stackitem.Item{ + expected = stackitem.NewArray([]stackitem.Item{ stackitem.NewByteArray([]byte("replaced first")), - stackitem.NewByteArray([]byte("second TXT record"))})) + stackitem.NewByteArray([]byte("second TXT record"))}) + c.Invoke(t, expected, "getRecords", "testdomain.com", int64(nns.TXT)) } func TestNNSUpdateSOA(t *testing.T) { - bc := NewChain(t) - h := DeployContract(t, bc, nnsPath, nil) + c := newNNSInvoker(t, true) refresh, retry, expire, ttl := int64(101), int64(102), int64(103), int64(104) - tx := PrepareInvoke(t, bc, CommitteeAcc, h, "register", - "com", CommitteeAcc.Contract.ScriptHash(), + c.Invoke(t, true, "register", + "testdomain.com", c.CommitteeHash, "myemail@nspcc.ru", refresh, retry, expire, ttl) - AddBlockCheckHalt(t, bc, tx) - - tx = PrepareInvoke(t, bc, CommitteeAcc, h, "register", - "testdomain.com", CommitteeAcc.Contract.ScriptHash(), - "myemail@nspcc.ru", refresh, retry, expire, ttl) - AddBlockCheckHalt(t, bc, tx) refresh *= 2 retry *= 2 expire *= 2 ttl *= 2 - tx = PrepareInvoke(t, bc, CommitteeAcc, h, "updateSOA", + c.Invoke(t, stackitem.Null{}, "updateSOA", "testdomain.com", "newemail@nspcc.ru", refresh, retry, expire, ttl) - b := AddBlockCheckHalt(t, bc, tx) - tx = PrepareInvoke(t, bc, CommitteeAcc, h, "getRecords", "testdomain.com", int64(nns.SOA)) - CheckTestInvoke(t, bc, tx, stackitem.NewArray([]stackitem.Item{stackitem.NewBuffer( + b := c.TopBlock(t) + expected := stackitem.NewArray([]stackitem.Item{stackitem.NewBuffer( []byte(fmt.Sprintf("testdomain.com newemail@nspcc.ru %d %d %d %d %d", - b.Timestamp, refresh, retry, expire, ttl)))})) + b.Timestamp, refresh, retry, expire, ttl)))}) + c.Invoke(t, expected, "getRecords", "testdomain.com", int64(nns.SOA)) } func TestNNSGetAllRecords(t *testing.T) { - bc := NewChain(t) - h := DeployContract(t, bc, nnsPath, nil) + c := newNNSInvoker(t, true) refresh, retry, expire, ttl := int64(101), int64(102), int64(103), int64(104) - tx := PrepareInvoke(t, bc, CommitteeAcc, h, "register", - "com", CommitteeAcc.Contract.ScriptHash(), + c.Invoke(t, true, "register", + "testdomain.com", c.CommitteeHash, "myemail@nspcc.ru", refresh, retry, expire, ttl) - AddBlockCheckHalt(t, bc, tx) - tx = PrepareInvoke(t, bc, CommitteeAcc, h, "register", - "testdomain.com", CommitteeAcc.Contract.ScriptHash(), - "myemail@nspcc.ru", refresh, retry, expire, ttl) - AddBlockCheckHalt(t, bc, tx) + c.Invoke(t, stackitem.Null{}, "addRecord", "testdomain.com", int64(nns.TXT), "first TXT record") + c.Invoke(t, stackitem.Null{}, "addRecord", "testdomain.com", int64(nns.A), "1.2.3.4") - tx = PrepareInvoke(t, bc, CommitteeAcc, h, "addRecord", - "testdomain.com", int64(nns.TXT), "first TXT record") - AddBlockCheckHalt(t, bc, tx) - - tx = PrepareInvoke(t, bc, CommitteeAcc, h, "addRecord", - "testdomain.com", int64(nns.A), "1.2.3.4") - b := AddBlockCheckHalt(t, bc, tx) + b := c.TopBlock(t) expSOA := fmt.Sprintf("testdomain.com myemail@nspcc.ru %d %d %d %d %d", b.Timestamp, refresh, retry, expire, ttl) - tx = PrepareInvoke(t, bc, CommitteeAcc, h, "getAllRecords", "testdomain.com") - v, err := TestInvoke(bc, tx) + s, err := c.TestInvoke(t, "getAllRecords", "testdomain.com") require.NoError(t, err) - iter := v.Estack().Pop().Value().(*storage.Iterator) + iter := s.Pop().Value().(*storage.Iterator) require.True(t, iter.Next()) require.Equal(t, stackitem.NewStruct([]stackitem.Item{ stackitem.Make("testdomain.com"), stackitem.Make(int64(nns.A)), @@ -196,153 +175,99 @@ func TestNNSGetAllRecords(t *testing.T) { } func TestExpiration(t *testing.T) { - bc := NewChain(t) - h := DeployContract(t, bc, nnsPath, nil) + c := newNNSInvoker(t, true) refresh, retry, expire, ttl := int64(101), int64(102), int64(103), int64(104) - tx := PrepareInvoke(t, bc, CommitteeAcc, h, "register", - "com", CommitteeAcc.Contract.ScriptHash(), + c.Invoke(t, true, "register", + "testdomain.com", c.CommitteeHash, "myemail@nspcc.ru", refresh, retry, expire, ttl) - b := AddBlockCheckHalt(t, bc, tx) - tx = PrepareInvoke(t, bc, CommitteeAcc, h, "register", - "testdomain.com", CommitteeAcc.Contract.ScriptHash(), - "myemail@nspcc.ru", refresh, retry, expire, ttl) - AddBlockCheckHalt(t, bc, tx) + b := c.NewUnsignedBlock(t) + b.Timestamp = c.TopBlock(t).Timestamp + uint64(msPerYear) - 1 + require.NoError(t, c.Chain.AddBlock(c.SignBlock(b))) - addCustomBlock(t, bc, func(curr *block.Block) { - curr.Timestamp = b.Timestamp + uint64(msPerYear) - 1 - }) - - tx = PrepareInvoke(t, bc, CommitteeAcc, h, "getAllRecords", "testdomain.com") - _, err := TestInvoke(bc, tx) - require.Error(t, err) - require.True(t, strings.Contains(err.Error(), "parent domain has expired")) - - tx = PrepareInvoke(t, bc, CommitteeAcc, h, "ownerOf", "testdomain.com") - _, err = TestInvoke(bc, tx) - require.Error(t, err) - require.True(t, strings.Contains(err.Error(), "parent domain has expired"), err.Error()) + c.InvokeFail(t, "name has expired", "getAllRecords", "testdomain.com") + c.InvokeFail(t, "name has expired", "ownerOf", "testdomain.com") } func TestNNSSetAdmin(t *testing.T) { - bc := NewChain(t) - h := DeployContract(t, bc, nnsPath, nil) + c := newNNSInvoker(t, true) refresh, retry, expire, ttl := int64(101), int64(102), int64(103), int64(104) - tx := PrepareInvoke(t, bc, CommitteeAcc, h, "register", - "com", CommitteeAcc.Contract.ScriptHash(), + c.Invoke(t, true, "register", + "testdomain.com", c.CommitteeHash, "myemail@nspcc.ru", refresh, retry, expire, ttl) - AddBlockCheckHalt(t, bc, tx) - tx = PrepareInvoke(t, bc, CommitteeAcc, h, "register", - "testdomain.com", CommitteeAcc.Contract.ScriptHash(), - "myemail@nspcc.ru", refresh, retry, expire, ttl) - AddBlockCheckHalt(t, bc, tx) - - acc := NewAccount(t, bc) - - tx = PrepareInvoke(t, bc, acc, h, "addRecord", + acc := c.NewAccount(t) + cAcc := c.WithSigners(acc) + cAcc.InvokeFail(t, "not witnessed by admin", "addRecord", "testdomain.com", int64(nns.TXT), "won't be added") - AddBlock(t, bc, tx) - CheckFault(t, bc, tx.Hash(), "not witnessed by admin") - tx = PrepareInvoke(t, bc, []*wallet.Account{CommitteeAcc, acc}, h, "setAdmin", - "testdomain.com", acc.Contract.ScriptHash()) - AddBlockCheckHalt(t, bc, tx) + c1 := c.WithSigners(c.Committee, acc) + c1.Invoke(t, stackitem.Null{}, "setAdmin", "testdomain.com", acc.ScriptHash()) - tx = PrepareInvoke(t, bc, acc, h, "addRecord", + cAcc.Invoke(t, stackitem.Null{}, "addRecord", "testdomain.com", int64(nns.TXT), "will be added") - AddBlockCheckHalt(t, bc, tx) } func TestNNSIsAvailable(t *testing.T) { - bc := NewChain(t) - h := DeployContract(t, bc, nnsPath, nil) + c := newNNSInvoker(t, false) - tx := PrepareInvoke(t, bc, CommitteeAcc, h, "isAvailable", "com") - CheckTestInvoke(t, bc, tx, true) - - tx = PrepareInvoke(t, bc, CommitteeAcc, h, "isAvailable", "domain.com") - _, err := TestInvoke(bc, tx) - require.Error(t, err) - require.True(t, strings.Contains(err.Error(), "TLD not found")) + c.Invoke(t, true, "isAvailable", "com") + c.InvokeFail(t, "TLD not found", "isAvailable", "domain.com") refresh, retry, expire, ttl := int64(101), int64(102), int64(103), int64(104) - tx = PrepareInvoke(t, bc, CommitteeAcc, h, "register", - "com", CommitteeAcc.Contract.ScriptHash(), + c.Invoke(t, true, "register", + "com", c.CommitteeHash, "myemail@nspcc.ru", refresh, retry, expire, ttl) - AddBlockCheckHalt(t, bc, tx) - tx = PrepareInvoke(t, bc, CommitteeAcc, h, "isAvailable", "com") - CheckTestInvoke(t, bc, tx, false) + c.Invoke(t, false, "isAvailable", "com") + c.Invoke(t, true, "isAvailable", "domain.com") - tx = PrepareInvoke(t, bc, CommitteeAcc, h, "isAvailable", "domain.com") - CheckTestInvoke(t, bc, tx, true) - - acc := NewAccount(t, bc) - tx = PrepareInvoke(t, bc, []*wallet.Account{CommitteeAcc, acc}, h, "register", - "domain.com", acc.Contract.ScriptHash(), + acc := c.NewAccount(t) + c1 := c.WithSigners(c.Committee, acc) + c1.Invoke(t, true, "register", + "domain.com", acc.ScriptHash(), "myemail@nspcc.ru", refresh, retry, expire, ttl) - AddBlockCheckHalt(t, bc, tx) - tx = PrepareInvoke(t, bc, CommitteeAcc, h, "isAvailable", "domain.com") - CheckTestInvoke(t, bc, tx, false) + c.Invoke(t, false, "isAvailable", "domain.com") } func TestNNSRenew(t *testing.T) { - bc := NewChain(t) - h := DeployContract(t, bc, nnsPath, nil) + c := newNNSInvoker(t, true) + acc := c.NewAccount(t) + c1 := c.WithSigners(c.Committee, acc) refresh, retry, expire, ttl := int64(101), int64(102), int64(103), int64(104) - tx := PrepareInvoke(t, bc, CommitteeAcc, h, "register", - "com", CommitteeAcc.Contract.ScriptHash(), + c1.Invoke(t, true, "register", + "testdomain.com", c.CommitteeHash, "myemail@nspcc.ru", refresh, retry, expire, ttl) - AddBlockCheckHalt(t, bc, tx) - acc := NewAccount(t, bc) - tx = PrepareInvoke(t, bc, []*wallet.Account{CommitteeAcc, acc}, h, "register", - "testdomain.com", acc.Contract.ScriptHash(), - "myemail@nspcc.ru", refresh, retry, expire, ttl) - b := AddBlockCheckHalt(t, bc, tx) + const msPerYear = 365 * 24 * time.Hour / time.Millisecond + b := c.TopBlock(t) + ts := b.Timestamp + 2*uint64(msPerYear) - tx = PrepareInvoke(t, bc, acc, h, "renew", "testdomain.com") - AddBlockCheckHalt(t, bc, tx) - - tx = PrepareInvoke(t, bc, acc, h, "properties", "testdomain.com") - CheckTestInvoke(t, bc, tx, stackitem.NewMapWithValue([]stackitem.MapElement{ + cAcc := c.WithSigners(acc) + cAcc.Invoke(t, ts, "renew", "testdomain.com") + expected := stackitem.NewMapWithValue([]stackitem.MapElement{ {stackitem.Make("name"), stackitem.Make("testdomain.com")}, - {stackitem.Make("expiration"), stackitem.Make(b.Timestamp + 2*uint64(msPerYear))}, - })) + {stackitem.Make("expiration"), stackitem.Make(ts)}}) + cAcc.Invoke(t, expected, "properties", "testdomain.com") } func TestNNSResolve(t *testing.T) { - bc := NewChain(t) - h := DeployContract(t, bc, nnsPath, nil) + c := newNNSInvoker(t, true) refresh, retry, expire, ttl := int64(101), int64(102), int64(103), int64(104) - tx := PrepareInvoke(t, bc, CommitteeAcc, h, "register", - "com", CommitteeAcc.Contract.ScriptHash(), + c.Invoke(t, true, "register", + "test.com", c.CommitteeHash, "myemail@nspcc.ru", refresh, retry, expire, ttl) - AddBlockCheckHalt(t, bc, tx) - tx = PrepareInvoke(t, bc, CommitteeAcc, h, "register", - "test.com", CommitteeAcc.Contract.ScriptHash(), - "myemail@nspcc.ru", refresh, retry, expire, ttl) - AddBlockCheckHalt(t, bc, tx) - - tx = PrepareInvoke(t, bc, CommitteeAcc, h, "addRecord", + c.Invoke(t, stackitem.Null{}, "addRecord", "test.com", int64(nns.TXT), "expected result") - AddBlockCheckHalt(t, bc, tx) records := stackitem.NewArray([]stackitem.Item{stackitem.Make("expected result")}) - tx = PrepareInvoke(t, bc, CommitteeAcc, h, "resolve", "test.com", int64(nns.TXT)) - CheckTestInvoke(t, bc, tx, records) - - tx = PrepareInvoke(t, bc, CommitteeAcc, h, "resolve", "test.com.", int64(nns.TXT)) - CheckTestInvoke(t, bc, tx, records) - - tx = PrepareInvoke(t, bc, CommitteeAcc, h, "resolve", "test.com..", int64(nns.TXT)) - AddBlock(t, bc, tx) - CheckFault(t, bc, tx.Hash(), "invalid domain name format") + c.Invoke(t, records, "resolve", "test.com", int64(nns.TXT)) + c.Invoke(t, records, "resolve", "test.com.", int64(nns.TXT)) + c.InvokeFail(t, "invalid domain name format", "resolve", "test.com..", int64(nns.TXT)) } diff --git a/tests/util.go b/tests/util.go new file mode 100644 index 0000000..1e2958d --- /dev/null +++ b/tests/util.go @@ -0,0 +1,13 @@ +package tests + +import ( + "testing" + + "github.com/nspcc-dev/neo-go/pkg/neotest" + "github.com/nspcc-dev/neo-go/pkg/neotest/chain" +) + +func newExecutor(t *testing.T) *neotest.Executor { + bc, acc := chain.NewSingle(t) + return neotest.NewExecutor(t, bc, acc, acc) +}