forked from TrueCloudLab/frostfs-contract
[#161] tests: reuse neo-go testing framework
Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
This commit is contained in:
parent
63673a5e54
commit
8553320e1c
10 changed files with 324 additions and 779 deletions
3
go.mod
3
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
|
||||
)
|
||||
|
|
31
go.sum
31
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=
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
282
tests/basic.go
282
tests/basic.go
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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[:])
|
||||
}
|
||||
|
|
11
tests/helpers.go
Normal file
11
tests/helpers.go
Normal file
|
@ -0,0 +1,11 @@
|
|||
package tests
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
)
|
||||
|
||||
func randomBytes(n int) []byte {
|
||||
a := make([]byte, n)
|
||||
rand.Read(a)
|
||||
return a
|
||||
}
|
|
@ -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)}),
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
|
|
13
tests/util.go
Normal file
13
tests/util.go
Normal file
|
@ -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)
|
||||
}
|
Loading…
Reference in a new issue