Compare commits

...

1454 commits

Author SHA1 Message Date
Anna Shaleva
b66cea5ccc
Merge pull request #3483 from nspcc-dev/bump-neofs-sdk
go.mod: update NeoFS SDK to RC12
2024-06-07 16:37:04 +03:00
Roman Khimov
e5eb20bbae go.mod: update NeoFS SDK to RC12
Signed-off-by: Roman Khimov <roman@nspcc.ru>
2024-06-07 15:08:25 +03:00
Anna Shaleva
cf4d4a2611
Merge pull request #3469 from nspcc-dev/warn
logs: distinguish WARN and INFO for `peer disconnected`
2024-06-05 15:39:52 +03:00
Anna Shaleva
7a7a5d0322
Merge pull request #3470 from nspcc-dev/contract-acc
wallet: do not store deployed contract script inside `Contract` account field
2024-06-05 15:35:04 +03:00
Ekaterina Pavlova
4d6333866d network: extend errInvalidInvType error
Add type to the errInvalidInvType.

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-06-05 15:32:43 +03:00
Ekaterina Pavlova
4a5e8f8592 logs: distinguish WARN and INFO for peer disconnected
Peer disconnections are not warnings in some cases.

Close #3182

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-06-05 15:32:42 +03:00
Ekaterina Pavlova
b4fdf8c3c9 wallet: do not store deployed contract script inside Contract account
`Contract` account field should not contain deployed contract script.

Close #3348

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-06-05 15:27:20 +03:00
Anna Shaleva
3c471f0b7e
Merge pull request #3455 from nspcc-dev/sast
Adjust minor SAST warnings
2024-06-05 12:21:42 +03:00
Ekaterina Pavlova
41109f442a oracle: add length check o.MainCfg.NeoFS.Nodes
Prevent the risk of a division by zero error when accessing the
`o.MainCfg.NeoFS.Nodes[index]` array.

Close #3419

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-06-05 11:53:52 +03:00
Ekaterina Pavlova
5c408f7fe4 core: adjust prevHeader nil check
prevHeader is never nil.

Refs #3419

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-06-05 11:53:52 +03:00
Anna Shaleva
cd525a1df5
Merge pull request #3468 from nspcc-dev/logs
logs: hide timestamp if the program is run not in TTY
2024-06-05 10:46:13 +03:00
Roman Khimov
836183ecb6
Merge pull request #3475 from nspcc-dev/rel-0.106.1 2024-06-03 17:15:44 +03:00
Anna Shaleva
3c1c650ddf CHANGELOG: release 0.106.1
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-06-03 16:12:36 +03:00
Anna Shaleva
45b8af359d
Merge pull request #3472 from nspcc-dev/pick-proper-exe-context
interop: use executing contract state for permissions checks
2024-06-03 16:10:39 +03:00
Anna Shaleva
4945145b09 interop: use executing contract state for permissions checks
Do not use the updated contract state from native Management to perform
permissions checks. We need to use the currently executing state
instead got from the currently executing VM context until context is
unloaded.

Close #3471.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-06-03 12:32:10 +03:00
Ekaterina Pavlova
f48e992a78 logs: hide timestamp if the program is run not in TTY
If the program is run in TTY then logger adds timestamp to its entries.

Close #3358

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-06-03 11:49:54 +03:00
Roman Khimov
0b136c1c9c
Merge pull request #3463 from nspcc-dev/fool-protection 2024-05-25 00:59:23 +03:00
Anna Shaleva
f4aeaa6387 workflows: protect go.mod from unexpected imports
Avoid situations like #3458.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-05-24 21:11:39 +03:00
Roman Khimov
0ae5e7ea83
Merge pull request #3458 from nspcc-dev/remove-contract-deps
go.mod: remove unused dependency
2024-05-21 21:46:15 +03:00
Anna Shaleva
228052360e go.mod: remove unused dependency
Was accidentally added in
aa5a0cb49b.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-05-21 20:40:38 +03:00
Roman Khimov
5cbfe215a4
Merge pull request #3453 from nspcc-dev/rel-0.106.0
CHANGELOG: release 0.106.0
2024-05-21 15:48:52 +03:00
Anna Shaleva
72161fe902 CHANGELOG: release 0.106.0
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-05-21 15:44:22 +03:00
Anna Shaleva
aceaabe9d6 ROADMAP: update roadmap
Reschedule deprecated functionality removal for 0.107.0 release.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-05-21 14:26:05 +03:00
Anna Shaleva
9ba532ce9c docs: adjust release instructions
Add a note about checking NeoFS networks for compatibility.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-05-21 14:26:05 +03:00
Roman Khimov
2aa3c93acd
Merge pull request #3452 from nspcc-dev/p2pnotary-role
core: move P2PNotary node role out of P2PSigExtensions
2024-05-21 13:53:52 +03:00
Anna Shaleva
aa5a0cb49b *: update interop deps
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-05-21 12:36:51 +03:00
Anna Shaleva
7868578571 core: move P2PNotary node role out of P2PSigExtensions
Port https://github.com/neo-project/neo/pull/3172.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-05-21 12:10:47 +03:00
Roman Khimov
6a5833759c
Merge pull request #3448 from nspcc-dev/migrate-to-hf
Bind 0.106.0 protocol chages to Cockatrice hardfork
2024-05-20 15:51:26 +03:00
Roman Khimov
6be757af3e
Merge pull request #3444 from nspcc-dev/fix-native-init
native: perform initialisation for the set of hardforks
2024-05-17 16:34:00 +03:00
Roman Khimov
67b6d5da31
Merge pull request #3446 from nspcc-dev/enable-cockatrice
config: enable Cockatrice hardfork
2024-05-17 16:33:16 +03:00
Anna Shaleva
b5bb605651
Merge pull request #3443 from nspcc-dev/fix-blocked-accounts
native: fix Policy's IsBlocked behaviour
2024-05-17 16:10:59 +03:00
Anna Shaleva
d91a0945df config: enable Cockatrice hardfork
Close #3434.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-05-17 16:01:48 +03:00
Anna Shaleva
c90f6785b9 native: perform initialisation for the set of hardforks
Close #3433.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-05-17 15:58:02 +03:00
Anna Shaleva
c30e7ec8d7 native: bind CryptoLib's verifyWithECDsa changes to Cockatrice
A part of #3440.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-05-17 15:52:00 +03:00
Anna Shaleva
ce442a1942 rpcsrv: remove test for Koblitz-based witness verification
It will be built properly in #3447.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-05-17 15:45:04 +03:00
Anna Shaleva
e92606a7ae native: bind Neo's CommitteeChanged event to Cockatrice
A part of #3440.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-05-17 15:22:29 +03:00
Anna Shaleva
df1ed68d98 native: support native method/event removal
Port a part of https://github.com/neo-project/neo/issues/3210.
A part of #3440.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-05-17 15:22:26 +03:00
Anna Shaleva
82a7c1bd9c native: adjust test helper behaviour
Supply the account with expected balance.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-05-17 12:33:59 +03:00
Anna Shaleva
c43cfae24c native: fix Policy's IsBlocked behaviour
Account is blocked when it's in the Policy's storage, not when it's
missing from the Policy storage. Introduced in
bbbc6805a8.

This bug leads to the fact that during native Neo cache initialization
at the last block in the dBFT epoch, all candidates accounts are
"blocked", and thus, stand-by committee and validators are used in the
subsequent new epoch. Close #3424.

This bug may lead to the consequences described in #3273, but it needs
to be confirmed.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-05-17 12:33:51 +03:00
Anna Shaleva
2d4993a837
Merge pull request #3438 from nspcc-dev/unwrap-fault-exception
unwrap: implement Exception type for better exception handling
2024-05-17 10:24:26 +03:00
Anna Shaleva
647b8c7fb1
Merge pull request #3439 from nspcc-dev/getnativecontracts
state: drop NativeContract, fix #3430
2024-05-17 10:23:45 +03:00
Roman Khimov
0b69901d1e
Merge pull request #3441 from nspcc-dev/boltdb-clone 2024-05-16 19:49:11 +03:00
Roman Khimov
502f024e7c storage: bytes.Clone(nil) == nil
Signed-off-by: Roman Khimov <roman@nspcc.ru>
2024-05-16 19:29:11 +03:00
Roman Khimov
b1bb12df48 state: drop NativeContract, fix #3430
This unifies getnativecontracts RPC API with regular contracts.

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2024-05-16 18:46:46 +03:00
Roman Khimov
31a99d44eb
Merge pull request #3437 from nspcc-dev/fix-conflicts 2024-05-16 13:38:03 +03:00
Anna Shaleva
dc8b2f639a dao: do not remove block executable by conflict record stub
It's possible for transaction to include block hash into Conflicts
attribure. If so, then we must not remove block executable record while
cleaning transation's conflict records.

This commit is a direct consequence of
e6ceee0f230a21c87006a9297636be29c0d8ea47. Ref. #3427.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-05-16 12:13:41 +03:00
Anna Shaleva
2ad4c86712 dao: move conflict record value length to a separate const
Conflicts-related code contains more and more these magic numbers, and
there's no good in it even if all the usages are commented. This
approach produces bugs like #3426.

No functional changes, just a refactoring.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-05-16 12:13:41 +03:00
Anna Shaleva
9a1075d332 dao: fix transaction application log decoding
Conflict record stub has value of 5 bytes length: 1 byte for
storage.ExecTransaction prefix and 4 bytes for the block index LE. This
scheme was implemented in #3138, and this commit should be a part of
this PR.

Also, transaction.DummyVersion is removed since it's unused anymore.

Close #3426. The reason of `failed to locate application log: EOF` error
during genesis AER request is in the following: genesis executable was
overwritten by conflict record stub produced by transaction
0x289c235dcdab8be7426d05f0fbb5e86c619f81481ea136493fa95deee5dbb7cc (ref.
 #3427). As a consequence, an attempt to decode transaction AER was
initited, but conflict record scheme was changed in #3138.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-05-16 12:13:41 +03:00
Anna Shaleva
58a086ea91 core: allow transaction to conflict with block
Transaction
0x289c235dcdab8be7426d05f0fbb5e86c619f81481ea136493fa95deee5dbb7cc is
already on mainnet at block 5272006 and we can't do anything with it.
This transaction has genesis block hash in Conflicts attribute. It leads
to the following consequences:
1. Genesis block executable record is overwritten by conflict record
   stub. Genesis block can't be retrieved anymore. This bug is described
   in #3427.
2. Somehow this transaction has passed verification on NeoGo CN without
   any warnings:
```
Apr 24 16:12:30 kangra neo-go[2453907]: 2024-04-24T16:12:30.865+0300        INFO        initializing dbft        {"height": 5272006, "view": 0, "index": 6, "role": "Backup"}
Apr 24 16:12:31 kangra neo-go[2453907]: 2024-04-24T16:12:31.245+0300        INFO        persisted to disk        {"blocks": 1, "keys": 37, "headerHeight": 5272005, "blockHeight": 5272005, "took": "14.548903ms"}
Apr 24 16:12:34 kangra neo-go[2453907]: 2024-04-24T16:12:34.977+0300        ERROR        can't add SV-signed state root        {"error": "stateroot mismatch at block 5272005: 9d5f95784f26c862d6f889f213aad1e3330611880c02330e88db8802c750aa46 vs d25304d518645df725014897d13bbf023919928e79074abcea48f31cf9f32a25"}
Apr 24 16:12:45 kangra neo-go[2453907]: 2024-04-24T16:12:45.820+0300        INFO        received PrepareRequest        {"validator": 5, "tx": 1}
Apr 24 16:12:45 kangra neo-go[2453907]: 2024-04-24T16:12:45.821+0300        INFO        sending PrepareResponse        {"height": 5272006, "view": 0}
Apr 24 16:12:45 kangra neo-go[2453907]: 2024-04-24T16:12:45.827+0300        INFO        received PrepareResponse        {"validator": 4}
Apr 24 16:12:45 kangra neo-go[2453907]: 2024-04-24T16:12:45.830+0300        INFO        received PrepareResponse        {"validator": 3}
Apr 24 16:12:45 kangra neo-go[2453907]: 2024-04-24T16:12:45.875+0300        INFO        received PrepareResponse        {"validator": 2}
Apr 24 16:12:45 kangra neo-go[2453907]: 2024-04-24T16:12:45.878+0300        INFO        sending Commit        {"height": 5272006, "view": 0}
Apr 24 16:12:45 kangra neo-go[2453907]: 2024-04-24T16:12:45.879+0300        INFO        received Commit        {"validator": 4}
Apr 24 16:12:45 kangra neo-go[2453907]: 2024-04-24T16:12:45.881+0300        INFO        received PrepareResponse        {"validator": 0}
Apr 24 16:12:45 kangra neo-go[2453907]: 2024-04-24T16:12:45.881+0300        INFO        received Commit        {"validator": 3}
Apr 24 16:12:45 kangra neo-go[2453907]: 2024-04-24T16:12:45.906+0300        INFO        received Commit        {"validator": 0}
Apr 24 16:12:45 kangra neo-go[2453907]: 2024-04-24T16:12:45.907+0300        INFO        received PrepareResponse        {"validator": 1}
Apr 24 16:12:45 kangra neo-go[2453907]: 2024-04-24T16:12:45.915+0300        INFO        received Commit        {"validator": 1}
Apr 24 16:12:45 kangra neo-go[2453907]: 2024-04-24T16:12:45.915+0300        INFO        approving block        {"height": 5272006, "hash": "6b111519537343ce579d04ccad71c43318b12c680d0f374dfcd466aa22643fb6", "tx_count": 1, "merkle": "ccb7dbe5ee5da93f4936a11e48819f616ce8b5fbf0056d42e78babcd5d239c28", "prev": "12ad6cc5d0cd357b9fc9fb0c1a016ba8014d3cdd5a96818598e6a40a1a4a2a21"}
Apr 24 16:12:45 kangra neo-go[2453907]: 2024-04-24T16:12:45.917+0300        WARN        contract invocation failed        {"tx": "289c235dcdab8be7426d05f0fbb5e86c619f81481ea136493fa95deee5dbb7cc", "block": 5272006, "error": "at instruction 86 (ASSERT): ASSERT failed"}
Apr 24 16:12:45 kangra neo-go[2453907]: 2024-04-24T16:12:45.950+0300        INFO        initializing dbft        {"height": 5272007, "view": 0, "index": 6, "role": "Primary"}
Apr 24 16:12:46 kangra neo-go[2453907]: 2024-04-24T16:12:46.256+0300        INFO        persisted to disk        {"blocks": 1, "keys": 67, "headerHeight": 5272006, "blockHeight": 5272006, "took": "16.576594ms"}
```
   And thus, we must treat this transaction as valid for this behaviour
   to be reproducable.

This commit contains two fixes:
1. Do not overwrite block executable records by conflict record stubs.
   If some transaction conflicts with block, then just skip the conflict
   record stub for this attribute since it's impossible to create
   transaction with the same hash.
2. Do not fail verification for those transactions that have Conflicts
   attribute with block hash inside. This one is controversial, but we
   have to adjust this code to treat already accepted transaction as
   valid.

Close #3427.

The transaction itself:
```
{
   "id" : 1,
   "jsonrpc" : "2.0",
   "result" : {
      "attributes" : [
         {
            "height" : 0,
            "type" : "NotValidBefore"
         },
         {
            "hash" : "0x1f4d1defa46faa5e7b9b8d3f79a06bec777d7c26c4aa5f6f5899a291daa87c15",
            "type" : "Conflicts"
         }
      ],
      "blockhash" : "0xb63f6422aa66d4fc4d370f0d682cb11833c471adcc049d57ce4373531915116b",
      "blocktime" : 1713964365700,
      "confirmations" : 108335,
      "hash" : "0x289c235dcdab8be7426d05f0fbb5e86c619f81481ea136493fa95deee5dbb7cc",
      "netfee" : "237904",
      "nonce" : 0,
      "script" : "CxAMFIPvkoyXujYCRmgq9qEfMJQ4wNveDBSD75KMl7o2AkZoKvahHzCUOMDb3hTAHwwIdHJhbnNmZXIMFPVj6kC8KD1NDgXEjqMFs/Kgc0DvQWJ9W1I5",
      "sender" : "NbcGB1tBEGM5MfhNbDAimvpJKzvVjLQ3jW",
      "signers" : [
         {
            "account" : "0x649ca095e38a790d6c15ff78e0c6175099b428ac",
            "scopes" : "None"
         },
         {
            "account" : "0xdedbc03894301fa1f62a68460236ba978c92ef83",
            "scopes" : "None"
         }
      ],
      "size" : 412,
      "sysfee" : "997778",
      "validuntilblock" : 5277629,
      "version" : 0,
      "vmstate" : "FAULT",
      "witnesses" : [
         {
            "invocation" : "DECw8XNuyRg5vPeHxisQXlZ7VYNDxxK4xEm8zwpPyWJSSu+JaRKQxdrlPkXxXj34wc4ZSrZvKICGgPFE0ZHXhLPo",
            "verification" : "DCEC+PI2tRSlp0wGwnjRuQdWdI0tBXNS7SlzSBBHFsaKUsdBVuezJw=="
         },
         {
            "invocation" : "DEAxwi97t+rg9RsccOUzdJTJK7idbR7uUqQp0/0/ob9FbuW/tFius3/FOi82PDZtwdhk7s7KiNM/pU7vZLsgIbM0",
            "verification" : "DCEDbInkzF5llzmgljE4HSMvtrNgPaz73XO5wgVJXLHNLXRBVuezJw=="
         }
      ]
   }
}
```

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-05-16 12:13:41 +03:00
Anna Shaleva
59c98c4d09 core: always warn if accepted transaction fails verification
These warnings must be monitored by developers since it might be a sign
of behaviour difference between Go and C# nodes.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-05-16 12:13:40 +03:00
Roman Khimov
f4731eab91 unwrap: implement Exception type for better exception handling
Fix #3130. "Exception" is used for name since it's shorter and that's the name
used in JSON. "VMFault" was also considered as well as "FaultException"
(which mirrors result.Invoke).

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2024-05-15 23:00:27 +03:00
Roman Khimov
13020ccd02
Merge pull request #3431 from nspcc-dev/nativehashes-autogen
nativehashes: autogenerate native contract hashes
2024-05-15 13:36:33 +03:00
Roman Khimov
bce94dfa66
Merge pull request #3436 from nspcc-dev/fix-lint
scripts: fix linting
2024-05-14 16:16:46 +03:00
Anna Shaleva
244ca6f438 workflows: enable testing jobs for go scripts
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-05-14 15:55:23 +03:00
Anna Shaleva
a32217fac8 scripts: fix linting
Should be a part of #3435.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-05-14 15:53:08 +03:00
Roman Khimov
0435551eee
Merge pull request #3435 from nspcc-dev/extend-compare-scripts
scripts: dump diff for OnPersist and PostPersist applog
2024-05-14 15:13:03 +03:00
Anna Shaleva
0a3bf01a8f scripts: dump diff for OnPersist and PostPersist applog
Related to #3424.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-05-14 13:38:52 +03:00
Anna Shaleva
0aecddea10 native: autogenerate nativehashes package
Ref.
https://github.com/nspcc-dev/neo-go/pull/3402#discussion_r1577879141.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-05-14 09:39:53 +03:00
Roman Khimov
02ecbeb519
Merge pull request #3425 from nspcc-dev/cryptolib-test
native: add test for custom Koblitz witness verification script
2024-05-13 16:35:10 +03:00
Anna Shaleva
e275495850 *: update interop deps
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-05-13 10:16:04 +03:00
Anna Shaleva
6e0926e59f native: adjust NamedCurveHash values
Use 122 and 123 respectively for Secp256k1Keccak256 and
Secp256r1Keccak256, ref.
https://github.com/neo-project/neo/pull/3209#issuecomment-2095798056.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-05-13 10:10:56 +03:00
Anna Shaleva
988440949b native: reduce callflag scope for Koblitz verification scripts
callflag.All is too wide.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-05-13 09:33:42 +03:00
Roman Khimov
701ea8d5f3 native: use ABORT in Koblitz multisig
Make the script a bit shorter. ABORTMSG would cost a bit more.

Signed-off-by: Roman Khimov <roman@nspcc.ru>
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-05-13 09:33:42 +03:00
Roman Khimov
3d1e33a502 native: make multisig koblitz easier to parse
1. Make prologue be exactly the same as regular CheckMultisig.
2. But instead of "SYSCALL System.Crypto.CheckMultisig" do INITSLOT and K check.
3. This makes all of the code from INITSLOT below be independent of N/M, so
   one can parse the script beginning in the same way CheckMultisig is parsed and
   then just compare the rest of it with some known-good blob.
4. The script becomes a tiny bit larger now, but properties above are too good.

Signed-off-by: Roman Khimov <roman@nspcc.ru>
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-05-13 09:33:42 +03:00
Anna Shaleva
5053a073f9 rpcsrv: test calculatenetworkfee with custom Koblitz-based witness
Value calculated by calculatenetworkfee is enough to pass the real
tx verification. However, network fee may be decreased, so calculations
are not quite accurate. Need to investigate, why.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-05-13 09:33:42 +03:00
Anna Shaleva
71aa32406d native: add test for multisignature Koblitz witness verification
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-05-13 09:33:42 +03:00
Anna Shaleva
3acb132e9a native: add preferable method to TestCryptoLib_KoblitzVerificationScript
It's based on the constant-length network magic, ref.
https://github.com/nspcc-dev/neo-go/pull/3425#discussion_r1582068061.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-05-13 09:33:42 +03:00
Anna Shaleva
bd2f9c75e1 crypto: export GetSignedData function
It's needed for tests and further custom verification script build.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-05-13 09:33:42 +03:00
Anna Shaleva
34eef47a18 native: extend CryptoLib's verifyWithECDsa with hasher parameter
Replace native CryptoLib's verifyWithECDsa `curve` parameter by
`curveHash` parameter which is a enum over supported pairs of named
curves and hash functions.

Even though this change is a compatible extension of the protocol, it
changes the genesis state due to parameter renaming. But we're going to
resync chain in 3.7 release anyway, so it's not a big deal.

Also, we need to check mainnet and testnet compatibility in case if
anyone has ever called verifyWithECDsa with 24 or 25 `curve` value.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-05-13 09:33:41 +03:00
Anna Shaleva
7995229f6b native: add test for custom Koblitz witness verification script
Every single thing is already implemented in the protocol for Koblitz
verification scripts.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-05-13 09:27:42 +03:00
Roman Khimov
b21db99747
Merge pull request #3402 from nspcc-dev/native-upd
native: implement HF-based update
2024-05-10 11:53:55 +03:00
Roman Khimov
bc158eed51
Merge pull request #3428 from nspcc-dev/revert-gnark-upd
Revert "build(deps): bump github.com/consensys/gnark"
2024-05-01 16:02:43 +03:00
Anna Shaleva
ac70f069ff Revert "build(deps): bump github.com/consensys/gnark"
This reverts commit 874ed1ac2e.
We can't allow this gnark update since minimum required Go version for
NeoGo and all examples is 1.20. It will be done as a part of #3089.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-05-01 15:24:07 +03:00
Anna Shaleva
b54fcbcdd9
Merge pull request #3407 from nspcc-dev/copy-transaction
*: add Copy() to transaction.Transaction and payload.P2PNotaryRequest
2024-05-01 10:46:30 +03:00
Ekaterina Pavlova
8da7c0a671 notary: reuse (*Transaction).Copy where possible
Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-04-28 00:59:15 +05:30
Ekaterina Pavlova
956fd08adb *: add Copy() to transaction.Transaction and payload.P2PNotaryRequest
Add a method that makes a deep copy of all fields and resets size/hash
caches.

Close #3288

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-04-28 00:59:15 +05:30
Ekaterina Pavlova
1292a00ef9 crypto: adjust TestPublicKeys_Copy
Since the AllowedGroups []*keys.PublicKey slice is used in the
initialization, the test should use the same structures.

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-04-28 00:12:18 +05:30
Ekaterina Pavlova
7c8d2c3ec5 crypto: add nil check for PublicKeys Copy()
Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-04-27 14:56:42 +05:30
Ekaterina Pavlova
df2a56908b core: move transaction Attribute value to a designated interface
Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-04-26 21:40:23 +05:30
Anna Shaleva
198af7f3ae
Merge pull request #3421 from nspcc-dev/dependabot/go_modules/examples/zkp/cubic_circuit/github.com/consensys/gnark-0.10.0
build(deps): bump github.com/consensys/gnark from 0.9.1 to 0.10.0 in /examples/zkp/cubic_circuit
2024-04-25 17:34:23 +03:00
dependabot[bot]
874ed1ac2e
build(deps): bump github.com/consensys/gnark
Bumps [github.com/consensys/gnark](https://github.com/consensys/gnark) from 0.9.1 to 0.10.0.
- [Release notes](https://github.com/consensys/gnark/releases)
- [Changelog](https://github.com/Consensys/gnark/blob/master/CHANGELOG.md)
- [Commits](https://github.com/consensys/gnark/compare/v0.9.1...v0.10.0)

---
updated-dependencies:
- dependency-name: github.com/consensys/gnark
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-25 13:49:06 +00:00
Roman Khimov
4a8a43b983
Merge pull request #3420 from nspcc-dev/ensure-stringers 2024-04-25 16:48:26 +03:00
Anna Shaleva
6cf785ce54 workflows: ensure autogenerated code is up-to-date
In case if source of stringers or any other autogenerated code is
updated we need to regenerate the target files. It's easy to forget
about it.

Ref. 8995f11d39cc6b5f5b0081039bbe616dd7aaf38e.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-04-25 16:36:38 +03:00
Anna Shaleva
9b8d579bce core: add unit tests for HF-based native contracts update
A part of #3213.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-04-25 13:26:54 +03:00
Anna Shaleva
36e128516b core: add nativenames.All list
It's useful to keep the ordered set of native contract names.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-04-25 13:26:54 +03:00
Anna Shaleva
4ca2686583 core: distinguish empty Hardforks map from nil
Ensure that Blockchain constructor is able to distinguish empty
Hardforks map (no hardforks should be enabled) from nil hardforks map
(the default value should be used in this case, i.e. all hardforks
should be active from genesis).

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-04-25 13:26:54 +03:00
Anna Shaleva
235f4398c6 native: make Oracle service handle native Oracle updates
A part of #3213.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-04-25 13:26:54 +03:00
Anna Shaleva
ec6fc54bc6 *: use nativehashes package where possible
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-04-25 13:26:54 +03:00
Anna Shaleva
2d3d52e3d0 native: add nativehashes package
Similar to nativenames, instantiate once and then reuse everywhere.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-04-25 13:26:54 +03:00
Anna Shaleva
82993dab2b core: extend error message for contract state check
It will give us a clue on what's wrong with contract states if something
unexpected happen.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-04-25 13:26:54 +03:00
Anna Shaleva
5c75ee13d0 config, native: introduce Cockatrice hard-fork
With all associated native API changes ported from
https://github.com/neo-project/neo/pull/2925 and
https://github.com/neo-project/neo/pull/3154.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-04-25 13:26:54 +03:00
Anna Shaleva
3a2e301267 native: make HF-specific MD cache less lazy
Initialize all necessary HF-specific contract descriptors once during
contract construction.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-04-25 13:26:54 +03:00
Anna Shaleva
d74dc368e0 core: unexport generic native contract methods and events
External users should use HF-specific methods and events.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-04-25 13:26:54 +03:00
Anna Shaleva
73c742a466 native: emit Deploy/Update notifications on native deploy/update
Ported as a part of https://github.com/neo-project/neo/pull/2942.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-04-25 13:26:53 +03:00
Anna Shaleva
d62fad1268 native: implement HF-based update
A part of #3213.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-04-25 13:16:42 +03:00
Anna Shaleva
a13dc59bd9
Merge pull request #3416 from nspcc-dev/fix-linter-cache
workflows: disable cache for golangci-lint
2024-04-22 14:33:43 +03:00
Roman Khimov
678c1982f9
Merge pull request #3414 from nspcc-dev/test-empty-script
smartcontract: ensure nil ParameterContext Item's script is marshallable
2024-04-19 16:49:52 +03:00
Roman Khimov
c84adf856a
Merge pull request #3418 from nspcc-dev/dependabot/go_modules/golang.org/x/net-0.23.0 2024-04-19 16:36:53 +03:00
dependabot[bot]
7345dbcab4
build(deps): bump golang.org/x/net from 0.22.0 to 0.23.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.22.0 to 0.23.0.
- [Commits](https://github.com/golang/net/compare/v0.22.0...v0.23.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-19 13:19:48 +00:00
Anna Shaleva
fbe514ca91 workflows: disable cache for golangci-lint
Ref. https://github.com/golangci/golangci-lint-action/issues/135.
Otherwies we've got a set of errors on attempt to setup linter:
```
Run golangci/golangci-lint-action@v4
  with:
    version: latest
    github-token: ***
    only-new-issues: false
    skip-cache: false
    skip-pkg-cache: false
    skip-build-cache: false
    install-mode: binary
prepare environment
  Checking for go.mod: go.mod
  Received 125829120 of 781115092 (16.1%), 119.8 MBs/sec
  Received 331350016 of 781115092 (42.4%), 157.8 MBs/sec
  Received 541065216 of 781115092 (69.3%), 171.9 MBs/sec
  Received 738197504 of 781115092 (94.5%), 175.8 MBs/sec
  Cache Size: ~745 MB (781115092 B)
  /usr/bin/tar -xf /home/runner/work/_temp/6de9500e-163b-4dda-a82b-d6b2ee7b1625/cache.tzst -P -C /home/runner/work/neo-go/neo-go --use-compress-program unzstd
  Received 781115092 of 781115092 (100.0%), 148.8 MBs/sec
  /usr/bin/tar: ../../../go/pkg/mod/google.golang.org/protobuf@v1.31.0/LICENSE: Cannot open: File exists
  /usr/bin/tar: ../../../go/pkg/mod/google.golang.org/protobuf@v1.31.0/.github/workflows/test.yml: Cannot open: File exists
  /usr/bin/tar: ../../../go/pkg/mod/google.golang.org/protobuf@v1.31.0/README.md: Cannot open: File exists
  Error: /usr/bin/tar: ../../../go/pkg/mod/google.golang.org/protobuf@v1.31.0/cmd/protoc-gen-go/annotation_test.go: Cannot open: File exists
  Error: /usr/bin/tar: ../../../go/pkg/mod/google.golang.org/protobuf@v1.31.0/cmd/protoc-gen-go/retention_test.go: Cannot open: File exists
  Error: /usr/bin/tar: ../../../go/pkg/mod/google.golang.org/protobuf@v1.31.0/cmd/protoc-gen-go/main.go: Cannot open: File exists
  Error: /usr/bin/tar: ../../../go/pkg/mod/google.golang.org/protobuf@v1.31.0/cmd/protoc-gen-go/testdata/imports/fmt/m.pb.go: Cannot open: File exists
  /usr/bin/tar: ../../../go/pkg/mod/google.golang.org/protobuf@v1.31.0/cmd/protoc-gen-go/testdata/imports/fmt/m.proto: Cannot open: File exists
  Error: /usr/bin/tar: ../../../go/pkg/mod/google.golang.org/protobuf@v1.31.0/cmd/protoc-gen-go/testdata/imports/test_import_a1m2.pb.go: Cannot open: File exists
  Error: /usr/bin/tar: ../../../go/pkg/mod/google.golang.org/protobuf@v1.31.0/cmd/protoc-gen-go/testdata/imports/test_import_a1m1.pb.go: Cannot open: File exists
  /usr/bin/tar: ../../../go/pkg/mod/google.golang.org/protobuf@v1.31.0/cmd/protoc-gen-go/testdata/imports/test_import_all.proto: Cannot open: File exists
  /usr/bin/tar: ../../../go/pkg/mod/google.golang.org/protobuf@v1.31.0/cmd/protoc-gen-go/testdata/imports/test_import_a1m2.proto: Cannot open: File exists
  Error: /usr/bin/tar: ../../../go/pkg/mod/google.golang.org/protobuf@v1.31.0/cmd/protoc-gen-go/testdata/imports/test_b_1/m2.pb.go: Cannot open: File exists
  Error: /usr/bin/tar: ../../../go/pkg/mod/google.golang.org/protobuf@v1.31.0/cmd/protoc-gen-go/testdata/imports/test_b_1/m1.pb.go: Cannot open: File exists
  /usr/bin/tar: ../../../go/pkg/mod/google.golang.org/protobuf@v1.31.0/cmd/protoc-gen-go/testdata/imports/test_b_1/m1.proto: Cannot open: File exists
  /usr/bin/tar: ../../../go/pkg/mod/google.golang.org/protobuf@v1.31.0/cmd/protoc-gen-go/testdata/imports/test_b_1/m2.proto: Cannot open: File exists
  Error: /usr/bin/tar: ../../../go/pkg/mod/google.golang.org/protobuf@v1.31.0/cmd/protoc-gen-go/testdata/imports/test_import_all.pb.go: Cannot open: File exists
  /usr/bin/tar: ../../../go/pkg/mod/google.golang.org/protobuf@v1.31.0/cmd/protoc-gen-go/testdata/imports/test_import_a1m1.proto: Cannot open: File exists
  Error: /usr/bin/tar: ../../../go/pkg/mod/google.golang.org/protobuf@v1.31.0/cmd/protoc-gen-go/testdata/imports/test_a_1/m2.pb.go: Cannot open: File exists
  Error: /usr/bin/tar: ../../../go/pkg/mod/google.golang.org/protobuf@v1.31.0/cmd/protoc-gen-go/testdata/imports/test_a_1/m1.pb.go: Cannot open: File exists
  /usr/bin/tar: ../../../go/pkg/mod/google.golang.org/protobuf@v1.31.0/cmd/protoc-gen-go/testdata/imports/test_a_1/m1.proto: Cannot open: File exists
  /usr/bin/tar: ../../../go/pkg/mod/google.golang.org/protobuf@v1.31.0/cmd/protoc-gen-go/testdata/imports/test_a_1/m2.proto: Cannot open: File exists
  /usr/bin/tar: ../../../go/pkg/mod/google.golang.org/protobuf@v1.31.0/cmd/protoc-gen-go/testdata/imports/test_a_2/m3.proto: Cannot open: File exists
  Error: /usr/bin/tar: ../../../go/pkg/mod/google.golang.org/protobuf@v1.31.0/cmd/protoc-gen-go/testdata/imports/test_a_2/m4.pb.go: Cannot open: File exists
  /usr/bin/tar: ../../../go/pkg/mod/google.golang.org/protobuf@v1.31.0/cmd/protoc-gen-go/testdata/imports/test_a_2/m4.proto: Cannot open: File exists
  Error: /usr/bin/tar: ../../../go/pkg/mod/google.golang.org/protobuf@v1.31.0/cmd/protoc-gen-go/testdata/imports/test_a_2/m3.pb.go: Cannot open: File exists
  /usr/bin/tar: ../../../go/pkg/mod/google.golang.org/protobuf@v1.31.0/cmd/protoc-gen-go/testdata/extensions/ext/ext.proto: Cannot open: File exists
  Error: /usr/bin/tar: ../../../go/pkg/mod/google.golang.org/protobuf@v1.31.0/cmd/protoc-gen-go/testdata/extensions/ext/ext.pb.go: Cannot open: File exists
  Error: /usr/bin/tar: ../../../go/pkg/mod/google.golang.org/protobuf@v1.31.0/cmd/protoc-gen-go/testdata/extensions/extra/extra.pb.go: Cannot open: File exists
  /usr/bin/tar: ../../../go/pkg/mod/google.golang.org/protobuf@v1.31.0/cmd/protoc-gen-go/testdata/extensions/extra/extra.proto: Cannot open: File exists
  /usr/bin/tar: ../../../go/pkg/mod/google.golang.org/protobuf@v1.31.0/cmd/protoc-gen-go/testdata/extensions/proto3/ext3.proto: Cannot open: File exists
  Error: /usr/bin/tar: ../../../go/pkg/mod/google.golang.org/protobuf@v1.31.0/cmd/protoc-gen-go/testdata/extensions/proto3/ext3.pb.go: Cannot open: File exists
  /usr/bin/tar: ../../../go/pkg/mod/google.golang.org/protobuf@v1.31.0/cmd/protoc-gen-go/testdata/extensions/base/base.proto: Cannot open: File exists
  Error: /usr/bin/tar: ../../../go/pkg/mod/google.golang.org/protobuf@v1.31.0/cmd/protoc-gen-go/testdata/extensions/base/base.pb.go: Cannot open: File exists
  Error: /usr/bin/tar: ../../../go/pkg/mod/google.golang.org/protobuf@v1.31.0/cmd/protoc-gen-go/testdata/proto2/fields.pb.go: Cannot open: File exists
  /usr/bin/tar: ../../../go/pkg/mod/google.golang.org/protobuf@v1.31.0/cmd/protoc-gen-go/testdata/proto2/nested_messages.proto: Cannot open: File exists
  /usr/bin/tar: ../../../go/pkg/mod/google.golang.org/protobuf@v1.31.0/cmd/protoc-gen-go/testdata/proto2/proto2.proto: Cannot open: File exists
  /usr/bin/tar: ../../../go/pkg/mod/google.golang.org/protobuf@v1.31.0/cmd/protoc-gen-go/testdata/proto2/enum.proto: Cannot open: File exists
  Error: /usr/bin/tar: ../../../go/pkg/mod/google.golang.org/protobuf@v1.31.0/cmd/protoc-gen-go/testdata/proto2/enum.pb.go: Cannot open: File exists
  Error: /usr/bin/tar: ../../../go/pkg/mod/google.golang.org/protobuf@v1.31.0/cmd/protoc-gen-go/testdata/proto2/proto2.pb.go: Cannot open: File exists
  /usr/bin/tar: ../../../go/pkg/mod/google.golang.org/protobuf@v1.31.0/cmd/protoc-gen-go/testdata/proto2/fields.proto: Cannot open: File exists
  Error: /usr/bin/tar: ../../../go/pkg/mod/google.golang.org/protobuf@v1.31.0/cmd/protoc-gen-go/testdata/proto2/nested_messages.pb.go: Cannot open: File exists
  Error: /usr/bin/tar: ../../../go/pkg/mod/google.golang.org/protobuf@v1.31.0/cmd/protoc-gen-go/testdata/import_public/b.pb.go: Cannot open: File exists
  /usr/bin/tar: ../../../go/pkg/mod/google.golang.org/protobuf@v1.31.0/cmd/protoc-gen-go/testdata/import_public/a.proto: Cannot open: File exists
...
```

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-04-18 19:24:30 +03:00
Roman Khimov
83fdcc8568
Merge pull request #3412 from NeoGoBros/fix-seq-points-after-shorten-jump 2024-04-18 14:24:07 +03:00
Anna Shaleva
4b9024fa45 smartcontract: ensure nil ParameterContext Item's script is marshallable
Ensure that ParameterContext's Item with nil script can be properly
marshalled. Ref. https://github.com/neo-project/neo/pull/3198.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-04-18 13:55:05 +03:00
Slava0135
9b688a9ee9 compiler: reevaluate debug sequence points after shortening jumps
Signed-off-by: Slava0135 <super.novalskiy_0135@inbox.ru>
2024-04-16 10:37:06 +03:00
Roman Khimov
1786136a23
Merge pull request #3405 from nspcc-dev/dynamic-hash
cli: allow dynamic contract hash for contract bindings
2024-04-15 13:16:13 +03:00
Anna Shaleva
d3993ad54c
Merge pull request #3408 from nspcc-dev/hex-string-pub
crypto: add StringCompressed() for PublicKey
2024-04-15 12:31:18 +03:00
Anna Shaleva
db37101e34
Merge pull request #3413 from nspcc-dev/up-dbft
go.mod: import official dbft 0.2.0
2024-04-15 10:41:08 +03:00
Roman Khimov
567f9f9c6e go.mod: import official dbft 0.2.0
Signed-off-by: Roman Khimov <roman@nspcc.ru>
2024-04-14 22:14:24 +03:00
Roman Khimov
fb4a4f074f
Merge pull request #3411 from nspcc-dev/improve-statediff-dumper
scripts: add contract ID/prefix parsing to state dump comparator
2024-04-11 21:23:36 +03:00
Anna Shaleva
97a19df6f0 scripts: add contract ID/prefix parsing to state dump comparator
I had this code locally for some time, let it be public.

The example output for key diff:
```
file BlockStorage_0/dump-block-0.json: block 0: key mismatch:
	Key: /////wz////4
	Contract ID: -1
	Item key (base64): DP////g=
	Item key (hex): 0cfffffff8
	Item key (bytes): [12 255 255 255 248]
vs
	Key: /////wz////5
	Contract ID: -1
	Item key (base64): DP////k=
	Item key (hex): 0cfffffff9
	Item key (bytes): [12 255 255 255 249]
```

The example output for state diff:
```
file BlockStorage_0/dump-block-0.json: block 0: state mismatch for key /////wz////4:
	Contract ID: -1
	Item key (base64): DP////g=
	Item key (hex): 0cfffffff8
	Item key (bytes): [12 255 255 255 248]
	Diff: Added vs Removed
```

The example output for value diff:
```
block 0: value mismatch for key /////wj1Y+pAvCg9TQ4FxI6jBbPyoHNA7w==:
	Contract ID: -1
	Item key (base64): CPVj6kC8KD1NDgXEjqMFs/Kgc0Dv
	Item key (hex): 08f563ea40bc283d4d0e05c48ea305b3f2a07340ef
	Item key (bytes): [8 245 99 234 64 188 40 61 77 14 5 196 142 163 5 179 242 160 115 64 239]
	Diff: QAUhAfshACgU9WPqQLwoPU0OBcSOowWz8qBzQO8o005FRjNuZW8tY29yZS12My4wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACFEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQHvz5gNBCCgITmVvVG9rZW5AAEgAQAEoBk5FUC0xN0ECQBNBBSgJYmFsYW5jZU9mQAFBAigHYWNjb3VudCEBFCEBESEAIAFBBSgIZGVjaW1hbHNAACEBESEBByABQQUoD2dldEFjY291bnRTdGF0ZUABQQIoB2FjY291bnQhARQhASAhAQ4gAUEFKBBnZXRBbGxDYW5kaWRhdGVzQAAhATAhARUgAUEFKBBnZXRDYW5kaWRhdGVWb3RlQAFBAigGcHViS2V5IQEWIQERIQEcIAFBBSgNZ2V0Q2FuZGlkYXRlc0AAIQEgIQEjIAFBBSgMZ2V0Q29tbWl0dGVlQAAhASAhASogAUEFKA5nZXRHYXNQZXJCbG9ja0AAIQERIQExIAFBBSgWZ2V0TmV4dEJsb2NrVmFsaWRhdG9yc0AAIQEgIQE4IAFBBSgQZ2V0UmVnaXN0ZXJQcmljZUAAIQERIQE/IAFBBSgRcmVnaXN0ZXJDYW5kaWRhdGVAAUECKAZwdWJrZXkhARYhARAhAUYgAEEFKA5zZXRHYXNQZXJCbG9ja0ABQQIoC2dhc1BlckJsb2NrIQERIQL/ACEBTSAAQQUoEHNldFJlZ2lzdGVyUHJpY2VAAUECKA1yZWdpc3RlclByaWNlIQERIQL/ACEBVCAAQQUoBnN5bWJvbEAAIQETIQFbIAFBBSgLdG90YWxTdXBwbHlAACEBESEBYiABQQUoCHRyYW5zZmVyQARBAigEZnJvbSEBFEECKAJ0byEBFEECKAZhbW91bnQhARFBAigEZGF0YSEAIQEQIQFpIABBBSgMdW5jbGFpbWVkR2FzQAJBAigHYWNjb3VudCEBFEECKANlbmQhAREhAREhAXAgAUEFKBN1bnJlZ2lzdGVyQ2FuZGlkYXRlQAFBAigGcHVia2V5IQEWIQEQIQF3IABBBSgEdm90ZUACQQIoB2FjY291bnQhARRBAigGdm90ZVRvIQEWIQEQIQF+IABAA0ECKBVDYW5kaWRhdGVTdGF0ZUNoYW5nZWRAA0ECKAZwdWJrZXkhARZBAigKcmVnaXN0ZXJlZCEBEEECKAV2b3RlcyEBEUECKARWb3RlQARBAigHYWNjb3VudCEBFEECKARmcm9tIQEWQQIoAnRvIQEWQQIoBmFtb3VudCEBEUECKBBDb21taXR0ZWVDaGFuZ2VkQAJBAigDb2xkIQEgQQIoA25ldyEBIEABQQIAAEAAKARudWxs vs QAUhAfshACgU9WPqQLwoPU0OBcSOowWz8qBzQO8o005FRjNuZW8tY29yZS12My4wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACFEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQHvz5gNBCCgITmVvVG9rZW5AAEgAQAEoBk5FUC0xN0ECQBNBBSgJYmFsYW5jZU9mQAFBAigHYWNjb3VudCEBFCEBESEAIAFBBSgIZGVjaW1hbHNAACEBESEBByABQQUoD2dldEFjY291bnRTdGF0ZUABQQIoB2FjY291bnQhARQhASAhAQ4gAUEFKBBnZXRBbGxDYW5kaWRhdGVzQAAhATAhARUgAUEFKBBnZXRDYW5kaWRhdGVWb3RlQAFBAigGcHViS2V5IQEWIQERIQEcIAFBBSgNZ2V0Q2FuZGlkYXRlc0AAIQEgIQEjIAFBBSgMZ2V0Q29tbWl0dGVlQAAhASAhASogAUEFKA5nZXRHYXNQZXJCbG9ja0AAIQERIQExIAFBBSgWZ2V0TmV4dEJsb2NrVmFsaWRhdG9yc0AAIQEgIQE4IAFBBSgQZ2V0UmVnaXN0ZXJQcmljZUAAIQERIQE/IAFBBSgRcmVnaXN0ZXJDYW5kaWRhdGVAAUECKAZwdWJrZXkhARYhARAhAUYgAEEFKA5zZXRHYXNQZXJCbG9ja0ABQQIoC2dhc1BlckJsb2NrIQERIQL/ACEBTSAAQQUoEHNldFJlZ2lzdGVyUHJpY2VAAUECKA1yZWdpc3RlclByaWNlIQERIQL/ACEBVCAAQQUoBnN5bWJvbEAAIQETIQFbIAFBBSgLdG90YWxTdXBwbHlAACEBESEBYiABQQUoCHRyYW5zZmVyQARBAigEZnJvbSEBFEECKAJ0byEBFEECKAZhbW91bnQhARFBAigEZGF0YSEAIQEQIQFpIABBBSgMdW5jbGFpbWVkR2FzQAJBAigHYWNjb3VudCEBFEECKANlbmQhAREhAREhAXAgAUEFKBN1bnJlZ2lzdGVyQ2FuZGlkYXRlQAFBAigGcHVia2V5IQEWIQEQIQF3IABBBSgEdm90ZUACQQIoB2FjY291bnQhARRBAigGdm90ZVRvIQEWIQEQIQF+IABABEECKAhUcmFuc2ZlckADQQIoBGZyb20hARRBAigCdG8hARRBAigGYW1vdW50IQERQQIoFUNhbmRpZGF0ZVN0YXRlQ2hhbmdlZEADQQIoBnB1YmtleSEBFkECKApyZWdpc3RlcmVkIQEQQQIoBXZvdGVzIQERQQIoBFZvdGVABEECKAdhY2NvdW50IQEUQQIoBGZyb20hARZBAigCdG8hARZBAigGYW1vdW50IQERQQIoEENvbW1pdHRlZUNoYW5nZWRAAkECKANvbGQhASBBAigDbmV3IQEgQAFBAgAAQAAoBG51bGw=
```

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-04-11 19:27:57 +03:00
Ekaterina Pavlova
c5dbecb754 smartcontract: support dynamic contract hash for bindings
Allow dynamic contract hash for contract bindings.

Close #3007

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-04-11 16:02:31 +03:00
Ekaterina Pavlova
fc79d38ad2 crypto: adjust NewPublicKeyFromString's comment
Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-04-11 15:24:47 +03:00
Ekaterina Pavlova
ae3515e819 crypto: add StringCompressed() for PublicKey
Add StringCompressed to get a string representation of the key in
compressed form.

Close #3263

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-04-11 15:24:46 +03:00
Roman Khimov
8913542f93
Merge pull request #3410 from nspcc-dev/fix-cli-desc 2024-04-10 23:21:20 +03:00
Anna Shaleva
69bcd4b7d9 cli: unify commands description
Always put blank line in the end of the command description.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-04-10 19:21:40 +03:00
Anna Shaleva
51537dfd29
Merge pull request #3404 from stevvns/neotest-options
neotest: add options to customize test chain
2024-04-10 10:17:40 +03:00
Anna Shaleva
ee1ee56f97
Merge pull request #3409 from nspcc-dev/update-codecov
workflows: update CodeCov action, use token for upload
2024-04-09 14:56:34 +03:00
Roman Khimov
8c1d061446 workflows: update CodeCov action, use token for upload
It fails now without a token.

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2024-04-09 13:39:11 +03:00
Anna Shaleva
a28e5b24b2
Merge pull request #3406 from nspcc-dev/error-message
native: adjust error message for ExecFeeFactor and StoragePrice
2024-04-09 10:59:03 +03:00
stevvns
7aa5983543 neotest: add options to customize test chain
Close #3403

Signed-off-by: stevvns <stevvns@yandex.com>
2024-04-09 09:18:36 +04:00
Ekaterina Pavlova
fcbfc3b807 native: adjust error message for ExecFeeFactor and StoragePrice
Close #3311

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-04-09 01:51:03 +03:00
Roman Khimov
cf49e8c4c8
Merge pull request #3401 from fyfyrchik/compiler-named-return-defaults
compiler: Initialize named returns to default values
2024-04-05 15:25:11 +03:00
Evgenii Stratonikov
78cefca5c9 compiler: Initialize named returns to default values
Make them behave as locals. We must initialize them at the start
because the default value could also be used inside the function body.

Signed-off-by: Evgenii Stratonikov <fyfyrchik@runbox.com>
2024-04-04 18:00:26 +03:00
Anna Shaleva
f2bb4d455b
Merge pull request #3389 from nspcc-dev/import-wallet-error
cli: improve wallet read related errors
2024-04-04 14:10:47 +03:00
Roman Khimov
f553f77d20
Merge pull request #3400 from nspcc-dev/fix-TestServerStartAndShutdown
network: take care of TestServerStartAndShutdown
2024-04-04 13:56:22 +03:00
Ekaterina Pavlova
700a550973 cli: improve wallet unmarshalling error
Made errors more user-friendly.
```
./bin/neo-go wallet import --wif qweqweqweqwe -w wallet1.json
failed to read wallet: open wallet: open wallet.json: no such file or
directory

touch wallet.json

./bin/neo-go wallet import --wif qweqweqweqwe -w wallet.json
failed to read wallet: unmarshal wallet: EOF
```

Close #3134

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-04-04 13:46:54 +03:00
Anna Shaleva
f84f072a29 network: take care of TestServerStartAndShutdown
We don't have a reliable way to know when transports are started since
their start is being performed in a separate goroutine:

927dbb6dc4/pkg/network/server.go (L297-L299)

And transports start is not connected with main server routine, thus,
just wait for some time for the transports goroutine to be started.

Also wait for the peer to be properly registered.

Close #3399.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-04-04 13:29:47 +03:00
Roman Khimov
927dbb6dc4
Merge pull request #3398 from nspcc-dev/enforce-testws-close 2024-04-04 13:12:38 +03:00
Anna Shaleva
e5c919f701 rpcsrv: enforce WS connection close on test cleanup
Do not wait until wsReader routine gracefully finishes its work before
WS connection close. Instead, firstly close the connection, and after
that wait for proper wsReader exit.

It's a harsh way, but I don't have any other options to try, because
wsReader routine hangs on `ws.ReadMessage()` operation for more than
ReadDeadline (more than 5 seconds) during test cleanup which results in
the test timeout.

Close #3378.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-04-04 12:03:06 +03:00
Roman Khimov
22af33a14e
Merge pull request #3397 from nspcc-dev/fix-TestWSClient_SubscriptionsCompat 2024-04-04 12:02:20 +03:00
Anna Shaleva
ef3ec190d0 rpcsrv: allow one-block slippage in TestWSClient_SubscriptionsCompat
Close #2956. The failure reason is similar to the one described in #3396
for TestNotary: Blockchain's notificationDispatcher is listening to
block events from storeBlock via separate channel. By the moment single
block addition is finished, notification may or may not be properly
handled by notificationDispatcher, especially given the fact that our
runners are slow. As a result, assert.Eventually with 1-second awaiting
period may fail. This issue is solved by adding one more block, because
the second AddBlock finishes only when it sends block addition event to
notificationDispatcher loop, which means that the previous event was
handled.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-04-04 11:02:15 +03:00
Anna Shaleva
b1a986fba8
Merge pull request #3386 from nspcc-dev/getversion
rpcsrv: add SessionEnabled, MaxIteratorResultItems to `getversion`
2024-04-04 10:38:09 +03:00
Roman Khimov
f6901806a8
Merge pull request #3396 from nspcc-dev/fix-TestNotary
services: allow some slippage in TestNotary
2024-04-03 23:26:00 +03:00
Ekaterina Pavlova
686c77aeea rpcsrv: add SessionEnabled, MaxIteratorResultItems to getversion
Extend getversion RPC response with RPC server settings (SessionEnabled,
MaxIteratorResultItems).Port neo-project/neo-modules#878.

Close #3276

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-04-03 22:42:14 +03:00
Anna Shaleva
89ef26164c
Merge pull request #3384 from nspcc-dev/TestWSClientsLimit
rpcsrv: fix TestWSClientsLimit
2024-04-03 20:01:18 +03:00
Anna Shaleva
4c288720cd services: allow some slippage in TestNotary
1. Allow 1-block slippage for multisignature request block generation to
   ensure that PostPersist for fb's NVB-th block is properly finished.
2. Allow 1-block slippage before sent request checks to ensure that
   PostPersist for NVB fb's NVB-th block was finished and all
   stale mains were properly marked by Notary service.

Overall, this commits ports the approach of #3390 to the whole test.

Close #3366.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-04-03 18:44:23 +03:00
Ekaterina Pavlova
f8c2d269fe rpcsrv: increase timeout in TestWSClientsLimit
Still not fast enough for connections to be alive for the default case
of 64+1 connections. Some of them are start to die after 5 seconds of
test:
```
2024-04-03T14:06:22.5504034Z === RUN   TestWSClientsLimit
2024-04-03T14:06:22.5504142Z === RUN   TestWSClientsLimit/default
2024-04-03T14:06:22.5504868Z     logger.go:146: 2024-04-03T14:04:30.637Z
	INFO	initial gas supply is not set or wrong, setting default
	value	{"InitialGASSupply": "52000000"}
2024-04-03T14:06:22.5505730Z     logger.go:146: 2024-04-03T14:04:30
.637Z	INFO	P2PNotaryRequestPayloadPool size is not set or wrong,
setting default value	{"P2PNotaryRequestPayloadPoolSize": 1000}
2024-04-03T14:06:22.5506373Z     logger.go:146: 2024-04-03T14:04:30
.637Z	INFO	MaxBlockSize is not set or wrong, setting default
value	{"MaxBlockSize": 262144}
2024-04-03T14:06:22.5507094Z     logger.go:146: 2024-04-03T14:04:30
.637Z	INFO	MaxBlockSystemFee is not set or wrong, setting default
 value	{"MaxBlockSystemFee": 900000000000}
2024-04-03T14:06:22.5507843Z     logger.go:146: 2024-04-03T14:04:30
.637Z	INFO	MaxTransactionsPerBlock is not set or wrong, using
default value	{"MaxTransactionsPerBlock": 512}
2024-04-03T14:06:22.5508644Z     logger.go:146: 2024-04-03T14:04:30
.637Z	INFO	MaxValidUntilBlockIncrement is not set or wrong, using
 default value	{"MaxValidUntilBlockIncrement": 5760}
2024-04-03T14:06:22.5509114Z     logger.go:146: 2024-04-03T14:04:30
.637Z	INFO	no storage version found! creating genesis block
2024-04-03T14:06:22.5509788Z     logger.go:146: 2024-04-03T14:04:30
.637Z	INFO	ExtensiblePoolSize is not set or wrong, using default
value	{"ExtensiblePoolSize": 20}
2024-04-03T14:06:22.5510476Z     logger.go:146: 2024-04-03T14:04:30
.637Z	INFO	SessionPoolSize is not set or wrong, setting default
value	{"SessionPoolSize": 20}
2024-04-03T14:06:22.5511258Z     logger.go:146: 2024-04-03T14:04:30
.637Z	INFO	MaxIteratorResultItems is not set or wrong, setting
default value	{"MaxIteratorResultItems": 100}
2024-04-03T14:06:22.5511951Z     logger.go:146: 2024-04-03T14:04:30
.637Z	INFO	MaxFindResultItems is not set or wrong, setting
default value	{"MaxFindResultItems": 100}
2024-04-03T14:06:22.5512598Z     logger.go:146: 2024-04-03T14:04:30
.637Z	INFO	MaxNEP11Tokens is not set or wrong, setting default
value	{"MaxNEP11Tokens": 100}
2024-04-03T14:06:22.5513316Z     logger.go:146: 2024-04-03T14:04:30
.637Z	INFO	MaxRequestBodyBytes is not set or wong, setting
default value	{"MaxRequestBodyBytes": 5242880}
2024-04-03T14:06:22.5514060Z     logger.go:146: 2024-04-03T14:04:30
.637Z	INFO	MaxRequestHeaderBytes is not set or wong, setting
default value	{"MaxRequestHeaderBytes": 1048576}
2024-04-03T14:06:22.5514755Z     logger.go:146: 2024-04-03T14:04:30
.637Z	INFO	MaxWebSocketClients is not set or wrong, setting
default value	{"MaxWebSocketClients": 64}
2024-04-03T14:06:22.5515215Z     logger.go:146: 2024-04-03T14:04:30
.637Z	INFO	starting rpc-server	{"endpoint": "127.0.0.1:0"}
2024-04-03T14:06:22.5515874Z     logger.go:146: 2024-04-03T14:04:31
.200Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5516442Z     logger.go:146: 2024-04-03T14:04:31
.200Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5516973Z     logger.go:146: 2024-04-03T14:04:31
.226Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5517502Z     logger.go:146: 2024-04-03T14:04:31
.388Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5518027Z     logger.go:146: 2024-04-03T14:04:31
.398Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5518551Z     logger.go:146: 2024-04-03T14:04:31
.420Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5519082Z     logger.go:146: 2024-04-03T14:04:31
.577Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5519606Z     logger.go:146: 2024-04-03T14:04:31
.587Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5520133Z     logger.go:146: 2024-04-03T14:04:31
.624Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5520850Z     logger.go:146: 2024-04-03T14:04:31
.780Z	INFO	persisted to disk	{"blocks": 0, "keys": 127,
"headerHeight": 0, "blockHeight": 0, "took": "121.8µs"}
2024-04-03T14:06:22.5521398Z     logger.go:146: 2024-04-03T14:04:31
.780Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5521925Z     logger.go:146: 2024-04-03T14:04:31
.812Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5522452Z     logger.go:146: 2024-04-03T14:04:31
.969Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5522975Z     logger.go:146: 2024-04-03T14:04:32
.016Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5523507Z     logger.go:146: 2024-04-03T14:04:32
.172Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5524033Z     logger.go:146: 2024-04-03T14:04:32
.219Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5524555Z     logger.go:146: 2024-04-03T14:04:32
.273Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5525081Z     logger.go:146: 2024-04-03T14:04:32
.376Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5525604Z     logger.go:146: 2024-04-03T14:04:32
.423Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5526131Z     logger.go:146: 2024-04-03T14:04:32
.563Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5526691Z     logger.go:146: 2024-04-03T14:04:32
.627Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5527254Z     logger.go:146: 2024-04-03T14:04:32
.767Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5527777Z     logger.go:146: 2024-04-03T14:04:32
.830Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5528304Z     logger.go:146: 2024-04-03T14:04:32
.955Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5528824Z     logger.go:146: 2024-04-03T14:04:33
.033Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5529352Z     logger.go:146: 2024-04-03T14:04:33
.158Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5529871Z     logger.go:146: 2024-04-03T14:04:33
.237Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5530395Z     logger.go:146: 2024-04-03T14:04:33
.322Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5530921Z     logger.go:146: 2024-04-03T14:04:33
.348Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5531472Z     logger.go:146: 2024-04-03T14:04:33
.444Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5532031Z     logger.go:146: 2024-04-03T14:04:33
.535Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5532555Z     logger.go:146: 2024-04-03T14:04:33
.645Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5533084Z     logger.go:146: 2024-04-03T14:04:33
.724Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5533604Z     logger.go:146: 2024-04-03T14:04:33
.848Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5534132Z     logger.go:146: 2024-04-03T14:04:33
.926Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5534662Z     logger.go:146: 2024-04-03T14:04:34
.036Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5535190Z     logger.go:146: 2024-04-03T14:04:34
.130Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5535712Z     logger.go:146: 2024-04-03T14:04:34
.224Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5536231Z     logger.go:146: 2024-04-03T14:04:34
.318Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5536758Z     logger.go:146: 2024-04-03T14:04:34
.413Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5537277Z     logger.go:146: 2024-04-03T14:04:34
.423Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5537805Z     logger.go:146: 2024-04-03T14:04:34
.423Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5538329Z     logger.go:146: 2024-04-03T14:04:34
.523Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5538855Z     logger.go:146: 2024-04-03T14:04:34
.602Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5539382Z     logger.go:146: 2024-04-03T14:04:34
.612Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5539908Z     logger.go:146: 2024-04-03T14:04:34
.712Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5540431Z     logger.go:146: 2024-04-03T14:04:34
.805Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5540956Z     logger.go:146: 2024-04-03T14:04:34
.915Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5541515Z     logger.go:146: 2024-04-03T14:04:34
.993Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5542070Z     logger.go:146: 2024-04-03T14:04:35
.118Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5542599Z     logger.go:146: 2024-04-03T14:04:35
.181Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5543125Z     logger.go:146: 2024-04-03T14:04:35
.307Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5543650Z     logger.go:146: 2024-04-03T14:04:35
.385Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5544169Z     logger.go:146: 2024-04-03T14:04:35
.426Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5544695Z     logger.go:146: 2024-04-03T14:04:35
.510Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5545262Z     logger.go:146: 2024-04-03T14:04:35
.589Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5545839Z     logger.go:146: 2024-04-03T14:04:35
.698Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5546421Z     logger.go:146: 2024-04-03T14:04:35
.777Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5547045Z     logger.go:146: 2024-04-03T14:04:35
.902Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5547593Z     logger.go:146: 2024-04-03T14:04:35
.980Z	DEBUG	processing rpc request	{"method": "getversion",
"params": "[]"}
2024-04-03T14:06:22.5551421Z     subscription_test.go:620:
2024-04-03T14:06:22.5551977Z         	Error Trace:
D:/a/neo-go/neo-go/pkg/services/rpcsrv/subscription_test.go:620
2024-04-03T14:06:22.5552611Z
C:/hostedtoolcache/windows/go/1.22.1/x64/src/runtime/asm_amd64.s:1695
2024-04-03T14:06:22.5552821Z         	Error:      	Received
unexpected error:
2024-04-03T14:06:22.5553328Z         	            	read tcp 127.0
.0.1:51969->127.0.0.1:51909: i/o timeout
2024-04-03T14:06:22.5553535Z         	Test:
TestWSClientsLimit/default
2024-04-03T14:06:22.5553676Z     subscription_test.go:620:
2024-04-03T14:06:22.5554223Z         	Error Trace:
D:/a/neo-go/neo-go/pkg/services/rpcsrv/subscription_test.go:620
2024-04-03T14:06:22.5554831Z
C:/hostedtoolcache/windows/go/1.22.1/x64/src/runtime/asm_amd64.s:1695
2024-04-03T14:06:22.5555036Z         	Error:      	Received
unexpected error:
2024-04-03T14:06:22.5555521Z         	            	read tcp 127.0
.0.1:51970->127.0.0.1:51909: i/o timeout
2024-04-03T14:06:22.5555723Z         	Test:
TestWSClientsLimit/default
2024-04-03T14:06:22.5555860Z     subscription_test.go:620:
2024-04-03T14:06:22.5556336Z         	Error Trace:
D:/a/neo-go/neo-go/pkg/services/rpcsrv/subscription_test.go:620
2024-04-03T14:06:22.5556953Z
C:/hostedtoolcache/windows/go/1.22.1/x64/src/runtime/asm_amd64.s:1695
2024-04-03T14:06:22.5557160Z         	Error:      	Received
unexpected error:
2024-04-03T14:06:22.5557636Z         	            	read tcp 127.0
.0.1:51973->127.0.0.1:51909: i/o timeout
2024-04-03T14:06:22.5557831Z         	Test:
TestWSClientsLimit/default
2024-04-03T14:06:22.5557967Z     subscription_test.go:620:
2024-04-03T14:06:22.5558437Z         	Error Trace:
D:/a/neo-go/neo-go/pkg/services/rpcsrv/subscription_test.go:620
2024-04-03T14:06:22.5559028Z
C:/hostedtoolcache/windows/go/1.22.1/x64/src/runtime/asm_amd64.s:1695
2024-04-03T14:06:22.5559229Z         	Error:      	Received
unexpected error:
2024-04-03T14:06:22.5559696Z         	            	read tcp 127.0
.0.1:51971->127.0.0.1:51909: i/o timeout
2024-04-03T14:06:22.5559891Z         	Test:
TestWSClientsLimit/default
2024-04-03T14:06:22.5560024Z     subscription_test.go:620:
2024-04-03T14:06:22.5560490Z         	Error Trace:
D:/a/neo-go/neo-go/pkg/services/rpcsrv/subscription_test.go:620
2024-04-03T14:06:22.5561142Z
C:/hostedtoolcache/windows/go/1.22.1/x64/src/runtime/asm_amd64.s:1695
2024-04-03T14:06:22.5561371Z         	Error:      	Received
unexpected error:
2024-04-03T14:06:22.5561849Z         	            	read tcp 127.0
.0.1:51972->127.0.0.1:51909: i/o timeout
2024-04-03T14:06:22.5562043Z         	Test:
TestWSClientsLimit/default
2024-04-03T14:06:22.5562179Z     subscription_test.go:630:
2024-04-03T14:06:22.5562638Z         	Error Trace:
D:/a/neo-go/neo-go/pkg/services/rpcsrv/subscription_test.go:630
2024-04-03T14:06:22.5562879Z         	Error:      	An error is
expected but got nil.
2024-04-03T14:06:22.5563073Z         	Test:
TestWSClientsLimit/default
2024-04-03T14:06:22.5563361Z         	Messages:   	The connection
 beyond the limit should fail
2024-04-03T14:06:22.5563886Z     logger.go:146: 2024-04-03T14:04:36
.481Z	INFO	shutting down RPC server	{"endpoint": "127.0.0
.1:51908"}
```

Close #3379

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-04-03 18:03:55 +03:00
Ekaterina Pavlova
698bdc7eea rpcsrv: fix TestWSClientsLimit
Made connections in parallel to check the limit and attempt to make one
more connection beyond the limit. Only "default" test case is failing,
because default number of connections is 64 (quite large for slow
runners). The failure reason is:
* given ~1 second for [dealing + request] per connection (time is taken
from the test log)
* by the moment 65-th connection is reached, some connections from the
start of the test have died due to inactivity (this process literally
takes 1 minute)

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-04-03 18:03:55 +03:00
Roman Khimov
0280ceefe6
Merge pull request #3395 from nspcc-dev/fix-awaitabletxtest
cli: ensure all outcomes are handled in TestAwaitUtilCancelTx
2024-04-03 17:55:35 +03:00
Anna Shaleva
b6a9c64c55 cli: ensure all outcomes are handled in TestAwaitUtilCancelTx
Close #3365.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-04-03 16:40:11 +03:00
Roman Khimov
be1b97d04e
Merge pull request #3392 from nspcc-dev/adjust-deadlines
*: adjust WS connection RW deadlines
2024-04-03 14:50:14 +03:00
Anna Shaleva
29deba45ca services: refactor test WS reader
1. Replace isFinished atomic variable with a channel, no functional changes
   here, just use more common way as all our services do.

2. Do not check erors from SetReadDeadline and ReadMessage on exit. It
   seems to be not quite right because connection is not closed by this
   moment, and thus, these error checks are racy.
3. Add read timeout for the message reader. It is needed because some
   tests may leave message unread in the end which results in hanging
   test cleanup.
4. Add drain loop to message reader in order not to block WS reader on
   sending message.

Ref. https://github.com/nspcc-dev/neo-go/pull/3392#issuecomment-2031590403.
It's clear that TestBadSubUnsub is hanging on test cleanup, in
particular, on attempt to wait for wsRead routine to exit. The only
place where wsRead routine may hang is sending to msgCh in case if
receiver is not going to read from this channel:
```
2024-04-02T08:14:51.4957621Z goroutine 14329 [chan receive]:
2024-04-02T08:14:51.4958010Z github.com/nspcc-dev/neo-go/pkg/services/rpcsrv.initCleanServerAndWSClient.func1()
2024-04-02T08:14:51.4958344Z 	D:/a/neo-go/neo-go/pkg/services/rpcsrv/subscription_test.go:80 +0x71
2024-04-02T08:14:51.4958457Z testing.(*common).Cleanup.func1()
2024-04-02T08:14:51.4958757Z 	C:/hostedtoolcache/windows/go/1.22.1/x64/src/testing/testing.go:1175 +0x17a
2024-04-02T08:14:51.4958903Z testing.(*common).runCleanup(0xc002cf5860, 0x0)
2024-04-02T08:14:51.4959193Z 	C:/hostedtoolcache/windows/go/1.22.1/x64/src/testing/testing.go:1353 +0x262
2024-04-02T08:14:51.4959291Z testing.tRunner.func2()
2024-04-02T08:14:51.4959566Z 	C:/hostedtoolcache/windows/go/1.22.1/x64/src/testing/testing.go:1683 +0x51
2024-04-02T08:14:51.4959695Z testing.tRunner(0xc002cf5860, 0x141687410)
2024-04-02T08:14:51.4959976Z 	C:/hostedtoolcache/windows/go/1.22.1/x64/src/testing/testing.go:1695 +0x25e
2024-04-02T08:14:51.4960115Z created by testing.(*T).Run in goroutine 1
2024-04-02T08:14:51.4960385Z 	C:/hostedtoolcache/windows/go/1.22.1/x64/src/testing/testing.go:1742 +0x826
```

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-04-03 12:56:07 +03:00
Anna Shaleva
c81ed22698
Merge pull request #3394 from nspcc-dev/better-notary-actor
rpcclient: make default Notary actor options customizable
2024-04-03 11:02:24 +03:00
Anna Shaleva
c5ba53986f
Merge pull request #3385 from nspcc-dev/findstorage
rpcsrv: fix findstorage if a contract state is not found
2024-04-03 11:00:55 +03:00
Ekaterina Pavlova
fff25bd85c rpcsrv: fix findstorage if a contract state is not found
Previously findstorage returns null for the results key if a contract
state is not found. C# returns an empty list.

Close #3370

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-04-02 19:56:44 +03:00
Anna Shaleva
182762af5a rpcclient: make default Notary actor options customizable
This commit allows to override only MainModifier omitting overriding
MainCheckerModifier.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-04-02 18:56:43 +03:00
Roman Khimov
e7a0ded65e
Merge pull request #3391 from nspcc-dev/fix-tx-awaiting
cli: unify `canceltx` command output
2024-04-02 15:28:01 +03:00
Roman Khimov
7202518fcf
Merge pull request #3390 from nspcc-dev/fix-notary-test
services: fix race in TestNotary
2024-04-02 15:26:31 +03:00
Anna Shaleva
e0e7fdf810 cli: unify canceltx command output
Always return "Target transaction accepted" error if the target transation was
either accepted by the moment of command run or during the command
handling. Exit with code 1 in both cases. Adjust TestAwaitUtilCancelTx
correspondingly, allow both cases in test. Simplify the test along the
way, remove useless code.

Close #3365.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-04-02 15:23:25 +03:00
Anna Shaleva
f95004ad83 services: fix race in TestNotary
Close #3366. Roll back the test structure to the one that it has before
d2a7162217. Add one extra block to ensure
that main transaction won't be finilized. Add NVB increment slippage to
avoid race between the first fallback acceptance and block acceptance.
Add NVB increment slippage to the rest of fallbacks for test structure
unification.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-04-02 15:15:02 +03:00
Anna Shaleva
309016561d
Merge pull request #3393 from nspcc-dev/testrpc
rpc: fix TestRPC timeout
2024-04-02 12:37:16 +03:00
Ekaterina Pavlova
65dbd537ec rpc: fix TestRPC timeout
Increase timeout to prevent `context deadline exceeded (Client.Timeout
exceeded while awaiting headers)`.

Close #2975

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-04-02 11:11:14 +03:00
Anna Shaleva
b947d09552 *: adjust WS connection RW deadlines
Yet another attempt to close #3378.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-04-02 10:31:38 +03:00
Roman Khimov
5c995e71b5
Merge pull request #3387 from nspcc-dev/fix-test-wsreader 2024-04-01 19:22:55 +03:00
Anna Shaleva
5b30d15f8e rpcsrv: properly cleanup network server in tests
Port the idea of https://github.com/nspcc-dev/neo-go/pull/3380.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-04-01 18:54:35 +03:00
Anna Shaleva
57d82c1281 rpcsrv: properly cleanup WS reader in tests
Close #3378.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-04-01 18:54:35 +03:00
Roman Khimov
e341e64684
Merge pull request #3388 from nspcc-dev/wrkfl-upd
workflows: update CodeQL version
2024-04-01 18:46:59 +03:00
Anna Shaleva
cd215fe096
Merge pull request #3382 from xiaoxianBoy/fix-typos
chore: fix typos
2024-04-01 18:41:01 +03:00
Anna Shaleva
d7ab7634ef workflows: update CodeQL version
Warning: CodeQL Action v2 will be deprecated on December 5th, 2024. Please update all occurrences of the CodeQL Action in your workflow files to v3. For more information, see https://github.blog/changelog/2024-01-12-code-scanning-deprecation-of-codeql-action-v2/

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-04-01 18:27:59 +03:00
Anna Shaleva
00ac38b545
Merge pull request #3377 from nspcc-dev/test-subclient
rpcsrv: fix TestSubClientWaitWithMissedEvent
2024-04-01 11:13:23 +03:00
Ekaterina Pavlova
56e6119f78 rpcsrv: fix TestSubClientWaitWithMissedEvent
Add error channel to prevent data race in the test.
Increase waiting interval for subscriptions awaiting up to 2 seconds.
Failing is caused by slow subscriptions.

Close #2958

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-04-01 10:52:13 +03:00
snoppy
d3c8916827
chore: fix typos 2024-04-01 09:43:20 +08:00
Anna Shaleva
86f16bb931
Merge pull request #3375 from nspcc-dev/standby-note
docs: adjust StandByCommittee node config documentation
2024-03-27 21:32:34 +03:00
Anna Shaleva
e27a822d4b
Merge pull request #3376 from nspcc-dev/test-nep17-transfer
cli: fix TestNEP17Transfer fail
2024-03-27 20:55:27 +03:00
Anna Shaleva
687a724d2c docs: adjust StandByCommittee node config documentation
Add a note about elements order.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-03-27 20:52:18 +03:00
Ekaterina Pavlova
8d0d5cb7cd cli: fix TestNEP17Transfer fail
To prevent `Expired transaction (-510) - transaction has expired:
ValidUntilBlock = 8, current height = 8` VUB have been increased.

Close #3343

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-03-27 11:16:43 +03:00
Anna Shaleva
627a0abb57
Merge pull request #3371 from nspcc-dev/upd-dbft
consensus: integrate dBFT pre-0.2.0
2024-03-25 19:54:05 +03:00
Anna Shaleva
beee2605a3 consensus: use better dbFT
Fetch fresh dbft version with minor adjustments.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-03-25 19:21:51 +03:00
Anna Shaleva
708b439f4a consensus: remove unused dBFT payload methods
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-03-25 19:21:51 +03:00
Anna Shaleva
3e6dfff503 consensus: fetch dbft pre-0.2.0 version
Try out updated dBFT interface.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-03-25 19:21:50 +03:00
Roman Khimov
f8ca51db93
Merge pull request #3374 from nspcc-dev/improve-err
*: improve error text for System.Crypto.CheckMultisig handling
2024-03-25 19:20:35 +03:00
Anna Shaleva
85a2a9a989 *: improve error text for System.Crypto.CheckMultisig handling
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-03-25 19:16:21 +03:00
Anna Shaleva
37d7a3a2d5
Merge pull request #3301 from nspcc-dev/keccak256
interop: add keccak256 implementation
2024-03-23 14:23:10 +03:00
Ekaterina Pavlova
c090628ea5 rpcsrv: update block20StateRootLE
Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-03-22 17:20:06 +03:00
Ekaterina Pavlova
6d1a22dcb3 *: update interop deps
Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-03-22 17:17:30 +03:00
Ekaterina Pavlova
1840c057bd interop: add keccak256 implementation
Port neo-project/neo#2925.

Close #3295

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-03-22 17:15:43 +03:00
Anna Shaleva
fa1c07e7e6
Merge pull request #3362 from nspcc-dev/getCommitteeAddress
native: add getCommitteeAddress method
2024-03-22 17:13:29 +03:00
Anna Shaleva
d5a5e4c125
Merge pull request #3368 from nspcc-dev/test-dial
rpcsrv: fix TestRPC failing
2024-03-22 16:53:09 +03:00
Ekaterina Pavlova
f8ebed2da4 *: update interop deps
Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-03-22 16:48:58 +03:00
Ekaterina Pavlova
72484a33eb rpcsrv: update block20StateRootLE
Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-03-22 16:46:59 +03:00
Ekaterina Pavlova
e0328cc1f8 native: add getCommitteeAddress method
Port neo-project/neo#3154.

Close #3334

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-03-22 16:46:59 +03:00
Anna Shaleva
900ef462df
Merge pull request #3369 from nspcc-dev/test-await
cli: fix TestAwaitUtilCancelTx failing
2024-03-22 16:33:25 +03:00
Ekaterina Pavlova
d80e14dcbb cli: fix TestAwaitUtilCancelTx failing
Occasionally the block is being accepted right after main transaction
submission. Added two branches into this TestAwaitUtilCancelTx. One
branch handles the case of original transaction acceptance, the
other branch handles the conflicting transaction acceptance.

Close #3365

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-03-22 16:22:11 +03:00
Ekaterina Pavlova
f409fc36e2 rpcsrv: fix TestRPC failing
Default http.Client and http.Transport can be really slow. Also on
windows Timeout: time.Second was not enough. Probably network related
issue. As mentioned in https://github
.com/nspcc-dev/neo-go/issues/2975#issuecomment-1750523651 forcely use
only tcp4 and FallbackDelay: -1. This made TestRPC little bit faster so
gh windows runner can manage it without timeout or POST request fails.

Close #2975
Close #3314

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-03-22 16:18:19 +03:00
Anna Shaleva
b028c772f2
Merge pull request #3364 from nspcc-dev/fuzz
network: fix logging data race in the package
2024-03-21 19:52:33 +03:00
Anna Shaleva
308475f746
Merge pull request #3351 from nspcc-dev/CommitteeChanged
native: add committee change events
2024-03-21 19:37:43 +03:00
Ekaterina Pavlova
31548dc28f network: fix logging data race in the package
Nested goroutines could cause logging race.

Close #3316

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-03-20 13:12:14 +03:00
Ekaterina Pavlova
7c2575568d rpcsrv: update block20StateRootLE
Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-03-19 23:00:06 +03:00
Ekaterina Pavlova
270515de6a native: add committee change events
Port neo-project/neo#3158.

Close #3326

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-03-19 23:00:06 +03:00
Roman Khimov
a81dc5c795
Merge pull request #3356 from fyfyrchik/fix-checkresok
rpcclient: return FaultException in checkResOk if any
2024-03-19 22:32:45 +03:00
Roman Khimov
da4e80e7a0
Merge pull request #3357 from nspcc-dev/fix-notary
core: prohibit reentry to Notary withdraw
2024-03-19 22:31:49 +03:00
Evgenii Stratonikov
1a3a494459 rpcclient: return FaultException in checkResOk if any
FaultException can be non-empty even in Halt state when there were
problems with stack marshaling to JSON.

Signed-off-by: Evgenii Stratonikov <fyfyrchik@runbox.com>
2024-03-19 18:39:02 +03:00
Roman Khimov
7e12cc11e4
Merge pull request #3361 from nspcc-dev/fix-rpc-511
rpcsrv: fix insufficient funds use
2024-03-18 20:49:10 +03:00
Roman Khimov
27f79b8c63 rpcsrv: fix insufficient funds use
This is not the way intended in https://github.com/neo-project/proposals/pull/156.
-511 covers _both_ cases because users hardly can distinguish one from another,
it's just that our mempool implementation has error codes for both..

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2024-03-18 20:37:39 +03:00
Roman Khimov
445ab97906
Merge pull request #3360 from nspcc-dev/adj-mempool-err-codes
rpcsrv: fix RPC error codes proposal compatibility
2024-03-18 18:55:42 +03:00
Anna Shaleva
82e52c4f6d rpcsrv: fix RPC error codes proposal compatibility
mempool.ErrInsufficientFunds is used when sender doesn't have enough
balance to pay the submitted transaction fees (-511 code according to
https://github.com/neo-project/proposals/pull/156). mempool.ErrConflict is
used when sender is not able to pay the overall transactions fee sum in
the pool (generic -500 error according to the proposal).

This bugfix is kind of breaking change for those users who relied on the
old -511 code previously returning "insufficient funds" error.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-03-18 18:05:19 +03:00
Anna Shaleva
335550fb1e rpcsrv: generate randome nonce for RPC server test transactions
Avoid mempool conflicts in tests.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-03-18 18:03:58 +03:00
Anna Shaleva
a6f52a7180 core: prohibit reentry to Notary withdraw
If we're withdrawing funds to contract that has onNEP17Payment method,
then it may call Notary's withdraw one more time, but the account's
state is not yet updated by this moment.

The problem is similar to https://github.com/neo-project/neo/pull/2734.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-03-18 17:08:32 +03:00
Anna Shaleva
bfc3aa6b67
Merge pull request #3349 from nspcc-dev/LastGasPerVote
native: clear LastGasPerVote when voting for NULL
2024-03-15 12:06:48 +03:00
Ekaterina Pavlova
0e6fbadfd5 native: clear LastGasPerVote when voting for NULL
Port neo-project/neo#3173.

Close #3345

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-03-15 10:51:32 +03:00
Roman Khimov
9c83beffbb
Merge pull request #3355 from nspcc-dev/close-rpc-clietn
rpcsrv: properly close RPC clients in tests
2024-03-14 11:56:04 +03:00
Anna Shaleva
37d4012306 rpcsrv: properly close RPC clients in tests
This commit doesn't fix anything, but clients should be closed, it's
just a good practice.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-03-14 11:04:39 +03:00
Anna Shaleva
67d39177d8
Merge pull request #3350 from nspcc-dev/tune-rpc-tests
rpcsrv: close idle client connections in doRPCCallOverHTTP
2024-03-14 10:52:35 +03:00
Roman Khimov
1679b162b8
Merge pull request #3354 from nspcc-dev/dependabot/go_modules/google.golang.org/protobuf-1.33.0
build(deps): bump google.golang.org/protobuf from 1.32.0 to 1.33.0
2024-03-14 08:29:11 +03:00
Roman Khimov
45c6a7dcd7
Merge pull request #3352 from nspcc-dev/dependabot/go_modules/examples/zkp/cubic_circuit/google.golang.org/protobuf-1.33.0
build(deps): bump google.golang.org/protobuf from 1.31.0 to 1.33.0 in /examples/zkp/cubic_circuit
2024-03-14 08:28:56 +03:00
Roman Khimov
077b4f9097
Merge pull request #3353 from nspcc-dev/dependabot/go_modules/examples/nft-nd-nns/google.golang.org/protobuf-1.33.0 2024-03-14 08:28:34 +03:00
dependabot[bot]
b015c7b05d
build(deps): bump google.golang.org/protobuf from 1.32.0 to 1.33.0
Bumps google.golang.org/protobuf from 1.32.0 to 1.33.0.

---
updated-dependencies:
- dependency-name: google.golang.org/protobuf
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-13 23:40:17 +00:00
dependabot[bot]
57d828c4ab
build(deps): bump google.golang.org/protobuf in /examples/nft-nd-nns
Bumps google.golang.org/protobuf from 1.31.0 to 1.33.0.

---
updated-dependencies:
- dependency-name: google.golang.org/protobuf
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-13 23:07:18 +00:00
dependabot[bot]
b78b715259
build(deps): bump google.golang.org/protobuf
Bumps google.golang.org/protobuf from 1.31.0 to 1.33.0.

---
updated-dependencies:
- dependency-name: google.golang.org/protobuf
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-13 23:06:06 +00:00
Roman Khimov
86faf7b343 rpcsrv: close idle client connections in doRPCCallOverHTTP
Shouldn't affect things much, yet at the same time we no longer need any
connection after we're done with the request.

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2024-03-13 12:58:15 +03:00
Anna Shaleva
319880e201
Merge pull request #3340 from nspcc-dev/wsclient-test
rpcclient: fix TestWSClientNonBlockingEvents
2024-03-13 12:08:11 +03:00
Ekaterina Pavlova
0016b6b630 rpc: add synchronisation for httptest.Server in tests
Add waiting for startSending to ensure that the client is ready before
the server starts sending messages.

Close #3005
Close #3312

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-03-13 11:41:43 +03:00
Anna Shaleva
b12ef701f0
Merge pull request #3344 from nspcc-dev/concurrent-test
rpcsrv: fix concurrent test TestClient_IteratorSessions
2024-03-12 00:04:31 +03:00
Ekaterina Pavlova
588d7c6418 rpcsrv: fix concurrent test TestClient_IteratorSessions
The default for `MaxConnsPerHost` is "no limit", so it'll use as many
connections as it can (potentially hitting MacOS/Windows limits
https://github.com/golang/go/issues/20960#issuecomment-447918270 ).

Close #3300

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-03-11 22:00:23 +03:00
Anna Shaleva
0e47d662b5
Merge pull request #3347 from nspcc-dev/inc-test-timeout
workflows: give tests more time
2024-03-11 10:38:15 +03:00
Roman Khimov
54c53cf6ca workflows: give tests more time
We have more and more timeouts happening for test runs, so 10m is not enough
for busy GH machines sometime. I think we can just give them a bit more time.

Refs. #2379 though.

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2024-03-09 14:34:40 +03:00
Roman Khimov
025bf228a2
Merge pull request #3335 from nspcc-dev/TestFailedPreconditionShutdown
rpcsrv: fix TestFailedPreconditionShutdown shutdown
2024-03-06 10:24:30 +03:00
Anna Shaleva
bdcc036073
Merge pull request #3339 from nspcc-dev/workaround-coverage
workflows: workaround Go 1.22 coverage problem
2024-03-06 10:15:58 +03:00
Roman Khimov
d31b01d4b1 workflows: workaround Go 1.22 coverage problem
See https://github.com/golang/go/issues/65653, the fix can be postponed up
to Go 1.23 and we need green.

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2024-03-06 10:03:02 +03:00
Ekaterina Pavlova
ee39b5ca18 rpcsrv: add close of http server in tests
The HTTP server should be closed at the end of the test.

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-03-06 01:17:59 +03:00
Ekaterina Pavlova
46f2da0fb1 rpcsrv: add close of blockchain and rpc server in tests
The logs race issue is a result of improper shutdown during testing.

Close #3217

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-03-06 01:17:59 +03:00
Roman Khimov
b7efccc040
Merge pull request #3333 from nspcc-dev/upd-go-ordered-js
go.mod: better go-ordered-json
2024-03-05 19:29:05 +03:00
Anna Shaleva
a256eac619
Merge pull request #3337 from nspcc-dev/fix-notary-test
notary: fix "Condition never satisfied" in Notary test, fix #2422
2024-03-05 19:11:59 +03:00
Anna Shaleva
261b389e24 go.mod: better go-ordered-json
Almost no functional changes, the most important one is that virtuald
dependency is removed.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-03-05 19:05:32 +03:00
Anna Shaleva
9e99e35a63
Merge pull request #3338 from nspcc-dev/dep-up
Dependency update
2024-03-05 19:03:28 +03:00
Roman Khimov
b2936e602c notary: fix getCompletedTx error
It checks for any transaction given (like fb), not exactly the main one.

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2024-03-05 19:01:03 +03:00
Roman Khimov
d65b1fd66d *: use v2 LRU, fix #3322
Signed-off-by: Roman Khimov <roman@nspcc.ru>
2024-03-05 18:39:17 +03:00
Roman Khimov
72ebcbec72 go.mod: update all external dependencies
Except for github.com/urfave/cli which breaks the CLI if upgraded to v1.22.14.
Refs. #3097.

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2024-03-05 18:38:29 +03:00
Roman Khimov
d2a7162217 notary: fix "Condition never satisfied" in Notary test, fix #2422
The theory is:
 * we add a block
 * it triggers notary
 * which can process the fallback before we're to setFinalizeWithError
 * it'll fail and require an additional block to enter, but it's never added
 * FAIL

The solution is:
 * always add an additional block, but treat the first fb specially

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2024-03-05 18:09:25 +03:00
Roman Khimov
49edf9e498
Merge pull request #3336 from nspcc-dev/go-upd
Add Go 1.22 support, drop Go 1.19 support
2024-03-05 15:40:02 +03:00
Anna Shaleva
8162e9033d *: replace slice.Copy with bytes.Clone
And refactor some code a bit, don't use bytes.Clone where type-specific
helpers may be used instead.

Close #2907.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-03-05 13:54:10 +03:00
Anna Shaleva
b030c331b0 core: copy SC storage iterator prefix while returning values
It's a bug since Prefix is shared between all iterator items and
appending is not enough. If prefix has enough capacity, then new slice
won't be created and the previous item's prefix will be changed.

This commit fixes the following test failure caused by moving from
bytes.Clone to slice.Copy:
```
 --- FAIL: TestComlileAndInvokeFunction/test_Storage.Find (0.02s)
        --- FAIL: TestComlileAndInvokeFunction/test_Storage.Find/keys_only (0.01s)
            contract_test.go:866:
                	Error Trace:	/home/anna/Documents/GitProjects/nspcc-dev/neo-go/cli/smartcontract/contract_test.go:866
                	Error:      	Not equal:
                	            	expected: []stackitem.Item{(*stackitem.ByteArray)(0xc000a1cdf8), (*stackitem.ByteArray)(0xc000a1ce10)}
                	            	actual  : []stackitem.Item{(*stackitem.ByteArray)(0xc000a1cdb0), (*stackitem.ByteArray)(0xc000a1cdc8)}

                	            	Diff:
                	            	--- Expected
                	            	+++ Actual
                	            	@@ -2,3 +2,3 @@
                	            	  (*stackitem.ByteArray)((len=8) {
                	            	-  00000000  66 69 6e 64 6b 65 79 31                           |findkey1|
                	            	+  00000000  66 69 6e 64 6b 65 79 32                           |findkey2|
                	            	  }),
                	Test:       	TestComlileAndInvokeFunction/test_Storage.Find/keys_only
        --- FAIL: TestComlileAndInvokeFunction/test_Storage.Find/both (0.01s)
            contract_test.go:881:
                	Error Trace:	/home/anna/Documents/GitProjects/nspcc-dev/neo-go/cli/smartcontract/contract_test.go:881
                	Error:      	Not equal:
                	            	expected: []stackitem.Item{(*stackitem.ByteArray)(0xc000515920), (*stackitem.ByteArray)(0xc000515938)}
                	            	actual  : []stackitem.Item{(*stackitem.ByteArray)(0xc000515848), (*stackitem.ByteArray)(0xc000515860)}

                	            	Diff:
                	            	--- Expected
                	            	+++ Actual
                	            	@@ -2,3 +2,3 @@
                	            	  (*stackitem.ByteArray)((len=8) {
                	            	-  00000000  66 69 6e 64 6b 65 79 31                           |findkey1|
                	            	+  00000000  66 69 6e 64 6b 65 79 32                           |findkey2|
                	            	  }),
                	Test:       	TestComlileAndInvokeFunction/test_Storage.Find/both
```

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-03-05 13:54:10 +03:00
Anna Shaleva
1560df6913 *: add nolint comment to deprecated math/rand usages
They are used in tests only.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-03-05 13:54:10 +03:00
Anna Shaleva
0c6627f13d *: use multierror wrapping where possible
Revert 5f6c01336c, remove all multierror
related nolint comments and use multierror wrapping instead.

Close #2906.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-03-05 13:54:10 +03:00
Anna Shaleva
13ff95a3d3 go.mod: upgrade minimum required Go version to 1.20
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-03-05 13:54:10 +03:00
Anna Shaleva
5485cf60da Dockerfile: switch to Go 1.22 based images
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-03-05 13:53:58 +03:00
Anna Shaleva
3f772c2711 workflows: use newer Go 1.22, drop Go 1.19
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-03-05 11:43:23 +03:00
Anna Shaleva
c660a6e8f3 workflows: remove cache argument from setup-go action
`actions/setup-go@v5` doesn't have `cache` argument.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-03-05 11:43:23 +03:00
Anna Shaleva
90db72abc9 workflows: upgrade runners
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-03-05 11:42:53 +03:00
Roman Khimov
8d67f17943
Merge pull request #3332 from nspcc-dev/fix-nep17-test
cli: fix race in TestNEP17Balance
2024-03-03 15:27:25 +03:00
Anna Shaleva
46a3ff3348 *: regenerate all wallets with adjusted parameters
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-03-01 19:19:03 +03:00
Anna Shaleva
9525bc7785 wallet: fix scrypt parameters in wallet regeneration tests
Default NEP2 scrypt parameters should be overriden where needed,
otherwise our regeneration tests won't generate proper wallets.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-03-01 19:19:03 +03:00
Anna Shaleva
685d095fa4 cli: fix race in TestNEP17Balance
`wallet1_solo.json` can't be used in this test because it contains
committee member that receives reward for accepted blocks. The race in
this test happens due to the  fact that it uses running blockchain and
checks expected GAS balance via call to blockchain's
GetUtilityTokenBalance API. This call is racy with the CLI command
executed prior to the call which causes the following test failure:
```
2023-04-06T08:44:08.6038406Z === NAME  TestNEP17Balance/all_accounts
2023-04-06T08:44:08.6038738Z     executor.go:240:
2023-04-06T08:44:08.6039454Z         	Error Trace:	/opt/github-runner/_work/neo-go/neo-go/cli/nep_test/executor.go:240
2023-04-06T08:44:08.6040628Z         	            				/opt/github-runner/_work/neo-go/neo-go/cli/nep_test/executor.go:236
2023-04-06T08:44:08.6041787Z         	            				/opt/github-runner/_work/neo-go/neo-go/cli/nep_test/nep17_test.go:73
2023-04-06T08:44:08.6042389Z         	Error:      	Expect "	Amount : 1" to match "^\s*Amount\s*:\s*1.5$"
2023-04-06T08:44:08.6042865Z         	Test:       	TestNEP17Balance/all_accounts
```

The fix is do not use committee accounts for balance checks. Let's use
side accounts and transfer funds to some of them before the test start.
Close #2960.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-03-01 19:19:02 +03:00
Anna Shaleva
1f4e1922ee cli: add new testing wallet
It contains several simple signature accounts that are not related to
network committee or validators. Needed for tests, existing
`testwallet.json` can't de reused since some tests need testing wallet
with a single account.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-02-29 23:48:10 +03:00
Roman Khimov
2404145133
Merge pull request #3331 from nspcc-dev/upd-go-ordered-json
go.mod: upgrade go-ordered-json
2024-02-29 13:36:32 +03:00
Anna Shaleva
e1e2b5304f go.mod: upgrade go-ordered-json
Fetch C# node compatibility fixes for the rest of corner cases. Ref.
https://github.com/nspcc-dev/go-ordered-json/pull/11.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-02-29 13:31:06 +03:00
Roman Khimov
9d7357c9fd
Merge pull request #3329 from nspcc-dev/support-rpc-maps 2024-02-28 16:26:29 +03:00
Anna Shaleva
132531fabe rpcsrv: support Map parameter in invokefunction RPC handler
We have smartcontract.ParameterPair structure that can be properly
marshalled and passed to RPC server as an element of smartcontract.Map
structure. However, RPC server can't unmarshal map values properly
without this change.

This change is compatible with C# node.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-02-28 15:54:33 +03:00
Anna Shaleva
6a560b9a95
Merge pull request #3330 from nspcc-dev/add-macos
Add ARM-based MacOS tests
2024-02-28 12:39:17 +03:00
Roman Khimov
630bd29b8d workflows: drop manual go mod downloads
It's done automatically since like forever, these steps are useless.

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2024-02-28 12:09:15 +03:00
Roman Khimov
5fcae176b8 workflows: add MacOS 14 runner for tests
It's ARM-based, so it's a very nice combination.

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2024-02-28 12:08:13 +03:00
Roman Khimov
cc38221d77
Merge pull request #3307 from nspcc-dev/test-register-peers
services: fix logging data race after shutdown
2024-02-27 17:09:08 +03:00
Ekaterina Pavlova
5cf0c75744 network: fix server shutdown by waiting for goroutines to finish
s.Shutdown() does not wait for all goroutines of the node server to
finish normally just because the server exits without dependent
goroutines awaiting. Which causes logs to attempt to write after the
test has ended. The consequence of this bug fix is that corresponding
tests are fixed.

Close #2973
Close #2974

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-02-27 15:10:51 +03:00
Ekaterina Pavlova
5bb7c6b715 services: update logs flush after services shutdown
Added sync logs for every service separately to provide the ability to
have a custom logger for each service. This commit makes the code follow
the zap usages rules: `Sync calls the underlying Core's Sync method,
flushing any buffered log entries. Applications should take care to
call Sync before exiting.`

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-02-27 15:10:51 +03:00
Ekaterina Pavlova
9b540770cd network: fix typo
Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-02-27 15:10:51 +03:00
Ekaterina Pavlova
775c56e87e network: ensure server is started and shut down only once
Use started atomic.Bool field to ensure that the node server shutdown
procedure is executed only once. Prevent the following panic caused by
server double-shutdown in testing code:
```
--- FAIL: TestServerRegisterPeer (0
.06s)
 panic: closed twice
 goroutine 60 [running]:
 testing.tRunner.func1.2({0x104c40b20, 0x104d0ec90})
 	/opt/homebrew/opt/go/libexec/src/testing/testing.go:1545 +0x1c8
 testing.tRunner.func1()
 	/opt/homebrew/opt/go/libexec/src/testing/testing.go:1548 +0x360
 panic({0x104c40b20?, 0x104d0ec90?})
 	/opt/homebrew/opt/go/libexec/src/runtime/panic.go:914 +0x218
 github.com/nspcc-dev/neo-go/pkg/network.(*fakeTransp).Close
 (0x14000159e08?)
 	/Users/ekaterinapavlova/Workplace/neo-go/pkg/network
 	/discovery_test.go:83 +0x54
 github.com/nspcc-dev/neo-go/pkg/network.(*Server).Shutdown
 (0x14000343400)
 	/Users/ekaterinapavlova/Workplace/neo-go/pkg/network/server.go:299
 	 +0x104
 github.com/nspcc-dev/neo-go/pkg/network.startWithCleanup.func1()
 	/Users/ekaterinapavlova/Workplace/neo-go/pkg/network/server_test
 	.go:408 +0x20
 testing.(*common).Cleanup.func1()
 	/opt/homebrew/opt/go/libexec/src/testing/testing.go:1169 +0x110
 testing.(*common).runCleanup(0x1400032c340, 0x14000159d80?)
 	/opt/homebrew/opt/go/libexec/src/testing/testing.go:1347 +0xd8
 testing.tRunner.func2()
 	/opt/homebrew/opt/go/libexec/src/testing/testing.go:1589 +0x2c
 testing.tRunner(0x1400032c340, 0x104d0c5d0)
 	/opt/homebrew/opt/go/libexec/src/testing/testing.go:1601 +0x114
 created by testing.(*T).Run in goroutine 1
 	/opt/homebrew/opt/go/libexec/src/testing/testing.go:1648 +0x33c
```

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-02-27 15:10:51 +03:00
Ekaterina Pavlova
4715e523e0 services: move blockchain/mempool subscriptions to separate routine
Start of some services is bound to blockchain subscriptions, and thus,
can't be run before the blockchain notifications dispatcher.

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-02-27 15:10:51 +03:00
Ekaterina Pavlova
f8dc5ec44f network: change server Start() behavior
Previously user should Start server in a separate goroutine. Now
separate goroutine is created inside the Start(). For normal server
operation, the caller should wait for Start to finish. Also, fixed
TestTryInitStateSync test which was exiting earlier than logs are
called.

Close #3112

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-02-27 15:10:51 +03:00
Roman Khimov
224808975b
Merge pull request #3328 from nspcc-dev/mod-upd
.github: use minimum required Go version from go.mod
2024-02-27 14:02:42 +03:00
Anna Shaleva
8ab08c6221 github: reorder actions/checkout and actions/setup-go steps
Otherwise setup-go action won't work with go-version-file. Ref.
https://github.com/actions/setup-go/issues/340.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-02-27 11:56:49 +03:00
Anna Shaleva
e55809f198
Merge pull request #3327 from nspcc-dev/fix-rpcclient-doc
rpcclient: fix address used in doc
2024-02-27 11:43:42 +03:00
Anna Shaleva
a81804e296 .github: use minimum required Go version from go.mod
For linter job only, port
e0ec4d24cb.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-02-27 11:39:51 +03:00
Roman Khimov
9d3258495f rpcclient: use better RPC endpoint for example
Signed-off-by: Roman Khimov <roman@nspcc.ru>
2024-02-26 23:18:45 +03:00
Roman Khimov
e09fc00188 rpcclient: fix address used in doc
This one doesn't really work now, it's Legacy. Replace with something N3-ish.

Thanks @lock9 for reporting.

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2024-02-26 22:18:32 +03:00
Anna Shaleva
be17924ef8
Merge pull request #3325 from stepanovdmitrii/fix/tcp_peer_deadlock
tcp_peer: Fix possible goroutine leak
2024-02-26 12:12:28 +03:00
Dmitrii Stepanov
6147bf452a tcp_peer: Fix possible goroutine leak
Scenario:
1. Two messages were read from the connection `p.conn`
2. The first message has started to be processed
3. The second message was queued to be added to the channel `p.incoming`
4. Processing of the first message failed with an error
5. TCP peer is closed, but processing of the second message continues

Signed-off-by: Dmitrii Stepanov <dima-stepan@yandex.ru>
2024-02-25 22:38:18 +03:00
Anna Shaleva
327e766cd9
Merge pull request #3321 from nspcc-dev/leveldb-windows
vm: fix exit in vm tests
2024-02-21 19:47:07 +03:00
Ekaterina Pavlova
b6a65e4d80 cli: fix exit in vm test
Add exit function at the end of the test to prevent
errors in t.Cleanup of the t.TempDir for levelDB instance.

Close #3154

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-02-21 13:22:38 +03:00
Anna Shaleva
00a1a8da56
Merge pull request #3320 from nspcc-dev/update-actions
workflows: update actions
2024-02-20 13:16:20 +03:00
Roman Khimov
07b2de73cd workflows: update actions
I'm tired of warnings for our workflow runs.

The only unupdated is Codecov, we can't switch to token-based uploads at the
moment (and it's required for new version).

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2024-02-19 22:14:24 +03:00
Roman Khimov
f94df6c013
Merge pull request #3318 from nspcc-dev/TestContractInitAndCompile 2024-02-19 21:49:22 +03:00
Ekaterina Pavlova
5128b84e1d *: update go.mod
According to https://go.dev/doc/modules/gomod-ref go version should be
placed before `require` section.

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-02-19 19:12:21 +03:00
Ekaterina Pavlova
5d425a6e45 smartcontract: fix go version mismatch in TestContractInitAndCompile
Needs to updated dependencies inside the test for go1.18 and higher to
match with interop module.

Close #3152

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-02-19 19:08:36 +03:00
Anna Shaleva
71fb759c0d
Merge pull request #3313 from nspcc-dev/TestRun_WithNewVMContextAndBreakpoints
config: fix windows paths in VM tests
2024-02-15 11:07:04 +03:00
Ekaterina Pavlova
588e911ad6 config: fix TestRun_WithNewVMContextAndBreakpoints path for windows
Fix VM test for windows. We don't have notary enabled in unit testchains
 so it was removed.

Close #3309

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-02-14 13:22:07 +03:00
Roman Khimov
5fe4778b2e
Merge pull request #3306 from nspcc-dev/test-windows-path
config: fix TestGetConfigFromContext on Windows
2024-02-14 11:24:48 +03:00
Ekaterina Pavlova
939631c3f9 config: fix TestGetConfigFromContext on Windows
Failing test caused by hardcoded relative path check which is different
for Windows.

Close #3305

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-02-12 19:37:26 +03:00
Roman Khimov
51ac153a7b
Merge pull request #3293 from nspcc-dev/import-multisig
cli: update import-multisig with making --wif optional
2024-01-27 11:26:47 +03:00
Roman Khimov
9d95a2691b
Merge pull request #3291 from nspcc-dev/nns_wrapper 2024-01-27 11:25:50 +03:00
Ekaterina Pavlova
57aa05add3 wallet: make --wif optional in import-multisig command
We have a full list of public keys in the import-multisig command, so if
 we have a key in the wallet that corresponds to one of these keys
 (simple sig), just reuse it for the account automatically

Closes #3266

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-01-26 18:36:29 +03:00
Ekaterina Pavlova
000109bfd1 smartcontract: update nns wrapper
Added missing function from smart-contract manifest.

Close #2732

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-01-26 18:30:17 +03:00
Anna Shaleva
36b89215ab
Merge pull request #3299 from nspcc-dev/autogeneration-linter
smartcontract: fix generation of nns wrapper for follow Go naming
2024-01-26 12:50:35 +03:00
Roman Khimov
a19f85ba34
Merge pull request #3297 from nspcc-dev/sc-convertible
smartcontract: introduce Convertible interface
2024-01-25 17:16:47 +03:00
Anna Shaleva
161b83fd7f rpcclient: ensure nns.RecordType can be passed as a parameter to invoker
Implement smartcontract.Convertible for nns.RecordType.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-01-25 17:04:21 +03:00
Ekaterina Pavlova
9b7eff18c0 smartcontract: fix generation of nns wrapper for follow Go naming
Autogenerated RPC wrapper used underscores to differentiate between
methods/event overloads. Now it adds increasing suffices instead.

Close #3296

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-01-24 16:21:36 +03:00
Anna Shaleva
a22a7177e3 smartcontract: improve TestParameterFromValue
Run error cases in the same loop with test cases. No functional changes.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-01-23 16:09:58 +03:00
Anna Shaleva
b90c0ece87 smartcontract: introduce Convertible interface
Allow to pass Convertible to NewParameterFromValue. Close #3285.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-01-23 16:09:57 +03:00
Anna Shaleva
ef99a7a9e3
Merge pull request #3294 from nspcc-dev/config-validation
config: update validation with check committee
2024-01-22 12:09:17 +03:00
Ekaterina Pavlova
5f745dff72 config: update validation with check committee
ProtocolConfiguration section must include stand by committee and the
number of validators or committee/validators history.

Close #3247

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-01-22 10:25:23 +03:00
Anna Shaleva
ed73628100
Merge pull request #3289 from nspcc-dev/rel-0.105.1
CHANGELOG: release 0.105.1
2024-01-12 15:37:46 +05:00
Anna Shaleva
d20775dd30 CHANGELOG: release 0.105.1
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-01-12 13:35:40 +03:00
Roman Khimov
d428cfc4f1
Merge pull request #3290 from nspcc-dev/ntr-log
services: improve notary service logging
2024-01-12 13:23:00 +03:00
Anna Shaleva
32fab1adf1
Merge pull request #3286 from nspcc-dev/quotes
Upgrade go-ordered-json version
2024-01-12 14:30:12 +05:00
Anna Shaleva
2c0c111fd5
Merge pull request #3287 from nspcc-dev/additional-networking-debugs
Additional networking debugs
2024-01-12 14:29:18 +05:00
Anna Shaleva
ef9f75547a services: improve notary service logging
Let the user know whether it's main or fallback transaction that failed
to be relayed to the network.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-01-12 12:25:11 +03:00
Roman Khimov
f9a82ae45f network: add debug for transactions as well
Signed-off-by: Roman Khimov <roman@nspcc.ru>
2024-01-12 12:18:06 +03:00
Roman Khimov
db2e214f7e network: add debug for notary payloads
Can be handy if things go wrong.

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2024-01-12 12:18:06 +03:00
Ekaterina Pavlova
baac738ec3 smartcontract: add test of extraToStackItem with double quotes
C# double quotes marshalling compatibility test.

Refs #3284

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-01-12 11:18:24 +03:00
Ekaterina Pavlova
188a5e6a8f *: upgrade go-ordered-json version
Ref. nspcc-dev/go-ordered-json/pull/9 needed for C# double quotes
marshalling compatibility.

Closes #3284

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-01-12 11:17:25 +03:00
Anna Shaleva
d901697615
Merge pull request #3282 from nspcc-dev/rel-0.105.0
CHANGELOG: release 0.105.0
2023-12-29 18:33:44 +05:00
Anna Shaleva
2da728d176 CHANGELOG: release 0.105.0
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-12-29 16:31:23 +03:00
Anna Shaleva
012da4501d ROADMAP: update release roadmap
Drop deprecated plans, add new ones.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-12-29 16:20:40 +03:00
Anna Shaleva
d8320372b8
Merge pull request #3283 from nspcc-dev/waiter-refactor
waiter: refactor naming and implement header-based WS transactions awaiting
2023-12-29 18:05:27 +05:00
Anna Shaleva
f5b1bd3978 waiter: adopt headers subscription for WS-based tx awaiting
Try to subscribe for headers firstly, and then if RPC server doesn't
have this ability, fallback to block subscriptions to manage transaction
awaiting.

Close #3260.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-12-29 16:00:56 +03:00
Anna Shaleva
7c9b1d05d2 rpcclient: refactor waiter package naming
Adjust names of all used structures, no need to duplicate `Waiter` everywhere,
we already in the `waiter` package. Also, adjust comments to Actor so that links
to Waiter are properly described in docs.

Ref. #3265.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-12-29 15:22:50 +03:00
Anna Shaleva
1ca7b0bbeb
Merge pull request #3265 from nspcc-dev/cli_await
cli: add await flag for operations with transactions
2023-12-29 17:22:23 +05:00
Ekaterina Pavlova
0ffa24932b cli: add await flag for operations with transactions
New --await flag is an option to synchronize on transaction execution
for CLI commands.

Closes #3244

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2023-12-29 15:14:16 +03:00
Anna Shaleva
0d3f749b5e
Merge pull request #3274 from fyfyrchik/partial-iterator
Allow to partially unwrap session iterator
2023-12-29 16:21:18 +05:00
Evgenii Stratonikov
78050e8b2c unwrap: Add test for HALT state with an empty stack
Missing piece for perfect coverage. Check that an error is returned an
no panic occurs.

Signed-off-by: Evgenii Stratonikov <fyfyrchik@runbox.com>
2023-12-29 10:50:46 +03:00
Evgenii Stratonikov
4b7b71ce25 vm: Add tests for iterator unwrap scripts
Check that is uses only 3 syscalls and also specify boundary behaviour.

Signed-off-by: Evgenii Stratonikov <fyfyrchik@runbox.com>
2023-12-29 10:50:43 +03:00
Evgenii Stratonikov
402a73b7f3 unwrap: Add ArrayAndSessionIterator(), close #3272
It can be used to work with the results of
CreateCallAndPrefetchIteratorScript() execution. The first item must be
an array and the optional second item must be an iterator, containing
remaining elements.

Signed-off-by: Evgenii Stratonikov <fyfyrchik@runbox.com>
2023-12-29 10:50:39 +03:00
Evgenii Stratonikov
ba1417397f smartcontract: Add CreateCallAndPrefetchIteratorScript()
There is CreateCallAndUnwrapIteratorScript() which can traverse
iterator for nodes with sessions disabled. For other nodes this may
still be beneficial: if there is a small number of items, we might read
(or prefetch) all of them in one request. However, this script continues
to work even for large collections, returning both accumulated array and
remaining iterator.

Signed-off-by: Evgenii Stratonikov <fyfyrchik@runbox.com>
2023-12-29 10:49:53 +03:00
Ekaterina Pavlova
4f5e3f363a cli: fix canceltx ValidUntilBlock parameter of conflicting transaction
If main transaction is known, then conflicting transaction shouldn't be
valid longer than the main one.

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2023-12-28 15:30:15 +03:00
Ekaterina Pavlova
4c6dca876c rpcclient: move Waiter to a separate package
There are use-cases when not only Actor, but also Invoker and even
simple RPC client must wait (e.g. sendtx or dumptx CLI commands). Actor
requires optional signers in constructor, and it's not always
appropriate to create Actor only to be able to use Waiter, sometimes
it's needed to use only Waiter without Actor.

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2023-12-28 15:30:15 +03:00
Ekaterina Pavlova
28f1beff64 rpcclient: export NewWaiter function
Change first argument of NewWaiter to be able to directly accept RPC
Client and export for external usage.

Refs #3244.

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2023-12-28 15:30:15 +03:00
Anna Shaleva
3176f72878
Merge pull request #3258 from nspcc-dev/rpc_validation
rpc: subscription filters validity check
2023-12-28 15:49:59 +05:00
Ekaterina Pavlova
cc06674253 neorpc: add WS notification filter IsValid functionality
Additional check of filters parameters added for filter validation.

Closes #3241.

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2023-12-28 11:08:46 +03:00
Ekaterina Pavlova
275e814271 rpc: change the type of BlockFilter.Primary from int to byte
BlockFilter has PrinaryIndex of int type while block.Block structure
itself has PrimaryIndex of byte. It's needed to prevent changing
filters field type and all associated subscriptions logic on
server side.

Refs #3241.

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2023-12-25 18:24:06 +03:00
Anna Shaleva
3283fda790
Merge pull request #3277 from nspcc-dev/add-label-doc
docs: minimally outline local labels
2023-12-25 17:00:12 +05:00
Anna Shaleva
6c88fccc64
Merge pull request #3280 from nspcc-dev/do_not_edit
smartcontract: fix DO NOT EDIT warning to autogenerated files
2023-12-25 16:56:11 +05:00
Ekaterina Pavlova
1237c719e3 smartcontract: fix DO NOT EDIT warning to autogenerated files
The text must appear as the first line of a properly formatted Go //
comment, and that comment must appear before but not be attached to the
package clause and before any /* */ comment.

Closes #3254

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2023-12-25 13:01:36 +03:00
Roman Khimov
9015215228
Merge pull request #3252 from nspcc-dev/header_added
rpc: add header_of_added_block event subscription
2023-12-22 15:18:24 +03:00
Ekaterina Pavlova
5d514538cf rpc: add new header_of_added_block event subscription
New event is to notify the user about header's content by the moment
when block is stored (which happens after block's processing). This is
needed for proper Waiter work.

Closes #2751.

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2023-12-22 15:14:01 +03:00
Roman Khimov
56d32a010e
Merge pull request #3256 from fyfyrchik/fix-signer
Allow complex contract signature schemes in `wallet.Account`
2023-12-21 22:50:57 +03:00
Roman Khimov
a872c200b0
Merge pull request #3279 from nspcc-dev/fix-next-vals-panic
native: prevent improper Neo cache invalidation
2023-12-21 22:17:43 +03:00
Anna Shaleva
47aefad7ea consensus: remove unnecessary call to ComputeNextBlockValidators
dBFT doesn't use validators got from this call to GetValidators callback,
because NeoGo doesn't properly set WithGetConsensusAddress, and thus
this call can be safely skipped. Instead, NeoGo fills NextConsensus field
by itself in NewBlockFromContext callback.

This commit technically doesn't perform any functional changes and doesn't
affect the problem described in #3253 in any way. This commit is just a
removal of the code that was never used by NeoGo library.

This commit is a direct consequence of https://github.com/nspcc-dev/dbft/issues/84.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-12-21 18:16:34 +03:00
Anna Shaleva
d7d850ac7d native: never set Neo's newEpoch* cache values to nil
We have cache update mechanism (Neo's cache votesChanged flag), it must
be used for current epoch and new epoch cached values update. And the
cached current/new epoch values themselves must always contain valid
information for the current/new epoch. These cached values must only be
changed once per epoch, never set them to nil.

This commit prevents CN node panic described in #3253 when dBFT tries
to retrieve new epoch validators with some votes modifications made
before at the same dBFT epoch.

Close #3253.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-12-21 17:56:07 +03:00
Roman Khimov
b62541b6a3 docs: minimally outline local labels
Fixes #2707.

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-12-21 13:25:34 +03:00
Evgenii Stratonikov
c8ff44560e neotest: reuse wallet.Account for contract signers
Refs #3245
Refs #3233

Signed-off-by: Evgenii Stratonikov <fyfyrchik@runbox.com>
2023-12-21 11:27:41 +03:00
Evgenii Stratonikov
962b161652 wallet: allow complex contract verification schemes, close #3015
This was recently added in neotest, but working with the real RPC is
still not enjoyable. This commit extends `wallet.Account` with
invocation script builder to aid network fee calculations and signing.

Signed-off-by: Evgenii Stratonikov <fyfyrchik@runbox.com>
2023-12-21 11:26:55 +03:00
Roman Khimov
de98b39a95
Merge pull request #3269 from nspcc-dev/dependabot/go_modules/golang.org/x/crypto-0.17.0
build(deps): bump golang.org/x/crypto from 0.14.0 to 0.17.0
2023-12-19 09:03:39 +03:00
Roman Khimov
2df0ba7c10
Merge pull request #3270 from nspcc-dev/dependabot/go_modules/examples/zkp/cubic_circuit/golang.org/x/crypto-0.17.0
build(deps): bump golang.org/x/crypto from 0.14.0 to 0.17.0 in /examples/zkp/cubic_circuit
2023-12-19 09:03:20 +03:00
Roman Khimov
bcee8c268c
Merge pull request #3271 from nspcc-dev/dependabot/go_modules/examples/nft-nd-nns/golang.org/x/crypto-0.17.0
build(deps): bump golang.org/x/crypto from 0.14.0 to 0.17.0 in /examples/nft-nd-nns
2023-12-19 09:03:00 +03:00
dependabot[bot]
0baa35ed77
build(deps): bump golang.org/x/crypto in /examples/nft-nd-nns
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.14.0 to 0.17.0.
- [Commits](https://github.com/golang/crypto/compare/v0.14.0...v0.17.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-18 23:42:52 +00:00
dependabot[bot]
ad122aec41
build(deps): bump golang.org/x/crypto in /examples/zkp/cubic_circuit
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.14.0 to 0.17.0.
- [Commits](https://github.com/golang/crypto/compare/v0.14.0...v0.17.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-18 23:40:58 +00:00
dependabot[bot]
ead5b3dc09
build(deps): bump golang.org/x/crypto from 0.14.0 to 0.17.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.14.0 to 0.17.0.
- [Commits](https://github.com/golang/crypto/compare/v0.14.0...v0.17.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-18 23:34:02 +00:00
Roman Khimov
3766206f44
Merge pull request #3255 from smallhive/3177-wallet-from-bytes
wallet: Add new wallet constructors
2023-12-14 18:45:44 +03:00
Evgeny Baydakov
2012c56031
wallet: Add new wallet constructors
Closes #3177

Signed-off-by: Evgeny Baydakov <e.bajdakov@gmail.com>
2023-12-12 08:33:30 +04:00
Roman Khimov
a5a87a72c2
Merge pull request #3261 from nspcc-dev/fix-client-init-test
rpcclient: fix failing initialisation-based tests
2023-12-11 13:11:10 +03:00
Anna Shaleva
d5dee8fc94 rpcclient: fix failing initialisation-based tests
Must be a part of #3257.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-12-11 12:41:56 +03:00
Anna Shaleva
6f3a219d67
Merge pull request #3235 from nspcc-dev/actor_refactor
cli: move actor handling
2023-12-11 12:19:33 +05:00
Anna Shaleva
bbbb12af20
Merge pull request #3236 from nspcc-dev/filter_NotaryRequestEvents
rpc: add an ability to filter out NotaryRequestEvents
2023-12-11 12:19:10 +05:00
Ekaterina Pavlova
3fd48a743e rpc: add an ability to filter out NotaryRequestEvents
Add new filter NotaryRequestFilter, support for filtering
NotaryRequestEvents by mempoolevent.Type
(added or removed).

Closes #2425.

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2023-12-09 11:37:25 +03:00
Roman Khimov
afca64f164
Merge pull request #3257 from nspcc-dev/check-init
rpcclient: check network initialisation for blocks subscriptions
2023-12-08 22:40:08 +03:00
Anna Shaleva
21ccb1a02a rpcclient: check network initialisation for blocks subscriptions
StateRootInHeader depends on it, so we better immediately return error
if client is not initialised.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-12-08 21:57:40 +03:00
Ekaterina Pavlova
44e21c9a8e cli: optimize CosignersSeparator check in loops
No functional changes.
We have 2 exactly the same cycles,and in the 1st cycle we set
cosignersOffset to the right value. So we don't need to check for arg ==
 cmdargs.CosignersSeparator one more time.

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2023-12-07 10:37:01 +03:00
Ekaterina Pavlova
8bdbac3c5e cli: move actor-related functions handling to options package
Move actor handling into CLI package.
GetRPCWithActor returns RPC with actor instances.

Close #2682.

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2023-12-07 10:35:37 +03:00
Ekaterina Pavlova
d7cab3b82c cli: move wallet-related flags handling to options package
Move GetAccFromContext, GetUnlockedAccount, ReadWalletConfig handling
into options package to reuse this code from all CLI handlers.
getDecryptedAccount is replaced by GetUnlockedAccount.

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2023-12-06 10:49:50 +03:00
Ekaterina Pavlova
f93e2fbba4 cli: use (*transaction.Transaction).HasSigner where possible
No functional changes.
tx.HasSigner usage to avoid code duplication.

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2023-12-06 10:49:50 +03:00
Anna Shaleva
441eb8aa86
Merge pull request #3250 from nspcc-dev/bbolt
go.mod: upgrade BoltDB to 1.3.8
2023-12-06 11:18:02 +05:00
Anna Shaleva
af0d1fe3c9
Merge pull request #3251 from nspcc-dev/mac
github: enable amd64 builds for osx
2023-12-06 11:16:44 +05:00
Ekaterina Pavlova
cab358dba1 github: enable amd64 builds for osx
Enable AMD64 builds for Intel based OSX.

Closes #3238.

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2023-12-05 21:49:10 +03:00
Roman Khimov
0639cedd05 go.mod: upgrade BoltDB to 1.3.8
Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-12-05 21:01:44 +03:00
Roman Khimov
9a270ae30c
Merge pull request #3233 from stepanovdmitrii/feat/neotest_contract_signer_support
neotest: Add contract signer support
2023-12-04 10:03:49 +03:00
Dmitrii Stepanov
7b53a0c239 neotest: Add contract signer support
Signed-off-by: Dmitrii Stepanov <dima-stepan@yandex.ru>
2023-12-01 10:50:08 +03:00
Roman Khimov
6c0c2a6a98
Merge pull request #3246 from nspcc-dev/fix-doc
neotest: adjust Signer documentation
2023-12-01 10:23:46 +03:00
Roman Khimov
26f96fe7ee
Merge pull request #3243 from nspcc-dev/add-management-test
native: test immediate contract availability
2023-12-01 10:21:09 +03:00
Anna Shaleva
daa2b3b920 neotest: adjust Signer documentation
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-12-01 09:25:41 +03:00
Roman Khimov
b31d39836a native: test immediate contract availability
I had some reason to suspect something is wrong here (but it's all OK). Even
though this is kinda tested in TestDeployGetUpdateDestroyContract, it uses
internal APIs and with neotest we can ensure it work OK for a complete tx/block
environment. So, won't hurt having these tests as well.

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-11-30 15:58:00 +03:00
Roman Khimov
34be76efb7
Merge pull request #3240 from nspcc-dev/fix-native-upd
core: remove UpdateHistory from NativeContract structure
2023-11-29 16:18:34 +03:00
Roman Khimov
90e18ec743
Merge pull request #3242 from nspcc-dev/improve-subs-doc
Improve notification subsystem documentation
2023-11-29 14:35:38 +03:00
Anna Shaleva
e3aa6bba4d docs: add ordering guarantees for notary request events
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-11-29 14:00:44 +03:00
Anna Shaleva
81a439a0d6 docs: fix typo
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-11-29 13:55:54 +03:00
Anna Shaleva
6fdda0f15d rpcclient: add doc link to notifications ordering guarantees
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-11-29 13:53:45 +03:00
Anna Shaleva
8e8936912d core: remove UpdateHistory from NativeContract structure
Although it doesn't raise an exception on our side, we still have this
unrelevant information in the resulting RPC call response structure.
This should be a part of https://github.com/nspcc-dev/neo-go/pull/3212.

Port https://github.com/neo-project/neo-modules/pull/851.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-11-29 09:25:04 +03:00
Roman Khimov
76261f1605
Merge pull request #3239 from nspcc-dev/ntr-doc-upd
rpcclient: improve documentation
2023-11-28 20:25:08 +03:00
Anna Shaleva
42b84ad905 rpcclient: improve documentation
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-11-28 20:23:33 +03:00
Roman Khimov
98de5b9ccb
Merge pull request #3237 from nspcc-dev/emit-smth
vm: allow to emit `any` based on its type
2023-11-28 18:01:06 +03:00
Anna Shaleva
b637048122 vm: allow to emit any based on its type
No functional changes, just moved a part of emit.Array to a separate
exported method. It may be useful for contract-based witness invocation
scripts construction and not only. Ref.
https://github.com/nspcc-dev/neo-go/pull/3233#discussion_r1407786333.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-11-28 17:17:34 +03:00
Roman Khimov
e8e964e3da
Merge pull request #3234 from nspcc-dev/add-response-source
examples: improve cubic circuit documentation
2023-11-28 17:07:12 +03:00
Anna Shaleva
d7b84c0b47 examples: improve ZKP production example
Add more detailed errors and comments.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-11-28 17:00:34 +03:00
Anna Shaleva
29f344fd9b examples: add one more source of suitable response* files for Groth16
Turns out that Zcash swiched to BLS12-381 since https://github.com/zcash/zcash/issues/2502,
thanks to @EdgeDLT for pointing that out. I've checked that our
TestCubicCircuit_EndToEnd_Prod test passes with response file downloaded
from the attestations page of Zcash ceremony, thus I propose to put theirs
attestations link before the link to PPoT, because PPoT attestations contain
outdated links and not all responses can be downloaded.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-11-28 17:00:33 +03:00
Roman Khimov
2f9b4a2dbf
Merge pull request #3232 from nspcc-dev/storage-limits
interop: add contract storage limits
2023-11-28 13:19:55 +03:00
Anna Shaleva
2eab743a5b compiler: add compatibility test for storage limits
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-11-28 10:51:03 +03:00
Anna Shaleva
a159054f10 *: update interop dependency
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-11-28 10:49:39 +03:00
Anna Shaleva
b35f351f0b interop: add contract storage limits
Users of NeoGo interop package may have a demand to use these limits
for custom purposes, it would be nice to have them as constants.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-11-27 19:56:13 +03:00
Roman Khimov
fd7b7ffc13
Merge pull request #3231 from nspcc-dev/rel-0.104.0
CHANGELOG: release 0.104.0
2023-11-27 18:14:27 +03:00
Anna Shaleva
a9803b3477 CHANGELOG: release 0.104.0
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-11-27 17:34:53 +03:00
Roman Khimov
7179efec35
Merge pull request #3223 from nspcc-dev/cancel_command
cli: cancel transaction command
2023-11-27 17:32:48 +03:00
Ekaterina Pavlova
fc77754098 cli: cancel transaction command
CLI side method for canceling not yet accepted transaction. It's
alternative to unsupported `canceltransaction` RPC method.

Close #3151.

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2023-11-27 18:10:54 +04:00
Ekaterina Pavlova
7a2eb32c42 cli: wallet flag set
Wallet operations flags moved to options and joint into Wallet flag set.

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2023-11-25 10:05:05 +04:00
Ekaterina Pavlova
20a57d8337 cli: export GetAccFromContext and GetUnlockedAccount methods
Exported to avoid code duplication.

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2023-11-25 10:05:05 +04:00
Roman Khimov
7a1bf77585
Merge pull request #3229 from nspcc-dev/fix-service-init
core, services: fix Designation-dependant service initialisation
2023-11-24 15:47:42 +03:00
Anna Shaleva
15b4e0a8cd services: adjust StateRoot service initialisation
Perform initialisation of StateRoot service with designated
StateValidator's node list in the service constructor. There's no need
to wait until the next role update event, and it may lead to inaccuraces
in service work on SIGHUP/server restart.

A part of #3228.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-11-24 15:25:51 +03:00
Anna Shaleva
11ec0db350 core, services: fix Designation-dependant service initialisation
Initialise services dependant on roles designation based on N+1
block so that Genesis roles extension work properly. There's not
much sence to fetch node roles information for the latest persisted
block because Designation contract itself makes designated nodes
responsible since the next subsequent block.

A part of #3228.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-11-24 15:25:51 +03:00
Roman Khimov
4216efbe6c
Merge pull request #3227 from nspcc-dev/upd-zkp-deps
examples: do not replace neo-go library for ZKP examples
2023-11-24 09:32:58 +03:00
Anna Shaleva
626f1ee198 examples: do not replace neo-go library for ZKP examples
0.103.1 contains all necessary changes to run tests.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-11-24 09:21:09 +03:00
Anna Shaleva
5d1e0192f1
Merge pull request #3206 from nspcc-dev/relative_path_flag
cli: add --relative-path option
2023-11-24 08:16:16 +03:00
Roman Khimov
1f84756c21
Merge pull request #3222 from nspcc-dev/doc/contracts-storage-seek-call-improvement
doc/Mention prefix trimming in `Seek` operations where applicable
2023-11-23 23:03:20 +03:00
Roman Khimov
61d5b6eb0c
Merge pull request #3221 from nspcc-dev/json-limits
Anti-DOS RPC limitations
2023-11-23 23:02:50 +03:00
Ekaterina Pavlova
f457d50773 cli: add --relative-path option
To be able running the node from any working directory by simply
pointing the relative-path as prefix for relative parameters set in
config.

Closes #3179.

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2023-11-23 21:41:50 +04:00
Anna Shaleva
d511f6e5a9 confi: add MaxRequestHeaderBytes RPC configuration option
A part of #3131, follow the notion of https://github.com/neo-project/neo-modules/pull/827,
but don't restrict request line size due to https://github.com/golang/go/issues/15494.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-11-23 20:17:49 +03:00
Anna Shaleva
802d8d24b9 config: add MaxRequestBodySize RPC configuration option
A part of #3131, follow the https://github.com/neo-project/neo-modules/pull/827.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-11-23 20:17:49 +03:00
Roman Khimov
195bb742ca
Merge pull request #3225 from nspcc-dev/ojson-upd
*: upgrade go-ordered-json version
2023-11-23 19:27:24 +03:00
Anna Shaleva
251b8c57b9 *: upgrade go-ordered-json version
Close #3224.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-11-23 19:14:28 +03:00
Pavel Karpy
62b710868b *: mention prefix trimming in Seek operations where applicable
Signed-off-by: Pavel Karpy <carpawell@nspcc.ru>
2023-11-23 18:44:19 +03:00
Anna Shaleva
7362fd94e6
Merge pull request #3220 from nspcc-dev/stable-func-debug-data
compiler: walk over functions in reproducible order, fix #3219
2023-11-23 14:50:01 +03:00
Roman Khimov
341d978e5b compiler: walk over functions in reproducible order, fix #3219
It affects both Debug data and bindings, otherwise two unnamed structures can
get any of unnamed/unnamedx names depending on particular invocation.

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-11-23 13:21:51 +03:00
Anna Shaleva
22c654b200 neorpc: restrict maximum subitems number in SignerWithWitness
Restrict the number of Rules, Contracts and Groups. A part of #3131.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-11-23 12:12:34 +03:00
Anna Shaleva
2f6ba1fded rpcsrv: define GetSignersWithWitnesses on a pointer
Nil receiver can be properly handled and all other `Param`'s mathods
are defined on a pointer.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-11-23 11:44:29 +03:00
Roman Khimov
25ef2c7f16
Merge pull request #3218 from nspcc-dev/serialization-limits
Introduce stackitem serialization limits
2023-11-22 21:28:25 +03:00
Anna Shaleva
910d53b27b core: do not check manifest size on deploy/update
Manifest will be a part of the state.Contract which will be checked on its
way to the storage. Tiny optimisation which allows not to serialize manifest
twice. Ref. https://github.com/nspcc-dev/neo-go/pull/3218#discussion_r1402374232.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-11-22 20:17:09 +03:00
Anna Shaleva
1d189fd90c Revert "native: ignore decoding errors during cache init"
This reverts commit 822722bd2e.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-11-22 19:39:03 +03:00
Anna Shaleva
6824bd9f40 smartcontract: require manifest serialization in (*Manifest).IsValid
Port the restrictive part of https://github.com/neo-project/neo/pull/2948.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-11-22 19:39:03 +03:00
Anna Shaleva
387c411da0 vm: add default limit to SI serialization context
Follow the notion of https://github.com/neo-project/neo/pull/2948.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-11-22 19:39:01 +03:00
Roman Khimov
00c6a811ab
Merge pull request #3215 from nspcc-dev/tiny-compiler-fixes
Tiny compiler fixes
2023-11-22 19:29:37 +03:00
Roman Khimov
e21664cd7d
Merge pull request #3216 from nspcc-dev/drop-fyrchik
*: drop fyrchik from code owners
2023-11-22 19:29:28 +03:00
Roman Khimov
23e553f647 *: drop fyrchik from code owners
His account is disabled (which technically leads to an invalid CODEOWNERS
file) and he's no longer active, unfortunately.

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-11-22 11:18:27 +03:00
Roman Khimov
4c9cd438f8 rpcbinding: sort named types to stabilize output
Same input -> same output, otherwise tests fail and @AnnaShaleva is annoyed.

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-11-21 21:47:51 +03:00
Roman Khimov
eade327b9b compiler: check for pkg nilness, fix #3202
Unfortunately, when import cycle happens somewhere deep in the import chain we
dont't get an error from packages.Load(). But it leaves some imports
uninitialized, so at least we can check for them.

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-11-21 21:47:51 +03:00
Roman Khimov
8aeb30e019
Merge pull request #3214 from nspcc-dev/doc-canceltx-rpc
docs: canceltransaction is not going to be supported
2023-11-21 20:29:45 +03:00
Roman Khimov
fced6a27ba compiler: iterate over autoguessed events in reproducible way
Otherwise it's undertermined which of two unnamed structures will get "Unnamed"
and "UnnamedX" which can break the test from time to time.

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-11-21 18:43:40 +03:00
Roman Khimov
5370034955 compiler: deduplicate autoguessed event names, fix #3088
Make them stable wrt parameter order and use proper names in event structures
as well.

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-11-21 18:35:26 +03:00
Roman Khimov
a5d041a1ac compiler: check range first, analyze funcs then
Type data is added while walking through function ins/outs even if we're to
throw this function away. But we don't need it, these types are not used, so
we can deal with the main part of #3071 by optimizing this out.

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-11-21 17:52:17 +03:00
Roman Khimov
7f9e2e5047 cli/sc: don't rewrite RPC bindings by default
TestAssistedRPCBindings didn't respect rewriteExpectedOutputs setting, with
this behavior compiler could produce any result and the test wouldn't notice.

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-11-21 17:43:45 +03:00
Roman Khimov
2ae44e074d docs: canceltransaction is not going to be supported
Refs. neo-project/neo-modules#837.

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-11-21 16:11:58 +03:00
Roman Khimov
ff958706f4
Merge pull request #3212 from nspcc-dev/drop-history
Move NativeUpdateHistory logic uner hardforks
2023-11-21 15:46:16 +03:00
Roman Khimov
28ee1621b8
Merge pull request #3155 from nspcc-dev/apptr-pricing
*: introduce Policy attributes pricing
2023-11-21 15:44:40 +03:00
Anna Shaleva
58102a9a80 *: move NativeUpdateHistory logic under Hardforks management
Close #3196.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-11-21 14:05:28 +03:00
Roman Khimov
4d8601297d
Merge pull request #3211 from nspcc-dev/fix-curr-height
core: review usages of (*intero.Context).BlockHeight method
2023-11-21 13:51:03 +03:00
Anna Shaleva
64b5ba24e9 *: fix less then typos everywhere
My poor grammar...

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-11-21 13:47:59 +03:00
Anna Shaleva
3b11f98cd0 core: review usages of (*intero.Context).BlockHeight method
This method returns persisted block height and doesn't take into account
persisting block height. Some of the callers of this method relay on
the wrong assumption that BlockHeight() returns persisting block index.

Fix improper usages of this method and adjust tests. Ref.
61a066583e/src/Neo/SmartContract/ApplicationEngine.cs (L634).

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-11-21 13:46:13 +03:00
Anna Shaleva
c6d259b285 *: update interop deps
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-11-21 13:44:02 +03:00
Anna Shaleva
0493ddbd70 ROADMAP: add new line to the end of the file
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-11-21 13:42:56 +03:00
Anna Shaleva
474225d425 core, rpcsrv: apply generic attributes fee logic to NotaryServiceFeePerKey
Remove related methods from native Notary and add relevant code to native
Policy.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-11-21 13:42:56 +03:00
Anna Shaleva
82cb2e718d native: introduce attribute pricing
Port the https://github.com/neo-project/neo/pull/2916.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-11-21 13:42:56 +03:00
Roman Khimov
80fcf81102
Merge pull request #3209 from nspcc-dev/strict-cfg
Forbid unknown YAML node configuration fields
2023-11-21 13:20:57 +03:00
Roman Khimov
8e5a724f5d
Merge pull request #3210 from nspcc-dev/service-err
wallet: provide more detailed errors on failed NewWalletFromFile
2023-11-21 13:20:11 +03:00
Anna Shaleva
59baecd39b wallet: provide more detailed errors on failed NewWalletFromFile
Close #3180.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-11-21 13:07:11 +03:00
Roman Khimov
f10d2d2be7
Merge pull request #3208 from nspcc-dev/strlen
Support `strLen` native StdLib method
2023-11-20 21:29:08 +03:00
Anna Shaleva
63de821ff4 config: forbid unknown YAML configuration fields
Close #3128 and fix one of the privnet configurations along the way.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-11-20 20:04:09 +03:00
Anna Shaleva
a4779de375 core: improve TestConfigNativeUpdateHistory subtests naming
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-11-20 20:03:28 +03:00
Anna Shaleva
0fef119f5f rpcsrv: update test data
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-11-20 19:41:45 +03:00
Anna Shaleva
16b7a83f30 *: update interop deps
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-11-20 19:25:52 +03:00
Anna Shaleva
406c9f8b92 core, interop: add strLen method for native StdLib contract
Close #3195.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-11-20 19:23:33 +03:00
Roman Khimov
b5cf3f592f
Merge pull request #3207 from nspcc-dev/limit-rpc-signers
rpcsrv/params: limit tx signers/witnesses
2023-11-20 16:29:42 +03:00
Roman Khimov
f6cb698cd1 rpcsrv/params: limit tx signers/witnesses
Inspired by https://github.com/neo-project/neo-modules/pull/845.

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-11-20 16:01:14 +03:00
Roman Khimov
7fb077e999
Merge pull request #3186 from nspcc-dev/reduce-max-nef-size
Restrict maximum serialized NEF file size
2023-11-20 15:19:40 +03:00
Roman Khimov
48bd8057dd
Merge pull request #3058 from nspcc-dev/current-signers
core: support `System.Runtime.CurrentSigners` syscall
2023-11-20 15:14:05 +03:00
Anna Shaleva
90705e37e9 compiler: perform NEF size check on serialization
Retun an error if the serialized NEF size exceeds stackitem.MaxSize.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-11-20 15:14:05 +03:00
Anna Shaleva
06c99fb2af *: update interop deps
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-11-20 14:50:30 +03:00
Anna Shaleva
e63a93b8a0 compiler: add tests for System.Runtime.CurrentSigners
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-11-20 14:49:07 +03:00
Anna Shaleva
2fba04490a core: add System.Runtime.CurrentSigners syscall
Port the https://github.com/neo-project/neo/pull/2827.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-11-20 14:46:27 +03:00
Anna Shaleva
90b01bcea6 core: move SignersToStackItem to transaction package
It will be reused from interops.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-11-20 14:46:27 +03:00
Anna Shaleva
14d98811a5 smartcontract: restrict maximum NEF file size on deserialisation
Port https://github.com/neo-project/neo/pull/2939.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-11-20 14:32:32 +03:00
Roman Khimov
b2205940fa
Merge pull request #3194 from nspcc-dev/add-test
manifest: add compatibility test for Permissions and Trust serialization
2023-11-18 22:44:57 +03:00
Anna Shaleva
fdcc369d60 manifest: add compatibility test for Permissions and Trust serialization
We already have tests for Permission deserialisation, so port the first
part of https://github.com/neo-project/neo/pull/2948.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-11-18 13:32:28 +03:00
Roman Khimov
dd48f810cc
Merge pull request #3203 from nspcc-dev/doc-upd
docs: adjust ValidatorsHistory documentation
2023-11-17 17:23:21 +03:00
Anna Shaleva
f88df92925 docs: adjust ValidatorsHistory documentation
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-11-17 16:57:41 +03:00
Roman Khimov
de2a445088
Merge pull request #3185 from nspcc-dev/fix-stackitem-limits
vm: reduce maximum stckitem size
2023-11-13 22:53:19 +03:00
Roman Khimov
5e220754d7
Merge pull request #3199 from nspcc-dev/fix-err
neorpc: adjust common error messages
2023-11-13 22:17:07 +03:00
Anna Shaleva
b0cdae4666 vm: reduce maximum stckitem size
To prevent possible DoS. Port the https://github.com/neo-project/neo-vm/pull/514,
close #3170.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-11-13 20:40:30 +03:00
Anna Shaleva
963a22e280 neorpc: adjust common error messages
According to the initial proposal and
https://github.com/neo-project/proposals/pull/156/files#diff-2b5f7c12a23f7dbe4cb46bbf4be6936882f8e0f0b3a4db9d8c58eb294b02e6ed.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-11-13 20:29:13 +03:00
Roman Khimov
dbd647e3a6
Merge pull request #3193 from nspcc-dev/rel-0.103.1
Release 0.103.1
2023-11-09 10:36:51 +03:00
Anna Shaleva
ed4610f8b4 CHANGELOG: release 0.103.1
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-11-09 10:28:12 +03:00
Roman Khimov
7045d3bd63
Merge pull request #3192 from nspcc-dev/rpc-err
neorpc: ensure errors.Is and errors.As work properly with neorpc.Error
2023-11-08 09:34:05 +03:00
Roman Khimov
f8d8b03f64
Merge pull request #3191 from nspcc-dev/fix-roundtrip
native: prohibit non-zero GAS/NEO roundtrip with zero balance
2023-11-08 09:32:56 +03:00
Anna Shaleva
fca7eb35a1 neorpc: ensure errors.Is and errors.As work properly with neorpc.Error
Close #3188.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-11-07 23:59:53 +03:00
Anna Shaleva
b4866bd69e native: prohibit NEP-17 roundtrip with zero balance
Close #3190.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-11-07 19:37:37 +03:00
Roman Khimov
c5e284c117
Merge pull request #3187 from nspcc-dev/fix-neo-init
Fix native Neo cache initialization
2023-11-03 10:56:02 +03:00
Anna Shaleva
ba4c58780c native: optimize policy check for transaction's signers
Do not retrieve RO cache for each signer, make it ones per transaction
instead.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-11-03 10:29:47 +03:00
Anna Shaleva
de38163f89 core: log block height before MPT/natives cache initialization
We have this log on the network server side, but it would also be
useful in case of failed blockchain initialization.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-11-03 10:29:46 +03:00
Anna Shaleva
bbbc6805a8 native: fix NeoToken initialization process
Refactored native NeoToken cache scheme introduced in #3110 sometimes requires
validators list recalculation during native cache initialization process (when
initializing with the existing storage from the block that is preceded each N-th block).
To recalculate validators from candidates, native NeoToken needs an access to
cached native Policy blocked accounts. By the moment of native Neo initialization,
the cache of native Policy is not yet initialized, thus we need a direct DAO access
for Policy to handle blocked account check.

Close #3181.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-11-02 17:56:02 +03:00
Anna Shaleva
91c8aa21cc core: fix typo in comment
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-11-02 17:15:34 +03:00
Roman Khimov
8ed6d97085
Merge pull request #3178 from nspcc-dev/dependabot/go_modules/google.golang.org/grpc-1.57.1
build(deps): bump google.golang.org/grpc from 1.57.0 to 1.57.1
2023-10-27 12:25:58 +03:00
dependabot[bot]
c9803f5448
build(deps): bump google.golang.org/grpc from 1.57.0 to 1.57.1
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.57.0 to 1.57.1.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.57.0...v1.57.1)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-25 21:37:52 +00:00
Roman Khimov
9de9320d55
Merge pull request #3172 from nspcc-dev/rel-0.103.0
Release 0.103.0
2023-10-20 22:05:51 +03:00
Roman Khimov
b9297a4b2c
Merge pull request #3175 from nspcc-dev/fix-nns-dep
examples: update neo-go dependency and fetch fresh gnark-crypto
2023-10-20 22:04:27 +03:00
Anna Shaleva
a755a2be30 CHANGELOG: release 0.103.0
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-10-20 21:33:34 +03:00
Anna Shaleva
0e458f473f examples: update neo-go dependency and fetch fresh gnark-crypto
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-10-20 21:20:45 +03:00
Roman Khimov
d89c8801d6
Merge pull request #3173 from nspcc-dev/dep-upd
*: update interop dependencies
2023-10-20 21:15:54 +03:00
Roman Khimov
dffd87c6c8
Merge pull request #3171 from nspcc-dev/fix-linter
Fix linter problems
2023-10-20 21:14:41 +03:00
Anna Shaleva
1605496002 *: update interop dependencies
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-10-20 19:38:20 +03:00
Anna Shaleva
7a6b908cae neorpc: fix exported structure comment
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-10-20 19:31:23 +03:00
Roman Khimov
c3955f87d1
Merge pull request #3165 from nspcc-dev/fix-win-timeout
Improve timeout of RPC tests on Windows
2023-10-20 19:07:24 +03:00
Anna Shaleva
3544d65ecd rpcclient: disable linter for documentation example
Disable the following linter warning:
```
superfluous-else: if block ends with call to panic function, so drop this else and outdent its block (revive)
```

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-10-20 17:28:57 +03:00
Anna Shaleva
6e0af5ac90 network: fix linter warning
Fix the following linter warning:
```
dot-imports: should not use dot imports (revive)
```

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-10-20 17:23:35 +03:00
Anna Shaleva
39ce3a9d1d vm: fix linter warning
Fix the following linter warning:
```
indent-error-flow: if block ends with a return statement, so drop this else and outdent its block (move short variable declaration to its own line if necessary) (revive)
```

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-10-20 17:22:21 +03:00
Anna Shaleva
c93658b1c1 Partially revert "*: use localhost address instead of 127.0.0.1, fix #2575"
This partially reverts commit c26a962b55 for testing
chains configurations.

Ref. #2975, although this commit doesn't close it. This commit is an attempt to
enforce IPv4 for our test clients to avoid problem described in the issue.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-10-20 17:17:37 +03:00
Roman Khimov
890f64007a
Merge pull request #3168 from nspcc-dev/roles-init
Introduce Genesis protocol setting extensions
2023-10-19 18:49:45 +03:00
Anna Shaleva
8cc32a91b6 *: add GenesisTransaction extension to the protocol configuration
Provide a script that should be deployed in the genesis block.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-10-19 18:33:50 +03:00
Anna Shaleva
065bd3f0be *: introduce Genesis protocol configuration
This section contains genesis-related settings including genesis-related or natives-related
extensions. Currently it includes the set of node roles that may be designated
duing the native Designation contract initialisation.

Close #3156.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-10-19 18:30:20 +03:00
Anna Shaleva
1815bc8a32 *: update Stringers wrt fresh Stringer version
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-10-19 11:33:07 +03:00
Anna Shaleva
61a74ab331 native: introduce Stringer for noderoles types
And rename roles.go to role.go to match the role_string.go and the
existing naming pattern for enums.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-10-19 11:33:04 +03:00
Roman Khimov
04d778612e
Merge pull request #3167 from nspcc-dev/autogen-warn
smartcontract: add `DO NOT EDIT` warning to autogenerated files
2023-10-18 21:35:20 +03:00
Roman Khimov
cb0ef2de3d
Merge pull request #3166 from nspcc-dev/find-storage-param
rpcclient: always provide `start` parameter for `findstorage` RPC
2023-10-18 21:32:50 +03:00
Anna Shaleva
3353599b38 cli: adjust usage text of contract generate-rpcwrapper command
Hash is optional since f97eaddf.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-10-18 20:38:54 +03:00
Anna Shaleva
6476241b3a smartcontract: add DO NOT EDIT warning to autogenerated files
Close #3139.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-10-18 20:34:36 +03:00
Anna Shaleva
1841d818ec rpcclient: always provide start parameter for findstorage RPC
Close #3137.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-10-18 20:12:05 +03:00
Roman Khimov
ef2bc7ca04
Merge pull request #3164 from nspcc-dev/pretty-generator
Apply `gofmt` to autogenerated bindings
2023-10-18 18:41:32 +03:00
Anna Shaleva
6a706d5c5a rpcbinding: fix formatting of binding template
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-10-18 18:15:33 +03:00
Anna Shaleva
c42486587d smartcontract: apply gofmt to the resulting bindings
Close #3133.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-10-18 18:14:52 +03:00
Roman Khimov
d24579748e
Merge pull request #3162 from nspcc-dev/dependabot/go_modules/examples/zkp/cubic_circuit/github.com/consensys/gnark-0.9.1
build(deps): bump github.com/consensys/gnark from 0.9.0 to 0.9.1 in /examples/zkp/cubic_circuit
2023-10-18 10:40:47 +03:00
dependabot[bot]
19cfbc8d85
build(deps): bump github.com/consensys/gnark
Bumps [github.com/consensys/gnark](https://github.com/consensys/gnark) from 0.9.0 to 0.9.1.
- [Release notes](https://github.com/consensys/gnark/releases)
- [Changelog](https://github.com/Consensys/gnark/blob/master/CHANGELOG.md)
- [Commits](https://github.com/consensys/gnark/compare/v0.9.0...v0.9.1)

---
updated-dependencies:
- dependency-name: github.com/consensys/gnark
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-18 07:20:33 +00:00
Anna Shaleva
b1ad19864f
Merge pull request #3163 from nspcc-dev/dependabot/go_modules/github.com/consensys/gnark-0.9.1
build(deps): bump github.com/consensys/gnark from 0.9.0 to 0.9.1
2023-10-18 10:19:11 +03:00
dependabot[bot]
0bd618bee4
build(deps): bump github.com/consensys/gnark from 0.9.0 to 0.9.1
Bumps [github.com/consensys/gnark](https://github.com/consensys/gnark) from 0.9.0 to 0.9.1.
- [Release notes](https://github.com/consensys/gnark/releases)
- [Changelog](https://github.com/Consensys/gnark/blob/master/CHANGELOG.md)
- [Commits](https://github.com/consensys/gnark/compare/v0.9.0...v0.9.1)

---
updated-dependencies:
- dependency-name: github.com/consensys/gnark
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-17 14:24:56 +00:00
Roman Khimov
38f77c39d0
Merge pull request #3142 from Ayrtat/fix/wsclient_hang
rpcclient: fix wsclient hang on making request
2023-10-16 15:26:13 +03:00
Roman Khimov
1aabdc9672
Merge pull request #3145 from nspcc-dev/gnark-upd
go.mod: upgrade gnark to v0.9.0
2023-10-16 15:25:19 +03:00
Anna Shaleva
545dbbc668 go.mod: upgrade gnark to v0.9.0
Close #3079.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-10-16 15:06:30 +03:00
Ayrtat
ff19189937 rpcclient: fix #3135 wsclient hangs on making request
* Rename c.done channel to c.readerDone
* Introduce c.writerDone channel that is closed if the wsWriter's loop
  is done
* Make the error returned by makeWsRequests verbose

Signed-off-by: Ayrtat <amper.meter1775@gmail.com>
2023-10-16 13:01:12 +03:00
Roman Khimov
a9a848a306
Merge pull request #3160 from nspcc-dev/add-version-hf
rpcsrv: add hardforks to `getversion` response
2023-10-16 10:37:10 +03:00
Anna Shaleva
69a0104d05 rpcsrv: add hardforks to getversion response
Port https://github.com/neo-project/neo-modules/pull/823.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-10-16 10:33:21 +03:00
Roman Khimov
f31e3f70aa
Merge pull request #3157 from nspcc-dev/upd-go
*: drop go 1.18 support, add go 1.21 support
Close #2626, close #2627, close #2629.
2023-10-12 23:37:01 +03:00
Anna Shaleva
c8ed629b5d
Merge pull request #3158 from nspcc-dev/dependabot/go_modules/golang.org/x/net-0.17.0
build(deps): bump golang.org/x/net from 0.14.0 to 0.17.0
2023-10-12 18:33:30 +03:00
Anna Shaleva
645076d04f examples: update neo-go dependency
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-10-12 18:19:30 +03:00
Anna Shaleva
3c13a3d74d *: update interop deps
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-10-12 18:09:08 +03:00
Anna Shaleva
e06051e14c cli: use fmt.Append* where possibble
Close #2629.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-10-12 18:07:54 +03:00
Anna Shaleva
3aa858a69f *: drop go 1.18 support in doc and build targets
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-10-12 17:59:42 +03:00
Anna Shaleva
241d5f593e *: use methods of binary.AppendByteOrder where applicable
We often use binary.PutUint*, but almost all these cases have preallocated
buffer of the size that matches exactly the desired one and use a single or
a couple of calls to PutUint*. Thus, I don't think that replacing
binary.PutUint* by AppendUint* will make things better for all these usages.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-10-12 17:59:42 +03:00
Anna Shaleva
dc3d1300dd *: replace go.uber.org/atomic with sync/atomic
Use sync/atomic everywhere and exclude go.uber.org/atomic from go.mod.
Close #2626.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-10-12 17:59:34 +03:00
Anna Shaleva
7ca4ce0f79 core: fix race in stateroot initialization error logging
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-10-12 13:37:31 +03:00
Anna Shaleva
9cd5c88077 Dockerfile.wsc: use official golang image for Windows NeoGo image
Don't need to keep the copy of the official Golang image in our
dockerfile, let's use it as a base builder image.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-10-12 13:28:59 +03:00
Anna Shaleva
45dcf38563 .github, Dockerfiles: bump minimum\maximum go versions
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-10-12 13:28:59 +03:00
Anna Shaleva
995d774ff8 *: bump minimum required go version to 1.19
For all components.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-10-12 13:28:59 +03:00
Anna Shaleva
e6b4fbc999 rpcsrv: format code
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-10-12 13:28:59 +03:00
dependabot[bot]
6e9ac29d5c
build(deps): bump golang.org/x/net from 0.14.0 to 0.17.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.14.0 to 0.17.0.
- [Commits](https://github.com/golang/net/compare/v0.14.0...v0.17.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-11 23:07:53 +00:00
Roman Khimov
b284b902d6
Merge pull request #3138 from nspcc-dev/fix-conflicts
*: refactor Notary conflict records storage scheme
2023-10-10 18:09:20 +03:00
Anna Shaleva
32bfed4741 core: improve conflict records storage scheme
Implement the https://github.com/neo-project/neo/issues/2907#issuecomment-1722506014
and port a part of https://github.com/neo-project/neo/pull/2913.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-10-10 17:34:27 +03:00
Roman Khimov
fce98a0af8
Merge pull request #3153 from nspcc-dev/fix-codecov
.github: upgrade coverage uploading action
2023-10-10 14:30:30 +03:00
Roman Khimov
2f747dd8d9
Merge pull request #3150 from nspcc-dev/drop-deprecated
Drop deprecated things
2023-10-10 14:29:47 +03:00
Roman Khimov
8fcf1eecfa
Merge pull request #3110 from nspcc-dev/fix-tests
Fix race caused by design of native Neo validators/committee cache
2023-10-10 14:29:28 +03:00
Anna Shaleva
bb9b8368a8 .github: upgrade coverage uploading action
Currently it's failing, but no token is required for public repos:
```
[2023-10-10T10:35:11.917Z] ['error'] There was an error running the uploader: Error uploading to https://codecov.io: Error: There was an error fetching the storage URL during POST: 404 - {'detail': ErrorDetail(string='Unable to locate build via Github Actions API. Please upload with the Codecov repository upload token to resolve issue.', code='not_found')}
```

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-10-10 13:53:20 +03:00
Roman Khimov
460362ab2e config: drop deprecated Protocol configurations
Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-10-10 13:26:07 +03:00
Roman Khimov
9f7b19f886 config: drop implicit consensus config via UnlockWallet
Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-10-10 13:26:07 +03:00
Roman Khimov
6865848ca7 config: drop deprecated P2P configuration
Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-10-10 13:26:07 +03:00
Roman Khimov
de69560c7d config: drop deprecated address/port configurations
Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-10-10 13:26:07 +03:00
Roman Khimov
a59afa8ea3 config: drop obsolete SecondsPerBlock protocol configuration
Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-10-10 13:26:07 +03:00
Roman Khimov
eb995c8600 rpcclient: drop deprecated Notifications an Subscribe*
Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-10-10 13:26:07 +03:00
Roman Khimov
413caac941 rpcclient: drop deprecated Client APIs
Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-10-10 13:26:07 +03:00
Anna Shaleva
d9644204ee native: make newEpochNextValidators always contain non-empty value
If it's the end of epoch, then it contains the updated validators list recalculated
during the last block's PostPersist. If it's middle of the epoch, then it contains
previously calculated value (value for the previous completed epoch) that is equal
to the current nextValidators cache value.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-10-10 13:18:05 +03:00
Anna Shaleva
f78f915071 native: optimize NEO's committee/validators cache handling
Do not recalculate new committee/validators value in the start of every
subsequent epoch. Use values that was calculated in the PostPersist method
of the previously processed block in the end of the previous epoch.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-10-10 13:18:05 +03:00
Anna Shaleva
27dddb4d50 native: refactor argument of NEO's getCommitteeMembers function
No funcional changes, just refactoring. It doesn't need the whole cache,
only the set of committee keys with votes.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-10-10 13:18:05 +03:00
Anna Shaleva
794658b54c native: rename NEO's cached validators list to newEpochNextValidators
Adjust all comments, make the field name match its meaning.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-10-10 13:18:05 +03:00
Anna Shaleva
312534af7c native: don't recalculate validators every block
Recalculate them once per epoch. Consensus is aware of it and must
call CalculateNextValidators exactly when needed.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-10-10 13:18:05 +03:00
Anna Shaleva
07e1bc7cd7 core: rename (*Blockchain).GetValidators to ComputeNextBlockValidators
We have two similar blockchain APIs: GetNextBlockValidators and GetValidators.
It's hard to distinguish them, thus renaming it to match the meaning, so what
we have now is:

GetNextBlockValidators literally just returns the top of the committee that
was elected in the start of batch of CommitteeSize blocks batch. It doesn't
change its valie every block.

ComputeNextBlockValidators literally computes the list of validators based on
the most fresh committee members information got from the NeoToken's storage
and based on the latest register/unregister/vote events. The list returned by
this method may be updated every block.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-10-10 13:18:05 +03:00
Anna Shaleva
96449d803a native: rework native NEO next block validators cache
Blockchain passes his own pure unwrapped DAO to
(*Blockchain).ComputeNextBlockValidators which means that native
RW NEO cache structure stored inside this DAO can be modified by
anyone who uses exported ComputeNextBlockValidators Blockchain API,
and technically it's valid, and we should allow this, because it's
the only purpose of `validators` caching. However, at the same time
some RPC server is allowed to request a subsequent wrapped DAO for
some test invocation. It means that descendant wrapped DAO
eventually will request RW NEO cache and try to `Copy()`
the underlying's DAO cache which is in direct use of
ComputeNextBlockValidators. Here's the race:
ComputeNextBlockValidators called by Consensus service tries to
update cached `validators` value, and descendant wrapped DAO
created by the  RPC server tries to copy DAO's native cache and
read the cached `validators` value.

So the problem is that native cache not designated to handle
concurrent access between parent DAO layer and derived (wrapped)
DAO layer. I've carefully reviewed all the usages of native cache,
and turns out that the described situation is the only place where
parent DAO is used directly to modify its cache concurrently with
some descendant DAO that is trying to access the cache. All other
usages of native cache (not only NEO, but also all other native
contrcts) strictly rely on the hierarchical DAO structure and don't
try to perform these concurrent operations between DAO layers.
There's also persist operation, but it keeps cache RW lock taken,
so it doesn't have this problem as far. Thus, in this commit we rework
NEO's `validators` cache value so that it always contain the relevant
list for upper Blockchain's DAO and is updated every PostPersist (if
needed).

Note: we must be very careful extending our native cache in the
future, every usage of native cache must be checked against the
described problem.

Close #2989.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-10-10 13:18:05 +03:00
Roman Khimov
19c59c3a59
Merge pull request #3149 from nspcc-dev/fix-compiler-version-race
internal: avoid race access to config.Version by tests
2023-10-10 12:23:08 +03:00
Anna Shaleva
eeb439f548 internal: avoid race access to config.Version by tests
Network server constructor reads config.Version variable, and
testcli.DeployContract writes dummy config.Version which causes
race in tests. Avoid this race by moving config.Version initialisation
to a separate package and perform it inside test packages init().

Close #3011, close #3017.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-10-10 11:59:53 +03:00
Roman Khimov
cef70091f6
Merge pull request #3148 from fyfyrchik/fix-dump
storage: Use timeout for boltdb database opening
2023-10-09 12:40:07 +03:00
Evgenii Stratonikov
f1c6b9fe8f storage: Use timeout for boltdb database opening
To dump the DB, the service must be stopped.
If this is not the case `dump` command just hangs without any output,
which _may_ be unexpected from the ops POV.
Introduce a 1 second timeous, which is more than enough, given
that bbolt retries doing flock() every 50ms.

Signed-off-by: Evgenii Stratonikov <fyfyrchik@runbox.com>
2023-10-06 13:10:11 +03:00
Roman Khimov
b78bea17c0
Merge pull request #3147 from fyfyrchik/fix-big-uint64
compiler: Fix emitting big uint64 constants
2023-10-05 22:34:07 +03:00
Roman Khimov
32eb1e2606
Merge pull request #3146 from nspcc-dev/fix-link
zkpbinding: fix example link
2023-10-05 16:16:24 +03:00
Evgenii Stratonikov
96ee2e2b2d compiler: Fix emitting big uint64 constants
Currently we take int64 value from the Go parser and push it to the
stack. Using uint64 is not a common practice (usually we just use `int`),
but can be a problem while doing bit arithmetic and serializing numbers.

Signed-off-by: Evgenii Stratonikov <fyfyrchik@runbox.com>
2023-10-05 16:03:57 +03:00
Anna Shaleva
d27d2a8561 zkpbinding: fix example link
Should be a part of #3043.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-10-05 15:16:11 +03:00
Roman Khimov
91c928e8d3
Merge pull request #3043 from nspcc-dev/groth16-verify-compat
smartcontract, examples: add API for Groth16 Verifier contract building and examples
2023-10-05 13:58:21 +03:00
Anna Shaleva
fc6e87af2f *: update interop deps
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-10-05 13:46:56 +03:00
Anna Shaleva
a2d28272ef native: fix error message on unexpected BLS12-381 curve point
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-10-05 13:46:05 +03:00
Anna Shaleva
b5a75b1485 scripts: add zkp examples to dependencies updator
And ignore on dependency checks, we update all the examples at once
anyway, so may safely skip the check for zkp folder.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-10-05 13:46:05 +03:00
Anna Shaleva
1745b21142 *: upgrade gnark-crypto up to v0.12.0
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-10-05 13:46:05 +03:00
Anna Shaleva
e2abb5cb7c zkpbinding: update templates of go.sum and go.mod for Verifier contract
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-10-05 13:46:05 +03:00
Anna Shaleva
ca71bd51d3 zkpbinding: format formulae in Verifier template
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-10-05 13:46:05 +03:00
Anna Shaleva
b7e019e7ef native: ensure proper endianness is used for CryptoLib's field element multiplier
Field element multiplier must be provided in the LE form, confirmed by
cross-node invocation: https://github.com/nspcc-dev/neo-go/pull/3043#issuecomment-1733424840.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-10-05 13:46:05 +03:00
Anna Shaleva
8c46517522 zkpbinding: use proper field size for BLS12-381
It's not differ from BN254, but we'd better use the proper package.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-10-05 13:46:05 +03:00
Anna Shaleva
ff260a6a9b zkpbinding: allow to handle serialisation format of gnark >= v0.9.0
An upgrade from gnark v0.8.X to v0.9.0 changes serialization format of verifying/proving keys
and proofs. In neo-go zkpbinding package we have to support both at least for now, because
gnark@v0.9.0 requires minimum go 1.19.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-10-05 13:46:05 +03:00
Anna Shaleva
03951c94b0 examples: add production CRS generation instructions for ZKP examples
Add an example and instructions for production CRS generation to ZKP examples
with gnark >= v0.9.0.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-10-05 13:45:58 +03:00
Anna Shaleva
9e74fc5b47 zkp: add end-to-end Groth-16 proof generation/verification example
The example shows that the proover knows the solution of the cubic
equation: y = x^3 + x + 5. The example is constructed for BLS12-381
curve points using Groth-16 prooving algorithm. The example includes
everything that developer needs to start using ZKP on the NEO platform
with Go SDK:
1. The described cubic circuit implementation.
2. The off-chain proof generation with the help of gnark-crypto library.
3. Go verification contract generation and deployment with the help of
   NeoGo libraries.
4. The on-chain proof verification for various sets of input data.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-10-05 12:32:47 +03:00
Anna Shaleva
0a3260c22c examples: add compatibility example for Groth16 veification
Port the C# contract provided in the
https://github.com/neo-project/neo/issues/2647#issuecomment-1129849870 and
add an integration test for it. Part of the #3002.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-10-05 11:01:25 +03:00
Roman Khimov
4598f3d3c2
Merge pull request #3141 from nspcc-dev/limit-calculatenetworkfee-gas
Limit calculatenetworkfee GAS
2023-09-28 09:13:27 +03:00
Roman Khimov
49a44b0b9d rpcsrv: use stricter GAS limit for calculatenetworkfee
Valid transactions can't use more than MaxVerificationGAS for script execution
and this applies to the whole set of signers, so use this value by default
unless local instance configuration suggests something lower for generic
invocations.

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-09-27 19:33:06 +03:00
Roman Khimov
fd2774ea91 rpcsrv: return core.ErrVerificationFailed from calculatenetworkfee
We can ignore core.ErrInvalidSignature (which means that the script has
executed, but returned false), but we shouldn't ignore other errors which
likely mean that the script is incorrect (or hits some resource limits).

Use neorpc.ErrInvalidSignature as a return to separate this case from
contract-based verification.

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-09-27 19:30:23 +03:00
Roman Khimov
3628b824e1
Merge pull request #3140 from nspcc-dev/fix-wildcard-trusts-deserialization
smartcontract: fix wildcard trusts deserialization
2023-09-25 12:01:20 +03:00
Anna Shaleva
2581146a01 smartcontract: fix wildcard trusts deserialization
If manifest trusts presented as Null stackitem, then they should be
treated as wildcard, not as restricted.

It's not the same problem as described and fixed in
https://github.com/neo-project/neo/pull/2901 and
https://github.com/neo-project/neo/pull/2892, although these
two PRs are related.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-09-25 11:53:47 +03:00
Roman Khimov
f66abd020d
Merge pull request #3136 from nspcc-dev/fix-mainnet-neofs-config
config: fix mainnet neofs config
2023-09-19 18:40:19 +03:00
Roman Khimov
fda0e8364f config: fix mainnet neofs config
For some reason it got out of sync with the reality, Notary is enabled since
April there.

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-09-19 18:30:33 +03:00
Roman Khimov
eb571a1356
Merge pull request #3129 from nspcc-dev/neofs-sdk-up
oracle/neofs: upgrade to SDK RC11
2023-09-13 11:13:53 +03:00
Roman Khimov
a0f9743515 oracle/neofs: avoid panic on failed neofs requests
2023-09-13T06:04:07.114Z        WARN        failed to perform oracle request        {"url": "neofs:BE2c15AbYnKdcsVh77LisCtjifoNEJUekANo1yhQ211X/FMDZvqUCqcduZa8HD6wJNsHWrJ6sqkgBveGuYuL38pvH", "error": "header: status: code = 3072 message = container not found"}
  panic: runtime error: invalid memory address or nil pointer dereference
  [signal SIGSEGV: segmentation violation code=0x1 addr=0x50 pc=0xde7c8f]
  goroutine 302 [running]:
  github.com/nspcc-dev/neofs-sdk-go/client.(*PayloadReader).close(0x0?, 0x0?)
          github.com/nspcc-dev/neofs-sdk-go@v1.0.0-rc.11/client/object_get.go:200 +0x2f
  github.com/nspcc-dev/neofs-sdk-go/client.(*PayloadReader).Close(0x0?)
          github.com/nspcc-dev/neofs-sdk-go@v1.0.0-rc.11/client/object_get.go:229 +0x1e
  github.com/nspcc-dev/neo-go/pkg/services/oracle/neofs.clientCloseWrapper.Close({{0x14b45f8?, 0x0?}, 0xc0010a1380?})
          github.com/nspcc-dev/neo-go/pkg/services/oracle/neofs/neofs.go:97 +0x3c
  github.com/nspcc-dev/neo-go/pkg/services/oracle.(*Oracle).processRequest(0xc000255800, 0xc001dfa210, {0xb2d?, 0xc001ad8000?})
          github.com/nspcc-dev/neo-go/pkg/services/oracle/request.go:168 +0xee7
  github.com/nspcc-dev/neo-go/pkg/services/oracle.(*Oracle).runRequestWorker(0xc000255800)
          github.com/nspcc-dev/neo-go/pkg/services/oracle/request.go:36 +0xe5
  created by github.com/nspcc-dev/neo-go/pkg/services/oracle.(*Oracle).start
          github.com/nspcc-dev/neo-go/pkg/services/oracle/oracle.go:216 +0xae

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-09-13 10:50:42 +03:00
Roman Khimov
0f57ad4a12 oracle/neofs: upgrade to SDK RC11
It requires explicit signers, and we have a problem with the old code:

  2023-09-12T18:42:00.063Z        WARN        failed to perform oracle request        {"url": "neofs:FMDZvqUCqcduZa8HD6wJNsHWrJ6sqkgBveGuYuL38pvH/5DCg4wUgWuWN3zsF4P4HdAzY2iKvXcrZ8QBLYGd1D1g2", "error": "failed to create client: incorrect signer: expected ECDSA_DETERMINISTIC_SHA256 scheme"}

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-09-13 10:50:42 +03:00
Roman Khimov
2d88ed9fe5
Merge pull request #3125 from nspcc-dev/rel-0.102.0
Release 0.102.0
2023-09-06 23:15:10 +03:00
Roman Khimov
31cc349725 ROADMAP: adjust wrt 0.102.0 release
Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-09-06 22:08:26 +03:00
Roman Khimov
eb9735750c CHANGELOG: release 0.102.0
Co-Authored-by: Anna Shaleva <shaleva.ann@nspcc.ru>
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-09-06 22:08:26 +03:00
Roman Khimov
26c97a58ed
Merge pull request #3124 from nspcc-dev/hardforks
Set Basilisk hardforks for all networks
2023-09-06 16:54:29 +03:00
Roman Khimov
ee12520cbd config: set Basilisk fork height for NeoFS mainnet
Testnet doesn't need any (confirmed to have the same state for non-NEO
contracts) and can go with Basilisk from height 0.

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-09-06 16:04:18 +03:00
Roman Khimov
a703e54563
Merge pull request #3122 from nspcc-dev/fix-neo-state-deserialization
state: always deserialize LastGasPerVote
2023-09-06 08:28:32 +03:00
Roman Khimov
9bdf66a5e0 state: always deserialize LastGasPerVote
It can be non-zero even if VoteTo is NULL. Fixes state diff with 3.6.0:

  block 41660: value mismatch for key +////xTrvgat3qG/w8hQoD/I4MgUz6rygA==: QQQhAS8hA7yiAAAhAA== vs QQQhAS8hA7yiAAAhB+POSWfBCAE=

Related to #2844.

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-09-05 23:44:14 +03:00
Roman Khimov
98b946dcd3 config: set Basilisk hardfork heights for mainnet and testnet
Right from the https://github.com/neo-project/neo-node/pull/900

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-09-05 19:31:20 +03:00
Roman Khimov
c6850b49d9
Merge pull request #3121 from nspcc-dev/neotest-doc
neotest: improve doc based on #3120
2023-09-05 17:34:33 +03:00
Roman Khimov
4c015b30d5 neotest: improve doc based on #3120
We don't want anyone to have the same problem.

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-09-05 15:20:00 +03:00
Roman Khimov
2f54f176fb
Merge pull request #3119 from nspcc-dev/neotest-doc
neotest: fix NewSingleSigner description, fix #3118
2023-09-05 13:04:48 +03:00
Roman Khimov
7cedcb9197 neotest: fix NewSingleSigner description, fix #3118
Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-09-05 12:36:49 +03:00
Roman Khimov
e9d582f525
Merge pull request #2962 from nspcc-dev/notary-attr-upd
*: move NVB and Conflicts attributes out of extensions
2023-09-04 17:37:28 +03:00
Roman Khimov
fff7e91709 dao: simplify NewSimple()
We no longer need P2PSigExtension flag here, conflicts attribute is a part
of the normal protocol.

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-09-04 16:56:59 +03:00
Anna Shaleva
f3c1283ac6 *: move NVB and Conflicts attributes out of extensions
They're a part of the regular protocol now.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-09-04 16:39:44 +03:00
Roman Khimov
a59fd50844
Merge pull request #3115 from nspcc-dev/3030-opcode-dumps
Add address and swap endianness to vm opcode dump for hashes
2023-09-04 12:05:35 +03:00
Tatiana Nesterenko
259cbc3356 vm: add address&swap endianness to opcode dump for hashes
If the parameter in the opcode dump is a 20-byte value, the converted values,
such as the address and the swapped endianness, have been added.

Signed-off-by: Tatiana Nesterenko <tatiana@nspcc.io>
2023-09-04 08:41:22 +01:00
Roman Khimov
5180305240
Merge pull request #3117 from nspcc-dev/3070-unwrap-nothing
Add `unwrap.Nothing` function
2023-09-04 08:49:14 +03:00
Roman Khimov
cb1432233b
Merge pull request #3116 from nspcc-dev/2931-DBconfig-docs
Fix `DBConfiguration` description
2023-09-04 08:47:28 +03:00
Tatiana Nesterenko
59f72429b4 dbconfig: fix DBConfiguration description
The list of three supported types (`Type`) in the `DBConfiguration` struct
has been added.

Signed-off-by: Tatiana Nesterenko <tatiana@nspcc.io>
2023-09-03 18:02:38 +01:00
Tatiana Nesterenko
acd821948f unwrap: add Nothing function
The `Nothing` function expects zero stack items and a successful invocation
(HALT state).

Signed-off-by: Tatiana Nesterenko <tatiana@nspcc.io>
2023-09-03 16:54:50 +01:00
Roman Khimov
0d30c834d5
Merge pull request #3098 from nspcc-dev/2951-getrawnotarypool
Implement `getrawnotaryrequest` and `getrawnotarytransaction` RPC extensions, close #2951.
2023-08-31 22:05:51 +03:00
Tatiana Nesterenko
7afa950eb7 docs: add getrawnotarypool, getrawnotarytransaction
Signed-off-by: Tatiana Nesterenko <tatiana@nspcc.io>
2023-08-31 18:51:43 +01:00
Tatiana Nesterenko
d06f135792 rpcclient: support getrawnotarytransaction and getrawnotarypool RPC methods
GetRawNotaryTransaction returns a fallback or main transaction that was
previously added to the memory pool by P2PNotaryRequest. This function
invokes the RPC server's `getrawnotarytransaction` method.
GetRawNotaryPool returns hashes from all the verified transactions,
including both main and fallback transactions. This function invokes
the RPC server's `getrawnotarypool` method.

Also, these functions were added to doc.go.

Signed-off-by: Tatiana Nesterenko <tatiana@nspcc.io>
2023-08-31 18:51:43 +01:00
Tatiana Nesterenko
9e31e42bd9 rpcsrv: add getrawnotarypool, getrawnotarytransaction handlers
`getrawnotarytransaction` takes a transaction hash and attempts to find
the corresponding transaction in the notary requests mempool. It searches
through all the verified main and fallback transactions.
`getrawnotarypool` returns hashes of all the verified transactions,
including both main and fallback transactions.

Additionally add struct result.RawNotaryPool.

Close https://github.com/nspcc-dev/neo-go/issues/2951

Signed-off-by: Tatiana Nesterenko <tatiana@nspcc.io>
2023-08-31 18:51:43 +01:00
Tatiana Nesterenko
d285342d54 core: add function IterateVerifiedTransactions
IterateVerifiedTransactions iterates through verified transactions in
memory pool and invokes function cont. Where cont callback returns
whether we should continue with the traversal process.

Signed-off-by: Tatiana Nesterenko <tatiana@nspcc.io>
2023-08-31 18:51:43 +01:00
Roman Khimov
1e6ef0c0e6
Merge pull request #3114 from omahs/patch-1
docs: fix typos
2023-08-31 18:04:14 +03:00
omahs
edf21e0b79 examples: fix typo
Signed-off-by: omahs <73983677+omahs@users.noreply.github.com>
2023-08-31 14:14:14 +02:00
omahs
e83916cef1 docs: fix typos
Signed-off-by: omahs <73983677+omahs@users.noreply.github.com>
2023-08-31 14:13:51 +02:00
Roman Khimov
abb35ad6fd
Merge pull request #3113 from nspcc-dev/prettify-dco
.github: prettify DCO check display name
2023-08-31 11:58:15 +03:00
Anna Shaleva
f330aaf313 .github: rename testing workflow file
Make it unified with the rest of workflow files.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-31 11:20:10 +03:00
Anna Shaleva
c80702cc4a .github: prettify DCO check display name
Extend the YAML scope and prettify the job check name.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-31 11:17:43 +03:00
Roman Khimov
5463a91edc
Merge pull request #3111 from nspcc-dev/rpcsrv-drop-unused-iface
rpcsrv: drop unused method from the Ledger interface
2023-08-30 10:55:23 +03:00
Roman Khimov
4a648692a2 rpcsrv: drop unused method from the Ledger interface
Inspired by #3110.

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-08-29 22:33:26 +03:00
Roman Khimov
ad24aad9c0
Merge pull request #3108 from nspcc-dev/create-fallback-copy
notary: avoid changing pooled fallback transaction witnesses
2023-08-29 16:16:24 +03:00
Anna Shaleva
c63289a564 notary: avoid changing pooled fallback transaction witnesses
Forbid Notary service to change the fallback's witnesses in any way.
Fix the problem described in review comment:
https://github.com/nspcc-dev/neo-go/pull/3098#discussion_r1308336339.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-29 16:06:40 +03:00
Roman Khimov
2d4e1b598f
Merge pull request #3109 from nspcc-dev/reuse-org-dco-workflow
workflows: reuse org-wide DCO workflow
2023-08-29 15:08:51 +03:00
Roman Khimov
0b67fa9bca
Merge pull request #3107 from nspcc-dev/default-iter-items-conut
rpcsrv: enforce default config values on server creation if malformed value specified
2023-08-29 15:06:58 +03:00
Roman Khimov
1863b79c5c workflows: reuse org-wide DCO workflow
Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-08-29 14:59:53 +03:00
Anna Shaleva
b89078c42a rpcsrv: set MaxNEP11Tokens to default if not specified
Do not use RPC configuration constructor for this, some external services
may skip this part.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-29 13:26:10 +03:00
Anna Shaleva
f5b0489d74 rpcsrv: set MaxFindStorageResultItems to default if not specified
Do not use RPC configuration constructor for this, some external services
may skip this part.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-29 13:26:10 +03:00
Anna Shaleva
dd7c762ff9 rpcsrv: set MaxFindResultItems to default if not specified
Do not use RPC configuration constructor for this, some external services
may skip this part.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-29 13:26:10 +03:00
Anna Shaleva
aeb7ee1021 rpcsrv: improve error formatting
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-29 13:26:05 +03:00
Anna Shaleva
97a57de82d rpcsrv: set MaxIteratorResultItems to default if not specified
Do not use RPC configuration constructor for this, some external services
may skip this part.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-29 13:19:39 +03:00
Roman Khimov
b4dff7b040
Merge pull request #3104 from nspcc-dev/hardforks-check
core: adjust hardfork enabling logic
2023-08-25 19:17:18 +03:00
Anna Shaleva
5d3938ae23 core: adjust hardfork enabling logic
Follow the logic described in https://github.com/neo-project/neo/pull/2886#issuecomment-1674745298
and port the https://github.com/neo-project/neo/pull/2886.

Close #3096.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-25 18:24:15 +03:00
Roman Khimov
7d75526c20
Merge pull request #3099 from nspcc-dev/findstorage
rpcsrv, rpcclient: support `findstorage`, `findstoragehistoric` and `getstoragehistoric` calls
2023-08-24 17:21:45 +03:00
Anna Shaleva
7b64b693bd rpcsrv: refactor findstoragehistoric handler to avoid DoS attack
Do not retrieve the whole set of storage items when trying to find
the ones from the specified start. Use DAO's Seek interface
implemented over MPT TrieStore to retrieve only the necessary items.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-24 17:15:59 +03:00
Anna Shaleva
c7d5ee0898 docs: refactor historical RPC calls documentation
1. Reorder paragraphs.
2. Extend common historical calls description.
2. Document `getstoragehistoric` and `findstoragehistoric` extensions.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-24 17:15:59 +03:00
Anna Shaleva
1fb0c96e2c rpcsrv, rpcclient: support getstoragehistoric call
Make it similar to `findstoragehistoric`.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-24 17:15:59 +03:00
Anna Shaleva
97d523ceed docs: fix typo
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-24 17:15:59 +03:00
Anna Shaleva
617c628c24 rpcsrv, rpcclient: support findstorage and findstoragehistoric
Close #3095 and add the corresponding historic extension.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-24 17:15:58 +03:00
Roman Khimov
87e4b6beaa
Merge pull request #3102 from nspcc-dev/upd-license
*: update LICENSE.md
2023-08-23 15:03:29 +03:00
Anna Shaleva
b9e957a05a *: update LICENSE.md
Adjust year, sort authors by contribution and fit authors in one line.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-23 14:26:45 +03:00
Anna Shaleva
124c3df2ff rpcsrv: rename testcases related to unsupported state
Testcase name should match the test purpose.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-22 19:54:07 +03:00
Roman Khimov
227b0c5480
Merge pull request #3041 from nspcc-dev/generic-decl
compiler: temporary disallow generics usages
2023-08-18 21:24:56 +03:00
Anna Shaleva
66a80017d3 docs: add note about type aliases and generics support
Part of #3023.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-18 17:01:45 +03:00
Roman Khimov
c5d9bf6e39
Merge pull request #3086 from nspcc-dev/ntf-strict-check
core: move strict notifications check under `HFBasilisk`
2023-08-18 16:55:20 +03:00
Anna Shaleva
bb2a99d451 smartcontract: disallow Null and non-utf8 String
Follow the https://github.com/neo-project/neo/pull/2810#discussion_r1295900728.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-18 16:41:33 +03:00
Anna Shaleva
ed2c4b0319 core: improve error checks in TestNotify
Ensure that the error returned from runtime.Notify is exactly the error
that was expected.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-18 16:41:33 +03:00
Anna Shaleva
2872c1c668 core: move contract notifications check under HFBasilisk
Follow the https://github.com/neo-project/neo/pull/2884.
A part of the https://github.com/neo-project/neo/pull/2810.
Fix failing tests along the way (a lot of them have invalid notifications
format which differs from the one declared in manifest).

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-18 16:40:20 +03:00
Anna Shaleva
35c3b65c8a compiler: disallow generic type decl
Need to be reverted and properly handled within the scope of #2376.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-18 16:02:40 +03:00
Anna Shaleva
380de580a7 compiler: disallow generic function parameter types
Need to be reverted and properly handled within the scope of #2376.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-18 16:02:40 +03:00
Anna Shaleva
1b1b454ce4 compiler: disallow generic method receiver
Either non-pointer or pointer, both cases are disallowed to be generic.
Need to be reverted and properly handled within the scope of #2376.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-18 16:02:39 +03:00
Anna Shaleva
415d44792a compiler: properly retrieve name of generic functions
Fix panic described in #3040. Ref. #2376.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-18 16:00:54 +03:00
Anna Shaleva
87aaaf1a67 core: rename TestManagement_DeployUpdateHardfork
So that hardfork name was explicitly present in the test name. We'll
have a set of similar tests later.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-18 12:02:43 +03:00
Anna Shaleva
60795a899f smartcontract: improve invalid notification error text
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-18 12:02:43 +03:00
Roman Khimov
5c6a111d00
Merge pull request #3063 from tatiana-nspcc/rpcsrv-errors
RPC: add error codes and response errors
2023-08-16 17:38:18 +03:00
Tatiana Nesterenko
90f1b0fd17 core: change text in ErrInvalidVerificationContract
No functional changes, just a refactoring.
Change error text to be able to use this error from external packages.

Signed-off-by: Tatiana Nesterenko <tatiana@nspcc.io>
2023-08-16 14:16:14 +01:00
Tatiana Nesterenko
f3760c1a98 rpcsrv: return ErrUnknownSession and ErrUnknownIterator
Behaviour change.
`terminatesession` returns ErrUnknownSession in case of impossibility of finding session,
previously there was no-error response with `false` result.
`traverseIterator`returns ErrUnknownSession in case of impossibility of finding session,
previously there was no-error response with default result; `traverseIterator`returns ErrUnknownIterator,
there were no such errors before.
Accordingly to proposal:
https://github.com/neo-project/proposals/pull/156
Also adding description of `traverseIterator` in docs/rpc.md.

Signed-off-by: Tatiana Nesterenko <tatiana@nspcc.io>
2023-08-16 14:16:14 +01:00
Tatiana Nesterenko
f557959c24 rpcsrv: return error on invalid proof from verifyProof
This change makes code incompatible with C# node,
because currently no error is returned on invalid proof.
According to proposal:
https://github.com/neo-project/proposals/pull/156
Also adding `verifyProof` descpiption in docs/rpc.md.

Signed-off-by: Tatiana Nesterenko <tatiana@nspcc.io>
2023-08-16 14:00:24 +01:00
Tatiana Nesterenko
2598257628 core: rename ErrInvalidVerification and ErrInvalidInvocation
No functional changes, just a refactoring.
Use more specific and meaningful names to be able to use these errors from external packages.

Signed-off-by: Tatiana Nesterenko <tatiana@nspcc.io>
2023-08-16 14:00:24 +01:00
Tatiana Nesterenko
1e6372e6d9 rpcsrv: return error on unknown storage item from getstorage
Follow the reference implementation, the behaviour was changed in
237ef7d057.

Signed-off-by: Tatiana Nesterenko <tatiana@nspcc.io>
2023-08-16 14:00:24 +01:00
Tatiana Nesterenko
d3fe92de14 rpcsrv: remove default request HTTP codes from switch statement
No functional changes, just a refactoring.

Signed-off-by: Tatiana Nesterenko <tatiana@nspcc.io>
2023-08-16 14:00:24 +01:00
Tatiana Nesterenko
3b29720298 neorpc: add deprecated error codes for C#-compatibility
While our server no longer uses these codes (-100, -400) they still can come
from C# servers and while we consider them deprecated we better at least have
some definition of them until C# implements our proposal:
https://github.com/neo-project/proposals/pull/156
Also adding description of deprecated RPC error codes in ROADMAP.md.

Signed-off-by: Tatiana Nesterenko <tatiana@nspcc.io>
2023-08-16 13:59:39 +01:00
Tatiana Nesterenko
3178c8ff78 docs: add proposal regarding response error codes
According to proposal:
https://github.com/neo-project/proposals/pull/156

Close #2248

Signed-off-by: Tatiana Nesterenko <tatiana@nspcc.io>
2023-08-16 13:59:37 +01:00
Tatiana Nesterenko
31ceb568cb neorpc: add error codes and response errors
According to proposal:
https://github.com/neo-project/proposals/pull/156

Close #2248

Signed-off-by: Tatiana Nesterenko <tatiana@nspcc.io>
2023-08-16 13:59:33 +01:00
Tatiana Nesterenko
3abddc78c0 core: split ErrAlreadyExists into ErrAlreadyExists and ErrAlreadyInPool
ErrAlreadyExists is in blockchain and ErrAlreadyInPool is in mempool.

Signed-off-by: Tatiana Nesterenko <tatiana@nspcc.io>
2023-08-16 12:36:56 +01:00
Roman Khimov
9fb154a376
Merge pull request #3074 from nspcc-dev/fix-debug-info
compiler: fix sequence point boundaries
2023-08-12 00:17:19 +03:00
Anna Shaleva
d1fe64470d compiler: fix sequence point boundaries
Thanks to @fyrchik, see the
https://github.com/neo-project/neo-devpack-dotnet/pull/154/files#diff-ebf53d00d5ba1f1197fedd2b8111fe9a8f44fb96699ef1314d54d05d5ceeb3f3R27

See also the standard:
https://github.com/neo-project/proposals/blob/master/nep-19.mediawiki#method.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-11 20:16:02 +03:00
Roman Khimov
4e61e8238a
Merge pull request #3087 from nspcc-dev/smart-binding
rpcbinding: export any unexported fields of structures/events
2023-08-11 18:11:47 +03:00
Anna Shaleva
16d1d1e5eb rpcbinding: check duplicating struct fields before binding generation
RPC binding config may be malformed or the source .go contract may contain
structures like this:
```
type Str struct {
    Field int
    field int
}
```
We need to recognise these cases and return error. otherwise the resulting
binding can't be compiled.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-11 17:48:54 +03:00
Anna Shaleva
b4c0fcfaad cli: move RPC bindings related testdata to a separate folder
It helps us to keep the index clean and ordered. When some new RPC binding
test should be added, we don't need to search for a suitable place for it.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-11 17:03:04 +03:00
Anna Shaleva
b2f84c83b3 rpcbinding: reuse upperFirst helper where possible
No functional changes.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-11 15:32:00 +03:00
Anna Shaleva
1356721862 rpcbinding: export any unexported fields of structures/events
Perform private -> public transformation at the last step of RPC binding
generation so that it works not only with NeoGo contracts, but with any
other contracts.

Close #3083.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-11 15:31:08 +03:00
Roman Khimov
11c0f13d06
Merge pull request #3080 from nspcc-dev/extend-int-prec
vm: increase BigInt parsing precision
2023-08-10 13:30:04 +03:00
Anna Shaleva
624f193f94 vm: move JNumbers parsing precision under HFBasilisk
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-10 13:14:16 +03:00
Anna Shaleva
d90608ddbf vm: increase BigInt parsing precision
Follow the https://github.com/neo-project/neo/pull/2883.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-10 13:14:16 +03:00
Roman Khimov
562293c74b
Merge pull request #3066 from nspcc-dev/abort-msg
vm, compiler: support `ASSERTMSG` and `ABORTMSG`
2023-08-10 13:11:41 +03:00
Anna Shaleva
3608314c15 .github: enable submodules sync for actions/checkout@v3
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-10 12:54:07 +03:00
Anna Shaleva
158d8e69a4 vm: update VM json tests path
It was changed way back in 5a11f4b4ca.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-10 12:54:07 +03:00
Anna Shaleva
5b12be2ac7 compiler: add test for util.AbortMsg and util.AssertMsg
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-10 12:54:07 +03:00
Anna Shaleva
de43b39c2a *: update interop deps
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-10 12:54:06 +03:00
Anna Shaleva
11bb733f1a interop: support ABORTMSG, ASSERT, ASSERTMSG opcodes
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-10 12:41:30 +03:00
Anna Shaleva
e7f77e052f vm: add ABORTMSG and ASSERTMSG opcodes
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-10 12:41:30 +03:00
Roman Khimov
2493400525
Merge pull request #3085 from nspcc-dev/fix-oracle-instance 2023-08-10 12:02:26 +03:00
Anna Shaleva
c39153756a rpcsrv: carefully store Oracle service
And simplify atomic service value stored by RPC server. Oracle service can
either be an untyped nil or be the proper non-nil *oracle.Oracle.
Otherwise `submitoracleresponse` RPC handler doesn't work properly.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-10 10:12:01 +03:00
Roman Khimov
25f61b45dd
Merge pull request #3056 from nspcc-dev/revert-script-check-removal
core: create hardfork for strict script check
2023-08-09 20:55:55 +03:00
Anna Shaleva
50ee241377 core: move strict script check on deploy under HF condition
Follow the https://github.com/neo-project/neo/pull/2881.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-09 18:32:30 +03:00
Anna Shaleva
bd937bc500 Revert "core: remove contract script check on deploy/update"
This reverts commit 762a8da76a.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-09 18:30:47 +03:00
Anna Shaleva
6c1240d023 cli: fix failing TestRunWithHistoricState
Broken by #3084.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-09 15:26:38 +03:00
Roman Khimov
5fc61be5f6
Merge pull request #3084 from nspcc-dev/wrkshp-upd
examples, config: minor adjustments for workshop
2023-08-08 22:54:20 +03:00
Anna Shaleva
4e6b1c4a38 examples: extend storage contract
Add method that returns iterator. It's needed for the workshop.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-08 18:30:22 +03:00
Anna Shaleva
b5f17215db config: enable session-based iterators on privnet
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-08 18:29:02 +03:00
Roman Khimov
afa4530c7d
Merge pull request #3078 from nspcc-dev/fix-failing-tests
Take care of master branch after 0.101.4 release
2023-08-02 10:53:07 +03:00
Anna Shaleva
e82fcb48c4 go.sum: update sums after 0.101.4 merge
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-02 10:35:22 +03:00
Anna Shaleva
50a77f3fae rpcclient: fix test after 0.101.4 merge
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-02 10:35:19 +03:00
Roman Khimov
7e867aefc4
Merge pull request #3077 from nspcc-dev/rel-0.101.4
Rel 0.101.4
2023-08-01 19:41:26 +03:00
Anna Shaleva
18c42f7993
Merge branch 'master' into rel-0.101.4
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-01 19:34:34 +03:00
Anna Shaleva
80fdb1c90c CHANGELOG: release 0.101.4
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-01 19:23:01 +03:00
Anna Shaleva
e2c6bbb6b1 rpcsrv: properly set content-type and CORS for all headers
Not only for successful ones. Close #3075.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-01 17:47:48 +03:00
Anna Shaleva
8d5a41de6e vm: allow parsing scientific JSON numbers
52-bit precision is not enough for our 256-bit VM, but this value
matches the reference implementation, see the
https://github.com/neo-project/neo/issues/2879.

MaxIntegerPrec will be increased (or even removed) as soon as the
ref. issue is resolved.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-01 17:46:56 +03:00
Anna Shaleva
6615cce81d rpcclient: adjust unwrapContract helper
There may be no such contract, then Null stackitem is expected on stack.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-01 17:46:12 +03:00
Anna Shaleva
c0abc61613 smartcontract: allow to pass nil as parameter to (*Invoker).Call
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-01 17:45:52 +03:00
Anna Shaleva
bf871760c6 core: do not use formatted error if not needed
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-01 17:44:48 +03:00
Anna Shaleva
96aa10bb80 neorpc: adjust the way SignerWithWitness is marshalled
Marshal account with `0x` prefix and add a test.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-01 17:44:43 +03:00
Anna Shaleva
8db997c58a neorpc: adjust SignerWithWitness scopes parsing
Ensure that Scopes can be properly parsed not only from the string
representation, but also from a single byte. transaction.Signer
is not affected (checked against the C# implementation), only
RPC-related signer scopes are allowed to be unmarshalled from byte.

Close #3059.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-01 17:44:37 +03:00
Anna Shaleva
e30e262e66 network: forbid Notary contract to be a sender of main transaction
This prevents the possible attack on notary request sender when
malicious partie is allowed to send notary request with main transaction
being someone else's fallback.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-01 17:44:24 +03:00
Anna Shaleva
ebe4c4ce2b cli: add test for incremental DB dump and restore
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-01 17:44:03 +03:00
Roman Khimov
b560475e67 server: allow to create incremental dumps
Anything not starting from 0 is incremental by definition.

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-08-01 17:43:57 +03:00
Roman Khimov
4383832aa2 go.mod: upgrade bolt to v1.3.7
Refs. nspcc-dev/neofs-node#999, it fixes a number of other Windows-related
issues as well.

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-08-01 17:43:30 +03:00
Anna Shaleva
6abf5f6388 cli: allow to provide network-specific node config file
Close #2978.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-01 17:41:03 +03:00
Anna Shaleva
d560395985 core: prevent direct access to Notary contract if not active
Otherwise it will cause panic, which isn't expected behaviour.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-01 17:30:11 +03:00
Anna Shaleva
2c984e2393 core: initialize natives cache wrt NativeActivations
If the contract was deployed then cache must be initialized after
in-memory data reset. If the contract isn't active yet, then no
cache will be initialized on deploy (i.e. on call to Initialize()
method by native Management).

Close #2984.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-01 17:30:05 +03:00
Anna Shaleva
d0718a680f core: add InitializeCache method to Contract interface
Make the contracts cache initialization unified. The order of cache
iniitialization is not important and Nottary contract is added to the
bc.contracts.Contracts wrt P2PSigExtensions setting, thus no functional
changes, just refactoring for future applications.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-01 17:30:01 +03:00
Anna Shaleva
97b93c6833 *: adjust Prometheus metrics initialisation on node start
Initialize Prometheus metrics on node start where appropriate and review
the usage of the following metrics:
```
anna@kiwi:~/Documents/GitProjects/nspcc-dev/neo-go$ find | grep prometheus.go
./pkg/network/prometheus.go
./pkg/core/stateroot/prometheus.go
./pkg/core/prometheus.go
./pkg/services/rpcsrv/prometheus.go
./pkg/services/metrics/prometheus.go
```

Close #2970.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-01 17:29:36 +03:00
Roman Khimov
288dee8871 rpcclient: close subscriber channels on wsReader exit
The reader is about to exit and it will close legacy c.Notifications, but it
will leave subscription channels at the same time. This is wrong since these
channels will no longer receive any new events, game over.

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-08-01 17:29:14 +03:00
Roman Khimov
08b273266b rpcclient: correctly handle request channel closure
wsReader() closes c.done first and then goes over the list of
c.respChannels. Technically this means that any of the two can be taken in
this select.

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-08-01 17:29:08 +03:00
Anna Shaleva
ab64f7cfe4 docs: fix typo
Remove unnecessary word left after documentation refactoring.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-01 17:28:52 +03:00
Leonard Lyubich
6e990f39de cli/node: Fix deadlock produced by instant RPC service start
If `StartWhenSynchronized` is unset in config, `node` command runs RPC
service instantly. Previously there was a ground for deadlock. Command
started RPC server synchronously. According to server implementation, it
sends all internal failures to the parameterized error channel. Deadlock
occured because main routine didn't scan the channel.

Run `rpcsrv.Server.Start` in a separate go-routine in `startServer`.
This prevents potential deadlock caused by writing into unread channel.

Fixes #2896.

Signed-off-by: Leonard Lyubich <leonard@morphbits.io>
2023-08-01 17:27:28 +03:00
Leonard Lyubich
465d3f43d2 services/rpcsrv: Wait for subscription process to complete when stopped
Previously RPC server shutdown procedure listened to the execution
channel and stopped at the first element that arrived in the queue. This
could lead to the following problems:
 * stopper could steal the execution result from subscriber
 * stopper didn't wait for other subscription actions to complete

Add dedicated channel to `Server` for subscription routine. Close the
channel on `handleSubEvents` return and wait for signal in `Shutdown`.

Signed-off-by: Leonard Lyubich <leonard@morphbits.io>
2023-08-01 17:27:21 +03:00
Leonard Lyubich
f8227aa5f7 services/rpcsrv: Fix potential shutdown deadlock of RPC server
Previously RPC server could never be shut down completely due to
some start precondition failure (in particular, inability to serve HTTP
on any configured endpoint). The problem was caused by next facts:
 * start method ran subscription routine after HTTP init succeeded only
 * stop method blocked waiting for the subscription routine to return

Run `handleSubEvents` routine on fresh `Start` unconditionally. With
this change, `Shutdown` method won't produce deadlock since
`handleSubEvents` closes wait channel.

Refs #2896.

Signed-off-by: Leonard Lyubich <leonard@morphbits.io>
2023-08-01 17:27:11 +03:00
Leonard Lyubich
758c455c7e services/rpcsrv: Test Server shutdown with failed precondition
There is an existing problem with RPC server shutdown freeze after start
failure due to some init actions (at least HTTP listen) described in
#2896.

Add dedicated unit test which checks that `Shutdown` returns within 5s
after `Start` method encounters internal problems.

Signed-off-by: Leonard Lyubich <leonard@morphbits.io>
2023-08-01 17:27:03 +03:00
Anna Shaleva
c880873105 core: improve documentation to SetOracle/SetNotary
I've carefully checked the way how new service can be added to the
Blockchain instance or to be removed from it. Current implemention
of SetNotary and SetOracle methods doesn't contain dangerous code,
and native contracts have atomic values everywhere where service
is stored.

Current implementation of Notary, Oracle and StateRoot services'
reload/disabling/enabling on SIGUSR1 is safe and doesn't require
any adjustment.

This commit closes #2944, it's not a bug in the code, it's just
stale documentation.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-01 17:26:17 +03:00
Anna Shaleva
d5f964f181 config: do not allow negative validators count
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-01 17:22:39 +03:00
Anna Shaleva
6cd0f78649 config: do not allow zero numbers for validators/committee history
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-01 17:22:33 +03:00
Anna Shaleva
56b93d279e config: use uint32 for validators/committee members count
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-01 17:22:28 +03:00
Anna Shaleva
7028930bd6 network: do not use error channel to start network srv
It's obsolete thing, we have looger and it perfectly suits our needs.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-01 17:22:01 +03:00
Roman Khimov
eeab9c1b2e
Merge pull request #3076 from nspcc-dev/fix-content-type
rpcsrv: properly set content-type and CORS for all headers
2023-08-01 16:17:38 +03:00
Anna Shaleva
01a5816f04 rpcsrv: properly set content-type and CORS for all headers
Not only for successful ones. Close #3075.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-08-01 16:12:53 +03:00
Roman Khimov
03b9b4a4a1
Merge pull request #3073 from nspcc-dev/fix-sci-jnum
JSON scientific numbers kludge
2023-08-01 15:06:32 +03:00
Anna Shaleva
4be692193e vm: allow parsing scientific JSON numbers
52-bit precision is not enough for our 256-bit VM, but this value
matches the reference implementation, see the
https://github.com/neo-project/neo/issues/2879.

MaxIntegerPrec will be increased (or even removed) as soon as the
ref. issue is resolved.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-07-31 17:19:05 +03:00
Roman Khimov
3bbb21bf8f
Merge pull request #3072 from nspcc-dev/fix-contract-unwrap
rpcclient: adjust `unwrapContract` helper
2023-07-28 20:12:09 +03:00
Anna Shaleva
e57967b11c rpcclient: adjust unwrapContract helper
There may be no such contract, then Null stackitem is expected on stack.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-07-28 18:51:25 +03:00
Roman Khimov
081f9d3ac5
Merge pull request #3061 from nspcc-dev/check-onchain-conflicts
core: check the signers of on-chained conflicting transaction during new transaction verification
2023-07-21 22:36:21 +03:00
Anna Shaleva
ee4b8f883b core: check signers of on-chained conflict during new tx verification
During new transaction verification if there's an on-chain conflicting
transaction, we should check the signers of this conflicting transaction.
If the signers intersect with signers of the incoming transaction, then
the conflict is treated as valid and verification for new incoming
transaction should fail. Otherwise, the conflict is treated as the
malicious attack attempt and will not be taken into account;
verification for the new incoming transaction should continue.

This commint implements the scheme described at
https://github.com/neo-project/neo/pull/2818#issuecomment-1632972055,
thanks to @shargon for digging.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-07-21 17:27:47 +03:00
Roman Khimov
7a7d0a06ce
Merge pull request #3067 from nspcc-dev/allow-nil-arg
smartcontract: allow to pass nil as parameter to (*Invoker).Call
2023-07-21 14:51:10 +03:00
Anna Shaleva
0d17273476 core: fix formatted error on transaction verification
Witnesses are not yet created by the moment we return this error,
thus, it was always 0 as an actual number of witnesses in
ErrInvalidWitnessNum.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-07-21 13:50:20 +03:00
Anna Shaleva
0a2be89964 core: remove unused blockchain API
`(*Blockchain).HasTransaction` is one of the oldest methods in our
codebase, and currently it's completely unused. I also doubt that
this method works as expected because it returns `true` if transaction
in the mempool.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-07-21 13:37:02 +03:00
Anna Shaleva
c926d53869 smartcontract: allow to pass nil as parameter to (*Invoker).Call
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-07-21 13:19:25 +03:00
Roman Khimov
862c2e4ed3
Merge pull request #3060 from nspcc-dev/extend-rpc-signers
neorpc: adjust `SignerWithWitness` marshalling scheme
2023-07-20 17:27:23 +03:00
Roman Khimov
35ebdc1c91
Merge pull request #3065 from nspcc-dev/forbid-notary-sender
network: forbid Notary contract to be a sender of main transaction
2023-07-20 11:09:19 +03:00
Anna Shaleva
966111f4a8 network: forbid Notary contract to be a sender of main transaction
This prevents the possible attack on notary request sender when
malicious partie is allowed to send notary request with main transaction
being someone else's fallback.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-07-20 10:56:48 +03:00
Anna Shaleva
8253025c90 core: do not use formatted error if not needed
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-07-20 10:33:50 +03:00
Anna Shaleva
165525b7e9 neorpc: adjust the way SignerWithWitness is marshalled
Marshal account with `0x` prefix and add a test.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-07-20 10:33:50 +03:00
Anna Shaleva
9f69522ff5 neorpc: adjust SignerWithWitness scopes parsing
Ensure that Scopes can be properly parsed not only from the string
representation, but also from a single byte. transaction.Signer
is not affected (checked against the C# implementation), only
RPC-related signer scopes are allowed to be unmarshalled from byte.

Close #3059.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-07-20 10:33:48 +03:00
Anna Shaleva
e7a83cbef9
Merge pull request #3057 from nspcc-dev/upd-release-doc
docs: adjust release instructions
2023-07-11 18:32:03 +05:00
Anna Shaleva
8fcfa2c11a docs: adjust release instructions
Our assets will be automatically attached to the release after #3010.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-07-11 08:36:05 +03:00
Anna Shaleva
ee885bafdf
Merge pull request #3053 from nspcc-dev/rel-0.101.3
Release 0.101.3
2023-07-08 14:11:28 +05:00
Anna Shaleva
146775213a CHANGELOG: release 0.101.3
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-07-08 11:54:07 +03:00
Anna Shaleva
762a8da76a core: remove contract script check on deploy/update
This check is good and was present here since #1729, but it was
accidently removed from the reference implementation (see the
discussion in https://github.com/neo-project/neo/issues/2848). The
removal of this check from the C# node leaded to the T5 testnet state
diff since 1670095 heigh which causes inability to process new blocks
since 2272533 height (see #3049). This check was added back to the
C# node in https://github.com/neo-project/neo/pull/2849, but it is
planned to be the part of the upcoming 3.6.0 C# node release.

We need to keep our testnet healthy, thus, strict contract script
check will be temporary removed from the node code and is planned
to be added back to be a part of the next 3.6.0-compatible release.

Close #3049.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-07-08 11:49:31 +03:00
Anna Shaleva
f611a793a7
Merge pull request #3052 from nspcc-dev/remove-script-check
core: remove contract script check on deploy/update
2023-07-08 13:40:05 +05:00
Anna Shaleva
68ad542639
Merge pull request #3047 from nspcc-dev/incremental-dump-creation
server: allow to create incremental dumps
2023-07-06 16:15:35 +05:00
Anna Shaleva
48c8ae359f
Merge pull request #3055 from nspcc-dev/dependabot/go_modules/google.golang.org/grpc-1.53.0
build(deps): bump google.golang.org/grpc from 1.48.0 to 1.53.0
2023-07-06 16:14:07 +05:00
dependabot[bot]
ca80cfea2b
build(deps): bump google.golang.org/grpc from 1.48.0 to 1.53.0
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.48.0 to 1.53.0.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.48.0...v1.53.0)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-05 21:28:13 +00:00
Anna Shaleva
6fa4bcdc1d core: remove contract script check on deploy/update
This check is good and was present here since #1729, but it was
accidently removed from the reference implementation (see the
discussion in https://github.com/neo-project/neo/issues/2848). The
removal of this check from the C# node leaded to the T5 testnet state
diff since 1670095 heigh which causes inability to process new blocks
since 2272533 height (see #3049). This check was added back to the
C# node in https://github.com/neo-project/neo/pull/2849, but it is
planned to be the part of the upcoming 3.6.0 C# node release.

We need to keep our testnet healthy, thus, strict contract script
check will be temporary removed from the node code and is planned
to be added back to be a part of the next 3.6.0-compatible release.

Close #3049.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-07-04 14:17:04 +03:00
Anna Shaleva
bfe8867e63 cli: add test for incremental DB dump and restore
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-07-03 13:53:41 +03:00
Roman Khimov
abb58fb7de
Merge pull request #3048 from nspcc-dev/rel-0.101.2
Release 0.101.2
2023-06-29 13:34:06 +03:00
Roman Khimov
91b57745ac
Merge pull request #3046 from nspcc-dev/mainnet-state-fix
interop/contract: fix state rollbacks for nested contexts
2023-06-29 12:24:23 +03:00
Roman Khimov
e993003b46 CHANGELOG: release 0.101.2
Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-06-29 12:20:26 +03:00
Anna Shaleva
3bf8192f98 rpcclient: make Notary Actor follow the request creation doc
All Notary contract witnesses in incomplete transaction (both main
and fallback) may either have invocation scripts pushing dummy signature
on stack or be empty, both ways are OK. Notary actor keeps main tx's
Notary witness empty and keeps fallback tx's Notary witness filled
with dummy signature.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-06-29 12:04:40 +03:00
Anna Shaleva
60e6fe05a7 docs: improve Notary's till value documentation
Close #2986.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-06-29 12:03:51 +03:00
Roman Khimov
70aed34d77 interop/contract: fix state rollbacks for nested contexts
Our wrapping optimization relied on the caller context having a TRY block,
but each context (including internal calls!) has an exception handling stack
of its own, which means that for an invocation stack of

    entry
    A.someMethodFromEntry()   # this one has a TRY
    A.internalMethodViaCALL() # this one doesn't
    B.someMethod()

we get `HasTryBlock() == false` for `A.internalMethodViaCALL()` context, which
leads to missing wrapper and missing rollbacks if B is to THROW. What this
patch does instead is it checks for any context within contract boundaries.

Fixes #3045.

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-06-29 11:58:12 +03:00
Roman Khimov
50c8805034 *: drop legacy addresses from examples
They can't even be used now because they'll fail the conversion.

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-06-29 11:56:26 +03:00
Anna Shaleva
84b00d46aa rpc: emit Null in case of Any parameter with zero-len value
Otherwise it leads to the following error in the TestActor_CallWithNilParam:
```
=== RUN   TestActor_CallWithNilParam
    logger.go:130: 2023-04-03T15:58:27.672+0300	INFO	initial gas supply is not set or wrong, setting default value	{"InitialGASSupply": "52000000"}
    logger.go:130: 2023-04-03T15:58:27.672+0300	INFO	P2PNotaryRequestPayloadPool size is not set or wrong, setting default value	{"P2PNotaryRequestPayloadPoolSize": 1000}
    logger.go:130: 2023-04-03T15:58:27.672+0300	INFO	MaxBlockSize is not set or wrong, setting default value	{"MaxBlockSize": 262144}
    logger.go:130: 2023-04-03T15:58:27.672+0300	INFO	MaxBlockSystemFee is not set or wrong, setting default value	{"MaxBlockSystemFee": 900000000000}
    logger.go:130: 2023-04-03T15:58:27.672+0300	INFO	MaxTransactionsPerBlock is not set or wrong, using default value	{"MaxTransactionsPerBlock": 512}
    logger.go:130: 2023-04-03T15:58:27.672+0300	INFO	MaxValidUntilBlockIncrement is not set or wrong, using default value	{"MaxValidUntilBlockIncrement": 5760}
    logger.go:130: 2023-04-03T15:58:27.675+0300	INFO	no storage version found! creating genesis block
    logger.go:130: 2023-04-03T15:58:27.675+0300	INFO	ExtensiblePoolSize is not set or wrong, using default value	{"ExtensiblePoolSize": 20}
    logger.go:130: 2023-04-03T15:58:27.675+0300	INFO	SessionPoolSize is not set or wrong, setting default value	{"SessionPoolSize": 20}
    logger.go:130: 2023-04-03T15:58:27.675+0300	INFO	MaxWebSocketClients is not set or wrong, setting default value	{"MaxWebSocketClients": 64}
    logger.go:130: 2023-04-03T15:58:27.675+0300	INFO	starting rpc-server	{"endpoint": "localhost:0"}
    logger.go:130: 2023-04-03T15:58:27.677+0300	DEBUG	done processing headers	{"headerIndex": 1, "blockHeight": 0, "took": "436.313µs"}
    logger.go:130: 2023-04-03T15:58:27.679+0300	DEBUG	done processing headers	{"headerIndex": 2, "blockHeight": 1, "took": "272.891µs"}
    logger.go:130: 2023-04-03T15:58:27.680+0300	DEBUG	done processing headers	{"headerIndex": 3, "blockHeight": 2, "took": "276.949µs"}
    logger.go:130: 2023-04-03T15:58:27.681+0300	DEBUG	done processing headers	{"headerIndex": 4, "blockHeight": 3, "took": "286.028µs"}
    logger.go:130: 2023-04-03T15:58:27.681+0300	DEBUG	done processing headers	{"headerIndex": 5, "blockHeight": 4, "took": "268.673µs"}
    logger.go:130: 2023-04-03T15:58:27.681+0300	INFO	bad notification	{"contract": "565cff9508ebc75aadd7fe59f38dac610ab6093c", "event": "Transfer", "error": "parameter 0 type mismatch: Hash160 vs ByteString"}
    logger.go:130: 2023-04-03T15:58:27.682+0300	DEBUG	done processing headers	{"headerIndex": 6, "blockHeight": 5, "took": "380.988µs"}
    logger.go:130: 2023-04-03T15:58:27.683+0300	DEBUG	done processing headers	{"headerIndex": 7, "blockHeight": 6, "took": "273.543µs"}
    logger.go:130: 2023-04-03T15:58:27.683+0300	DEBUG	done processing headers	{"headerIndex": 8, "blockHeight": 7, "took": "275.163µs"}
    logger.go:130: 2023-04-03T15:58:27.684+0300	DEBUG	done processing headers	{"headerIndex": 9, "blockHeight": 8, "took": "259.578µs"}
    logger.go:130: 2023-04-03T15:58:27.685+0300	DEBUG	done processing headers	{"headerIndex": 10, "blockHeight": 9, "took": "266.882µs"}
    logger.go:130: 2023-04-03T15:58:27.686+0300	DEBUG	done processing headers	{"headerIndex": 11, "blockHeight": 10, "took": "295.3µs"}
    logger.go:130: 2023-04-03T15:58:27.687+0300	DEBUG	done processing headers	{"headerIndex": 12, "blockHeight": 11, "took": "295.568µs"}
    logger.go:130: 2023-04-03T15:58:27.688+0300	DEBUG	done processing headers	{"headerIndex": 13, "blockHeight": 12, "took": "258.197µs"}
    logger.go:130: 2023-04-03T15:58:27.689+0300	DEBUG	done processing headers	{"headerIndex": 14, "blockHeight": 13, "took": "261.602µs"}
    logger.go:130: 2023-04-03T15:58:27.689+0300	DEBUG	done processing headers	{"headerIndex": 15, "blockHeight": 14, "took": "268.922µs"}
    logger.go:130: 2023-04-03T15:58:27.690+0300	DEBUG	done processing headers	{"headerIndex": 16, "blockHeight": 15, "took": "276.176µs"}
    logger.go:130: 2023-04-03T15:58:27.691+0300	DEBUG	done processing headers	{"headerIndex": 17, "blockHeight": 16, "took": "256.068µs"}
    logger.go:130: 2023-04-03T15:58:27.692+0300	DEBUG	done processing headers	{"headerIndex": 18, "blockHeight": 17, "took": "262.303µs"}
    logger.go:130: 2023-04-03T15:58:27.692+0300	DEBUG	done processing headers	{"headerIndex": 19, "blockHeight": 18, "took": "265.087µs"}
    logger.go:130: 2023-04-03T15:58:27.693+0300	DEBUG	done processing headers	{"headerIndex": 20, "blockHeight": 19, "took": "260.758µs"}
    logger.go:130: 2023-04-03T15:58:27.694+0300	DEBUG	done processing headers	{"headerIndex": 21, "blockHeight": 20, "took": "263.482µs"}
    logger.go:130: 2023-04-03T15:58:27.694+0300	DEBUG	done processing headers	{"headerIndex": 22, "blockHeight": 21, "took": "327.812µs"}
    logger.go:130: 2023-04-03T15:58:27.696+0300	DEBUG	done processing headers	{"headerIndex": 23, "blockHeight": 22, "took": "284.104µs"}
    logger.go:130: 2023-04-03T15:58:27.697+0300	WARN	contract invocation failed	{"tx": "82279bfe9bada282ca0f8cb8e0bb124b921af36f00c69a518320322c6f4fef60", "block": 23, "error": "at instruction 0 (ABORT): ABORT"}
    logger.go:130: 2023-04-03T15:58:27.697+0300	DEBUG	processing rpc request	{"method": "getversion", "params": "[]"}
    logger.go:130: 2023-04-03T15:58:27.698+0300	DEBUG	processing rpc request	{"method": "invokefunction", "params": "[565cff9508ebc75aadd7fe59f38dac610ab6093c putValue  ]"}
    client_test.go:2562:
        	Error Trace:	/home/anna/Documents/GitProjects/nspcc-dev/neo-go/pkg/services/rpcsrv/client_test.go:2562
        	Error:      	Should be true
        	Test:       	TestActor_CallWithNilParam
        	Messages:   	at instruction 6 (PACK): OPACK: invalid length
    logger.go:130: 2023-04-03T15:58:27.699+0300	INFO	shutting down RPC server	{"endpoint": "127.0.0.1:46005"}
    logger.go:130: 2023-04-03T15:58:27.700+0300	INFO	persisted to disk	{"blocks": 23, "keys": 1236, "headerHeight": 23, "blockHeight": 23, "took": "908.825µs"}
--- FAIL: TestActor_CallWithNilParam (0.03s)

FAIL
```

See also the ref. df534f6b0c/src/Neo/SmartContract/ContractParameter.cs (L141)
and the way how parameters are handled by ref. RPC server:
4b3a76e1b7/src/RpcServer/RpcServer.SmartContract.cs (L202)
and FromJSON implementation:
df534f6b0c/src/Neo/SmartContract/ContractParameter.cs (L70)
2023-06-29 11:51:40 +03:00
Roman Khimov
a30f098f73 server: allow to create incremental dumps
Anything not starting from 0 is incremental by definition.

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-06-29 11:41:33 +03:00
Roman Khimov
20b19d4599 interop/contract: fix state rollbacks for nested contexts
Our wrapping optimization relied on the caller context having a TRY block,
but each context (including internal calls!) has an exception handling stack
of its own, which means that for an invocation stack of

    entry
    A.someMethodFromEntry()   # this one has a TRY
    A.internalMethodViaCALL() # this one doesn't
    B.someMethod()

we get `HasTryBlock() == false` for `A.internalMethodViaCALL()` context, which
leads to missing wrapper and missing rollbacks if B is to THROW. What this
patch does instead is it checks for any context within contract boundaries.

Fixes #3045.

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-06-29 11:35:10 +03:00
Roman Khimov
9185820289
Merge pull request #3042 from nspcc-dev/allow-gt-equality-comparison 2023-06-15 22:38:20 +03:00
Anna Shaleva
31e2076810 native: move BLS12-381-related operations to a separate file
No functional changes, just refactoring.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-06-15 18:58:27 +03:00
Anna Shaleva
ea13fbe94a core: improve errors logging for bls12381-related operations
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-06-15 15:01:10 +03:00
Anna Shaleva
71bcb8bade native: allow to use EQUAL opcode for BLS12-381 points comparison
That's the way how C# node handles equality checks for stackitem.Interop types
for these points. Ref. https://github.com/nspcc-dev/neo-go/issues/3002#issuecomment-1591220501.

Along the way, add GT case for CryptoLib's bls12381Equal method. It should be there since #2940.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-06-15 15:00:27 +03:00
Roman Khimov
a2daad6ba6
Merge pull request #3037 from nspcc-dev/sdk-upd
oracle: update NeoFS SDK to 1.0.0-rc.9
2023-06-06 18:02:08 +03:00
Anna Shaleva
0d470edf21 oracle: make use of ReadCloser returned from NeoFS's getters
Close #3032.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-06-06 17:40:19 +03:00
Anna Shaleva
4b2fc32462 oracle: update NeoFS SDK to 1.0.0-rc.9
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-06-06 11:47:24 +03:00
Roman Khimov
b86975b061
Merge pull request #3036 from nspcc-dev/fix-rpcbinding
rpcbinding: call `scriptFor*` as method
2023-06-06 00:12:15 +03:00
Anna Shaleva
802a2b3879 rpcbinding: call scriptFor* as method
Should be a part of #3035, otherwise generated bindings are failed to
be compiled.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-06-05 18:31:34 +03:00
Roman Khimov
f96ccf2bfe
Merge pull request #3035 from nspcc-dev/fix-rpcbinding
rpcbinding: convert `scriptFor*` from function to method
2023-06-05 18:00:40 +03:00
Anna Shaleva
c7836ed6e7 rpcbinding: convert scriptFor* from function to method
Should be a part of #3012, otherwise generated bindings are failed to
be compiled.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-06-05 17:50:07 +03:00
Roman Khimov
805157b7a0
Merge pull request #3034 from nspcc-dev/update-bolt
go.mod: upgrade bolt to v1.3.7
2023-06-05 16:25:23 +03:00
Roman Khimov
67ce9de181 go.mod: upgrade bolt to v1.3.7
Refs. nspcc-dev/neofs-node#999, it fixes a number of other Windows-related
issues as well.

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-06-05 14:59:08 +03:00
Roman Khimov
a0117042e8
Merge pull request #3012 from nspcc-dev/dynamic-rpc-hash
cli: allow dynamic RPC binding contract hash
2023-06-01 16:16:42 +03:00
Anna Shaleva
f97eaddfd1 cli: allow dynamic RPC binding contract hash
Close #3006 and make a light base for #3007.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-06-01 16:06:28 +03:00
Roman Khimov
50fad8455f
Merge pull request #3031 from nspcc-dev/conflicts-priority
mempool: adjust the rule of conflicting transaction ranking
2023-06-01 13:48:46 +03:00
Anna Shaleva
68b9ff1f17 mempool: adjust the rule of conflicting transaction ranking
Pay for all the conflicts if you'd like to went in. Close #3028.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-06-01 13:33:21 +03:00
Roman Khimov
772e723e8e
Merge pull request #3008 from nspcc-dev/event-gen
Close #2891.
2023-05-31 23:56:51 +03:00
Roman Khimov
9a15d2d781
Merge pull request #3029 from nspcc-dev/drop-legacy-addresses-from-examples
*: drop legacy addresses from examples
2023-05-31 18:36:34 +03:00
Roman Khimov
8beb3f4515 *: drop legacy addresses from examples
They can't even be used now because they'll fail the conversion.

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-05-31 18:32:02 +03:00
Anna Shaleva
9f9cec53bd rpcbinding: provide links to types in comments
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-05-31 15:53:43 +03:00
Anna Shaleva
8ae4a1e957 rpcbinding: adjust comment of FromStackItem template methods
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-05-31 15:53:43 +03:00
Anna Shaleva
2ce1454ef5 cli: improve error message for binding template
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-05-31 15:53:43 +03:00
Anna Shaleva
44dfe8342d compiler: disallow named types redeclaration via contract config
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-05-31 15:53:43 +03:00
Anna Shaleva
865bd6c9cc compiler: compare emitted event params if --guess-eventtypes enabled
In this case emitted event parameters should match from invocation to
invocation. It's an error otherwise (and if the type is not Any).

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-05-31 15:53:43 +03:00
Anna Shaleva
6379bcc15a compiler: properly set extended type name for unnamed structs
After the struct was registered as "unnamed", it has the own unique name.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-05-31 15:53:43 +03:00
Anna Shaleva
0195aae824 cli: add test for --guessed-eventtypes RPC binding generator flag
Currently we have problems with unnamed structs used as a parameter for
notifications, because there's no one-to-one correspondence between
notification parameter and the list of extended types used by the whole
contract. Otherwise eventtypes guessing works OK.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-05-31 15:53:43 +03:00
Anna Shaleva
3e2755e66d smartcontract: add test for user-defined extended event types configuration
config_extended.yml contains an example of user-defined configuration
file with extended event types. User-defined event types are allowed
to be named and complicated, i.e. properly support extended types
notation.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-05-31 15:53:43 +03:00
Anna Shaleva
a0d991a500 rpcbinding: support map[any]any conversion for extended types
Unfortunately, without pre-set user extended types configuration for events
and without --guess-eventtypes flag set we are allowed to rely only on manifest
information about types. Manifest can't give us a lot of information, but we
still need to be able to generate RPC binding. Arrays and structs are correctly
handled by the current code, but maps always rely on the fact that map's value
type is set. It's not true in the described case, so make the maps type convertor
handle this situation in a similar way how arrays are handled.

Without this commit the following panic occurs on attempt to generate RPC binding:
```
    --- FAIL: TestAssistedRPCBindings/testdata/notifications (0.01s)
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
	panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x7f7c0e]

goroutine 190 [running]:
testing.tRunner.func1.2({0x109cb40, 0x1d58760})
	/usr/local/go/src/testing/testing.go:1396 +0x24e
testing.tRunner.func1()
	/usr/local/go/src/testing/testing.go:1399 +0x39f
panic({0x109cb40, 0x1d58760})
	/usr/local/go/src/runtime/panic.go:884 +0x212
github.com/nspcc-dev/neo-go/pkg/smartcontract/rpcbinding.extendedTypeToGo({0x22, {0x0, 0x0}, {0x0, 0x0}, 0x0, 0x0, {0x0, 0x0, 0x0}}, ...)
	/home/anna/Documents/GitProjects/nspcc-dev/neo-go/pkg/smartcontract/rpcbinding/binding.go:515 +0x36e
github.com/nspcc-dev/neo-go/pkg/smartcontract/rpcbinding.scTypeToGo({0xc000206d92?, 0xc000206d80?}, 0x22, 0xc0005d70e0)
	/home/anna/Documents/GitProjects/nspcc-dev/neo-go/pkg/smartcontract/rpcbinding/binding.go:643 +0x138
github.com/nspcc-dev/neo-go/pkg/smartcontract/rpcbinding.scTemplateToRPC({{0xc00049bb07, 0x7}, 0xc0004c89c0, {0x33, 0x22, 0x11, 0x0, 0xff, 0xee, 0xdd, ...}, ...}, ...)
	/home/anna/Documents/GitProjects/nspcc-dev/neo-go/pkg/smartcontract/rpcbinding/binding.go:686 +0xbc4
github.com/nspcc-dev/neo-go/pkg/smartcontract/rpcbinding.Generate({{0xc00049bb07, 0x7}, 0xc0004c89c0, {0x33, 0x22, 0x11, 0x0, 0xff, 0xee, 0xdd, ...}, ...})
	/home/anna/Documents/GitProjects/nspcc-dev/neo-go/pkg/smartcontract/rpcbinding/binding.go:421 +0x387
github.com/nspcc-dev/neo-go/cli/smartcontract.contractGenerateSomething(0xc00043e2c0, 0x137cd00)
	/home/anna/Documents/GitProjects/nspcc-dev/neo-go/cli/smartcontract/generate.go:99 +0x855
github.com/nspcc-dev/neo-go/cli/smartcontract.contractGenerateRPCWrapper(0xc00043e2c0?)
	/home/anna/Documents/GitProjects/nspcc-dev/neo-go/cli/smartcontract/generate.go:60 +0x25
github.com/urfave/cli.HandleAction({0x1048380?, 0x137c660?}, 0x13?)
	/home/anna/go/pkg/mod/github.com/urfave/cli@v1.22.5/app.go:524 +0x50
github.com/urfave/cli.Command.Run({{0x123539d, 0x13}, {0x0, 0x0}, {0x0, 0x0, 0x0}, {0x12577ad, 0x2a}, {0x127ad35, ...}, ...}, ...)
	/home/anna/go/pkg/mod/github.com/urfave/cli@v1.22.5/command.go:173 +0x65b
github.com/urfave/cli.(*App).RunAsSubcommand(0xc0001f4000, 0xc00043e000)
	/home/anna/go/pkg/mod/github.com/urfave/cli@v1.22.5/app.go:405 +0x91b
github.com/urfave/cli.Command.startApp({{0x12281e1, 0x8}, {0x0, 0x0}, {0x0, 0x0, 0x0}, {0x1254d8a, 0x28}, {0x0, ...}, ...}, ...)
	/home/anna/go/pkg/mod/github.com/urfave/cli@v1.22.5/command.go:372 +0x6e7
github.com/urfave/cli.Command.Run({{0x12281e1, 0x8}, {0x0, 0x0}, {0x0, 0x0, 0x0}, {0x1254d8a, 0x28}, {0x0, ...}, ...}, ...)
	/home/anna/go/pkg/mod/github.com/urfave/cli@v1.22.5/command.go:102 +0x825
github.com/urfave/cli.(*App).Run(0xc00024e000, {0xc0004f6420, 0xb, 0xb})
	/home/anna/go/pkg/mod/github.com/urfave/cli@v1.22.5/app.go:277 +0x8a7
github.com/nspcc-dev/neo-go/cli/smartcontract.TestAssistedRPCBindings.func1.1(0x9f8829?)
	/home/anna/Documents/GitProjects/nspcc-dev/neo-go/cli/smartcontract/generate_test.go:395 +0x5fc
testing.tRunner(0xc0006824e0, 0xc0004a3680)
	/usr/local/go/src/testing/testing.go:1446 +0x10b
created by testing.(*T).Run
	/usr/local/go/src/testing/testing.go:1493 +0x35f
```

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-05-31 15:53:43 +03:00
Anna Shaleva
37af2031bb rpcbinding: properly add imports for simple types of event parameters
There are two ways of doing this: first one is to emit all notifications
parameter data into rpcbindings configuration on compile time (event if
the parameter has a simple type), and the second one is to fetch parameter
type from the manifest on rpcbinding file generation if needed (we always
have manifest at this stage, thus it's not a problem to retrieve necessary
information). The latter case is chosen to reduce the bindings configuration
file size.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-05-31 15:53:43 +03:00
Anna Shaleva
19cc6c6369 compiler: store ready-to-use notification names in bindings config
Notification and its parameters may have any UTF8-compatible name
which is inappropriate for bindings configuration and for the resulting
RPC bindings file. This commit stores the prettified version of
notification's name and parameters that are ready to be used in the
resulting RPC binding without any changes.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-05-31 15:53:43 +03:00
Anna Shaleva
41938ffa78 smartcontract: drop standard events before RPC binging generation
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-05-31 15:53:43 +03:00
Anna Shaleva
2c36802e23 binding: fix comment to the extended type field
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-05-31 15:53:43 +03:00
Anna Shaleva
e2580187a1 cli: fetch extended evet types from contract config
The user should specify it via parameter's `extendedtype` field and
via upper-level `namedtypes` field of the contract configuration YAML.

Also, as we have proper event structure source, make the `--guess-eventtype`
compilation option and make event types guess optional.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-05-31 15:53:41 +03:00
Anna Shaleva
194639bb15 compiler: fix typo in the method description
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-05-31 15:52:41 +03:00
Anna Shaleva
044ae477ca smartconract: generate RPC binding wrappers for events
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-05-31 15:52:39 +03:00
Anna Shaleva
ae52b2c2fa rpcbinding: fix binding indentation
New rule for writing blocks of code to our template: new line before
the block starts and new line after the block ends. This rule is the
same as the one we use during manual typing.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-05-30 17:37:06 +03:00
Roman Khimov
871ee18981
Merge pull request #3024 from nspcc-dev/add-mp-test
mempool: add test for concurrent conflicting tx addition
2023-05-26 22:52:29 +03:00
Anna Shaleva
db812f7fa5 mempool: add test for concurrent conflicting tx addition
Ref. https://github.com/neo-project/neo/pull/2818#discussion_r1206658847.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-05-26 20:20:47 +03:00
Anna Shaleva
0f0f7b364f rpcbinding: use typed return err value in etTypeConverter
Otherwise the resulting code can't be compiled.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-05-25 16:41:23 +03:00
Anna Shaleva
8beb9f23c3 smartcontract: add comments to binding config fields
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-05-25 16:41:23 +03:00
Anna Shaleva
36af361c2b smartcontract: add FromStackItem wrapper for RPC bindings
Make it exported and reusable from the user's code.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-05-24 11:27:49 +03:00
Anna Shaleva
b5ec1271d5 .gitignore: do not ignore compiler testdata
cli's testdata folder stores contracts examples and expected compilation
output, thus doesn't need to be ignored.

*.out files are the bindings outputs only, do not ignore them as far.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-05-24 11:27:49 +03:00
Anna Shaleva
7a06cea885 cli: allow to rewrite expected test output
Don't perform it manually every time.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-05-24 11:27:48 +03:00
Roman Khimov
aca12b58c0
Merge pull request #3020 from nspcc-dev/loadnef-enh-2
cli: properly load specified method for `run` VM CLI command
2023-05-19 16:39:41 +03:00
Anna Shaleva
ddfbf7a434 cli: remove code duplication in test
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-05-19 13:26:56 +03:00
Anna Shaleva
2f4fb3a079 cli: fix error description for run VM CLI command
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-05-19 13:26:56 +03:00
Anna Shaleva
b6b80f3abf cli: properly handle run VM CLI command
Properly load the provided method using NEF and hash specified. It allows
to have NEF properly set in the VM context and handle CALLT instruction
correctly.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-05-19 13:26:56 +03:00
Anna Shaleva
35c3518b37 examples: fix owner's verification of Runtime example contract
`update` and `destroy` methods of the contract should check for owner
witness without checking the trigger (and that's the way how Verify
method works for this contract).

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-05-19 13:26:56 +03:00
Roman Khimov
7b86a54fc0
Merge pull request #3016 from nspcc-dev/emit-convertible
vm: allow to emit stackitem.Convertible
2023-05-17 21:06:21 +03:00
Anna Shaleva
fc6029d006 vm: allow to emit uint and uint64 as a part of array
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-05-17 19:29:42 +03:00
Roman Khimov
d463bad96f
Merge pull request #3013 from nspcc-dev/loadnef-enh
cli: autocomplete contract-related filenames for `compile` and `loadnef` commands
2023-05-17 15:05:00 +03:00
Anna Shaleva
aace790651 cli: guess manifest filename from nef for loadnef VM CLI command
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-05-17 13:09:31 +03:00
Anna Shaleva
ed2b59e077 cli: use cosigners separator for VM CLI commands where appropriate
Needed for further VM CLI commands improvement, we'll add another
positional args.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-05-17 13:09:31 +03:00
Anna Shaleva
a2449ae8ae cli: autocomplete output filenames for contract compile cmd
It's enough to specify the input file only to get the standard output:
```
$ neo-go contract compile -i ./1-print/1-print.go
$ neo-go contract compile -i ./1-print/
```

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-05-17 13:09:30 +03:00
Anna Shaleva
3dbb733324 cli: require contract config file for bindings generation
It's an error if config file isn't provided and bindings config needs
to be generated.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-05-17 13:00:39 +03:00
Anna Shaleva
15138b2004 vm: allow to emit convertible
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-05-17 12:47:31 +03:00
Anna Shaleva
8e085d3ca3 vm: allow to make stackitem from *Uint160 and *Uint256
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-05-17 11:16:32 +03:00
Roman Khimov
d493afc941
Merge pull request #3018 from nspcc-dev/upd-dbft
gomod: fetch dBFT update
2023-05-16 16:08:09 +03:00
Anna Shaleva
8599e25fc3 gomod: fetch dBFT update
Send PrepareRequest on timeout only: https://github.com/nspcc-dev/dbft/pull/75.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-05-16 16:03:34 +03:00
Roman Khimov
4afc71ab6d
Merge pull request #3014 from nspcc-dev/node-cfg
cli: allow to provide single node config file

Close #2978.
2023-05-16 14:42:38 +03:00
Anna Shaleva
4be9e4347a cli: allow to provide network-specific node config file
Close #2978.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-05-16 13:23:55 +03:00
Roman Khimov
abf3ef5af7
Merge pull request #3009 from nspcc-dev/new-version
network: add `neogo_version` metric, deprecate `serv_node_version`
2023-05-11 14:38:35 +03:00
Anna Shaleva
649b9ac7b0 network: add neogo_version metric, deprecate serv_node_version
Close #2999.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-05-11 13:48:38 +03:00
Roman Khimov
230f54c38a
Merge pull request #3010 from AnnaShaleva/AS/upload-release-asset
github: automatically attach binaries to the release
2023-05-10 22:32:29 +03:00
Anna Shaleva
778ddfb277 github: automatically attach binaries to the release
Close #3001.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-05-10 19:39:45 +03:00
Roman Khimov
b47a891b9e
Merge pull request #3004 from nspcc-dev/require-error-is
*: use require.ErrorIs instead of require.True(t, error.Is())
2023-05-04 18:14:36 +03:00
Roman Khimov
433275265f *: use require.ErrorIs instead of require.True(t, error.Is())
This is just a much better way to do the same thing. Inspired by
nspcc-dev/neofs-sdk-go#407.

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-05-04 17:03:47 +03:00
Roman Khimov
8e6025fbc8
Merge pull request #3000 from nspcc-dev/conloss-error-for-wsclient
rpcclient: provide some exported error for disconnected WSClient
2023-05-03 16:42:12 +03:00
Roman Khimov
fcaa24f928 rpcclient: provide some exported error for disconnected WSClient
Regular Client doesn't care much about connections, because HTTP client's Do
method can reuse old ones or create additional ones on the fly. So one request
can fail and the next one easily succeed. WSClient is different, it works via
a single connection and if it breaks, it breaks forever for this
client. Callers will get some error on every request afterwards and it'd be
nice for this error to be the same so that API users could detect
disconnection this way too.

Related to nspcc-dev/neofs-node#2325.

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-05-03 16:08:54 +03:00
Roman Khimov
8bd9a7d420
Merge pull request #2995 from nspcc-dev/neofs-sdk-update
NeoFS SDK update
2023-05-02 14:25:31 +03:00
Roman Khimov
cef7ac2510
Merge pull request #2997 from nspcc-dev/fix-Lint
github: use minimum supported go version for Linter job
2023-04-28 12:28:26 +03:00
Roman Khimov
a0aef0e92f
Merge pull request #2996 from nspcc-dev/fix-lint
core: add nolint comment for deprecated error format style
2023-04-28 12:27:10 +03:00
Anna Shaleva
98d29570d3 github: use minimum supported go version for Linter job
It should be this way because we can't provide some features golangci-lint
require us to do due to the need to support not only the latest Go version,
but also two versions below.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-04-28 12:17:08 +03:00
Anna Shaleva
9c0a45c65e core: add nolint comment for deprecated error format style
Should be a part of 67d4d891ef.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-04-28 12:13:21 +03:00
Roman Khimov
0a160ee93b *: use CompareAndSwap instead of CAS for atomics
go.uber.org/atomic deprecated CAS methods in version 1.10 (that introduced
CompareAndSwap), so we need to fix it.

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-04-28 12:07:19 +03:00
Roman Khimov
2567c4c672 oracle: update NeoFS SDK to 1.0.0-rc.8
We were using _very_ old version, so there is a number of changes, including:
 * fix for unlimited reads
 * UTF-8 check for HTTP requests

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-04-27 21:29:59 +03:00
Roman Khimov
dcea3f6107
Merge pull request #2988 from nspcc-dev/client/close-blockers
rpcclient: close WSClient subscriber on overflow
2023-04-26 22:23:49 +03:00
Roman Khimov
1bd22adcb3
Merge pull request #2994 from nspcc-dev/fix-init-cache
core: rework natives cache initialization
2023-04-26 14:54:52 +03:00
Anna Shaleva
67d4d891ef core: prevent direct access to Notary contract if not active
Otherwise it will cause panic, which isn't expected behaviour.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-04-26 14:11:12 +03:00
Anna Shaleva
edb2d46d5b core: initialize natives cache wrt NativeActivations
If the contract was deployed then cache must be initialized after
in-memory data reset. If the contract isn't active yet, then no
cache will be initialized on deploy (i.e. on call to Initialize()
method by native Management).

Close #2984.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-04-26 13:57:45 +03:00
Anna Shaleva
33c971b0e4 core: add InitializeCache method to Contract interface
Make the contracts cache initialization unified. The order of cache
iniitialization is not important and Nottary contract is added to the
bc.contracts.Contracts wrt P2PSigExtensions setting, thus no functional
changes, just refactoring for future applications.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-04-26 12:57:48 +03:00
Roman Khimov
29b3df10b6
Merge pull request #2992 from nspcc-dev/init-metrics-on-start
*: adjust Prometheus metrics initialisation on node start
2023-04-25 16:27:38 +03:00
Anna Shaleva
e2782aef05 *: adjust Prometheus metrics initialisation on node start
Initialize Prometheus metrics on node start where appropriate and review
the usage of the following metrics:
```
anna@kiwi:~/Documents/GitProjects/nspcc-dev/neo-go$ find | grep prometheus.go
./pkg/network/prometheus.go
./pkg/core/stateroot/prometheus.go
./pkg/core/prometheus.go
./pkg/services/rpcsrv/prometheus.go
./pkg/services/metrics/prometheus.go
```

Close #2970.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-04-25 16:25:18 +03:00
Roman Khimov
bbdfdc3099
Merge pull request #2991 from nspcc-dev/revert-mgmt-ids
Revert "native: make management compatible with C# node 3.5.0"
2023-04-25 12:42:01 +03:00
Roman Khimov
b1f9ba193b
Merge pull request #2990 from nspcc-dev/adj-notary-doc
docs: improve Notary's `till` value documentation
2023-04-25 12:40:33 +03:00
Anna Shaleva
3f2e0e5441 Revert "native: make management compatible with C# node 3.5.0"
This reverts commit 236e633ee4.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-04-25 12:22:11 +03:00
Anna Shaleva
6e8328415c docs: improve Notary's till value documentation
Close #2986.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-04-25 12:03:01 +03:00
Anna Shaleva
dab13a4e2d rpcclient: close WSClient subscriber on overflow
Close #2894.

It should be noted that the subscriber's channel is being removed from the
list of receivers and closed, but it is still *in the list of subscribers*
and no unsubscription is performed by WSClient. Which means that RPC server
keeps sending notifications to WSClient and WSClient keeps dropping them
(because there's no receiver for this subscription and it's OK, WSClient
can handle this and this behaviour is documented). However, it's still the
caller's duty to call Unsubscribe() method for this subscription.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-04-25 11:42:17 +03:00
Anna Shaleva
4a49bf5de4 rpcclient: introduce WSOptions for WSClient
Make a separate structure for WSClient configuration.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-04-25 11:42:15 +03:00
Roman Khimov
f0a5430b5b
Merge pull request #2985 from nspcc-dev/bugfix/interop-unused-import
interop/util: Drop unused import
2023-04-22 17:37:17 +03:00
Leonard Lyubich
d90626d556 interop/util: Drop unused import
Remove no longer used import left after corresponding code removal in
4671fbb3be.

Signed-off-by: Leonard Lyubich <leonard@morphbits.io>
2023-04-22 16:36:49 +04:00
Roman Khimov
6bcdf32c31
Merge pull request #2981 from nspcc-dev/fix-ntr-actor
docs: adjust Notary request submission documentation
2023-04-20 16:29:56 +03:00
Roman Khimov
a8f05d9833
Merge pull request #2983 from nspcc-dev/upd-interops
*: update interop deps after #2892
2023-04-20 16:18:36 +03:00
Anna Shaleva
dd8218f87a *: update interop deps after #2892
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-04-20 16:11:57 +03:00
Roman Khimov
c50ab95164
Merge pull request #2892 from ZhangTao1596/optimize-vote-reward
Optimize vote reward data, see also neo-project/neo#2841.
2023-04-20 14:26:58 +03:00
ZhangTao1596
fb7fce0775 native: optimize vote reward data (fix #2844)
Signed-off-by: ZhangTao1596 <zhangtao@ngd.neo.org>
2023-04-20 17:41:14 +08:00
Roman Khimov
7b109586ca
Merge pull request #2980 from nspcc-dev/close-notification-chans-on-wsclient-disconnect
Close notification channels on wsclient disconnect
2023-04-19 18:11:36 +03:00
Anna Shaleva
77836ea1d0 rpcclient: make Notary Actor follow the request creation doc
All Notary contract witnesses in incomplete transaction (both main
and fallback) may either have invocation scripts pushing dummy signature
on stack or be empty, both ways are OK. Notary actor keeps main tx's
Notary witness empty and keeps fallback tx's Notary witness filled
with dummy signature.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-04-19 18:05:25 +03:00
Roman Khimov
6eaa76520f rpcclient: close subscriber channels on wsReader exit
The reader is about to exit and it will close legacy c.Notifications, but it
will leave subscription channels at the same time. This is wrong since these
channels will no longer receive any new events, game over.

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-04-19 16:25:43 +03:00
Roman Khimov
45b353781f rpcclient: correctly handle request channel closure
wsReader() closes c.done first and then goes over the list of
c.respChannels. Technically this means that any of the two can be taken in
this select.

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2023-04-18 19:36:27 +03:00
Roman Khimov
7bc9b6e323
Merge pull request #2979 from nspcc-dev/fix-typo
docs: fix typo
2023-04-18 19:11:04 +03:00
Anna Shaleva
ef925b2c0b docs: fix typo
Remove unnecessary word left after documentation refactoring.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-04-18 18:59:46 +03:00
Roman Khimov
a4cc6da766
Merge pull request #2966 from nspcc-dev/bugfix/2896-rpc-shutdown-deadlock
rpc: Fix deadlock produced during server shutdown
2023-04-17 10:36:30 +03:00
Leonard Lyubich
e29c33e449 cli/node: Fix deadlock produced by instant RPC service start
If `StartWhenSynchronized` is unset in config, `node` command runs RPC
service instantly. Previously there was a ground for deadlock. Command
started RPC server synchronously. According to server implementation, it
sends all internal failures to the parameterized error channel. Deadlock
occured because main routine didn't scan the channel.

Run `rpcsrv.Server.Start` in a separate go-routine in `startServer`.
This prevents potential deadlock caused by writing into unread channel.

Fixes #2896.

Signed-off-by: Leonard Lyubich <leonard@morphbits.io>
2023-04-17 10:42:50 +04:00
Leonard Lyubich
e126bcc462 services/rpcsrv: Wait for subscription process to complete when stopped
Previously RPC server shutdown procedure listened to the execution
channel and stopped at the first element that arrived in the queue. This
could lead to the following problems:
 * stopper could steal the execution result from subscriber
 * stopper didn't wait for other subscription actions to complete

Add dedicated channel to `Server` for subscription routine. Close the
channel on `handleSubEvents` return and wait for signal in `Shutdown`.

Signed-off-by: Leonard Lyubich <leonard@morphbits.io>
2023-04-17 10:42:50 +04:00
Leonard Lyubich
a113940f0b services/rpcsrv: Fix potential shutdown deadlock of RPC server
Previously RPC server could never be shut down completely due to
some start precondition failure (in particular, inability to serve HTTP
on any configured endpoint). The problem was caused by next facts:
 * start method ran subscription routine after HTTP init succeeded only
 * stop method blocked waiting for the subscription routine to return

Run `handleSubEvents` routine on fresh `Start` unconditionally. With
this change, `Shutdown` method won't produce deadlock since
`handleSubEvents` closes wait channel.

Refs #2896.

Signed-off-by: Leonard Lyubich <leonard@morphbits.io>
2023-04-17 10:42:50 +04:00
Leonard Lyubich
649877d8f3 services/rpcsrv: Test Server shutdown with failed precondition
There is an existing problem with RPC server shutdown freeze after start
failure due to some init actions (at least HTTP listen) described in
#2896.

Add dedicated unit test which checks that `Shutdown` returns within 5s
after `Start` method encounters internal problems.

Signed-off-by: Leonard Lyubich <leonard@morphbits.io>
2023-04-17 10:42:49 +04:00
Roman Khimov
e0abe2b858
Merge pull request #2969 from nspcc-dev/mp-metrics
Split notarypool and mempool metrics. Also, do not use metrics for temporary pools
created during block/transaction verification.

Close #2950.
2023-04-14 15:43:37 +03:00
Roman Khimov
b9f95a820c
Merge pull request #2972 from nspcc-dev/dynamic-services
core: improve documentation of SetOracle/SetNotary
2023-04-13 20:59:52 +03:00
Anna Shaleva
3a71aafc43 core: distinguish notarypool/mempool metrics
Move them to the core/network packages, close #2950. The name of
mempool's unsorted transactions metrics has been changed along the
way to match the core's metrics naming convention.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-04-13 18:40:19 +03:00
Anna Shaleva
7bcc62d99c *: fix Prometheus metrics comment formatting
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-04-13 18:36:08 +03:00
Anna Shaleva
49cea72e41 core: improve documentation to SetOracle/SetNotary
I've carefully checked the way how new service can be added to the
Blockchain instance or to be removed from it. Current implemention
of SetNotary and SetOracle methods doesn't contain dangerous code,
and native contracts have atomic values everywhere where service
is stored.

Current implementation of Notary, Oracle and StateRoot services'
reload/disabling/enabling on SIGUSR1 is safe and doesn't require
any adjustment.

This commit closes #2944, it's not a bug in the code, it's just
stale documentation.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-04-13 18:29:58 +03:00
Roman Khimov
a875409055
Merge pull request #2968 from nspcc-dev/bad-cfg-panic
config: do not allow negative validators/committee count
2023-04-13 14:31:07 +03:00
Anna Shaleva
a74454aaca config: do not allow negative validators count
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-04-13 13:43:14 +03:00
Anna Shaleva
0c049f620f config: do not allow zero numbers for validators/committee history
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-04-13 13:42:41 +03:00
Anna Shaleva
8149d33fef config: use uint32 for validators/committee members count
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-04-13 13:42:40 +03:00
Roman Khimov
8f9d101eab
Merge pull request #2967 from nspcc-dev/rpcsrv-err
network: do not use error channel to start network srv
2023-04-13 13:27:48 +03:00
Anna Shaleva
55ab38ed81 network: do not use error channel to start network srv
It's obsolete thing, we have looger and it perfectly suits our needs.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-04-13 13:21:34 +03:00
Roman Khimov
37f7c9d9a7
Merge pull request #2965 from nspcc-dev/cli-ops
cli: extend `util` with `ops` command
2023-04-12 17:29:29 +03:00
Anna Shaleva
541da7e83b cli: add util ops command
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-04-12 17:12:18 +03:00
Roman Khimov
fdec8ea3f7
Merge pull request #2952 from nspcc-dev/find-backwards
core: add `Backwards` option to System.Storage.Find

Port neo-project/neo#2819.
2023-04-12 17:09:30 +03:00
Anna Shaleva
1962dd956c *: update interop deps
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-04-12 16:47:08 +03:00
Anna Shaleva
d5bea0ad4c core: add Backwards option for storage iterators
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-04-12 16:45:38 +03:00
Roman Khimov
4f827de5cd
Merge pull request #2819 from nspcc-dev/optimize-state-reset
core: some state reset oprimizations
2023-04-11 19:11:10 +03:00
Anna Shaleva
400620a9fb core: avoid squashing of data from different state reset stages
`cache` persisting operation is concurrent with the storage modifications
made by further state reset stages. We can't allow situation when data
from the next stage are leaking into the previous stage. State reset stages
must be atomic in turms of DB persisting, thus, use another `upperCache`
MemCached store to keep them apart.

Here are the results of mainnet's BoltDB reset from 1.1M to 6K:

This patch:
```
anna@kiwi:~/Documents/GitProjects/nspcc-dev/neo-go$ ./bin/neo-go db reset -m --debug --height 600000
2023-04-11T16:15:25.783+0300	INFO	MaxBlockSize is not set or wrong, setting default value	{"MaxBlockSize": 262144}
2023-04-11T16:15:25.783+0300	INFO	MaxBlockSystemFee is not set or wrong, setting default value	{"MaxBlockSystemFee": 900000000000}
2023-04-11T16:15:25.783+0300	INFO	MaxTransactionsPerBlock is not set or wrong, using default value	{"MaxTransactionsPerBlock": 512}
2023-04-11T16:15:25.783+0300	INFO	MaxValidUntilBlockIncrement is not set or wrong, using default value	{"MaxValidUntilBlockIncrement": 5760}
2023-04-11T16:15:25.787+0300	INFO	restoring blockchain	{"version": "0.2.8"}
2023-04-11T16:15:25.906+0300	INFO	initializing state reset	{"target height": 600000}
2023-04-11T16:15:25.906+0300	DEBUG	trying to reset blocks, transactions and AERs
2023-04-11T16:15:57.031+0300	INFO	intermediate batch of removed blocks, transactions and AERs is collected	{"batch": 1, "took": "31.125057214s"}
2023-04-11T16:16:12.644+0300	DEBUG	intermediate batch of removed blocks, transactions and AERs is persisted	{"batch": 1, "took": "15.613156971s", "keys": 321895}
2023-04-11T16:16:13.895+0300	INFO	intermediate batch of removed blocks, transactions and AERs is collected	{"batch": 2, "took": "16.663444208s"}
2023-04-11T16:16:19.784+0300	INFO	last batch of removed blocks, transactions and AERs is collected	{"batch": 3, "took": "5.760308543s"}
2023-04-11T16:16:19.784+0300	INFO	blocks, transactions ans AERs are reset	{"took": "53.878632911s"}
2023-04-11T16:16:22.870+0300	DEBUG	intermediate batch of removed blocks, transactions and AERs is persisted	{"batch": 2, "took": "8.974838893s", "keys": 334823}
2023-04-11T16:16:22.870+0300	DEBUG	trying to reset contract storage items
2023-04-11T16:16:27.272+0300	DEBUG	last batch of removed blocks, transactions and AERs is persisted	{"batch": 3, "took": "7.487357441s", "keys": 208913}
2023-04-11T16:17:23.678+0300	INFO	intermediate batch of contract storage items and IDs is collected	{"batch": 1, "took": "1m0.80711106s"}
2023-04-11T16:18:00.769+0300	INFO	intermediate batch of contract storage items and IDs is collected	{"batch": 2, "took": "36.967660061s"}
2023-04-11T16:18:20.478+0300	DEBUG	intermediate batch of contract storage items is persisted	{"batch": 1, "took": "56.796257788s", "keys": 200000}
2023-04-11T16:18:54.115+0300	INFO	intermediate batch of contract storage items and IDs is collected	{"batch": 3, "took": "33.637412437s"}
2023-04-11T16:19:18.844+0300	DEBUG	intermediate batch of contract storage items is persisted	{"batch": 2, "took": "1m18.0737668s", "keys": 200000}
2023-04-11T16:19:27.650+0300	INFO	last batch of contract storage items is collected	{"batch": 4, "took": "8.806264019s"}
2023-04-11T16:19:27.650+0300	INFO	contract storage items are reset	{"took": "3m4.780232077s", "keys": 656944}
2023-04-11T16:20:15.660+0300	DEBUG	intermediate batch of contract storage items is persisted	{"batch": 3, "took": "1m21.544386403s", "keys": 200000}
2023-04-11T16:20:15.660+0300	DEBUG	trying to reset headers information
2023-04-11T16:20:16.385+0300	INFO	headers information is reset	{"took": "725.174932ms"}
2023-04-11T16:20:19.586+0300	DEBUG	last batch of contract storage items and IDs is persisted	{"batch": 4, "took": "51.936278608s", "keys": 56945}
2023-04-11T16:20:19.587+0300	DEBUG	trying to reset state root information and NEP transfers
2023-04-11T16:20:35.845+0300	INFO	state root information and NEP transfers are reset	{"took": "16.25852114s"}
2023-04-11T16:21:10.000+0300	DEBUG	headers information is persisted	{"took": "53.613638429s", "keys": 528438}
2023-04-11T16:21:10.003+0300	DEBUG	trying to remove stale storage items
2023-04-11T16:21:18.108+0300	INFO	stale storage items are reset	{"took": "8.105140658s", "keys": 1350176}
2023-04-11T16:21:18.108+0300	DEBUG	trying to remove state reset point
2023-04-11T16:21:18.108+0300	INFO	state reset point is removed	{"took": "8.554µs"}
2023-04-11T16:21:20.151+0300	DEBUG	state root information and NEP transfers are persisted	{"took": "44.305707049s", "keys": 602578}
2023-04-11T16:21:20.212+0300	INFO	state reset point information is persisted	{"took": "2.103764633s", "keys": 2}
2023-04-11T16:21:20.213+0300	INFO	reset finished successfully	{"took": "5m54.306861367s"}
```

The previous commit:
```
anna@kiwi:~/Documents/GitProjects/nspcc-dev/neo-go$ ./bin/neo-go db reset -m --debug --height 600000
2023-04-11T16:24:04.256+0300	INFO	MaxBlockSize is not set or wrong, setting default value	{"MaxBlockSize": 262144}
2023-04-11T16:24:04.256+0300	INFO	MaxBlockSystemFee is not set or wrong, setting default value	{"MaxBlockSystemFee": 900000000000}
2023-04-11T16:24:04.256+0300	INFO	MaxTransactionsPerBlock is not set or wrong, using default value	{"MaxTransactionsPerBlock": 512}
2023-04-11T16:24:04.256+0300	INFO	MaxValidUntilBlockIncrement is not set or wrong, using default value	{"MaxValidUntilBlockIncrement": 5760}
2023-04-11T16:24:04.261+0300	INFO	restoring blockchain	{"version": "0.2.8"}
2023-04-11T16:24:04.368+0300	INFO	initializing state reset	{"target height": 600000}
2023-04-11T16:24:04.368+0300	DEBUG	trying to reset blocks, transactions and AERs
2023-04-11T16:24:30.363+0300	INFO	intermediate batch of removed blocks, transactions and AERs is collected	{"batch": 1, "took": "25.995261037s"}
2023-04-11T16:24:44.947+0300	DEBUG	intermediate batch of removed blocks, transactions and AERs is persisted	{"batch": 1, "took": "14.584447338s", "keys": 321897}
2023-04-11T16:24:45.791+0300	INFO	intermediate batch of removed blocks, transactions and AERs is collected	{"batch": 2, "took": "15.428492824s"}
2023-04-11T16:24:51.252+0300	INFO	last batch of removed blocks, transactions and AERs is collected	{"batch": 3, "took": "5.460662766s"}
2023-04-11T16:24:51.252+0300	INFO	blocks, transactions ans AERs are reset	{"took": "46.884558096s"}
2023-04-11T16:24:55.399+0300	DEBUG	intermediate batch of removed blocks, transactions and AERs is persisted	{"batch": 2, "took": "9.607820004s", "keys": 334821}
2023-04-11T16:24:55.399+0300	DEBUG	trying to reset contract storage items
2023-04-11T16:24:59.981+0300	DEBUG	last batch of removed blocks, transactions and AERs is persisted	{"batch": 3, "took": "8.728713255s", "keys": 208913}
2023-04-11T16:25:50.827+0300	INFO	intermediate batch of contract storage items and IDs is collected	{"batch": 1, "took": "55.426411416s"}
2023-04-11T16:26:28.734+0300	INFO	intermediate batch of contract storage items and IDs is collected	{"batch": 2, "took": "37.902647706s"}
2023-04-11T16:26:53.960+0300	DEBUG	intermediate batch of contract storage items is persisted	{"batch": 1, "took": "1m3.129453265s", "keys": 200001}
2023-04-11T16:27:27.645+0300	INFO	intermediate batch of contract storage items and IDs is collected	{"batch": 3, "took": "33.685283662s"}
2023-04-11T16:27:52.173+0300	DEBUG	intermediate batch of contract storage items is persisted	{"batch": 2, "took": "1m23.438465575s", "keys": 199999}
2023-04-11T16:28:00.995+0300	INFO	last batch of contract storage items is collected	{"batch": 4, "took": "8.821990443s"}
2023-04-11T16:28:00.995+0300	INFO	contract storage items are reset	{"took": "3m5.595950958s", "keys": 656944}
2023-04-11T16:28:49.164+0300	DEBUG	intermediate batch of contract storage items is persisted	{"batch": 3, "took": "1m21.518344712s", "keys": 200000}
2023-04-11T16:28:49.164+0300	DEBUG	trying to reset headers information
2023-04-11T16:28:49.936+0300	INFO	headers information is reset	{"took": "772.36435ms"}
2023-04-11T16:28:53.122+0300	DEBUG	last batch of contract storage items and IDs is persisted	{"batch": 4, "took": "52.126928092s", "keys": 56945}
2023-04-11T16:28:53.122+0300	DEBUG	trying to reset state root information and NEP transfers
2023-04-11T16:29:09.332+0300	INFO	state root information and NEP transfers are reset	{"took": "16.20921699s"}
2023-04-11T16:29:46.264+0300	DEBUG	headers information is persisted	{"took": "56.326715249s", "keys": 528438}
2023-04-11T16:29:46.267+0300	DEBUG	trying to remove stale storage items
2023-04-11T16:29:53.986+0300	INFO	stale storage items are reset	{"took": "7.718950145s", "keys": 1350176}
2023-04-11T16:29:53.986+0300	DEBUG	trying to remove state reset point
2023-04-11T16:29:53.986+0300	INFO	state reset point is removed	{"took": "6.013µs"}
2023-04-11T16:29:55.899+0300	DEBUG	state root information and NEP transfers are persisted	{"took": "46.567302762s", "keys": 602578}
2023-04-11T16:29:55.929+0300	INFO	state reset point information is persisted	{"took": "1.942392208s", "keys": 2}
2023-04-11T16:29:55.929+0300	INFO	reset finished successfully	{"took": "5m51.561573137s"}
```

Master:
```
anna@kiwi:~/Documents/GitProjects/nspcc-dev/neo-go$ ./bin/neo-go db reset -m --debug --height 600000
2023-04-11T16:34:12.410+0300	INFO	MaxBlockSize is not set or wrong, setting default value	{"MaxBlockSize": 262144}
2023-04-11T16:34:12.410+0300	INFO	MaxBlockSystemFee is not set or wrong, setting default value	{"MaxBlockSystemFee": 900000000000}
2023-04-11T16:34:12.410+0300	INFO	MaxTransactionsPerBlock is not set or wrong, using default value	{"MaxTransactionsPerBlock": 512}
2023-04-11T16:34:12.410+0300	INFO	MaxValidUntilBlockIncrement is not set or wrong, using default value	{"MaxValidUntilBlockIncrement": 5760}
2023-04-11T16:34:12.413+0300	INFO	restoring blockchain	{"version": "0.2.8"}
2023-04-11T16:34:12.495+0300	INFO	initialize state reset	{"target height": 600000}
2023-04-11T16:34:12.513+0300	INFO	trying to reset blocks, transactions and AERs
2023-04-11T16:35:03.582+0300	INFO	intermediate batch of removed blocks, transactions and AERs is persisted	{"batches persisted": 1, "took": "51.087226195s", "keys": 321895}
2023-04-11T16:35:31.302+0300	INFO	intermediate batch of removed blocks, transactions and AERs is persisted	{"batches persisted": 2, "took": "27.719871393s", "keys": 334823}
2023-04-11T16:35:41.309+0300	INFO	last batch of removed blocks, transactions and AERs is persisted	{"batches persisted": 3, "took": "10.007017388s", "keys": 208913}
2023-04-11T16:35:41.309+0300	INFO	blocks, transactions ans AERs are reset	{"took": "1m28.814245057s", "overall persisted keys": 865631}
2023-04-11T16:35:41.309+0300	INFO	trying to reset contract storage items
2023-04-11T16:37:38.315+0300	INFO	intermediate batch of contract storage items and IDs is persisted	{"batch": 1, "took": "1m57.00650253s", "keys": 200000}
2023-04-11T16:39:29.704+0300	INFO	intermediate batch of contract storage items and IDs is persisted	{"batch": 2, "took": "1m51.385224725s", "keys": 200000}
2023-04-11T16:41:14.991+0300	INFO	intermediate batch of contract storage items and IDs is persisted	{"batch": 3, "took": "1m45.287483794s", "keys": 200000}
2023-04-11T16:41:31.667+0300	INFO	last batch of contract storage items and IDs is persisted	{"batch": 4, "took": "16.675347478s", "keys": 56945}
2023-04-11T16:41:31.667+0300	INFO	contract storage items and IDs are reset	{"took": "5m50.357775401s", "keys": 656944}
2023-04-11T16:41:31.667+0300	INFO	trying to reset headers information
2023-04-11T16:42:16.779+0300	INFO	headers information is reset	{"took": "45.111354262s", "keys": 528438}
2023-04-11T16:42:16.784+0300	INFO	trying to reset state root information and NEP transfers
2023-04-11T16:42:35.778+0300	INFO	state root information and NEP transfers are reset	{"took": "18.99373117s", "keys": 602578}
2023-04-11T16:42:35.781+0300	INFO	trying to remove stale storage items
2023-04-11T16:42:43.884+0300	INFO	stale storage items are reset	{"took": "8.103929306s", "keys": 1350176}
2023-04-11T16:42:43.885+0300	INFO	trying to remove state reset point
2023-04-11T16:42:43.926+0300	INFO	stale reset point is removed	{"took": "41.858883ms", "keys": 2}
2023-04-11T16:42:43.932+0300	INFO	reset finished successfully	{"took": "8m31.437493325s"}
```

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-04-11 18:49:09 +03:00
Anna Shaleva
cb0f786b28 core: move batch persist to a separate routine
Resetting mainnet from 2512046 blocks (full logs are attached
to https://github.com/nspcc-dev/neo-go/pull/2813#issuecomment-1324115555).

--------
LevelDB |
------------------------
  to  |  old   |   new  |
------|--------|--------|
  1   | 5m11s  | 4m50s  |
------|--------|--------|
  1M  | 10m40s | 9m40s  |
------|--------|--------|
 2.5M | 17m38s | 17m36s |
------------------------

--------
BoltDB  |
------------------------
  to  |  old   |   new  |
------|--------|--------|
  1   |  8m3s  | 5m51s  |
------|--------|--------|
  1M  | 20m30s | 13m2s  |
------|--------|--------|
 2.5M | 31m26s | 18m47s |
------------------------

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-04-11 16:58:11 +03:00
Anna Shaleva
e3747b1d57 core: change log level of reset stages notifications
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-04-11 16:58:03 +03:00
Anna Shaleva
41caeed5c0 core: fix state reset log message
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2023-04-11 16:57:56 +03:00
Roman Khimov
5322a3535b
Merge pull request #2940 from nspcc-dev/groth16
core: add BLS12_381 interops
2023-04-10 10:20:17 +03:00
Roman Khimov
601c26bbe6
Merge pull request #2914 from ixje/fix-getpeers
neorpc: change peer port to int type (fixes #2910)
2023-04-07 08:46:40 +03:00
Erik van den Brink
f479b2bc57 neorpc: change peer port to int type (fixes nspcc-dev#2910) 2023-04-06 18:33:09 +02:00
Roman Khimov
ce7658ef82
Merge pull request #2711 from aprasolova/dco-check
[nspcc-dev/nspcc-infra#840]: Add DCO check
2023-04-06 11:11:09 +03:00
Roman Khimov
a80d7bef80
Merge pull request #2889 from nspcc-dev/ask-nep2-label
cli: ask for NEP2 account label if not provided
2023-04-06 10:42:52 +03:00
Roman Khimov
e2cf5b868a
Merge pull request #2941 from nspcc-dev/drop-deprecated-0.102.0
Drop some deprecated things in 0.102.0
2023-04-06 10:42:26 +03:00
Roman Khimov
7e92b4a694
Merge pull request #2959 from nspcc-dev/fix-nil-param
Fixes Any type processing server-side.
2023-04-05 19:46:22 +03:00
Anna Shaleva
01ac2d9f31 rpc: emit Null in case of Any parameter with zero-len value
Otherwise it leads to the following error in the TestActor_CallWithNilParam:
```
=== RUN   TestActor_CallWithNilParam
    logger.go:130: 2023-04-03T15:58:27.672+0300	INFO	initial gas supply is not set or wrong, setting default value	{"InitialGASSupply": "52000000"}
    logger.go:130: 2023-04-03T15:58:27.672+0300	INFO	P2PNotaryRequestPayloadPool size is not set or wrong, setting default value	{"P2PNotaryRequestPayloadPoolSize": 1000}
    logger.go:130: 2023-04-03T15:58:27.672+0300	INFO	MaxBlockSize is not set or wrong, setting default value	{"MaxBlockSize": 262144}
    logger.go:130: 2023-04-03T15:58:27.672+0300	INFO	MaxBlockSystemFee is not set or wrong, setting default value	{"MaxBlockSystemFee": 900000000000}
    logger.go:130: 2023-04-03T15:58:27.672+0300	INFO	MaxTransactionsPerBlock is not set or wrong, using default value	{"MaxTransactionsPerBlock": 512}
    logger.go:130: 2023-04-03T15:58:27.672+0300	INFO	MaxValidUntilBlockIncrement is not set or wrong, using default value	{"MaxValidUntilBlockIncrement": 5760}
    logger.go:130: 2023-04-03T15:58:27.675+0300	INFO	no storage version found! creating genesis block
    logger.go:130: 2023-04-03T15:58:27.675+0300	INFO	ExtensiblePoolSize is not set or wrong, using default value	{"ExtensiblePoolSize": 20}
    logger.go:130: 2023-04-03T15:58:27.675+0300	INFO	SessionPoolSize is not set or wrong, setting default value	{"SessionPoolSize": 20}
    logger.go:130: 2023-04-03T15:58:27.675+0300	INFO	MaxWebSocketClients is not set or wrong, setting default value	{"MaxWebSocketClients": 64}
    logger.go:130: 2023-04-03T15:58:27.675+0300	INFO	starting rpc-server	{"endpoint": "localhost:0"}
    logger.go:130: 2023-04-03T15:58:27.677+0300	DEBUG	done processing headers	{"headerIndex": 1, "blockHeight": 0, "took": "436.313µs"}
    logger.go:130: 2023-04-03T15:58:27.679+0300	DEBUG	done processing headers	{"headerIndex": 2, "blockHeight": 1, "took": "272.891µs"}
    logger.go:130: 2023-04-03T15:58:27.680+0300	DEBUG	done processing headers	{"headerIndex": 3, "blockHeight": 2, "took": "276.949µs"}
    logger.go:130: 2023-04-03T15:58:27.681+0300	DEBUG	done processing headers	{"headerIndex": 4, "blockHeight": 3, "took": "286.028µs"}
    logger.go:130: 2023-04-03T15:58:27.681+0300	DEBUG	done processing headers	{"headerIndex": 5, "blockHeight": 4, "took": "268.673µs"}
    logger.go:130: 2023-04-03T15:58:27.681+0300	INFO	bad notification	{"contract": "565cff9508ebc75aadd7fe59f38dac610ab6093c", "event": "Transfer", "error": "parameter 0 type mismatch: Hash160 vs ByteString"}
    logger.go:130: 2023-04-03T15:58:27.682+0300	DEBUG	done processing headers	{"headerIndex": 6, "blockHeight": 5, "took": "380.988µs"}
    logger.go:130: 2023-04-03T15:58:27.683+0300	DEBUG	done processing headers	{"headerIndex": 7, "blockHeight": 6, "took": "273.543µs"}
    logger.go:130: 2023-04-03T15:58:27.683+0300	DEBUG	done processing headers	{"headerIndex": 8, "blockHeight": 7, "took": "275.163µs"}
    logger.go:130: 2023-04-03T15:58:27.684+0300	DEBUG	done processing headers	{"headerIndex": 9, "blockHeight": 8, "took": "259.578µs"}
    logger.go:130: 2023-04-03T15:58:27.685+0300	DEBUG	done processing headers	{"headerIndex": 10, "blockHeight": 9, "took": "266.882µs"}
    logger.go:130: 2023-04-03T15:58:27.686+0300	DEBUG	done processing headers	{"headerIndex": 11, "blockHeight": 10, "took": "295.3µs"}
    logger.go:130: 2023-04-03T15:58:27.687+0300	DEBUG	done processing headers	{"headerIndex": 12, "blockHeight": 11, "took": "295.568µs"}
    logger.go:130: 2023-04-03T15:58:27.688+0300	DEBUG	done processing headers	{"headerIndex": 13, "blockHeight": 12, "took": "258.197µs"}
    logger.go:130: 2023-04-03T15:58:27.689+0300	DEBUG	done processing headers	{"headerIndex": 14, "blockHeight": 13, "took": "261.602µs"}
    logger.go:130: 2023-04-03T15:58:27.689+0300	DEBUG	done processing headers	{"headerIndex": 15, "blockHeight": 14, "took": "268.922µs"}
    logger.go:130: 2023-04-03T15:58:27.690+0300	DEBUG	done processing headers	{"headerIndex": 16, "blockHeight": 15, "took": "276.176µs"}
    logger.go:130: 2023-04-03T15:58:27.691+0300	DEBUG	done processing headers	{"headerIndex": 17, "blockHeight": 16, "took": "256.068µs"}
    logger.go:130: 2023-04-03T15:58:27.692+0300	DEBUG	done processing headers	{"headerIndex": 18, "blockHeight": 17, "took": "262.303µs"}
    logger.go:130: 2023-04-03T15:58:27.692+0300	DEBUG	done processing headers	{"headerIndex": 19, "blockHeight": 18, "took": "265.087µs"}
    logger.go:130: 2023-04-03T15:58:27.693+0300	DEBUG	done processing headers	{"headerIndex": 20, "blockHeight": 19, "took": "260.758µs"}
    logger.go:130: 2023-04-03T15:58:27.694+0300	DEBUG	done processing headers	{"headerIndex": 21, "blockHeight": 20, "took": "263.482µs"}
    logger.go:130: 2023-04-03T15:58:27.694+0300	DEBUG	done processing headers	{"headerIndex": 22, "blockHeight": 21, "took": "327.812µs"}
    logger.go:130: 2023-04-03T15:58:27.696+0300	DEBUG	done processing headers	{"headerIndex": 23, "blockHeight": 22, "took": "284.104µs"}
    logger.go:130: 2023-04-03T15:58:27.697+0300	WARN	contract invocation failed	{"tx": "82279bfe9bada282ca0f8cb8e0bb124b921af36f00c69a518320322c6f4fef60", "block": 23, "error": "at instruction 0 (ABORT): ABORT"}
    logger.go:130: 2023-04-03T15:58:27.697+0300	DEBUG	processing rpc request	{"method": "getversion", "params": "[]"}
    logger.go:130: 2023-04-03T15:58:27.698+0300	DEBUG	processing rpc request	{"method": "invokefunction", "params": "[565cff9508ebc75aadd7fe59f38dac610ab6093c putValue  ]"}
    client_test.go:2562:
        	Error Trace:	/home/anna/Documents/GitProjects/nspcc-dev/neo-go/pkg/services/rpcsrv/client_test.go:2562
        	Error:      	Should be true
        	Test:       	TestActor_CallWithNilParam
        	Messages:   	at instruction 6 (PACK): OPACK: invalid length
    logger.go:130: 2023-04-03T15:58:27.699+0300	INFO	shutting down RPC server	{"endpoint": "127.0.0.1:46005"}
    logger.go:130: 2023-04-03T15:58:27.700+0300	INFO	persisted to disk	{"blocks": 23, "keys": 1236, "headerHeight": 23, "blockHeight": 23, "took": "908.825µs"}
--- FAIL: TestActor_CallWithNilParam (0.03s)

FAIL
```

See also the ref. df534f6b0c/src/Neo/SmartContract/ContractParameter.cs (L141)
and the way how parameters are handled by ref. RPC server:
4b3a76e1b7/src/RpcServer/RpcServer.SmartContract.cs (L202)
and FromJSON implementation:
df534f6b0c/src/Neo/SmartContract/ContractParameter.cs (L70)
2023-04-05 16:28:30 +03:00
Anna Shaleva
66b82d0a7d *: update interop dependency 2023-04-05 15:54:36 +03:00
Anna Shaleva
68cb07999b scripts: adjust dependency updator
We don't need these `--compat` flags anymore since 1.16 support is dropped.
2023-04-05 15:49:17 +03:00
Anna Shaleva
69102a6aa3 interop: add groth16 interop API 2023-04-05 15:37:50 +03:00
Anna Shaleva
115ec4d8dd core: add BLS12_381 interops 2023-04-05 15:37:50 +03:00
Roman Khimov
c053f1a4af
Merge pull request #2957 from nspcc-dev/rm-go-17
*: drop go 1.17 support
2023-04-04 15:25:14 +03:00
Anna Shaleva
4ab6d1e31a go.mod: fetch dbft update
Minimum required go version of dbft has been changed from 1.17 to 1.18.
2023-04-04 13:22:43 +03:00
Anna Shaleva
6b21ad9922 *: replace interface{} with any keyword
Everywhere including examples, external interop APIs, bindings generators
code and in other valuable places. A couple of `interface{}` usages are
intentionally left in the CHANGELOG.md, documentation and tests.
2023-04-04 13:22:42 +03:00
Anna Shaleva
83545b8451 network: fix Address test failing on Windows/macOS with go 1.20
See the trace:
```
2023-03-31T07:46:21.1886260Z === RUN   TestEncodeDecodeAddress
2023-03-31T07:46:21.1886420Z     address_test.go:30:
2023-03-31T07:46:21.1887000Z         	Error Trace:	/Users/runner/work/neo-go/neo-go/pkg/network/payload/address_test.go:30
2023-03-31T07:46:21.1887180Z         	Error:      	Not equal:
2023-03-31T07:46:21.1887580Z         	            	expected: net.IP{0x7f, 0x0, 0x0, 0x1}
2023-03-31T07:46:21.1888290Z         	            	actual  : net.IP{0x7f, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}
2023-03-31T07:46:21.1888450Z
2023-03-31T07:46:21.1888640Z         	            	Diff:
2023-03-31T07:46:21.1888960Z         	            	--- Expected
2023-03-31T07:46:21.1889180Z         	            	+++ Actual
2023-03-31T07:46:21.1889510Z         	            	@@ -1,3 +1,3 @@
2023-03-31T07:46:21.1889870Z         	            	-(net.IP) (len=4) {
2023-03-31T07:46:21.1890530Z         	            	- 00000000  7f 00 00 01                                       |....|
2023-03-31T07:46:21.1891140Z         	            	+(net.IP) (len=16) {
2023-03-31T07:46:21.1891780Z         	            	+ 00000000  7f 00 00 01 00 00 00 00  00 00 00 00 00 00 00 00  |................|
2023-03-31T07:46:21.1891970Z         	            	 }
2023-03-31T07:46:21.1892510Z         	Test:       	TestEncodeDecodeAddress
2023-03-31T07:46:21.1892770Z --- FAIL: TestEncodeDecodeAddress (0.00s)
```

I'm still not sure what's the original root of this problem, there's nothing
about resolving scheme changes in https://go.dev/doc/go1.20, but it didn't
happen earlier and it works as expected in Ubuntu.
2023-04-03 09:43:14 +03:00
Anna Shaleva
ec002f31df Dockerfile: build docker images on go 1.20 2023-03-31 10:35:38 +03:00
Anna Shaleva
3f6a88c239 .github: bump setup-go version from v3 to v4 2023-03-31 10:20:57 +03:00
Anna Shaleva
110356857d *: drop go 1.17 support for github actions and tests
And support go 1.20 for github workflows.
2023-03-31 10:20:56 +03:00
Anna Shaleva
856edcca39 *: bump min supported go version from 1.17 to 1.18 2023-03-31 09:59:24 +03:00
Roman Khimov
1633ae32df
Merge pull request #2954 from ZhangTao1596/fix-format
Fix lint jobs issues
2023-03-31 09:49:39 +03:00
ZhangTao1596
d36df15878 ci: fix lint issues (fix #2948) 2023-03-29 11:19:23 +08:00
Roman Khimov
9224878196
Merge pull request #2947 from ZhangTao1596/add-missing-rpc
rpcclient: add GetProof and VerifyProof
2023-03-28 09:02:45 +03:00
ZhangTao1596
f21e618be5 rpcclient: add GetProof and VerifyProof (fix #2942) 2023-03-23 17:03:22 +08:00
Roman Khimov
de7bff9cea
Merge pull request #2945 from nspcc-dev/adj-minpeers-doc
docs: add minor note to `MinPeers` config section
2023-03-22 18:03:18 +03:00
Anna Shaleva
f672a97d1b docs: add minor note to MinPeers config section 2023-03-22 16:22:02 +03:00
Roman Khimov
6e27883c10 rpcsrv: remove deprecated RPC counters 2023-03-18 10:52:24 +03:00
Roman Khimov
4671fbb3be interop: drop deprecated util.FromAddress
It still was used in a number of places, surprisingly.
2023-03-18 10:44:12 +03:00
Roman Khimov
7306beca4d
Merge pull request #2939 from nspcc-dev/release-0.101.1
Release 0.101.1
2023-03-17 12:48:24 +03:00
Roman Khimov
e3d8772f57 ROADMAP: correct schedule
We'll keep old RPC APIs in 0.102.0, they're still used in the wild.
2023-03-17 12:22:35 +03:00
Roman Khimov
5a34e819e9 CHANGELOG: release 0.101.1 2023-03-17 12:22:35 +03:00
Roman Khimov
fa392aa5ff CHANGELOG: fix 0.101.0 release date 2023-03-17 12:22:35 +03:00
Roman Khimov
0d5613cfcb
Merge pull request #2938 from nspcc-dev/failing-actor-test
actor: don't close already closed channel, fix #2932
2023-03-17 11:46:31 +03:00
Roman Khimov
da7eafd4c7
Merge pull request #2937 from nspcc-dev/copy-wsclient-filters
Copy wsclient filters
2023-03-17 10:49:13 +03:00
Roman Khimov
e197f3faef rpcclient: copy subscription params, fix #2890
Clients can change things and we better be safe here.
2023-03-17 10:33:30 +03:00
Roman Khimov
e84ea0207d actor: don't close already closed channel, fix #2932
Waiter should close its channels, but WSClient can also do that and it can do
that in a drain loop as well.
2023-03-17 09:57:41 +03:00
Roman Khimov
1a4da8c462 neorpc: add Copy to filters for easy deep copying 2023-03-16 23:43:00 +03:00
Roman Khimov
8acff056a9
Merge pull request #2936 from nspcc-dev/minor-doc-fixes-for-0.101.1
Minor doc fixes for 0.101.1
2023-03-16 21:37:06 +03:00
Roman Khimov
74623e64bc rpcclient: improve wsclient doc, fix #2895 2023-03-16 21:27:35 +03:00
Roman Khimov
88c1e65b5b
Merge pull request #2935 from nspcc-dev/dbft-upd
gomod: fetch dbft fix of committed nodes counting
2023-03-16 09:25:31 +03:00
Anna Shaleva
c2c2a49732 gomod: fetch dbft fix of committed nodes counting 2023-03-16 09:09:17 +03:00
Roman Khimov
44e84a5943 stateroot: fix spelling and enhance FindStates doc, fix #2925 2023-03-15 22:55:19 +03:00
Roman Khimov
a8aa29727b
Merge pull request #2930 from nspcc-dev/addblock-lock
consensus: prevent AddBlock lock caused by consensus service
2023-03-15 17:59:48 +03:00
Anna Shaleva
c7566c2a01 consensus: perform batched chain's block sync
If there are several blocks from chain, then initialize consensus only for the
latest one.
2023-03-15 17:45:56 +03:00
Anna Shaleva
0b352349eb consensus: adjust TestService_NextConsensus after dBFT upgrade 2023-03-15 17:37:47 +03:00
Anna Shaleva
04de604afd gomod: fetch dBFT fix from https://github.com/roman-khimov/dbft/pull/4
And other dBFT updates happened since nspcc-dev was blocked.
2023-03-15 17:37:47 +03:00
Anna Shaleva
0cbef58b3c consensus: enqueue newly created blocks
Do not add them directly to chain, it will be done by the block queue
manager. Close https://github.com/nspcc-dev/neo-go/issues/2923. However,
this commit is not valid without
https://github.com/roman-khimov/dbft/pull/4.
It's the neo-go's duty to initialize consensus after subsequent block
addition; the dBFT itself must wait for the neo-go to complete the block
addition and notify the dBFT, so that it can initialize at 0-th view to
collect the next block.
2023-03-15 17:37:47 +03:00
Anna Shaleva
04d0b45ceb network: move blockqueue to a separate package 2023-03-15 17:37:47 +03:00
Anna Shaleva
91a77c25a2 network: refactor blockqueuer interface
Remove unused argument.
2023-03-15 17:37:47 +03:00
Anna Shaleva
e57e74692f consensus: drain block notification channel after each message
Make blockchain lock less possible.
2023-03-15 17:37:47 +03:00
Anna Shaleva
ea46943815 services: use buffered channels for block subscription
Add a tiny buffer where possible to avoid Blockchain's blocking
on new block addition.
2023-03-15 17:37:47 +03:00
Roman Khimov
97c7023020
Merge pull request #2933 from nspcc-dev/fix-linter
*: add nolint comments to multiple errors wrapping
2023-03-15 16:57:43 +03:00
Anna Shaleva
5f6c01336c *: add nolint comments to multiple errors wrapping
To be enabled after go 1.20 support is added.
2023-03-15 16:38:01 +03:00
Roman Khimov
1db90e538f
Merge pull request #2929 from nspcc-dev/dependabot/go_modules/examples/nft-nd-nns/golang.org/x/crypto-0.1.0
build(deps): bump golang.org/x/crypto from 0.0.0-20210711020723-a769d52b0f97 to 0.1.0 in /examples/nft-nd-nns
2023-03-14 18:24:15 +03:00
dependabot[bot]
8329f29cde
build(deps): bump golang.org/x/crypto in /examples/nft-nd-nns
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.0.0-20210711020723-a769d52b0f97 to 0.1.0.
- [Release notes](https://github.com/golang/crypto/releases)
- [Commits](https://github.com/golang/crypto/commits/v0.1.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-13 22:30:12 +00:00
Roman Khimov
31ee21a83a
Merge pull request #2924 from nspcc-dev/drain-queues-on-disconnect
network: drain send queues on peer disconnection
2023-02-21 17:12:23 +03:00
Roman Khimov
4f708c037d network: drain send queues on peer disconnection
Fix potential memory leak with a lot of connected clients that keep requesting
things from node and then disconnect.
2023-02-21 16:19:06 +03:00
Roman Khimov
510bc91804
Merge pull request #2922 from nspcc-dev/fix-typo
network: fix grammar typo in the error message
2023-02-20 12:45:44 +03:00
Anna Shaleva
da757fa387 network: fix grammar typo in the error message 2023-02-20 11:08:07 +03:00
Roman Khimov
475d9de2d5
Merge pull request #2916 from nspcc-dev/not-so-local-client
Not so local RPC client
2023-02-20 10:38:30 +03:00
Roman Khimov
d54418bad0
Merge pull request #2920 from nspcc-dev/fix-seek-doc
core: adjust the documentation of SeekRange's Prefix field
2023-02-18 23:18:39 +03:00
Roman Khimov
08c42c1d00
Merge pull request #2919 from nspcc-dev/dependabot/go_modules/golang.org/x/net-0.7.0
build(deps): bump golang.org/x/net from 0.3.0 to 0.7.0
2023-02-18 23:17:40 +03:00
Roman Khimov
b945f22b13
Merge pull request #2918 from nspcc-dev/any-wrapper-fix
rpcbinding: fix wrappers for Any type, fix #2898
2023-02-18 23:15:15 +03:00
Anna Shaleva
09186127da core: adjust the documentation of SeekRange's Prefix field
It is used in different context (seeking through the storage or
through the contract storage), and sometimes empty prefix is not
supported.
2023-02-18 21:06:30 +03:00
dependabot[bot]
23e3801856
build(deps): bump golang.org/x/net from 0.3.0 to 0.7.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.3.0 to 0.7.0.
- [Release notes](https://github.com/golang/net/releases)
- [Commits](https://github.com/golang/net/compare/v0.3.0...v0.7.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-18 03:33:19 +00:00
Roman Khimov
b1e7f40226 rpcbinding: fix wrappers for Any type, fix #2898 2023-02-18 00:06:45 +03:00
Roman Khimov
1bdd62702c
Merge pull request #2917 from nspcc-dev/fix-link
docs: fix the link to RPC Client doc
2023-02-17 10:57:13 +03:00
Roman Khimov
bd4a9f3f22 rpcsrv: drop ws from subscriber
Subscribers can be local as well and no one uses this field anyway.
2023-02-16 23:49:58 +03:00
Roman Khimov
6f7fed344b rpcclient: add Internal client for direct RPC server calls
It has a special `requestF` and a special initialization function, but other
than that it's an absolutely regular WSClient. Can be used to call, can be
used to subscribe. Fixes #2909.
2023-02-16 23:49:58 +03:00
Roman Khimov
a55a01d456 rpcsrv: provide RegisterLocal for local clients
This allows to call RPC server more effectively in the same process (bypassing
TCP/HTTP). Refs. #2909.
2023-02-16 23:49:58 +03:00
Anna Shaleva
5892534211 docs: fix the link to RPC Client doc 2023-02-16 17:37:46 +03:00
Roman Khimov
e496084bee params: add FromAny function
Creating RPC server parameters from any data can be useful. Refs. #2909.
2023-02-15 16:46:59 +03:00
Roman Khimov
9f9c6f5dc0
Merge pull request #2915 from ixje/feat-endpoint
rpcclient: expose endpoint (fixes #2912)
2023-02-15 11:43:32 +03:00
Erik van den Brink
3bdb3a87b8 rpcclient: expose endpoint (fixes #2912) 2023-02-15 08:29:44 +01:00
Roman Khimov
1d6e48ee78
Merge pull request #2904 from nspcc-dev/export-deserialization-context
vm: export deserialization context
2023-02-08 13:04:56 +03:00
Anna Shaleva
25ed5fcd60 vm: allow custom limit duing Map\Array\Struct deserialization 2023-02-08 10:58:55 +03:00
Anna Shaleva
15fa65d30f vm: export stackitem's deserContext 2023-02-08 10:58:54 +03:00
Roman Khimov
bd26b9db83
Merge pull request #2893 from nspcc-dev/fix-wsc-sub-doc
rpcclient: adjust new subscriptions API doc
2023-01-30 15:10:57 +03:00
Anna Shaleva
51a28fac8d rpcclient: adjust new subscriptions API doc
Add a warning about consequences of unproper notifications reading.
Ref. https://github.com/morphbits/neofs-cdn-edge-manager/pull/88#discussion_r1088007680.
2023-01-30 14:36:11 +03:00
Anna Shaleva
7e709313d3 cli: ask for NEP2 account label if not provided
If NEP2 account label is not provided as a flag for import-related
CLI commands then ask it in the interactive mode.

This change breaks the compatibility with the old behaviour (add
the unnamed account if the name wasn't specified).
2023-01-26 08:50:06 +03:00
Roman Khimov
b56dff2b1e
Merge pull request #2887 from nspcc-dev/wallet-import
cli: refactor wallet import related commands
2023-01-26 08:49:18 +03:00
Anna Shaleva
b77c2846ee cli: allow to request NEP2 password from input
In case if wrong password was provided via config file we allow the
user to provide the password manually.
2023-01-25 14:20:59 +03:00
Anna Shaleva
1ef39a6e30 cli: properly handle --name and password-related wallet commands
Fetch account's name from the CLI argument and do not ask for the
user's input if provided, close #2882. Fetch password from config
if provided, close #2883.
2023-01-25 14:20:56 +03:00
Roman Khimov
1262a27065
Merge pull request #2884 from nspcc-dev/refactor/rpcsrv-error-channel
services/rpcsrv: Strengthen `Server` error channel's type
2023-01-23 19:04:58 +07:00
Leonard Lyubich
d09158161e services/rpcsrv: Strengthen Server error channel's type
According to docs, `Server` uses provided error channel only to write
encountered error to it. In this case, there is no need to accept rw
channel to create `Server` instance. Strengthening the type to
write-only will allow the caller to ensure control of reading errors
from the provided channel.

The change is backward compatible since any `chan` is `chan<-`.

Signed-off-by: Leonard Lyubich <ctulhurider@gmail.com>
2023-01-23 10:33:46 +03:00
Roman Khimov
0c43b1ddca
Merge pull request #2880 from nspcc-dev/docs/actor
rpcclient/actor: Document `RPCActor.CalculateNetworkFee` method
2023-01-18 01:46:11 +07:00
Leonard Lyubich
cbdc6ba469 rpcclient/actor: Document RPCActor.CalculateNetworkFee method
`Actor.MakeUnsignedUncheckedRun` method imposes restriction to
`CalculateNetworkFee` method's implementations: `Hash` or `Size` methods
must not be called on the pointer to the given transaction.

Add docs to adjust described requirement.

Signed-off-by: Leonard Lyubich <ctulhurider@gmail.com>
2023-01-17 21:28:20 +03:00
Roman Khimov
8c8c8d1bb1
Merge pull request #2879 from nspcc-dev/adj-doc
*: adjust subscription-related doc
2023-01-18 00:44:19 +07:00
Anna Shaleva
28927228f0 *: adjust subscription-related doc
Add a warning about received events modification where applicable.
2023-01-17 17:11:19 +03:00
Roman Khimov
22fc8d1adc
Merge pull request #2877 from nspcc-dev/chlog-101
CHANGELOG: release 0.101.0
2023-01-13 17:22:31 +07:00
Roman Khimov
ee3257df6e CHANGELOG: release 0.101.0 2023-01-13 13:13:34 +03:00
Roman Khimov
c46b7a9e34
Merge pull request #2876 from nspcc-dev/improve-consensus-doc
Improve consensus doc and docker configs
2023-01-13 16:51:50 +07:00
Roman Khimov
e2bd76713b config: improve 4 CN docker configs, three nodes are enough 2023-01-13 11:35:29 +03:00
Roman Khimov
1e35387c04 docs: fix the MinPeers consensus requirements
It won't work with 1 for a single node and 3 for 4 CN scenario doesn't allow
the network to start with just three nodes (although technically 3 out of 4 is
sufficient to operate). See #2874.
2023-01-13 11:33:19 +03:00
Roman Khimov
efbef4254a
Merge pull request #2873 from nspcc-dev/drop-circleci
Drop CircleCI support
2023-01-12 12:49:48 +07:00
Roman Khimov
40ef567527
Merge pull request #2872 from nspcc-dev/fix-missing-exception-in-applog
state: always marshal applog exception into JSON, fix #2869
2023-01-12 12:49:00 +07:00
Roman Khimov
babc44bfb3
Merge pull request #2871 from nspcc-dev/fix-shadowed-infinite-loop
Fix shadowed infinite loop
2023-01-12 12:48:39 +07:00
Roman Khimov
4862bb9aae drop CircleCI support
It stopped running our tests/builds, but we don't care, Github works well.
2023-01-11 17:43:07 +03:00
Roman Khimov
9a6fa84f70
Merge pull request #2867 from nspcc-dev/store-magic-in-db
core: store magic in the DB version, fix #2847
2023-01-11 20:42:00 +07:00
Roman Khimov
4e23695441
Merge pull request #2866 from nspcc-dev/findstates-ret-nothing
Fix findstates response difference
2023-01-11 20:41:10 +07:00
Roman Khimov
e037249d37
Merge pull request #2865 from nspcc-dev/fix-applog-values
Fix applog values
2023-01-11 20:40:44 +07:00
Roman Khimov
817f64f9fe state: always marshal applog exception into JSON, fix #2869
Fortunately, this is backwards-compatible in any direction. See
98b5e2b353 also.
2023-01-11 16:36:41 +03:00
Roman Khimov
8305389852 compiler: don't panic, return error for strange range loops
See #2870.
2023-01-11 16:21:40 +03:00
Roman Khimov
92acc71c80 compiler: create new locals for range loops when needed, fix #2855 2023-01-11 15:49:10 +03:00
Roman Khimov
1c4c783c3a core: store magic in the DB version, fix #2847 2023-01-11 12:05:05 +03:00
Roman Khimov
e780037cb4 rpcsrv: use valid stateroot hash in failing tests
Just in case.
2023-01-11 11:23:47 +03:00
Roman Khimov
9718602ce3 rpcsrv: return empty set from findstates when there is no data
Fix #2863.
2023-01-11 11:21:58 +03:00
Roman Khimov
584675ec23 state: optimize NEP17Transfer struct
We have both from and to here, so technically we can either drop the neg/neg
trick from the processTokenTransfer() or drop one field from the structure
(the other side is a part of the key). Drop the field since this can make the
DB a bit more compact. Change Amount to be a pointer along the way since
that's the "native" thing for big.Int, we've used non-pointer field
specifically to avoid Neg/Neg problems, but it looks like this is not
necessary.

This structure is only used by the RPC server and I doubt anyone uses it via
the *Blockchain.
2023-01-10 22:51:45 +03:00
Roman Khimov
dfd4f6978f bigint: don't reallocate big.Int in ToBytes(), fix #2864
In some cases n.Add() can reuse the []Word buffer and n.Sub() reallocate it
away. If that happens, we're out of luck with 0.99.0+ versions (since
3945e81857). I'm not sure why it does that, bit
width doesn't change in most of the cases and even if it does, we still have
enough of it in cap() to hold the old Abs() value (when we have a negative
value we in fact decreate its Abs() first and increase it back
afterwards). Still, that's what we have.

So when we have processTokenTransfer() doing Neg/Neg in-place its value is not
affected, but the original []Word bits that are reused by amount value are
(they're shared initially, Amount: *amount).

name                   old time/op    new time/op    delta
ToPreallocatedBytes-8    65.8ns ± 2%    45.6ns ± 2%  -30.73%  (p=0.008 n=5+5)

name                   old alloc/op   new alloc/op   delta
ToPreallocatedBytes-8     0.00B          0.00B          ~     (all equal)

name                   old allocs/op  new allocs/op  delta
ToPreallocatedBytes-8      0.00           0.00          ~     (all equal)
2023-01-10 22:51:45 +03:00
Roman Khimov
5ad1fcd321
Merge pull request #2852 from nspcc-dev/required-hash
cli: mark required flags of `generate-*` command
2023-01-10 02:23:28 +07:00
Roman Khimov
06d29bc0e9
Merge pull request #2860 from nspcc-dev/fix-vm-cli-doc
docs: adjust outdated VM CLI doc
2023-01-09 18:21:25 +07:00
Anna Shaleva
0314cf0430 docs: adjust outdated VM CLI doc 2023-01-09 13:58:27 +03:00
Roman Khimov
4e6ce9c3e6
Merge pull request #2846 from nspcc-dev/fix-getblockbyindex-req
network: do not allow to request invalid block count
2022-12-29 04:04:01 +07:00
Roman Khimov
00848cdc83
Merge pull request #2854 from nspcc-dev/update-deps
go.mod: Update dependencies
2022-12-29 04:02:43 +07:00
f8fed21285 go.mod: Update dependencies
Signed-off-by: Evgeniy Stratonikov <e.stratonikov@yadro.com>
2022-12-28 22:00:16 +03:00
Roman Khimov
c64dc9ab02
Merge pull request #2853 from nspcc-dev/release-0.100.1
Release 0.100.1
2022-12-28 19:36:38 +07:00
Anna Shaleva
9b364aa7ee network: do not allow to request invalid block count
The problem is in peer disconnection due to invalid GetBlockByIndex
payload (the logs are from some patched neo-go version):
```
дек 15 16:02:39 glagoli neo-go[928530]: 2022-12-15T16:02:39.490Z        INFO        new peer connected        {"addr": "10.78.69.115:50846", "peerCount": 3}
дек 15 16:02:39 glagoli neo-go[928530]: 2022-12-15T16:02:39.490Z        WARN        peer disconnected        {"addr": "10.78.69.115:50846", "error": "invalid block count", "peerCount": 2}
дек 15 16:02:39 glagoli neo-go[928530]: 2022-12-15T16:02:39.490Z        INFO        started protocol        {"addr": "10.78.69.115:50846", "userAgent": "/NEO-GO:1.0.0/", "startHeight": 0, "id": 1339571820}
дек 15 16:02:39 glagoli neo-go[928530]: 2022-12-15T16:02:39.491Z        INFO        new peer connected        {"addr": "10.78.69.115:50856", "peerCount": 3}
дек 15 16:02:39 glagoli neo-go[928530]: 2022-12-15T16:02:39.492Z        WARN        peer disconnected        {"addr": "10.78.69.115:50856", "error": "invalid block count", "peerCount": 2}
дек 15 16:02:39 glagoli neo-go[928530]: 2022-12-15T16:02:39.492Z        INFO        started protocol        {"addr": "10.78.69.115:50856", "userAgent": "/NEO-GO:1.0.0/", "startHeight": 0, "id": 1339571820}
дек 15 16:02:39 glagoli neo-go[928530]: 2022-12-15T16:02:39.492Z        INFO        new peer connected        {"addr": "10.78.69.115:50858", "peerCount": 3}
дек 15 16:02:39 glagoli neo-go[928530]: 2022-12-15T16:02:39.493Z        INFO        started protocol        {"addr": "10.78.69.115:50858", "userAgent": "/NEO-GO:1.0.0/", "startHeight": 0, "id": 1339571820}
дек 15 16:02:39 glagoli neo-go[928530]: 2022-12-15T16:02:39.493Z        WARN        peer disconnected        {"addr": "10.78.69.115:50858", "error": "invalid block count", "peerCount": 2}
дек 15 16:02:39 glagoli neo-go[928530]: 2022-12-15T16:02:39.494Z        INFO        new peer connected        {"addr": "10.78.69.115:50874", "peerCount": 3}
дек 15 16:02:39 glagoli neo-go[928530]: 2022-12-15T16:02:39.494Z        INFO        started protocol        {"addr": "10.78.69.115:50874", "userAgent": "/NEO-GO:1.0.0/", "startHeight": 0, "id": 1339571820}
дек 15 16:02:39 glagoli neo-go[928530]: 2022-12-15T16:02:39.494Z        WARN        peer disconnected        {"addr": "10.78.69.115:50874", "error": "invalid block count", "peerCount": 2}
```

GetBlockByIndex payload can't be decoded, and the only possible cause
is zero (or <-1, but it's probably not the case) block count requested.

Error is improved as far.
2022-12-28 13:04:56 +03:00
Anna Shaleva
c0a453a53b network: adjust requestBlocs logic
If the lastQueued block index is the same as the one we'd like to
request in payload, then we need to increment the payload's count.
2022-12-28 12:50:30 +03:00
Anna Shaleva
7bab81f196 cli: adjust flags description for smartcontract generate-* 2022-12-28 12:18:09 +03:00
AnnaShaleva
2334166423 cli: mark required flags of generate-* command 2022-12-28 12:15:56 +03:00
Roman Khimov
b7d2fd2cb1 CHANGELOG: release 0.100.1 2022-12-28 12:08:31 +03:00
Roman Khimov
5f2e25de11
Merge pull request #2851 from nspcc-dev/fuzz-tests
*: add fuzz tests for `bigint.FromBytes` and `vm.ParseMultisigContract`
2022-12-28 16:05:55 +07:00
Evgeniy Stratonikov
db977ce38d vm: add fuzz test for ParseMultiSigContract
Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2022-12-28 11:50:15 +03:00
Evgeniy Stratonikov
affe1ecb4f encoding: add bigint fuzz test
Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2022-12-28 11:50:13 +03:00
Roman Khimov
d9af122be5
Merge pull request #2850 from mike-petrov/feature/2289-add_logo_for_dark_theme
Add logo for dark theme
2022-12-21 22:41:07 +07:00
Mikhail Petrov
be9a231c98 [#2289] Add logo for dark theme
Signed-off-by: Mikhail Petrov <mike@nspcc.ru>
2022-12-21 18:08:30 +03:00
Roman Khimov
5fb9e1353d
Merge pull request #2848 from nspcc-dev/tune-management-callflags-for-aspidochelone
Tune management callflags for aspidochelone
2022-12-19 13:41:07 +07:00
Roman Khimov
3339824fe9 native: simplify code somewhat, get Metadata() only once 2022-12-16 23:48:04 +03:00
Roman Khimov
5d478b5514 native: add old management deploy/update call flags to Aspidochelone
d5a9af5860 is incompatible with the NeoFS
mainnet sidechain, so we add the old logic to the pre-Aspidochelone
behaviour. Changing flags at newMethodAndPrice() is a bit less convenient
unfortunately because this will affect interop validity checks, so let's have
this kludge here.
2022-12-16 23:45:47 +03:00
Roman Khimov
3e714a348e
Merge pull request #2842 from nspcc-dev/stringer
*: use zap.Stringer instead of zap.String where it can be used
2022-12-13 22:12:18 +07:00
Roman Khimov
e79dec15f9 *: use zap.Stringer instead of zap.String where it can be used
It's a bit more efficient in case we're not logging the message (mostly for
debug), makes the code somewhat simpler as well.
2022-12-13 12:44:54 +03:00
Roman Khimov
515cbf6a80
Merge pull request #2841 from nspcc-dev/more-robust-divisible-check
rpcsrv: use more robust NEP-11 divisibility check
2022-12-12 14:05:24 +07:00
Roman Khimov
c1afaf8ea8 rpcsrv: use more robust NEP-11 divisibility check
It's more heavyweight at the same time, but should be OK for the
purpose. Inspired by https://github.com/neo-project/neo-modules/issues/754#issuecomment-1345176986
2022-12-10 11:45:43 +03:00
Roman Khimov
628f04769b
Merge pull request #2840 from nspcc-dev/release-0.100.0
CHANGELOG: release 0.100.0
2022-12-08 15:56:54 +07:00
Roman Khimov
31b863591f CHANGELOG: release 0.100.0 2022-12-08 11:51:40 +03:00
Roman Khimov
bbb35f52e3
Merge pull request #2839 from nspcc-dev/port-string
config: use string type for Port
2022-12-08 03:29:37 +07:00
Roman Khimov
3ce1fc41a4 config: fix the default P2P ping settings
54c2aa8582 broke them, they're in seconds and we
have a 90s timeout.
2022-12-07 21:29:40 +03:00
Roman Khimov
0d65071abc config: use string type for Port
6b4dd5703e made it to be a uint16 which was
somewhat important for RPC, but now it's irrelevant and the fact that it was a
string in some cases may lead to errors like these:

  failed to unmarshal config YAML: yaml: unmarshal errors:
    line 48: cannot unmarshal !!str `20011` into uint16
    line 52: cannot unmarshal !!str `40001` into uint16

So for maximum backwards compatibility we better have string here and
eventually it'll be deleted anyway.
2022-12-07 21:21:05 +03:00
Roman Khimov
81d755736c
Merge pull request #2833 from nspcc-dev/proto-to-app-config-2
Move some settings from Protocol to Application config
2022-12-07 21:58:42 +07:00
Roman Khimov
4e7cee4e12 config: replace VerifyBlocks with SkipBlockVerification
It directly affects node security and the default here MUST BE the safe choice
which is to do the verification. Otherwise it's just dangerous, absent any
VerifyBlocks configuration we'll get an insecure node. This option is not
supposed to be frequently used and it doesn't affect the ability to process
blocks, so breaking compatibility (in a safe manner) should be OK here.
2022-12-07 17:35:56 +03:00
Roman Khimov
d92f35664b config: move Ledger config from Protocol to Application 2022-12-07 17:35:56 +03:00
Roman Khimov
7589733017 config: add a special Blockchain type to configure Blockchain
And include some node-specific configurations there with backwards
compatibility. Note that in the future we'll remove Ledger's
fields from the ProtocolConfiguration and it'll be possible to access them in
Blockchain directly (not via .Ledger).

The other option tried was using two configuration types separately, but that
incurs more changes to the codebase, single structure that behaves almost like
the old one is better for backwards compatibility.

Fixes #2676.
2022-12-07 17:35:53 +03:00
Roman Khimov
199a6de737 Merge pull request #2838 from nspcc-dev/neo-misuse
*: fix Neo and NeoGo misuses
2022-12-07 21:34:27 +07:00
Anna Shaleva
2d6db6f5c4 vm: adjust stale comment 2022-12-07 17:30:02 +03:00
Anna Shaleva
82221b0ca7 *: fix Neo and NeoGo misuses 2022-12-07 17:29:09 +03:00
Roman Khimov
b1f1405f42
Merge pull request #2836 from nspcc-dev/fix-subs
rpcclient: fix filtered naive subscriptions receiver
2022-12-07 21:17:07 +07:00
Anna Shaleva
2c0844221a rpcclient: fix filtered naive subscriptions receiver
We should return the filter itself instead of pointer.
2022-12-07 16:56:16 +03:00
Roman Khimov
c4d519f549
Merge pull request #2837 from nspcc-dev/350-compat
native: make management compatible with C# node 3.5.0
2022-12-07 20:19:04 +07:00
Roman Khimov
531ab4bd6c
Merge pull request #2832 from nspcc-dev/consensus-config-section
Consensus config section
2022-12-07 20:18:23 +07:00
Roman Khimov
573ed6c39e
Merge pull request #2834 from nspcc-dev/doc-updates
Minor documentation fixes
2022-12-07 20:16:59 +07:00
Roman Khimov
236e633ee4 native: make management compatible with C# node 3.5.0
It doesn't store id->hash mappings for native contracts. We need blockchain's
GetContractScriptHash to serve both anyway, so it was changed a bit. The only
other direct user of native.GetContractScriptHash is the VM CLI, but I doubt
anyone will use it for native contracts (they have ~zero VM code anyway).
2022-12-07 15:13:17 +03:00
Roman Khimov
dbb798d4b7 config: add dummy consensus config section into files
Just to make it easier to configure.
2022-12-07 13:23:08 +03:00
Roman Khimov
0efa9c5fc3 config: update configurations for Consensus 2022-12-07 13:22:11 +03:00
Roman Khimov
883c6c5286 config: add Consensus subsection for dBFT config, fix #2677
Old UnlockWallet is still supported and works just fine.
2022-12-07 13:20:21 +03:00
Roman Khimov
730849a1cd config: move common part of notary/state into InternalService 2022-12-07 13:18:50 +03:00
Roman Khimov
ce7995e045 README: update a little, fix #2779
Minor improvements, removing outdated data, plus
  NEO -> Neo
  neo-go -> NeoGo
2022-12-07 13:17:09 +03:00
Roman Khimov
90a85259a8
Merge pull request #2827 from nspcc-dev/multiaddr
network: support multiple bind addresses
2022-12-07 17:15:56 +07:00
Anna Shaleva
54c2aa8582 config: move P2P options to a separate config section
And convert time-related settings to a Duration format along the way.
2022-12-07 13:06:05 +03:00
Anna Shaleva
9cf6cc61f4 network: allow multiple bind addresses for server
And replace Transporter.Address() with Transporter.HostPort() along the way.
2022-12-07 13:06:03 +03:00
Anna Shaleva
9087854b1e services: allow multiple listen addresses for simple services
And deprecate the old way of Address/Port configuration for these services.
2022-12-07 11:23:01 +03:00
Roman Khimov
b1723f1a79 cli/wallet: improve wallet flag help text, fix #2820 2022-12-06 20:54:01 +03:00
Roman Khimov
cad0fab704
Merge pull request #2828 from nspcc-dev/rpcwrapper-structures
Handle structures in the RPC wrapper generator
2022-12-06 21:40:16 +07:00
Anna Shaleva
6b4dd5703e config: unify BasicService config within existing services
There are no changes visible from the user side (at least for those
users who doesn't put Prometheus's or pprof's port in quotes), just
internal refactoring. From now and on, BasicService configuration is
used by RPC server config, TLS for RPC server, pprof and Prometheus.
2022-12-06 16:35:09 +03:00
Roman Khimov
e5aa5ca294 rpcbinding: improve error reporting in generated code 2022-12-06 13:15:10 +03:00
Roman Khimov
ec5ebc8c18 rpcbinding: improve indentation for internal unwrappers 2022-12-06 13:15:10 +03:00
Roman Khimov
c058ab5604 rpcbinding: handle more complex non-structured types 2022-12-06 13:15:10 +03:00
Roman Khimov
ce67e6795e rpcbinding: properly support maps
I'm not sure that map with a `*big.Int` key is a good one, but it can work
this way.
2022-12-06 13:15:10 +03:00
Roman Khimov
8e0be6e7a5 rpcbinding: improve indentation for internal array code 2022-12-06 13:15:10 +03:00
Roman Khimov
0214628127 rpcbinding: generate bindings using new extended type data 2022-12-06 13:15:10 +03:00
Roman Khimov
2bcf3a4ad5 compiler: unwrap pointers for debug types
We have almost no difference between Type and *Type.
2022-12-06 13:15:10 +03:00
Roman Khimov
d7fafea328 compiler: handle ledger/management enums better for debug
Fix scAndVMInteropTypeFromExpr(), these types are not structures at all.
2022-12-06 13:15:10 +03:00
Roman Khimov
0f61a13006 compiler: Contract type is in the management package 2022-12-06 13:15:10 +03:00
Roman Khimov
b9d20b32e9 compiler: push additional type data into the bindings file
Structures/arrays and maps.
2022-12-06 13:15:10 +03:00
Roman Khimov
d6b99a9a27
Merge pull request #2831 from nspcc-dev/loglevel-config
LogLevel config
2022-12-06 13:35:59 +07:00
Roman Khimov
2e1b502463 cli: make the node use new logging level on SIGHUP
Fixes #2794.
2022-12-05 15:45:42 +03:00
Roman Khimov
cceb044a02 config: add LogLevel option to control logging level
And update zap, because the old version doesn't have zapcore.ParseLevel().
2022-12-05 14:58:16 +03:00
Roman Khimov
85b69141f7
Merge pull request #2830 from nspcc-dev/bump-aspid-again
config: move Aspidochelone fork height for NeoFS mainnet again
2022-12-05 14:48:54 +07:00
Roman Khimov
5ffe04269f config: move Aspidochelone fork height for NeoFS mainnet again 2022-12-05 10:41:43 +03:00
Roman Khimov
b7518423d4
Merge pull request #2829 from nspcc-dev/ms-per-block
TimePerBlock config
2022-12-05 14:27:55 +07:00
Roman Khimov
4972def311 config: use 100ms for unit_testnet.single
I do see some reduced testing time for cli components with this setting even
though it doesn't affect the overall time for me. Maybe it'll be beneficial in
some cases. Refs. #2379.
2022-12-02 19:52:14 +03:00
Roman Khimov
af66a0441e config: update configuration files to use TimePerBlock
Everything works like charm after this.
2022-12-02 19:52:14 +03:00
Roman Khimov
c2adbf768b config: add TimePerBlock to replace SecondsPerBlock
It's more generic and convenient than MillisecondsPerBlock. This setting is
made in backwards-compatible fashion, but it'll override SecondsPerBlock if
both are used. Configurations are specifically not changed here, it's
important to check compatibility.

Fixes #2675.
2022-12-02 19:52:14 +03:00
Roman Khimov
a654396150
Merge pull request #2702 from nspcc-dev/management-id-hash
Store ID->hash map in the ContractManagement
2022-12-02 23:48:44 +07:00
Roman Khimov
d909cab4a4 rpcclient/management: add new methods 2022-12-02 10:57:05 +03:00
Roman Khimov
4ce968e4d0 *: update interops, add tests for new management methods 2022-12-02 10:57:05 +03:00
Roman Khimov
cb5c18dc73 interop: add getContractByID and getContractHashes to management 2022-12-02 10:54:45 +03:00
Roman Khimov
4a626f505e core: drop old STContractID data
We have it in the ContractManagement now.
2022-12-02 10:54:45 +03:00
Roman Khimov
970862765d native: implement management.getContractById
Follow neo-project/neo#2807. Notice that this data is not cached, our previous
implementation wasn't too and it shouldn't be a problem (not on the hot path).
2022-12-02 10:21:08 +03:00
Roman Khimov
6c68da7a52 rpcsrv: add block 20 hash comparison test
Makes updating it somewhat easier.
2022-12-02 10:21:08 +03:00
Roman Khimov
f6a9969fa8
Merge pull request #2770 from nspcc-dev/push-bool
vm: add PUSHT and PUSHF opcodes
2022-12-02 14:20:11 +07:00
Roman Khimov
389bdfd1b6
Merge pull request #2719 from nspcc-dev/eval
runtime: implement System.Runtime.LoadScript, fix #2701
2022-12-02 14:08:40 +07:00
Roman Khimov
93cec0bba5
Merge pull request #2786 from nspcc-dev/simplify-getversion
Simplify result.Version
2022-12-02 14:07:55 +07:00
Roman Khimov
3ef66239a8
Merge pull request #2814 from nspcc-dev/startup-time
Optimize startup time and memory usage
2022-12-02 14:06:23 +07:00
Anna Shaleva
2b140631f4 rpc: adjust Boolean handling in ExpandArrayIntoScript
Use new PUSHT and PUSHF opcodes for Boolean scparameter.
2022-12-02 10:02:33 +03:00
Anna Shaleva
1250e82c2a vm: add PUSHT and PUSHF opcodes
Port https://github.com/neo-project/neo-vm/pull/497.
2022-12-02 10:02:33 +03:00
Roman Khimov
6912695b9d
Merge pull request #2826 from nspcc-dev/check-for-max-block-sysfee
core: filter out txes with system fee > MaxBlockSystemFee
2022-11-29 14:57:10 +07:00
Roman Khimov
6847e1760c core: filter out txes with system fee > MaxBlockSystemFee
They can stay in the memory pool forever because consensus process will never
accept these transactions (and maybe even block consensus process at all).
2022-11-29 10:31:00 +03:00
Roman Khimov
4ca478dfc4
Merge pull request #2824 from nspcc-dev/fix-load
core, vm: improve script invocation errors
2022-11-28 22:10:21 +07:00
Anna Shaleva
6d3cc0f7e7 core: extend error text for storage context in dynamic script 2022-11-28 17:17:36 +03:00
Anna Shaleva
0ceae612c6 vm: improve failed SYSCALL logging
For better user experience.
2022-11-28 17:16:27 +03:00
Roman Khimov
07e32e221d *: update interops, add System.Runtime.LoadScript wrapper check 2022-11-25 15:16:27 +03:00
Roman Khimov
de2de986a7 interop: add runtime.LoadScript 2022-11-25 15:11:49 +03:00
Roman Khimov
4e26f4b26e runtime: implement System.Runtime.LoadScript, fix #2701 2022-11-25 15:11:49 +03:00
Roman Khimov
1c38b45074 core: don't always store all hashes in memory
We're paging these hashes, so we need a previous full page and a current one
plus some cache for various requests. Storing 1M of hashes is 32M of memory
and it grows quickly. It also seriously affects node startup time, most of
what it's doing is reading these hashes, the longer the chain the more time it
needs to do that.

Notice that this doesn't change the underlying DB scheme in any way.
2022-11-25 14:30:51 +03:00
Roman Khimov
0ad6e295ea core: make GetHeaderHash accept uint32
It should've always been this way because block indexes are uint32.
2022-11-25 14:30:51 +03:00
Roman Khimov
16db4746cc core: drop another useless genesis-specific header handling branch
If we only have genesis block (or <2000 headers) then we might as well use
generic logic below with zero targetHash because genesis block has zero
PrevHash (and its hash will naturally be the last on the chain going
backwards).
2022-11-25 13:08:03 +03:00
Roman Khimov
83e2ca054f core: simplify header hash list restoration logic
We don't care about header, we only need hashes here.
2022-11-25 13:08:03 +03:00
Roman Khimov
ff284d5d5c core: remove genesis-specific header hash logic from init
The code below will do the same thing (via CreateGenesisBlock, but it doesn't
matter) generically, so this branch is useless.
2022-11-25 13:08:03 +03:00
Roman Khimov
a43a87675d
Merge pull request #2823 from nspcc-dev/bump-mainnet-neofs-fork-block
config: the network is past 2.7M non-upgraded
2022-11-24 15:08:41 +07:00
Roman Khimov
7d041aea56 config: the network is past 2.7M non-upgraded
Bump the fork block again.
2022-11-24 10:57:45 +03:00
Roman Khimov
027e94fbde compiler: don't push overrides for unexported methods
They're internal, no one cares about them externally.
2022-11-23 17:05:37 +03:00
Roman Khimov
92dfec61c9
Merge pull request #2822 from nspcc-dev/0997
CHANGELOG: release 0.99.7
2022-11-23 20:30:36 +07:00
Roman Khimov
f10311f974 CHANGELOG: release 0.99.7 2022-11-23 16:21:51 +03:00
Roman Khimov
3ac76c319d
Merge pull request #2821 from nspcc-dev/improve-wsclient-handshake-error
Improve wsclient handshake error
2022-11-23 18:40:06 +07:00
Roman Khimov
327dfb8dbf rpcsrv: add wsclient error message test for #2818
Now it can be done easily.
2022-11-23 12:24:20 +03:00
Roman Khimov
2591c39500 rpcsrv: make websocket client limit configurable 2022-11-23 12:19:49 +03:00
Roman Khimov
fb09670fd1 rpcclient: extract more detailed server-side on WS connection problem
If available. Fixes #2818.
2022-11-23 12:19:35 +03:00
Roman Khimov
ab0b23625b
Merge pull request #2817 from nspcc-dev/always-return-hash-vub-from-sender
Some actor/waiter interaction fixes
2022-11-23 14:37:38 +07:00
Roman Khimov
fd04b2befd actor: don't abort waiter on "already exists" error
It can happen in many cases of distributed tx generation/submission, we can
just wait normally in this case and there will be some proper result.
2022-11-23 10:07:37 +03:00
Roman Khimov
66ddeccdad
Merge pull request #2813 from nspcc-dev/fix-state-reset
core: fix broken state reset
2022-11-23 13:43:42 +07:00
Anna Shaleva
f3ef2890f0 core: check headers at the proper state on state reset
And fix the comment along the way.
2022-11-23 09:16:33 +03:00
Roman Khimov
cd6bb68246 actor: check for tx after the subscription in wsWaiter, fix #2805
Don't wait for VUB block, solve this race immediately.
2022-11-22 17:28:55 +03:00
Roman Khimov
c95d140113 rpcclient: always return tx hash from sendrawtransaction
Let upper-layer APIs like actor.Send() return it as well. Server can return
"already exists" which is an error and yet at the same time a very special
one, in many cases it means we can proceed with waiting for the TX to settle.
2022-11-22 15:18:37 +03:00
Anna Shaleva
b27a9bcf95 core: adjust info message for proper-stated chains
Make it prettier for those cases when `db reset` command was called
after interrupted reset.
2022-11-22 11:53:39 +03:00
Anna Shaleva
b82374823e core: increase persist batch size for reset storage changes 2022-11-22 11:53:39 +03:00
Anna Shaleva
bdc42cd595 core: reset blocks, txs and AERs in several stages
Sometimes it can be hard to persist all changes at ones, the process
can take almost all RAM and a lot of time. Here's the example of reset
for mainnet from 2.4M to 1:
```
anna@kiwi:~/Documents/GitProjects/nspcc-dev/neo-go$ ./bin/neo-go db reset -m --height 1
2022-11-20T17:16:48.236+0300	INFO	MaxBlockSize is not set or wrong, setting default value	{"MaxBlockSize": 262144}
2022-11-20T17:16:48.236+0300	INFO	MaxBlockSystemFee is not set or wrong, setting default value	{"MaxBlockSystemFee": 900000000000}
2022-11-20T17:16:48.237+0300	INFO	MaxTransactionsPerBlock is not set or wrong, using default value	{"MaxTransactionsPerBlock": 512}
2022-11-20T17:16:48.237+0300	INFO	MaxValidUntilBlockIncrement is not set or wrong, using default value	{"MaxValidUntilBlockIncrement": 5760}
2022-11-20T17:16:48.240+0300	INFO	restoring blockchain	{"version": "0.2.6"}
2022-11-20T17:16:48.297+0300	INFO	initialize state reset	{"target height": 1}
2022-11-20T17:16:48.300+0300	INFO	trying to reset blocks, transactions and AERs
2022-11-20T17:19:29.313+0300	INFO	blocks, transactions ans AERs are reset	{"took": "2m41.015126493s", "keys": 3958420}
...
```
To avoid OOM killer, split blocks reset into multiple stages. It increases
operation time due to intermediate DB persists, but makes things cleaner, the
result for almost the same DB height with the new approach:
```
anna@kiwi:~/Documents/GitProjects/nspcc-dev/neo-go$ ./bin/neo-go db reset -m --height 1
2022-11-20T17:39:42.023+0300	INFO	MaxBlockSize is not set or wrong, setting default value	{"MaxBlockSize": 262144}
2022-11-20T17:39:42.023+0300	INFO	MaxBlockSystemFee is not set or wrong, setting default value	{"MaxBlockSystemFee": 900000000000}
2022-11-20T17:39:42.023+0300	INFO	MaxTransactionsPerBlock is not set or wrong, using default value	{"MaxTransactionsPerBlock": 512}
2022-11-20T17:39:42.023+0300	INFO	MaxValidUntilBlockIncrement is not set or wrong, using default value	{"MaxValidUntilBlockIncrement": 5760}
2022-11-20T17:39:42.026+0300	INFO	restoring blockchain	{"version": "0.2.6"}
2022-11-20T17:39:42.071+0300	INFO	initialize state reset	{"target height": 1}
2022-11-20T17:39:42.073+0300	INFO	trying to reset blocks, transactions and AERs
2022-11-20T17:40:11.735+0300	INFO	intermediate batch of removed blocks, transactions and AERs is persisted	{"batches persisted": 1, "took": "29.66363737s", "keys": 210973}
2022-11-20T17:40:33.574+0300	INFO	intermediate batch of removed blocks, transactions and AERs is persisted	{"batches persisted": 2, "took": "21.839208683s", "keys": 241203}
2022-11-20T17:41:29.325+0300	INFO	intermediate batch of removed blocks, transactions and AERs is persisted	{"batches persisted": 3, "took": "55.750698386s", "keys": 250593}
2022-11-20T17:42:12.532+0300	INFO	intermediate batch of removed blocks, transactions and AERs is persisted	{"batches persisted": 4, "took": "43.205892757s", "keys": 321896}
2022-11-20T17:43:07.978+0300	INFO	intermediate batch of removed blocks, transactions and AERs is persisted	{"batches persisted": 5, "took": "55.445398156s", "keys": 334822}
2022-11-20T17:43:35.603+0300	INFO	intermediate batch of removed blocks, transactions and AERs is persisted	{"batches persisted": 6, "took": "27.625292032s", "keys": 317131}
2022-11-20T17:43:51.747+0300	INFO	intermediate batch of removed blocks, transactions and AERs is persisted	{"batches persisted": 7, "took": "16.144359017s", "keys": 355832}
2022-11-20T17:44:05.176+0300	INFO	intermediate batch of removed blocks, transactions and AERs is persisted	{"batches persisted": 8, "took": "13.428733899s", "keys": 357690}
2022-11-20T17:44:32.895+0300	INFO	intermediate batch of removed blocks, transactions and AERs is persisted	{"batches persisted": 9, "took": "27.718548783s", "keys": 393356}
2022-11-20T17:44:51.814+0300	INFO	intermediate batch of removed blocks, transactions and AERs is persisted	{"batches persisted": 10, "took": "18.917954658s", "keys": 366492}
2022-11-20T17:45:07.208+0300	INFO	intermediate batch of removed blocks, transactions and AERs is persisted	{"batches persisted": 11, "took": "15.392642196s", "keys": 326030}
2022-11-20T17:45:18.776+0300	INFO	intermediate batch of removed blocks, transactions and AERs is persisted	{"batches persisted": 12, "took": "11.568255716s", "keys": 299884}
2022-11-20T17:45:25.862+0300	INFO	last batch of removed blocks, transactions and AERs is persisted	{"batches persisted": 13, "took": "7.086079594s", "keys": 190399}
2022-11-20T17:45:25.862+0300	INFO	blocks, transactions ans AERs are reset	{"took": "5m43.791214084s", "overall persisted keys": 3966301}
...
```
2022-11-22 11:53:39 +03:00
Anna Shaleva
d67f0df516 core: reset block headers together with header height info
We need to keep the headers information consistent with header batches
and headers. This comit fixes the bug with failing blockchain
initialization on recovering from state reset interrupted after the
second stage (blocks/txs/AERs removal):
```
anna@kiwi:~/Documents/GitProjects/nspcc-dev/neo-go$ ./bin/neo-go db reset -t --height 83000
2022-11-20T16:28:29.437+0300	INFO	MaxValidUntilBlockIncrement is not set or wrong, using default value	{"MaxValidUntilBlockIncrement": 5760}
2022-11-20T16:28:29.440+0300	INFO	restoring blockchain	{"version": "0.2.6"}
failed to create Blockchain instance: could not initialize blockchain: could not get header 1898cd356a4a2688ed1c6c7ba1fd6ba7d516959d8add3f8dd26232474d4539bd: key not found
```
2022-11-22 11:53:39 +03:00
Anna Shaleva
283da8f599 core: use DAO-provided block height during during state reset
Don't use cache because it's not yet initialized. Also, perform
safety checks only if state reset wasn't yet started. These fixes
alloww to solve the following problem while recovering from
interrupted state reset:
```
anna@kiwi:~/Documents/GitProjects/nspcc-dev/neo-go$ ./bin/neo-go db reset -t --height 83000
2022-11-20T15:51:31.431+0300	INFO	MaxValidUntilBlockIncrement is not set or wrong, using default value	{"MaxValidUntilBlockIncrement": 5760}
2022-11-20T15:51:31.434+0300	INFO	restoring blockchain	{"version": "0.2.6"}
failed to create Blockchain instance: could not initialize blockchain: current block height is 0, can't reset state to height 83000
```
2022-11-22 11:53:39 +03:00
Anna Shaleva
7d55bf2cc1 core: log persisted storage item batches count during state reset 2022-11-22 11:53:39 +03:00
Anna Shaleva
f52451e582 core: fix state reset with broken contract
Sync up with #2802, bad contract -> no contract ID at all.
2022-11-22 11:53:39 +03:00
Anna Shaleva
ecda07736e core: stop storage items reset after any seek error 2022-11-22 11:53:39 +03:00
Anna Shaleva
bfe7aeae7b core: stop storage items reset after the first persist error
It's a bug, we mustn't continue if something bad had happend on persist,
otherwise this error will be overwritten by subsequent successfull persist.
2022-11-22 11:53:39 +03:00
Anna Shaleva
235518eb6c core: reset batch counter to zero after each persist in resetStateInternal
It's a bug, otherwise we'll persist each storage item after 10K-th one,
that's the reason of abnormous long storage items resetting stage.
2022-11-22 11:53:39 +03:00
Anna Shaleva
9f23fafc03 core: improve logging of resetStateInternal
Inform when starting subsequent stage, inform about keys persisted.
2022-11-22 11:53:36 +03:00
Roman Khimov
0039615ae3
Merge pull request #2816 from nspcc-dev/fix-pointer-serialization
Fix pointer serialization
2022-11-20 22:59:52 +07:00
Roman Khimov
9ba18b5dfa stackitem: serialize/deserialize pointers, fix #2815
They of course can't be serialized, but in protected mode we still need to
handle them somehow.
2022-11-20 16:02:50 +03:00
Roman Khimov
286f40b828 cli/vm: use tx system fee by default 2022-11-20 16:02:50 +03:00
Roman Khimov
2908965a8d cli/vm: add --gas parameter to load* commands
It's useful to reproduce different execution problems including executions
stopped because of GAS limit. Satoshi representation is deliberately used,
because that's what is usually found in logs.
2022-11-20 16:02:50 +03:00
Roman Khimov
48140320db
Merge pull request #2812 from nspcc-dev/improve-vm-context-handling
Improve vm istack/estack handling
2022-11-20 19:42:35 +07:00
Roman Khimov
ca9fde745b
Merge pull request #2809 from nspcc-dev/fix-subs
rpcsrv: do not block blockchain events receiver by subscription requests
2022-11-18 16:16:41 +07:00
Roman Khimov
8e7f65be17 vm: use proper estack for exception handler
v.estack might be some inner invoked contract and its stack must not be used
for exception handler set up by higher-order contract.
2022-11-18 11:36:38 +03:00
Roman Khimov
cb64957af5 vm: don't use Stack for istack
We don't use all of the Stack functionality for it, so drop useless methods
and avoid some interface conversions. It increases single-node TPS by about
0.9%, so nothing really important there, but not a bad change either. Maybe it
can be reworked again with generics though.
2022-11-18 11:35:29 +03:00
Anna Shaleva
4df9a5e379 rpcsrv: refactor subscribe routine
Move shutdown check after subsCounterLock is taken in the end of
`(s *Server) subscribe` in order to avoid extra locks holding.
2022-11-18 10:54:10 +03:00
Roman Khimov
bb9f17108e
Merge pull request #2811 from nspcc-dev/network-connections-fix
Network connections fix
2022-11-18 14:26:25 +07:00
Anna Shaleva
b7f19a54d5 services: fix chain locked by WS subscriptions handlers
Blockchain's subscriptions, unsubscriptions and notifications are
handled by a single notificationDispatcher routine. Thus, on attempt
to send the subsequent event to Blockchain's subscribers, dispatcher
can't handle subscriptions\unsubscriptions. Make subscription and
unsubscription to be a non-blocking operation for blockchain on the
server side, otherwise it may cause the dispatcher locks.

To achieve this, use a separate lock for those code that make calls
to blockchain's subscription API and for subscription counters on
the server side.
2022-11-18 09:30:12 +03:00
Roman Khimov
2bcb7bd06f compiler: don't use (*VM).Istack when it's not needed 2022-11-17 20:46:06 +03:00
Roman Khimov
b8c09f509f network: add random slight delay to connection attempts
Small (especially dockerized/virtualized) networks often start all nodes at
ones and then we see a lot of connection flapping in the log. This happens
because nodes try to connect to each other simultaneously, establish two
connections, then each one finds a duplicate and drops it, but this can be
different duplicate connections on other sides, so they retry and it all
happens for some time. Eventually everything settles, but we have a lot of
garbage in the log and a lot of useless attempts.

This random waiting timeout doesn't change the logic much, adds a minimal
delay, but increases chances for both nodes to establish a proper single
connection on both sides to only then see another one and drop it on both
sides as well. It leads to almost no flapping in small networks, doesn't
affect much bigger ones. The delay is close to unnoticeable especially if
there is something in the DB for node to process during startup.
2022-11-17 18:42:43 +03:00
Roman Khimov
075a54192c network: don't try too many connections
Consider mainnet, it has an AttemptConnPeers of 20, so may already have 3
peers and request 20 more, then have 4th connected and attemtp 20 more again,
this leads to a huge number of connections easily.
2022-11-17 18:03:04 +03:00
Roman Khimov
5d7b37a6ff
Merge pull request #2810 from nspcc-dev/fix-loadgo
cli: split TestLoad into multiple parts
2022-11-17 21:50:46 +07:00
Roman Khimov
6bce973ac2 network: drop duplicationg check from handleAddrCmd()
It was relevant with the queue-based discoverer, now it's not, discoverer
handles this internally.
2022-11-17 17:42:36 +03:00
Roman Khimov
1c7487b8e4 network: add a timer to check for peers
Consider initial connection phase for public networks:
 * simultaneous connections to seeds
 * very quick handshakes
 * got five handshaked peers and some getaddr requests sent
 * but addr replies won't trigger new connections
 * so we can stay with just five connections until any of them breaks or a
   (long) address checking timer fires

This new timers solves the problem, it's adaptive at the same time. If we have
enough peers we won't be waking up often.
2022-11-17 17:32:05 +03:00
Anna Shaleva
e73c3c7ec4 services: adjust WS waiter test
Make it more stable.
2022-11-17 17:15:01 +03:00
Roman Khimov
23f118a1a9 network: rework discoverer/server interaction
* treat connected/handshaked peers separately in the discoverer, save
   "original" address for connected ones, it can be a name instead of IP and
   it's important to keep it to avoid reconnections
 * store name->IP mapping for seeds if and when they're connected to avoid
   reconnections
 * block seed if it's detected to be our own node (which is often the case for
   small private networks)
 * add an event for handshaked peers in the server, connected but
   non-handshaked ones are not really helpful for MinPeers or GetAddr logic

Fixes #2796.
2022-11-17 17:07:19 +03:00
Roman Khimov
6ba4afc977 network: consider handshaked peers only when comparing with MinPeers
We don't know a lot about non-handshaked ones, so it's safer to try more
connection.
2022-11-17 16:40:29 +03:00
Anna Shaleva
f8f8d5effe cli: split TestLoad into multiple parts
Problem: failing part of TestLoad:
```
=== RUN   TestLoad/loadgo,_check_signers
    cli_test.go:160:
        	Error Trace:	/home/circleci/go/src/github.com/nspcc-dev/neo-go/cli/vm/cli_test.go:160
        	            				/home/circleci/go/src/github.com/nspcc-dev/neo-go/cli/vm/cli_test.go:147
        	            				/home/circleci/go/src/github.com/nspcc-dev/neo-go/cli/vm/cli_test.go:444
        	Error:      	command took too long time
        	Test:       	TestLoad/loadgo,_check_signers
```
Solution: split the test into multiple parts to reduce test execution time.
2022-11-17 16:23:33 +03:00
Roman Khimov
f8949564c8
Merge pull request #2807 from nspcc-dev/release-0.99.6
CHANGELOG: release 0.99.6
2022-11-17 04:29:10 +07:00
Roman Khimov
ad912392b4 CHANGELOG: release 0.99.6 2022-11-17 00:25:53 +03:00
Roman Khimov
ab0ff63ce1
Merge pull request #2804 from nspcc-dev/check-aer-sub
rpc: fix subscribers locking logic and properly drain poll-based waiter receiver
2022-11-17 04:24:35 +07:00
Anna Shaleva
1399496dfb rpcclient: refactor event-based waiting loop
Avoid receiver channels locks.
2022-11-16 23:57:00 +03:00
Anna Shaleva
95e23c8e46 actor: fix event-based tx awaiting
If VUB-th block is received, we still can't guaranty that transaction
wasn't accepted to chain. Back this situation by rolling back to a
poll-based waiter.
2022-11-16 23:44:31 +03:00
Anna Shaleva
6dbae7edc4 rpcclient: fix WS-client unsubscription process
Do not block subscribers until the unsubscription request to RPC server
is completed. Otherwise, another notification may be received from the
RPC server which will block the unsubscription process.

At the same time, fix event-based waiter. We must not block the receiver
channel during unsubscription because there's a chance that subsequent
event will be sent by the server. We need to read this event in order not
to block the WSClient's readloop.
2022-11-16 23:44:30 +03:00
Anna Shaleva
ddaba9e74d rpcsrv: fix "subscribe" parameters handling
If it's a subscription for AERs, we need to check the filter's state only
if it has been provided, otherwise filter is always valid.
2022-11-16 14:05:13 +03:00
Anna Shaleva
d043139b66 rpcsrv: adjust "subscribe" response error
Make it more detailed for better debugging experience.
2022-11-16 13:35:19 +03:00
Anna Shaleva
3f122fd591 rpcclient: adjust WS waiter error formatting
Follow the other errors formatting style.
2022-11-16 12:22:18 +03:00
Roman Khimov
5f763a26e7
Merge pull request #2802 from nspcc-dev/fix-node-startup-with-broken-contract
Fix node startup with broken contract
2022-11-16 16:21:56 +07:00
Roman Khimov
822722bd2e native: ignore decoding errors during cache init
Bad contract -> no contract. Unfortunately we've got a broken
6f1837723768f27a6f6a14452977e3e0e264f2cc contract on the mainnet which can't
be decoded (even though it had been saved successfully), so this is a
temporary fix for #2801 to be able to start mainnet node after shutdown.
2022-11-16 12:00:28 +03:00
Roman Khimov
0402a75d20 cli: fix error message formatting
This is not very useful:
   could not initialize blockchain: %!w([]interface {}=[0xc0018da2c0])
2022-11-16 11:34:29 +03:00
Roman Khimov
bd67fe5371
Merge pull request #2800 from nspcc-dev/fix-vm-bugz
Fix VM bug and istack printing
2022-11-16 13:24:07 +07:00
Roman Khimov
aef01bf663 vm: fix istack marshaling, fix #2799 2022-11-16 00:40:12 +03:00
Roman Khimov
90582faacd vm: save current stack slice when loading new context
v.estack is used throughout the code to work with estack, while ctx.sc.estack
is (theoretically) just a reference to it that is saved on script load and
restored to v.estack on context unload. The problem is that v.estack can grow
as we use it and can be reallocated away from its original slice (saved in the
ctx.sc.estack), so either ctx.sc.estack should be a pointer or we need to
ensure that it's correct when loading a new script. The second approach is a
bit safer for now and it fixes #2798.
2022-11-15 23:48:02 +03:00
Roman Khimov
e9407e2054
Merge pull request #2793 from nspcc-dev/ga-upd
.github: upgrade stale GithubActions workflow dependencies
2022-11-15 20:25:51 +07:00
Anna Shaleva
eaa0d42b9c .github: fix condition for adding latest tag to buider job 2022-11-15 16:16:02 +03:00
Anna Shaleva
59741bbffc .github: update deprecated workflows 2022-11-15 16:16:01 +03:00
Roman Khimov
5197723dfe
Merge pull request #2797 from nspcc-dev/adj-deposit-warning
network: adjust warning for deposit expiration
2022-11-15 18:40:22 +07:00
Anna Shaleva
6f3a0a6b4c network: adjust warning for deposit expiration
Provide additional info for better user experience.
2022-11-15 14:16:34 +03:00
Roman Khimov
c67ee54566
Merge pull request #2792 from nspcc-dev/rpcwrapper-arrays
RPC wrapper for simple arrays
2022-11-15 13:08:25 +07:00
Roman Khimov
82c6ce218b rpcbinding: use binding condig to generate code for simple arrays
Part of #2767.
2022-11-14 13:01:13 +03:00
Roman Khimov
b5c79f4be3 unwrap: add a complete set of simple array unwrappers
Arrays of basic types should be covered completely.
2022-11-14 13:01:13 +03:00
Roman Khimov
633413541c
Merge pull request #2791 from nspcc-dev/fix-win-reest
cli: properly close storage on `db reset`
2022-11-14 15:13:30 +07:00
Roman Khimov
ecf1f3195c
Merge pull request #2788 from nspcc-dev/dbft-tx-list
network: pre-filter transactions going into dbft
2022-11-14 15:10:10 +07:00
Anna Shaleva
aceeeeca33 cli: properly close storage on db reset
And fix failing test along the way:
```
2022-11-11T12:37:47.0413934Z === RUN   TestResetDB
2022-11-11T12:37:47.0414557Z 2022-11-11T12:36:54.510Z	INFO	initial gas supply is not set or wrong, setting default value	{"InitialGASSupply": "52000000"}
2022-11-11T12:37:47.0415288Z 2022-11-11T12:36:54.510Z	INFO	MaxBlockSize is not set or wrong, setting default value	{"MaxBlockSize": 262144}
2022-11-11T12:37:47.0416020Z 2022-11-11T12:36:54.510Z	INFO	MaxBlockSystemFee is not set or wrong, setting default value	{"MaxBlockSystemFee": 900000000000}
2022-11-11T12:37:47.0416786Z 2022-11-11T12:36:54.510Z	INFO	MaxTransactionsPerBlock is not set or wrong, using default value	{"MaxTransactionsPerBlock": 512}
2022-11-11T12:37:47.0417725Z 2022-11-11T12:36:54.510Z	INFO	MaxValidUntilBlockIncrement is not set or wrong, using default value	{"MaxValidUntilBlockIncrement": 5760}
2022-11-11T12:37:47.0418415Z 2022-11-11T12:36:54.510Z	INFO	Hardforks are not set, using default value
2022-11-11T12:37:47.0419272Z 2022-11-11T12:36:54.523Z	INFO	no storage version found! creating genesis block
2022-11-11T12:37:47.0419997Z 2022-11-11T12:36:54.529Z	INFO	chain is already at the proper state	{"height": 0}
2022-11-11T12:37:47.0420974Z     testing.go:1097: TempDir RemoveAll cleanup: remove C:\Users\RUNNER~1\AppData\Local\Temp\TestResetDB671187463\001\chains\privnet\000001.log: The process cannot access the file because it is being used by another process.
2022-11-11T12:37:47.0421606Z --- FAIL: TestResetDB (1.99s)
```
2022-11-14 10:29:10 +03:00
Roman Khimov
b930a970ce
Merge pull request #2789 from nspcc-dev/release-instr-upd
docs: update release instructions
2022-11-14 14:05:03 +07:00
Anna Shaleva
a8b40eafe0 docs: update release instructions 2022-11-14 09:03:42 +03:00
Roman Khimov
91e9b5fe9a
Merge pull request #2787 from nspcc-dev/0.99.5-changelog
*: add changelog for 0.99.5
2022-11-11 20:42:00 +07:00
Anna Shaleva
b9765fa720 *: add changelog for 0.99.5 2022-11-11 16:28:41 +03:00
Roman Khimov
c405092953 network: pre-filter transactions going into dbft
Drop some load from dbft loop during consensus process.
2022-11-11 15:32:51 +03:00
Roman Khimov
f78231fd9c
Merge pull request #2773 from nspcc-dev/state-reset
core: implement state reset
2022-11-10 22:26:43 +07:00
Roman Khimov
470822753b
Merge pull request #2785 from nspcc-dev/deprecation-roadmap
ROADMAP: add deprecated code removal schedule
2022-11-10 22:13:10 +07:00
Anna Shaleva
e7effef052 core: reuse appendTokenTransferInfo from appendTokenTransfer 2022-11-10 18:08:18 +03:00
Anna Shaleva
30cfe4d8c8 cli: add db reset command
Close #2576.
2022-11-10 18:08:18 +03:00
Anna Shaleva
bd6bb9e9e2 core: allow to reset blockchain state 2022-11-10 18:08:17 +03:00
Anna Shaleva
ec9317d5b4 core: fix typo 2022-11-10 17:58:06 +03:00
Roman Khimov
e208ef1478 ROADMAP: add deprecated code removal schedule
I think it's useful to have this publically available.
2022-11-10 17:57:03 +03:00
Roman Khimov
cb806d4233 result: drop Version (un)marshaler, we only need it for Protocol
Simplify code a bit.
2022-11-10 17:51:02 +03:00
Roman Khimov
8324a247d3 result: drop pre-0.99.0 compatibility code
0.99.0 is too old already.
2022-11-10 16:49:38 +03:00
Anna Shaleva
1dac45bbbb core: add ability to check whether blockchain is running 2022-11-10 16:47:04 +03:00
Roman Khimov
7f8a79ffaa result: drop deprecated Magic and StateRootInHeader from Version
It's more than a year now we have them deprecated.
2022-11-10 16:32:49 +03:00
Roman Khimov
4c9473872e
Merge pull request #2783 from nspcc-dev/rpcbindings-iterators
Initial iterator support for RPC bindings
2022-11-10 12:51:40 +07:00
Roman Khimov
ea44367c97 cli/smartcontract: generate bindings also for examples
We do compilation test for them, just to check that the compiler doesn't choke
for any reason, but we can do the same for wrapper generators.
2022-11-09 18:13:45 +03:00
Roman Khimov
145ebad90e binding: drop the only error condition from TemplateFromManifest
Simplify the interface, we do IsValid() check anyway in the CLI and it covers
this condition as well.
2022-11-09 18:13:45 +03:00
Roman Khimov
be02eea7b1 binding: precompile template, remove useless error condition 2022-11-09 18:13:45 +03:00
Roman Khimov
a7f86dcb7f rpcbinding: generate Expanded methods for iterators
Refs. #2768.
2022-11-09 18:13:45 +03:00
Roman Khimov
d569fe01e6 rpcbinding: initial support for iterators, see #2768
Already better than stackitem.Item.
2022-11-09 18:13:45 +03:00
Roman Khimov
47d0f0d137
Merge pull request #2784 from nspcc-dev/rpc-histogram
rpcsrv: provide Prometheus histograms for calls
2022-11-09 21:58:21 +07:00
Roman Khimov
d0b1015b2c rpcsrv: provide Prometheus histograms for calls
They're a bit more useful and they're naturally grouped under rpc
prefix. Simple counters will be removed eventually to avoid duplication.
2022-11-09 13:26:45 +03:00
Roman Khimov
57ec67b375
Merge pull request #2782 from nspcc-dev/websocket-origin
rpcsrv: allow any Origin in WS connections if EnableCORSWorkaround
2022-11-09 13:38:28 +07:00
Roman Khimov
3247aa40a7 rpcsrv: allow any Origin in WS connections if EnableCORSWorkaround
Break origin checks even more. Alternative to #2772.
2022-11-09 09:28:09 +03:00
Roman Khimov
e3c503cee9
Merge pull request #2781 from nspcc-dev/btcd-update
Update 256k1 dependency
2022-11-08 23:50:19 +07:00
Roman Khimov
1e07cacc79 rpcsrv: fix test
client_test.go:1935:
                Error Trace:    /home/rik/dev/neo-go/pkg/services/rpcsrv/client_test.go:1935
                Error:          Should NOT be empty, but was 00000000-0000-0000-0000-000000000000
                Test:           TestClient_Iterator_SessionConfigVariations/sessions_disabled

It's obviously empty, since we have sessions disabled, but it was not
considered to be empty in testify 1.7.0, now it is, see 840cb80149
2022-11-08 18:31:25 +03:00
Roman Khimov
40f1056d43 nft-nd-nns: update neo-go dependency to drop btcec 2022-11-08 18:10:01 +03:00
Roman Khimov
8746d9877e keys: move from btcd/btcec to decred/secp256k1 package
There is a security issue found in github.com/btcsuite/btcd that we don't care
about (we're only using 256k1 implementation), but GitHub complains about
it. We could update to github.com/btcsuite/btcd/btcec/v2, but it's now just a
thin wrapper over github.com/decred/dcrd/dcrec/secp256k1/v4, so we better use
it directly.
2022-11-08 17:59:59 +03:00
Roman Khimov
695f00cfeb
Merge pull request #2778 from nspcc-dev/rpc-wrapper-writer
State-changing methods in RPC wrappers
2022-11-08 21:35:18 +07:00
Roman Khimov
69d8905ad9 rpcbinding: exclude onNEPXXPayment methods from wrappers
They make no sense there.
2022-11-08 17:01:36 +03:00
Roman Khimov
130608ac67 rpcbinding: support writer-only wrappers
"verify" contract doesn't have any safe methods.
2022-11-08 17:01:36 +03:00
Roman Khimov
df29008a50 rpcbinding: add GAS testcase, fix methodless wrappers
* strip NEP-XX methods before going into generator to avoid unused imports
 * nepXX.Invoker types already include Call
 * always import util, it's used for Hash
2022-11-08 17:01:36 +03:00
Roman Khimov
aeb61fb61d rpcbinding: generate ASSERT for bool-returning methods
It's a common pattern.
2022-11-08 17:01:36 +03:00
Roman Khimov
2a4a5ab479 rpcbinding: support simple wrappers for writer methods
Fixes #2769.
2022-11-08 17:01:36 +03:00
Roman Khimov
eb0494764c
Merge pull request #2776 from nspcc-dev/move-neofs-mainnet-fork
config: move NeoFS mainnet Aspidochelone fork again
2022-11-07 16:09:28 +07:00
Roman Khimov
bb47d971dc rpcclient/nep11: make DivisibleWriter part reusable
Same rationale as for BaseWriter or nep17.TokenWriter, otherwise it's hard to
build on top of plain Divisible structure.
2022-11-07 10:44:39 +03:00
Roman Khimov
9882718372 config: move NeoFS mainnet Aspidochelone fork again
We're still 0.98.5 on this network.
2022-11-07 10:40:30 +03:00
Roman Khimov
b590d4ca04
Merge pull request #2766 from nspcc-dev/rpc-wrapper-autogen
Rpc wrapper autogeneration
2022-10-28 11:54:47 +07:00
Roman Khimov
02ce59cfd5 binding: avoid name conflicts with Go keywords
And clashing one name on another after rename.
2022-10-27 22:57:49 +03:00
Roman Khimov
3b635164b7 docs: initial RPC wrapper generator doc 2022-10-27 22:57:49 +03:00
Roman Khimov
3fba1dd8cf docs: add generate-wrapper explainer 2022-10-27 22:57:49 +03:00
Roman Khimov
617c31093f smartcontract: initial rpcbinding implementation, fix #2705
It can do some unwrapping and reuse nepXX packages. It only uses manifest data
at the moment, see #2767, #2768, #2769.
2022-10-27 22:57:49 +03:00
Roman Khimov
f0abc035af unwrap: add PublicKey to unwrap public keys
We have this type in NEP-14 directly.
2022-10-27 18:32:00 +03:00
Roman Khimov
e0eff94094 standard: correct Comply* comments 2022-10-27 18:32:00 +03:00
Roman Khimov
64b603b056 standard: export standard definitions
Make Comply* functions useful and expose standard definitions for some reuse.
2022-10-27 18:32:00 +03:00
Roman Khimov
b95c135856
Merge pull request #2764 from nspcc-dev/subs-refactoring
rpc: refactor WSClient subscriptions API
2022-10-26 19:48:45 +07:00
Anna Shaleva
4fc11c2924 rpc: revert deprecated subscriptions API changes
Revert deprecated subscriptions-related method signature changed in
673a495527, 8e84bb51d5
and d7c1f3eac7.
2022-10-26 15:32:54 +03:00
Anna Shaleva
f5441f6085 docs: fix doc for transaction_executed WS notification
It returns *state.AppExecResult.
2022-10-26 15:32:54 +03:00
Anna Shaleva
5811687836 rpc: fix bug in Actor's waiter
Execution events are followed by block events, not vise versa, thus,
we can wait until VUB block to be accepted to be sure that
transaction wasn't accepted to chain.
2022-10-26 15:32:54 +03:00
Anna Shaleva
0a5905390c rpc: refactor WSClient subscriptions API
Make it more specific, close #2756.
2022-10-26 15:32:54 +03:00
Anna Shaleva
2a53db42af neorpc: adjust and extend event filters documentation 2022-10-26 15:32:54 +03:00
Anna Shaleva
0d39602a50 docs: adjust docmentation for execution results notifications 2022-10-26 15:32:54 +03:00
Roman Khimov
ea48982b35
Merge pull request #2765 from nspcc-dev/fix-query-test
cli: fix race in TestQueryTx
2022-10-26 18:50:56 +07:00
Anna Shaleva
499adccbcb cli: fix race in TestQueryTx
Problem - failing TestQueryTx test:
```
=== RUN   TestQueryTx/verbose/FAULT
=== CONT  TestQueryTx
    logger.go:130: 2022-10-26T10:47:51.414Z	DEBUG	processing rpc request	{"method": "getversion", "params": "[]"}
    logger.go:130: 2022-10-26T10:47:51.415Z	DEBUG	processing rpc request	{"method": "getnativecontracts", "params": "[]"}
    logger.go:130: 2022-10-26T10:47:51.612Z	DEBUG	processing rpc request	{"method": "getversion", "params": "[]"}
    logger.go:130: 2022-10-26T10:47:51.615Z	DEBUG	processing rpc request	{"method": "invokefunction", "params": "[11fdb7bc30a306a60dac874711a2b37b7da402c4 randomMethod  ]"}
    logger.go:130: 2022-10-26T10:47:51.617Z	DEBUG	processing rpc request	{"method": "getblockcount", "params": "[]"}
    logger.go:130: 2022-10-26T10:47:51.617Z	INFO	persisted to disk	{"blocks": 2, "keys": 154, "headerHeight": 2, "blockHeight": 2, "took": "260.704µs"}
    logger.go:130: 2022-10-26T10:47:51.618Z	DEBUG	processing rpc request	{"method": "calculatenetworkfee", "params": "[AIpp7dreAw8AAAAAAAAAAAAAAAAABQAAAAHYzFqQTVJvyabKtVugLJpv54nJVgAAK8IfDAxyYW5kb21NZXRob2QMFMQCpH17s6IRR4esDaYGozC8t/0RQWJ9W1IBACoRDCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcIRQZ7Q3Do=]"}
    logger.go:130: 2022-10-26T10:47:51.712Z	DEBUG	processing rpc request	{"method": "sendrawtransaction", "params": "[AIpp7dreAw8AAAAAABQbEgAAAAAABQAAAAHYzFqQTVJvyabKtVugLJpv54nJVgAAK8IfDAxyYW5kb21NZXRob2QMFMQCpH17s6IRR4esDaYGozC8t/0RQWJ9W1IBQgxAO2nxSMSRNFqBD5lOA37E9Px+nYDGMy6IqZromHXFtVTYD1c1hdUK4vTccoOr2AksdGwDsdQ8qIGJhXdEDxv8NSoRDCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcIRQZ7Q3Do=]"}
    logger.go:130: 2022-10-26T10:47:51.713Z	DEBUG	done processing headers	{"headerIndex": 3, "blockHeight": 2, "took": "228.756µs"}
    logger.go:130: 2022-10-26T10:47:51.813Z	DEBUG	processing rpc request	{"method": "getversion", "params": "[]"}
    logger.go:130: 2022-10-26T10:47:51.815Z	DEBUG	processing rpc request	{"method": "getnativecontracts", "params": "[]"}
    logger.go:130: 2022-10-26T10:47:51.923Z	DEBUG	processing rpc request	{"method": "getrawtransaction", "params": "[22bbb08d3f4b9e601a05c1bb1f7ac456d44bfad013287599bf3f843a75b30076 1]"}
=== CONT  TestQueryTx/verbose/FAULT
    executor.go:238:
        	Error Trace:	executor.go:238
        	            				executor.go:234
        	            				query_test.go:119
        	            				query_test.go:97
        	Error:      	Expect "OnChain:		false" to match "OnChain:\s+true"
        	Test:       	TestQueryTx/verbose/FAULT
```

chain.GetTransaction is looking into mempool also, so we need to check for the
AER instead of transaction.
2022-10-26 14:24:56 +03:00
Roman Khimov
396f56f792 binding: drop unused lowerFirst 2022-10-26 12:47:39 +03:00
Roman Khimov
4191b18728 binding: make TemplateFromManifest more reusable
Other template generators can make use of it.
2022-10-26 12:43:48 +03:00
Roman Khimov
d6d4f07280 binding: always import some packages and do it outside
If the contract has no methods, it's probably a broken one.
2022-10-26 12:40:59 +03:00
Roman Khimov
6af71755c1
Merge pull request #2762 from nspcc-dev/optimize-emit-bool
emit: optimize Bool GAS cost
2022-10-26 15:06:05 +07:00
Roman Khimov
4e58bd7411 compiler: use shorter and cheaper sequence to convert to Boolean 2022-10-25 18:20:55 +03:00
Roman Khimov
e9b752cbbb
Merge pull request #2763 from nspcc-dev/wallet-config-doc
docs: clarify wallet-config format
2022-10-25 20:38:13 +07:00
Roman Khimov
265221f65a docs: clarify wallet-config format 2022-10-25 13:30:39 +03:00
Roman Khimov
5d43367082 emit: optimize Bool GAS cost
NOT is 1 byte shorter and 2048 times cheaper than CONVERT. Inspired by
neo-project/neo-vm#493.
2022-10-25 13:08:33 +03:00
Roman Khimov
e19d867d4e
Merge pull request #2761 from nspcc-dev/fancy-getaddr
Fancy getaddr
2022-10-25 16:51:38 +07:00
Roman Khimov
4313b7f0c7
Merge pull request #2760 from nspcc-dev/net42
network: it is 42
2022-10-24 21:23:01 +07:00
Roman Khimov
28f54d352a network: do getaddr requests periodically, fix #2745
Every 1000 blocks seems to be OK for big networks (that only had done some
initial requests previously and then effectively never requested addresses
again because there was a sufficient number of addresses), won't hurt smaller
ones as well (that effectively keep doing this on every connect/disconnect,
peer changes are very rare there, but when they happen we want to have some
quick reaction to these changes).
2022-10-24 15:10:51 +03:00
Roman Khimov
9efc110058 network: it is 42
32 is a very good number, but we all know 42 is a better one. And it can even
be proven by tests with higher peaking TPS values.

You may wonder why is it so good? Because we're using packet-switching
networks mostly and a packet is a packet almost irrespectively of how bit it
is. Yet a packet has some maximum possible size (hi, MTU) and this size most
of the time is 1500 (or a little less than that, hi VPN). Subtract IP header
(20 for IPv4 or 40 for IPv6 not counting options), TCP header (another 20) and
Neo message/payload headers (~8 for this case) and we have just a little more
than 1400 bytes for our dear hashes. Which means that in a single packet most
of the time we can have 42-44 of them, maybe 45. Choosing between these
numbers is not hard then.
2022-10-24 14:44:19 +03:00
Roman Khimov
9d6b18adec network: drop minPoolCount magic constant
We have AttemptConnPeers that is closely related, the more we have there the
bigger the network supposedly is, so it's much better than magic minPoolCount.
2022-10-24 14:36:10 +03:00
Roman Khimov
af24051bf5 network: sleep a bit before retrying reconnects
If Dial() is to exit quickly we can end up in a retry loop eating CPU.
2022-10-24 14:34:48 +03:00
Roman Khimov
a17d9f80a4
Merge pull request #2759 from nspcc-dev/avoid-db-lookup-in-hasblock
core: optimize HasBlock check for recent blocks
2022-10-24 14:33:38 +07:00
Roman Khimov
f42b8e78fc
Merge pull request #2758 from nspcc-dev/check-inflight-tx-invs
network: check inv against currently processed transactions
2022-10-24 14:16:33 +07:00
Roman Khimov
52df03ecbc
Merge pull request #2757 from nspcc-dev/batched-getdata
network: batch getdata replies
2022-10-24 14:15:55 +07:00
Roman Khimov
0551ddff4e
Merge pull request #2749 from nspcc-dev/rpc-waiter
rpc: implement transaction awaiting
2022-10-24 13:08:06 +07:00
Anna Shaleva
3cccc89dac rpc: add Wait wrapper to Notary actor 2022-10-24 06:09:36 +03:00
Anna Shaleva
1a6f1c805c rpc: fix race in TestWSClientEvents
```
2022-10-21T08:59:45.2219797Z === RUN   TestWSClientEvents/default_ntf_channel
2022-10-21T08:59:45.2219901Z ==================
2022-10-21T08:59:45.2220017Z WARNING: DATA RACE
2022-10-21T08:59:45.2220177Z Write at 0x00c000c82778 by goroutine 371:
2022-10-21T08:59:45.2220580Z   github.com/nspcc-dev/neo-go/pkg/rpcclient.TestWSClientEvents.func2()
2022-10-21T08:59:45.2221112Z       /home/runner/work/neo-go/neo-go/pkg/rpcclient/wsclient_test.go:171 +0x1c4
2022-10-21T08:59:45.2221244Z   testing.tRunner()
2022-10-21T08:59:45.2221617Z       /opt/hostedtoolcache/go/1.18.7/x64/src/testing/testing.go:1439 +0x213
2022-10-21T08:59:45.2221759Z   testing.(*T).Run.func1()
2022-10-21T08:59:45.2222124Z       /opt/hostedtoolcache/go/1.18.7/x64/src/testing/testing.go:1486 +0x47
2022-10-21T08:59:45.2222138Z
2022-10-21T08:59:45.2222308Z Previous read at 0x00c000c82778 by goroutine 37:
2022-10-21T08:59:45.2222694Z   github.com/nspcc-dev/neo-go/pkg/rpcclient.(*Client).StateRootInHeader()
2022-10-21T08:59:45.2223151Z       /home/runner/work/neo-go/neo-go/pkg/rpcclient/rpc.go:1104 +0xb0
2022-10-21T08:59:45.2223482Z   github.com/nspcc-dev/neo-go/pkg/rpcclient.(*WSClient).wsReader()
2022-10-21T08:59:45.2224077Z       /home/runner/work/neo-go/neo-go/pkg/rpcclient/wsclient.go:210 +0x651
2022-10-21T08:59:45.2224416Z   github.com/nspcc-dev/neo-go/pkg/rpcclient.NewWS.func2()
2022-10-21T08:59:45.2224892Z       /home/runner/work/neo-go/neo-go/pkg/rpcclient/wsclient.go:149 +0x39
2022-10-21T08:59:45.2224901Z
2022-10-21T08:59:45.2225049Z Goroutine 371 (running) created at:
2022-10-21T08:59:45.2225182Z   testing.(*T).Run()
2022-10-21T08:59:45.2225548Z       /opt/hostedtoolcache/go/1.18.7/x64/src/testing/testing.go:1486 +0x724
2022-10-21T08:59:45.2225911Z   github.com/nspcc-dev/neo-go/pkg/rpcclient.TestWSClientEvents()
2022-10-21T08:59:45.2226408Z       /home/runner/work/neo-go/neo-go/pkg/rpcclient/wsclient_test.go:167 +0x404
2022-10-21T08:59:45.2226539Z   testing.tRunner()
2022-10-21T08:59:45.2226900Z       /opt/hostedtoolcache/go/1.18.7/x64/src/testing/testing.go:1439 +0x213
2022-10-21T08:59:45.2227042Z   testing.(*T).Run.func1()
2022-10-21T08:59:45.2227398Z       /opt/hostedtoolcache/go/1.18.7/x64/src/testing/testing.go:1486 +0x47
2022-10-21T08:59:45.2227406Z
2022-10-21T08:59:45.2227552Z Goroutine 37 (finished) created at:
2022-10-21T08:59:45.2227851Z   github.com/nspcc-dev/neo-go/pkg/rpcclient.NewWS()
2022-10-21T08:59:45.2228327Z       /home/runner/work/neo-go/neo-go/pkg/rpcclient/wsclient.go:149 +0x6fb
2022-10-21T08:59:45.2228843Z   github.com/nspcc-dev/neo-go/pkg/rpcclient.TestWSClientEvents.func2()
2022-10-21T08:59:45.2229434Z       /home/runner/work/neo-go/neo-go/pkg/rpcclient/wsclient_test.go:168 +0x131
2022-10-21T08:59:45.2229569Z   testing.tRunner()
2022-10-21T08:59:45.2229930Z       /opt/hostedtoolcache/go/1.18.7/x64/src/testing/testing.go:1439 +0x213
2022-10-21T08:59:45.2230069Z   testing.(*T).Run.func1()
2022-10-21T08:59:45.2230424Z       /opt/hostedtoolcache/go/1.18.7/x64/src/testing/testing.go:1486 +0x47
2022-10-21T08:59:45.2230526Z ==================
2022-10-21T08:59:45.2230703Z     wsclient_test.go:186:
2022-10-21T08:59:45.2230988Z         	Error Trace:	wsclient_test.go:186
2022-10-21T08:59:45.2231209Z         	Error:      	Should be true
2022-10-21T08:59:45.2231536Z         	Test:       	TestWSClientEvents/default_ntf_channel
2022-10-21T08:59:45.2231812Z     testing.go:1312: race detected during execution of test
```
2022-10-24 06:09:36 +03:00
Anna Shaleva
d2a9e9120d rpc: extend Waiter interface to wait for several txs with context 2022-10-24 06:09:36 +03:00
Anna Shaleva
6b216050f3 rpc: add compat tests for RPC* interfaces and Client implementations 2022-10-24 06:09:36 +03:00
Anna Shaleva
00d44235c1 rpc: add tests for RPC waiters 2022-10-24 06:09:36 +03:00
Anna Shaleva
388112dcaa rpc: mark old WSClient's SubscribeFor* methods as deprecated 2022-10-24 06:09:36 +03:00
Anna Shaleva
5b81cb065f rpc: refactor waiter-related actor code 2022-10-24 06:09:36 +03:00
Anna Shaleva
8e84bb51d5 rpc: add "till" filter to WS block events 2022-10-24 06:09:36 +03:00
Anna Shaleva
345d48d051 rpc: improve WS-based transaction awaiting
Subscribe only for required aers.
2022-10-24 06:09:36 +03:00
Anna Shaleva
d7c1f3eac7 rpc: add "container" filter to WS execution notifications 2022-10-24 06:09:36 +03:00
Anna Shaleva
71069b0ed0 rpc: improve WS-enabled transaction awaiting
Fetch blocks since VUB+1, if block received and we haven't returned the
result yet, then transaction wasn't accepted at all.
2022-10-24 06:09:36 +03:00
Anna Shaleva
673a495527 rpc: add "since" filter to WS block events 2022-10-24 06:09:36 +03:00
Anna Shaleva
10a0716217 rpc: implement transaction awaiting functionality
Close #2704.
2022-10-24 06:09:36 +03:00
Anna Shaleva
6d38e75149 rpc: support multiple WSClient notification receivers 2022-10-24 06:09:36 +03:00
Anna Shaleva
4ce6bc6a66 rpc: adjust comment to Notification value cast
And explicitly specify field names on Notification creation.
2022-10-24 06:09:36 +03:00
Roman Khimov
0c3b03617e core: optimize HasBlock check for recent blocks
When block is being spread through the network we can get a lot of invs with
the same hash. Some more stale nodes may also announce previous or some
earlier block. We can avoid full DB lookup for them and minimize inv handling
time (timeouts in inv handler had happened in #2744).

It doesn't affect tests, just makes node a little less likely to spend some
considerable amount of time in the inv handler.
2022-10-21 21:21:58 +03:00
Roman Khimov
e26055190e network: check inv against currently processed transactions
Sometimes we already have it, but it's not yet processed, so we can save on
getdata request. It only affects very high-speed networks like 4-1 scenario
and it doesn't affect it a lot, but still we can do it.
2022-10-21 21:16:18 +03:00
Roman Khimov
cfb5058018 network: batch getdata replies
This is not exactly the protocol-level batching as was tried in #1770 and
proposed by neo-project/neo#2365, but it's a TCP-level change in that we now
Write() a set of messages and given that Go sets up TCP sockets with
TCP_NODELAY by default this is a substantial change, we have less packets
generated with the same amount of data. It doesn't change anything on properly
connected networks, but the ones with delays benefit from it a lot.

This also improves queueing because we no longer generate 32 messages to
deliver on transaction's GetData, it's just one stream of bytes with 32
messages inside.

Do the same with GetBlocksByIndex, we can have a lot of messages there too.

But don't forget about potential peer DoS attacks, if a peer is to request a
lot of big blocks we need to flush them before we process the whole set.
2022-10-21 17:16:32 +03:00
Roman Khimov
bf4636f70a
Merge pull request #2755 from nspcc-dev/improve-networking
Improve P2P transaction handling
2022-10-21 16:22:02 +07:00
Roman Khimov
e1b5ac9b81 network: separate tx handling from msg handling
This allows to naturally scale transaction processing if we have some peer
that is sending a lot of them while others are mostly silent. It also can help
somewhat in the event we have 50 peers that all send transactions. 4+1
scenario benefits a lot from it, while 7+2 slows down a little. Delayed
scenarios don't care.

Surprisingly, this also makes disconnects (#2744) much more rare, 4-node
scenario almost never sees it now. Most probably this is the case where peers
affect each other a lot, single-threaded transaction receiver can be slow
enough to trigger some timeout in getdata handler of its peer (because it
tries to push a number of replies).
2022-10-21 12:11:24 +03:00
Roman Khimov
09015e06d5
Merge pull request #2754 from nspcc-dev/move-neofs-mainnet-fork-date
config: reschedule Aspidochelone fork block for NeoFS mainnet
2022-10-21 16:02:23 +07:00
Roman Khimov
e003b67418 network: reuse inventory hash list for request hashes
Microoptimization, we can do this because we only use them in handleInvCmd().
2022-10-21 11:28:40 +03:00
Roman Khimov
831067c29e config: reschedule Aspidochelone fork block for NeoFS mainnet
We can't make it before 2550000, so move to 2600000. @anatoly-bogatyrev,
please ensure you're using this new height for mainnet NeoFS configurations
next week.
2022-10-21 10:52:11 +03:00
Roman Khimov
295add052b
Merge pull request #2752 from nspcc-dev/initialize-dbft-with-previous-timestamp
dbft: rev up, fix context timestamp initialization
2022-10-20 16:53:08 +07:00
Roman Khimov
493b979b95 dbft: rev up, fix context timestamp initialization
See nspcc-dev/dbft#64, fixes #2753.
2022-10-20 12:38:14 +03:00
Roman Khimov
0f625f04f0
Merge pull request #2748 from nspcc-dev/stop-tx-flow
network/consensus: use new dbft StopTxFlow callback
2022-10-18 16:29:37 +07:00
Roman Khimov
73ce898e27 network/consensus: use new dbft StopTxFlow callback
It makes sense in general (further narrowing down the time window when
transactions are processed by consensus thread) and it improves block times a
little too, especially in the 7+2 scenario.

Related to #2744.
2022-10-18 11:06:20 +03:00
Roman Khimov
903beeb5df
Merge pull request #2750 from nspcc-dev/network-prometheus-metrics
network: add prometheus histogram with cmd processing time
2022-10-18 13:07:50 +07:00
Roman Khimov
2791127ee4 network: add prometheus histogram with cmd processing time
It can be useful to detect some performance issues.
2022-10-17 22:51:16 +03:00
Roman Khimov
73079745ab
Merge pull request #2746 from nspcc-dev/optimize-tx-callbacks
network: only call tx callback if we're waiting for transactions
2022-10-17 16:39:41 +07:00
Roman Khimov
45f4e8c649
Merge pull request #2747 from aprasolova/codeowners
Add CODEOWNERS file
2022-10-17 13:37:25 +07:00
anastasia prasolova
f843b983ef Add CODEOWNERS file
Signed-off-by: anastasia prasolova <anastasia@nspcc.ru>
2022-10-16 21:14:58 +03:00
Roman Khimov
dce9f80585
Merge pull request #2743 from nspcc-dev/log-fan-out
Logarithmic gossip fan out
2022-10-14 23:18:34 +07:00
Roman Khimov
4dd3fd4ac0 network: only call tx callback if we're waiting for transactions
Until the consensus process starts for a new block and until it really needs
some transactions we can spare some cycles by not delivering transactions to
it. In tests this doesn't affect TPS, but makes block delays a bit more
stable. Related to #2744, I think it also may cause timeouts during
transaction processing (waiting on the consensus process channel while it does
something dBFT-related).
2022-10-14 18:45:48 +03:00
Roman Khimov
65f0fadddb network: register peer only if it's not a duplicate 2022-10-14 15:53:32 +03:00
Roman Khimov
851cbc7dab network: implement adaptive peer requests
When the network is big enough, MinPeers may be suboptimal for good network
connectivity, but if we know the network size we can do some estimation on the
number of sufficient peers.
2022-10-14 15:53:32 +03:00
Roman Khimov
c17b2afab5 network: add BroadcastFactor to control gossip, fix #2678 2022-10-14 15:53:32 +03:00
Roman Khimov
3ed140abbf config: raise mainnet/testnet MinPeers to 10
That's the configuration C# node has by default and 5 is really a very small
number of peers.
2022-10-14 15:53:32 +03:00
Roman Khimov
215e8704f1 network: simplify discoverer, make it almost a lib
We already have two basic lists: connected and unconnected nodes, we don't
need an additional channel and we don't need a goroutine to handle it.
2022-10-14 15:53:32 +03:00
Roman Khimov
c1ef326183 network: re-add addresses to the pool on UnregisterConnectedAddr
That's what we do anyway, but this way we can be a bit more efficient.
2022-10-14 14:12:33 +03:00
Roman Khimov
631f166709 network: broadcast to log-dependent number of nodes
Fixes #608.
2022-10-14 14:12:33 +03:00
Roman Khimov
c3001bc5bd
Merge pull request #2740 from nspcc-dev/cli-improvement
cli: improve VM CLI a bit more
2022-10-13 20:21:47 +07:00
Anna Shaleva
8b91428db8 cli: unify documentation of VM CLI commands
1. UsageText shows the command usage rule. Fixed/added where needed.
2. Description shows the command description, huh. It is shown right after
   UsageText, so there's no need to repeat the command usage rule. If
   Description contains Example, then it should be printed on a new line.
2022-10-13 16:07:34 +03:00
Anna Shaleva
62197929f4 cli: unify the style of Usage message for VM CLI commands
Usage message is shown on common --help command, thus it should be meaningful
and short. If user needs more detailed command description, then he can use
command-specific help.

As a result, current VM help looks pretty simple:
```
NEO-GO-VM > help
NAME:
   VM CLI - Official VM CLI for Neo-Go

USAGE:
    [global options] command [command options] [arguments...]

VERSION:
   0.99.5-pre-15-g5463ec41

COMMANDS:
   exit          Exit the VM prompt
   ip            Show current instruction
   break         Place a breakpoint
   jump          Jump to the specified instruction (absolute IP value)
   estack        Show evaluation stack contents
   istack        Show invocation stack contents
   sslot         Show static slot contents
   lslot         Show local slot contents
   aslot         Show arguments slot contents
   loadnef       Load a NEF-consistent script into the VM optionally attaching to it provided signers with scopes
   loadbase64    Load a base64-encoded script string into the VM optionally attaching to it provided signers with scopes
   loadhex       Load a hex-encoded script string into the VM optionally attaching to it provided signers with scopes
   loadgo        Compile and load a Go file with the manifest into the VM optionally attaching to it provided signers with scopes
   loadtx        Load transaction into the VM from chain or from parameter context file
   loaddeployed  Load deployed contract into the VM from chain optionally attaching to it provided signers with scopes
   reset         Unload compiled script from the VM and reset context to proper (possibly, historic) state
   parse         Parse provided argument and convert it into other possible formats
   run           Execute the current loaded script
   cont          Continue execution of the current loaded script
   step          Step (n) instruction in the program
   stepinto      Stepinto instruction to take in the debugger
   stepout       Stepout instruction to take in the debugger
   stepover      Stepover instruction to take in the debugger
   ops           Dump opcodes of the current loaded program
   events        Dump events emitted by the current loaded program
   env           Dump state of the chain that is used for VM CLI invocations (use -v for verbose node configuration)
   storage       Dump storage of the contract with the specified hash, address or ID as is at the current stage of script invocation
   changes       Dump storage changes as is at the current stage of loaded script invocation
   help, h       Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --help, -h     show help
   --version, -v  print the version

```
2022-10-13 16:07:34 +03:00
Anna Shaleva
884428ab93 cli: add 'jump' command
Close #2606.
2022-10-13 16:07:34 +03:00
Anna Shaleva
811e09675f cli: simplify VM preparation for VM CLI
Load script from provided transaction if so.
2022-10-13 16:07:34 +03:00
Anna Shaleva
7db9258104 vm: make LoadFileWithFlags actually load with flags provided 2022-10-13 16:07:34 +03:00
Anna Shaleva
d09a0c18a7 cli: unify signers parsing
Share signers parsing code between 'contract invokefunction' and
'vm load*' commands, quite a useful thing when it comes to witness
checks.
2022-10-13 16:07:34 +03:00
Anna Shaleva
4dbaf2a123 smartcontract: add comment to GetCompleteTransaction 2022-10-13 16:07:34 +03:00
Anna Shaleva
af658bc3e5 cli: support Null as an argument for invocation-related commands 2022-10-13 16:07:31 +03:00
Roman Khimov
cff3cd906b
Merge pull request #2742 from nspcc-dev/network-code-cleanup
Some network code cleanup
2022-10-13 12:39:24 +07:00
Anna Shaleva
7eb87afab8 cli: unify parameters parsing
Share parameters parsing code between 'contract invokefunction' and
'vm run' commands. It allows VM CLI to parse more complicated parameter
types including arrays and file-backed bytestrings.
2022-10-13 08:20:27 +03:00
Roman Khimov
dc62046019 network: add network size estimation metric 2022-10-12 22:29:55 +03:00
Roman Khimov
bcf77c3c42 network: filter out not-yet-ready nodes when broadcasting
They can fail right in the getPeers or they can fail later when packet send
is attempted. Of course they can complete handshake in-between these events,
but most likely they won't and we'll waste more resources on this attempt. So
rule out bad peers immediately.
2022-10-12 16:51:01 +03:00
Roman Khimov
137f2cb192 network: deduplicate TCPPeer code a bit
context.Background() is never canceled and has no deadline, so we can avoid
duplicating some code.
2022-10-12 15:43:31 +03:00
Roman Khimov
104da8caff network: broadcast messages, enqueue packets
Drop EnqueueP2PPacket, replace EnqueueHPPacket with EnqueueHPMessage. We use
Enqueue* when we have a specific per-peer message, it makes zero sense
duplicating serialization code for it (unlike Broadcast*).
2022-10-12 15:39:20 +03:00
Roman Khimov
d5f2ad86a1 network: drop unused EnqueueMessage interface from Peer 2022-10-12 15:27:08 +03:00
Roman Khimov
b345581c72 network: pings are broadcasted, don't send them to everyone
Follow the general rules of broadcasts, even though it's somewhat different
from Inv, we just want to get some reply from our neighbors to see if we're
behind. We don't strictly need all neighbors for it.
2022-10-12 15:25:03 +03:00
Anna Shaleva
3fba4e4f17 cli: support 'loaddeployed' VM CLI command 2022-10-12 14:57:13 +03:00
Anna Shaleva
9977606e40 cli: support 'loadtx' VM CLI command 2022-10-12 14:57:10 +03:00
Roman Khimov
ec4983e88e
Merge pull request #2741 from nspcc-dev/separate-broadcast-queue-handling
Rework broadcast logic
2022-10-12 16:33:27 +07:00
Roman Khimov
e1d5f18ff4 network: fix outdated Peer interface comments 2022-10-12 10:16:07 +03:00
Roman Khimov
8b26d9475b network: speculatively set GetAddrSent status
Otherwise we routinely get "unexpected addr received" error.
2022-10-11 18:42:40 +03:00
Roman Khimov
e80c60a3b9 network: rework broadcast logic
We have a number of queues for different purposes:
 * regular broadcast queue
 * direct p2p queue
 * high-priority queue

And two basic egress scenarios:
 * direct p2p messages (replies to requests in Server's handle* methods)
 * broadcasted messages

Low priority broadcasted messages:
 * transaction inventories
 * block inventories
 * notary inventories
 * non-consensus extensibles

High-priority broadcasted messages:
 * consensus extensibles
 * getdata transaction requests from consensus process
 * getaddr requests

P2P messages are a bit more complicated, most of the time they use p2p queue,
but extensible message requests/replies use HP queue.

Server's handle* code is run from Peer's handleIncoming, every peer has this
thread that handles incoming messages. When working with the peer it's
important to reply to requests and blocking this thread until we send (queue)
a reply is fine, if the peer is slow we just won't get anything new from
it. The queue used is irrelevant wrt this issue.

Broadcasted messages are radically different, we want them to be delivered to
many peers, but we don't care about specific ones. If it's delivered to 2/3 of
the peers we're fine, if it's delivered to more of them --- it's not an
issue. But doing this fairly is not an easy thing, current code tries performing
unblocked sends and if this doesn't yield enough results it then blocks (but
has a timeout, we can't wait indefinitely). But it does so in sequential
manner, once the peer is chosen the code will wait for it (and only it) until
timeout happens.

What can be done instead is an attempt to push the message to all of the peers
simultaneously (or close to that). If they all deliver --- OK, if some block
and wait then we can wait until _any_ of them pushes the message through (or
global timeout happens, we still can't wait forever). If we have enough
deliveries then we can cancel pending ones and it's again not an error if
these canceled threads still do their job.

This makes the system more dynamic and adds some substantial processing
overhead, but it's a networking code, any of this overhead is much lower than
the actual packet delivery time. It also allows to spread the load more
fairly, if there is any spare queue it'll get the packet and release the
broadcaster. On the next broadcast iteration another peer is more likely to be
chosen just because it didn't get a message previously (and had some time to
deliver already queued messages).

It works perfectly in tests, with optimal networking conditions we have much
better block times and TPS increases by 5-25%% depending on the scenario.

I'd go as far as to say that it fixes the original problem of #2678, because
in this particular scenario we have empty queues in ~100% of the cases and
this new logic will likely lead to 100% fan out in this case (cancelation just
won't happen fast enough). But when the load grows and there is some waiting
in the queue it will optimize out the slowest links.
2022-10-11 18:42:40 +03:00
Roman Khimov
0294e2eb18
Merge pull request #2738 from nspcc-dev/dont-block-forever-2
network: don't wait indefinitely for packet to be sent
2022-10-11 19:40:10 +07:00
Roman Khimov
44df4b9dbb
Merge pull request #2739 from nspcc-dev/fix-sc-conversion
smartcontract: fix underlying PublicKey parameter value
2022-10-11 18:06:19 +07:00
Anna Shaleva
641abd4d1c smartcontract: fix underlying PublicKey parameter value
Value of PublicKey parameter always stores public key bytes, not the
deserialized representation. All other code (CLI parameters parsing with
its NewParameterFromString, Parameter unmarshaller, etc.) is based on
the idea that value of PublicKey is []byte.
2022-10-11 13:50:32 +03:00
Roman Khimov
dabdad20ad network: don't wait indefinitely for packet to be sent
Peers can be slow, very slow, slow enough to affect node's regular
operation. We can't wait for them indefinitely, there has to be a timeout for
send operations.

This patch uses TimePerBlock as a reference for its timeout. It's relatively
big and it doesn't affect tests much, 4+1 scenarios tend to perform a little
worse with while 7+2 scenarios work a little better. The difference is in some
percents, but all of these tests easily have 10-15% variations from run to
run.

It's an important step in making our gossip better because we can't have any
behavior where neighbors directly block the node forever, refs. #2678 and
2022-10-10 22:15:21 +03:00
Roman Khimov
478b4b0c1c
Merge pull request #2737 from nspcc-dev/fix-win-cleanup
cli: properly cleanup state-dependand VM CLI
2022-10-10 15:49:18 +07:00
Anna Shaleva
63fddb3f1a core: close BoltDB on failed root bucket creation 2022-10-10 10:12:34 +03:00
Anna Shaleva
343ce4d4bb cli: properly cleanup state-dependand VM CLI
Close #2736.
2022-10-10 08:26:22 +03:00
Roman Khimov
f86cdd95b2
Merge pull request #2735 from nspcc-dev/changelog-0.99.4
CHANGELOG: 0.99.4
2022-10-07 21:23:48 +07:00
Roman Khimov
1426b54fd7
Merge pull request #2723 from nspcc-dev/smart-vm-cli
vm: make VM CLI state-dependant
2022-10-07 21:21:11 +07:00
Roman Khimov
4d2afa2624 cli/vm: use ParseInt to properly (and easily) check for int32 2022-10-07 17:10:04 +03:00
Anna Shaleva
735db08f84 services: adjust RPC server's getHistoricParams
Update documentation and add index upper bound check to get rid of
CodeQL warning.
2022-10-07 16:06:12 +03:00
Anna Shaleva
eac5e1526e cli: rename VMCLI to CLI 2022-10-07 15:57:33 +03:00
Anna Shaleva
16f5ae3812 cli: add upper bound check for contract ID for 'storage' VM CLI cmd 2022-10-07 15:57:33 +03:00
Anna Shaleva
95cbddf19e cli: use custom logger to filter out runtime.Log messages
```
anna@kiwi:~/Documents/GitProjects/nspcc-dev/neo-go$ ./bin/neo-go vm -p

    _   ____________        __________      _    ____  ___
   / | / / ____/ __ \      / ____/ __ \    | |  / /  |/  /
  /  |/ / __/ / / / /_____/ / __/ / / /____| | / / /|_/ /
 / /|  / /___/ /_/ /_____/ /_/ / /_/ /_____/ |/ / /  / /
/_/ |_/_____/\____/      \____/\____/      |___/_/  /_/

NEO-GO-VM > loadgo ./1-print/1-print.go
READY: loaded 21 instructions
NEO-GO-VM 0 > run
2022-10-07T15:28:20.461+0300	INFO	runtime log	{"tx": "", "script": "db03ceb3f672ee8cd0d714989b4d103ff7eed2f3", "msg": "Hello, world!"}
[]
```
2022-10-07 15:57:33 +03:00
Anna Shaleva
b2cd007d8d cli: move handleLoggingParams to 'options' package
It will be reused by other CLI packages.
2022-10-07 15:57:33 +03:00
Anna Shaleva
b3c8192d2e cli: add 'changes' command for VM CLI 2022-10-07 15:57:31 +03:00
Anna Shaleva
cac4f6a4a6 cli: allow to dump storage diff for 'storage' VM CLI command 2022-10-07 15:56:34 +03:00
Anna Shaleva
0db4e8d62c core: allow to perform storage search within given amount of DAO layers 2022-10-07 15:56:34 +03:00
Anna Shaleva
8c78177806 vm: add 'storage' VM CLI command to dump storage items
Another nice one, very useful for debugging.
2022-10-07 15:56:34 +03:00
Anna Shaleva
ff03c33e6d vm: allow historic calls inside VM CLI 2022-10-07 15:56:34 +03:00
Anna Shaleva
79e13f73d8 core, rpc: move getFakeNextBlock to Blockchain
It's needed for VM CLI as far and may be improved later.
2022-10-07 15:56:34 +03:00
Anna Shaleva
0036c89d63 vm: add 'env' command showing state of the blockchain-backed VM CLI
A useful one.
2022-10-07 15:56:34 +03:00
Anna Shaleva
f1ecdb82cc vm: add 'events' command to VM CLI
And dump events automatically after HALTed or FAULTed end of execution.
2022-10-07 15:56:34 +03:00
Anna Shaleva
f45d8fc08d vm: remove default syscall handler
It's not needed anymore. Close #1075.
2022-10-07 15:56:34 +03:00
Anna Shaleva
33ae8d0ddc vm: clear manifest on VM CLI reset
Fix the bug when outdated manifest was stored after new program was loaded.
2022-10-07 15:56:34 +03:00
Anna Shaleva
513821cfff vm: allow to provide state for VM CLI
Close #2528.

Also, add new simple testchain as an analogue for basicchain.
2022-10-07 15:56:34 +03:00
Anna Shaleva
0b717b0c22 vm: move vm CLI to cli/vm package 2022-10-07 15:56:34 +03:00
Anna Shaleva
4a46001746 smartcontract: fix error message for CreateMultiSigRedeemScript 2022-10-07 15:56:34 +03:00
Anna Shaleva
a91cf2a007 core: set default SecondsPerBlock value on blockchain creation
As mentioned in the node configuration docs.
2022-10-07 15:56:34 +03:00
Anna Shaleva
70e59d83c9 docs: fix supported database types 2022-10-07 15:56:34 +03:00
Anna Shaleva
2f5137e9b7 core: allow RO mode for Bolt and Level 2022-10-07 15:56:29 +03:00
Roman Khimov
d93f3f416a CHANGELOG: 0.99.4 2022-10-07 12:10:15 +03:00
Roman Khimov
da70b9e5ec
Merge pull request #2730 from nspcc-dev/neofs-configs
config: add NeoFS network configurations, fix #2714
2022-10-07 12:51:43 +07:00
Roman Khimov
5c94ffab37
Merge pull request #2731 from nspcc-dev/cli-tx-outs
Add ability to save any tx in the CLI
2022-10-07 12:47:17 +07:00
Roman Khimov
0efe3dd42c cli: deduplicate smartcontract/wallet tx confirm/sign/save/send
It's the same code.
2022-10-06 23:03:32 +03:00
Roman Khimov
5200765dab cli/wallet: add out/force flags to claim/candidate cmds
Fixes #2669.
2022-10-06 22:19:40 +03:00
Roman Khimov
5bafa5f6b4 cli/wallet: add sysgas option to candidate and claim commands
It doesn't make a lot of sense, but hey, it's a transaction, it can have a bit
more GAS.
2022-10-06 22:09:32 +03:00
Roman Khimov
1ea06e9757 cli/wallet: unify claim and candidate code
Add -g option to claim which doesn't have a lot of sense, but can be used
anyway.
2022-10-06 21:52:40 +03:00
Roman Khimov
d9f3ff3969 config: add NeoFS network configurations, fix #2714 2022-10-06 18:57:04 +03:00
Anna Shaleva
cbdd45cc96 core: return error on root BoltDB bucket creation if so 2022-10-06 14:01:56 +03:00
Anna Shaleva
03a1cf9f59 core: simplify newLevelDBForTesting function 2022-10-06 14:01:56 +03:00
Anna Shaleva
c4c93b591e cli: remove debug flag from VM CLI
It's not used.
2022-10-06 14:01:56 +03:00
Anna Shaleva
5698ce03be cli: move debug flag to options package 2022-10-06 14:01:56 +03:00
Anna Shaleva
37571162a0 cli: move config path flag to options package 2022-10-06 14:01:56 +03:00
Roman Khimov
4616600636
Merge pull request #2728 from nspcc-dev/fix-vub-comment
core: add example to VUB comment
2022-10-06 16:33:24 +07:00
Anna Shaleva
78cd2b4566 core: add example to VUB comment 2022-10-06 10:32:18 +03:00
Roman Khimov
1c99c21d9a
Merge pull request #2725 from nspcc-dev/move-cli-tests
Move CLI tests
2022-10-06 13:43:39 +07:00
Roman Khimov
29e858df66 cli: move nep11/nep17 tests into a package of their own
The tests are still there, coverage should counted fine, but it improves things:

?       github.com/nspcc-dev/neo-go/cli [no test files]
ok      github.com/nspcc-dev/neo-go/cli/app     0.058s  coverage: 100.0% of statements
ok      github.com/nspcc-dev/neo-go/cli/cmdargs 0.005s  coverage: 60.8% of statements
ok      github.com/nspcc-dev/neo-go/cli/flags   0.027s  coverage: 97.7% of statements
?       github.com/nspcc-dev/neo-go/cli/input   [no test files]
ok      github.com/nspcc-dev/neo-go/cli/nep_test        30.443s coverage: [no statements]
ok      github.com/nspcc-dev/neo-go/cli/options 0.054s  coverage: 50.0% of statements
?       github.com/nspcc-dev/neo-go/cli/paramcontext    [no test files]
ok      github.com/nspcc-dev/neo-go/cli/query   2.089s  coverage: 45.3% of statements
ok      github.com/nspcc-dev/neo-go/cli/server  1.510s  coverage: 67.8% of statements
ok      github.com/nspcc-dev/neo-go/cli/smartcontract   8.433s  coverage: 94.3% of statements
ok      github.com/nspcc-dev/neo-go/cli/util    0.013s  coverage: 10.9% of statements
?       github.com/nspcc-dev/neo-go/cli/vm      [no test files]
ok      github.com/nspcc-dev/neo-go/cli/wallet  47.252s coverage: 63.0% of statements
2022-10-06 09:21:26 +03:00
Roman Khimov
1ac60ada19 cli: move tests to subpackages
Refs. #2379, but not completely solves it, one package seriously outweights
others:

?       github.com/nspcc-dev/neo-go/cli [no test files]
ok      github.com/nspcc-dev/neo-go/cli/app     0.036s  coverage: 100.0% of statements
ok      github.com/nspcc-dev/neo-go/cli/cmdargs 0.011s  coverage: 60.8% of statements
ok      github.com/nspcc-dev/neo-go/cli/flags   0.009s  coverage: 97.7% of statements
?       github.com/nspcc-dev/neo-go/cli/input   [no test files]
ok      github.com/nspcc-dev/neo-go/cli/options 0.033s  coverage: 50.0% of statements
?       github.com/nspcc-dev/neo-go/cli/paramcontext    [no test files]
ok      github.com/nspcc-dev/neo-go/cli/query   2.155s  coverage: 45.3% of statements
ok      github.com/nspcc-dev/neo-go/cli/server  1.373s  coverage: 67.8% of statements
ok      github.com/nspcc-dev/neo-go/cli/smartcontract   8.819s  coverage: 94.3% of statements
ok      github.com/nspcc-dev/neo-go/cli/util    0.006s  coverage: 10.9% of statements
?       github.com/nspcc-dev/neo-go/cli/vm      [no test files]
ok      github.com/nspcc-dev/neo-go/cli/wallet  72.103s coverage: 88.2% of statements

Still a nice thing to have.
2022-10-06 09:21:26 +03:00
Roman Khimov
c50cda713a
Merge pull request #2726 from nspcc-dev/release-doc
docs: update release instruction
2022-10-06 13:19:57 +07:00
Roman Khimov
ece5fe731e
Merge pull request #2727 from nspcc-dev/test
.github: give proper names to CLI binaries and artifact archives
2022-10-06 13:19:45 +07:00
Roman Khimov
1ad416a973 docs: update release instruction
It can be simplified after b27e6918bd and
2022-10-06 08:53:46 +03:00
Anna Shaleva
cd7cd02c33 .github: exclude macOS amd64 binary from build CLI job 2022-10-06 08:51:37 +03:00
Anna Shaleva
a9d32fe8f6 .github: give proper names to CLI binaries and artifact archives 2022-10-06 07:39:31 +03:00
Roman Khimov
1c376ffa62
Merge pull request #2724 from nspcc-dev/rpc-options
rpcsrv: handle preflight OPTIONS with CORS kludge, fix #2721
2022-10-05 17:02:55 +07:00
Roman Khimov
b48d02f4a6 rpcsrv: handle preflight OPTIONS with CORS kludge, fix #2721 2022-10-05 11:09:45 +03:00
Roman Khimov
3609f26cc0
Merge pull request #2710 from nspcc-dev/check-notification-abi-compiliance
runtime: check notifications against ABI
2022-10-05 15:06:39 +07:00
Roman Khimov
8893163803 smartcontract: define parameter lengths as constants and use them 2022-10-05 10:46:21 +03:00
Roman Khimov
317dd42513 *: use uint*Size and SignatureLen constants where appropriate 2022-10-05 10:45:52 +03:00
Roman Khimov
79887f9d78 runtime: check notifications against ABI
Related to #2703, just a logged thing for now.
2022-10-04 17:52:38 +03:00
Roman Khimov
48567fbc61
Merge pull request #2722 from nspcc-dev/docs/cfg-mvub
docs: add MaxValidUntilBlockIncrement to config docs
2022-10-03 18:56:20 +07:00
Anna Shaleva
23795ab6e0 docs: add MaxValidUntilBlockIncrement to config docs 2022-10-03 13:13:20 +03:00
Roman Khimov
7d0840d5d5
Merge pull request #2720 from nspcc-dev/notifications-check
compiler: enforce runtime.Notify parameters cast to proper type
2022-10-01 03:02:29 +07:00
Anna Shaleva
554e48e7b7 compiler: enforce runtime.Notify parameters cast
If notification parameters type can be defined in a compile time then enforce
parameter cast to the desired type got from manifest.
2022-09-30 14:42:43 +03:00
Anna Shaleva
80f71a4e6e compiler: do not enforce variadic event args check on ellipsis usage
In case of ellipsis usage compiler defines argument type as ArrayT
(which is correct, because it's a natural representation of the last
argument, it represents the array of interface{}).
Here goes the problem:
```
=== RUN   TestEventWarnings/variadic_event_args_via_ellipsis
    compiler_test.go:251:
        	Error Trace:	compiler_test.go:251
        	Error:      	Received unexpected error:
        	            	event 'Event' should have 'Integer' as type of 1 parameter, got: Array
        	Test:       	TestEventWarnings/variadic_event_args_via_ellipsis
```

Parsing the last argument in this case is a separate complicated problem
due to the fact that we need to grab types of elements of []interface{} inside the
fully qualified ast node which may looks like:
```
runtime.Notify("Event", (append([]interface{}{1, 2}, (([]interface{}{someVar, 4}))...))...)
```

Temporary solution is to exclude such notifications from analysis until we're
able to properly resolve element types of []interface{}.
2022-09-30 08:42:48 +03:00
Anna Shaleva
08427f23b6 compiler: do not check Any event parameter for compliance
It's possible that declared manifest event has parameter of AnyT for
those cases when parameter type differs from method to method. If so,
then we don't need to enforce type check after compilation.
2022-09-30 08:40:55 +03:00
Roman Khimov
b7be4edf7f
Merge pull request #2718 from nspcc-dev/ok-conversion
compiler: prohibit to compile type assertion with two return values
2022-09-29 02:54:03 +07:00
Anna Shaleva
b98848bf49 compiler: prohibit to compile type assertion with two return values
Close #2692.
2022-09-28 11:27:13 +03:00
Roman Khimov
b2b5303d06
Merge pull request #2716 from nspcc-dev/test
compiler: take into account inlined types info on `append` builtin handling
2022-09-28 13:56:02 +07:00
Anna Shaleva
1828e79412 compiler: add test for foreign function inlining 2022-09-27 15:36:06 +03:00
Anna Shaleva
9ee05d3241 examples: update neo-go dependency 2022-09-27 15:35:15 +03:00
Anna Shaleva
08e2511676 *: update interop dependency 2022-09-27 15:34:20 +03:00
Anna Shaleva
24c107e3a2 interop: refactor address.FromHash160 code
Make it more simple.
2022-09-27 15:32:57 +03:00
Anna Shaleva
5d578fdd95 compiler: consider inlined types info on "append" handling
We need to search for "append" argument type info not only inside local
package type info map, but also inside the inlined type info map.
Close #2696.
2022-09-27 15:32:51 +03:00
Roman Khimov
3dbd36ef70
Merge pull request #2712 from nspcc-dev/upd
*: update dependencies and adjust updator script
2022-09-23 14:08:04 +07:00
Anna Shaleva
c7ece79cb4 scripts: ignore go 1.16 compat for dependency updator script
Otherwise the following error occurs while updating dependency:
```
github.com/nspcc-dev/neo-go/examples/nft-nd-nns tested by
	github.com/nspcc-dev/neo-go/examples/nft-nd-nns.test imports
	github.com/nspcc-dev/neo-go/pkg/compiler imports
	gopkg.in/yaml.v3 tested by
	gopkg.in/yaml.v3.test imports
	gopkg.in/check.v1 imports
	github.com/kr/pretty loaded from github.com/kr/pretty@v0.1.0,
	but go 1.16 would select v0.3.0
github.com/nspcc-dev/neo-go/examples/nft-nd-nns tested by
	github.com/nspcc-dev/neo-go/examples/nft-nd-nns.test imports
	github.com/nspcc-dev/neo-go/pkg/compiler imports
	gopkg.in/yaml.v3 tested by
	gopkg.in/yaml.v3.test imports
	gopkg.in/check.v1 imports
	github.com/kr/pretty imports
	github.com/kr/text loaded from github.com/kr/text@v0.1.0,
	but go 1.16 would select v0.2.0

To upgrade to the versions selected by go 1.16:
	go mod tidy -go=1.16 && go mod tidy -go=1.17
If reproducibility with go 1.16 is not needed:
	go mod tidy -compat=1.17
For other options, see:
	https://golang.org/doc/modules/pruning
```
2022-09-23 09:05:08 +03:00
Anna Shaleva
4ca89d23ec examples: update neo-go dependency 2022-09-23 09:00:26 +03:00
Anna Shaleva
ae511447f9 *: update interop dependency 2022-09-23 08:58:55 +03:00
anastasia prasolova
2093bf806f [nspcc-dev/nspcc-infra#840]: Add DCO check
Signed-off-by: anastasia prasolova <anastasia@nspcc.ru>
2022-09-22 19:29:14 +03:00
Roman Khimov
29564bdda2
Merge pull request #2695 from nspcc-dev/call-version
interop: implement System.Contract.CallWithVersion
2022-09-21 21:53:01 +07:00
Anna Shaleva
bfc65d35ce examples: update neo-go dependency 2022-09-21 17:43:15 +03:00
Anna Shaleva
25667914fa *: update interop dependency 2022-09-21 17:40:34 +03:00
Anna Shaleva
ea08a81726 interop: add CallWithVersion helper 2022-09-21 17:38:42 +03:00
Anna Shaleva
df802b6fc6 vm: adjust emit.AppCall comment
There's no APPCALL anymore.
2022-09-21 17:25:45 +03:00
Roman Khimov
5eb4ba772f
Merge pull request #2708 from nspcc-dev/fix-it-doc
interop: adjust Iterator documentation
2022-09-21 14:36:07 +07:00
Anna Shaleva
8d5f97a699 interop: adjust Iterator documentation
The only way to get Iterator is as a result of storage.Find.
2022-09-20 17:09:48 +03:00
Roman Khimov
5a7ab2054d
Merge pull request #2698 from nspcc-dev/address-helpers
interop: add a couple of `interop.Hash160` encoding helpers
2022-09-20 17:07:00 +07:00
Anna Shaleva
293dbf3d1b compiler: adjust test's checkInstrCount
Remove unnecessary code.
2022-09-20 09:45:07 +03:00
Anna Shaleva
2b8271055f examples: update neo-go version 2022-09-20 09:45:07 +03:00
Anna Shaleva
0477f83ea8 *: update interop version 2022-09-20 09:43:37 +03:00
Anna Shaleva
7e13140b04 interop: add Hash160 encoder\decoder helper
Close #2690.
2022-09-20 09:37:04 +03:00
Roman Khimov
113c0ce781
Merge pull request #2699 from nspcc-dev/add-atoi-tests
native: add some tests for stdlib's atoi
2022-09-19 21:39:38 +07:00
Roman Khimov
1b753cd4bc native: add some tests for stdlib's atoi
See neo-project/neo#2804 and neo-project/neo#2813. We're already compatible.
2022-09-19 16:18:53 +03:00
Roman Khimov
b8410a107d
Merge pull request #2697 from nspcc-dev/upd-deps-script
scripts: update dependency-updator script
2022-09-16 21:02:20 +03:00
Anna Shaleva
f1fbd6ad4b scripts: update dependency-updator script
Include Oracle contract to the list of contracts to be updated.
2022-09-16 20:33:48 +03:00
Roman Khimov
1f94ebe03d
Merge pull request #2679 from nspcc-dev/nns-upd
examples: NNS update, part 1
2022-09-16 17:06:38 +03:00
Anna Shaleva
94852ab7f4 nns: add admin to properties
See 14f43ba8cf/src/NameService/NameService.cs (L69).
2022-09-16 12:51:07 +03:00
Anna Shaleva
c03e420355 nns: allow to resolve FQDN
Port 4041924a75.
2022-09-16 12:51:07 +03:00
Anna Shaleva
e97467726c nns: allow hyphen in domain names
Port https://github.com/nspcc-dev/neofs-contract/pull/183.
2022-09-16 12:51:07 +03:00
Anna Shaleva
ce66610369 nns: adjust maxDomainNameFragmentLength
Port https://github.com/nspcc-dev/neofs-contract/pull/238.
2022-09-16 12:51:04 +03:00
Roman Khimov
8ecafaaadf
Merge pull request #2691 from nspcc-dev/sc-builder-len
smartcontract: add Len to Builder
2022-09-14 10:36:01 +03:00
Roman Khimov
18ed26194f smartcontract: add Len to Builder
Which is useful in some cases.
2022-09-14 10:25:10 +03:00
Roman Khimov
bd8d46e11a
Merge pull request #2689 from nspcc-dev/stateroot-shutdown-panic
stateroot: fix panic on shutdown
2022-09-13 13:29:57 +03:00
Roman Khimov
5979138306 stateroot: fix panic on shutdown
Stateroot service is always active, but it might have no wallet.

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x10 pc=0xc57d41]

goroutine 1 [running]:
github.com/nspcc-dev/neo-go/pkg/wallet.(*Wallet).Close(...)
        github.com/nspcc-dev/neo-go/pkg/wallet/wallet.go:175
github.com/nspcc-dev/neo-go/pkg/services/stateroot.(*service).Shutdown(0xc000105880?)
        github.com/nspcc-dev/neo-go/pkg/services/stateroot/validators.go:77 +0x81
github.com/nspcc-dev/neo-go/pkg/network.(*Server).Shutdown(0xc000105880)
        github.com/nspcc-dev/neo-go/pkg/network/server.go:271 +0x205
github.com/nspcc-dev/neo-go/cli/server.startServer(0xc0002702c0)
        github.com/nspcc-dev/neo-go/cli/server/server.go:641 +0x2675
github.com/urfave/cli.HandleAction({0xe456e0?, 0x1155f20?}, 0x4?)
        github.com/urfave/cli@v1.22.5/app.go:524 +0x50
github.com/urfave/cli.Command.Run({{0xfca38b, 0x4}, {0x0, 0x0}, {0x0, 0x0, 0x0}, {0xfd6a46, 0x10}, {0xffebe3, ...}, ...}, ...)
        github.com/urfave/cli@v1.22.5/command.go:173 +0x65b
github.com/urfave/cli.(*App).Run(0xc000272000, {0xc00003e180, 0x3, 0x3})
        github.com/urfave/cli@v1.22.5/app.go:277 +0x8a7
main.main()
        ./main.go:21 +0x33
2022-09-13 13:18:13 +03:00
Roman Khimov
b27e6918bd Makefile: complicate version detection script
We've declared that we are using semantic versioning. We also want to use `git
describe` to make version strings for us because it's very convenient for
development builds (tagged versions are way simpler). The problem is that the
default `git describe` behavior is not semver compliant. If the most recent
tag is v0.99.2 then it'll generate something like '0.99.2-131-g8dc5b385',
which according to semver is a development version _before_ 0.99.2. While it's
obviously a version _after_ 0.99.2.

That's the one and only reason we have vX.Y.Z-pre tags in our repo. We set
them right after the release according to the release process and that gives
us some '0.99.3-pre-131-g8dc5b385' versions we're all used to. But these tags
are ugly as hell and they clutter up our repo over time.

So there is this idea that we can do patch version increment dynamically.
Making '0.99.2-131-g8dc5b385' be '0.99.3-pre-131-g8dc5b385' without any *-pre
tags. This patch implements this. It's ugly as hell as well, but at least
that's an ugliness somewhere inside our Makefile and not directly visible in
our tags. If we're to do this we can then greatly simplify our release process
(and even allow for CHANGELOG patches to be merged normally).

I know this can be done with awk in somewhat easier way, but no, I'm not into
awk, sorry.
2022-09-09 17:06:55 +03:00
Roman Khimov
87a4fa827a CHANGELOG: release 0.99.3 2022-09-09 15:33:43 +03:00
Roman Khimov
31792e3132
Merge pull request #2686 from nspcc-dev/drop-at-block-rpcs
rpcclient: simplify historic API
2022-09-09 15:18:27 +03:00
Roman Khimov
a1ca28446d
Merge pull request #2683 from nspcc-dev/historic-cli
Historic calls from CLI
2022-09-09 15:08:22 +03:00
Roman Khimov
6a5a8c5e89
Merge pull request #2684 from nspcc-dev/build-fix
Tiny build corrections
2022-09-09 15:07:51 +03:00
Roman Khimov
d40eb79975 rpcclient: simplify historic API
util.Uint256 is util.Uint256 and it's same RPC behind the scenes, so we can
make it a bit easier to digest. See #2545 also.
2022-09-09 13:41:45 +03:00
Roman Khimov
f78a065230 vm/cli: generate Go 1.17 go.mods 2022-09-08 21:18:51 +03:00
Roman Khimov
db36be96b3 README: drop stale Go 1.16 reference 2022-09-08 21:18:02 +03:00
Roman Khimov
29d8d204ef Makefile: always use 8 chars for git revision in version
That's what we usually have today already, but it's dynamic by default.
2022-09-08 21:17:08 +03:00
Roman Khimov
d2d190913b cli: add historic abilities for all invoking commands
Notice that we can't do this for balance commands (unless we change the
interface in some manner) because they use getnepXXbalances.

Fixes #2620.
2022-09-08 19:20:18 +03:00
Roman Khimov
4403a95ae6 cli: don't return sender from invokeWithArgs
It's not really needed, deployer knows the sender exactly already.
2022-09-08 15:57:27 +03:00
Roman Khimov
8dc5b38568
Merge pull request #2681 from nspcc-dev/rpcclient-comments
RPC client examples, comments and small fixes
2022-09-08 14:47:31 +03:00
Roman Khimov
541d4b49e1 context: define a constant for transaction context type 2022-09-08 14:33:04 +03:00
Roman Khimov
6be9367f03 rpcclient/notary: add OnNEP17PaymentData and an example
Update documentation as well to mention it and not mention outdated APIs. We
can't link them yet, this will be done after the release.
2022-09-08 14:33:04 +03:00
Roman Khimov
4fb4f5a1ac smartcontract: make *util.Uint160 and *util.Uint256 usable for parameters
Use Any type for NULL.
2022-09-08 14:33:04 +03:00
Roman Khimov
1e54b422cd emit: make *util.Uint160 and *util.Uint256 emittable
They can be nil or can be regular uint types we're used to.
2022-09-08 14:33:04 +03:00
Roman Khimov
3c02177d3c rpcclient: improve comments for some methods 2022-09-08 14:33:04 +03:00
Roman Khimov
3e8e6857e5 rpcclient; deprecate more methods
They make little sense now.
2022-09-08 14:33:04 +03:00
Roman Khimov
c4ddf80742 rpcclient: correct Init requirement in documentation 2022-09-08 14:33:04 +03:00
Roman Khimov
ee55e95c28 rpcclient: add examples for nep11/nep17/neo
GAS doesn't need any, so just mention nep17 package there.
2022-09-08 14:33:04 +03:00
Roman Khimov
a1c9871d95 nns: it's NEP-11, so make NEP-11 methods available too 2022-09-08 14:33:04 +03:00
Roman Khimov
186e5c19b6 rpcclient: update documentation, mention subpackages
Drop TODOs (we have relevant GitHub issues), drop verbosity comment (we have
*Verbose APIs for that).
2022-09-08 14:33:04 +03:00
Roman Khimov
cb1a1f8532 actor: extend documentation, add example 2022-09-08 14:33:04 +03:00
Roman Khimov
e1fe76137e rpcclient: use separate reader/writer structs in nep11 and nep17
Which greatly simplifies reuse of these packages (and they're expected to be
reused since real tokens implement standards and also add something of their
own) and allows to avoid effects like

  doc_test.go:68:28: ambiguous selector neoContract.BalanceOf

when neo.Contract is used. Avoids duplication in NEP-11 implementation as
well.
2022-09-08 14:33:03 +03:00
Roman Khimov
00a9376311 invoker: update documentation, add example 2022-09-08 14:33:03 +03:00
Roman Khimov
ea92f3d716 smartcontract: add some notes on API limitations 2022-09-08 13:27:07 +03:00
Roman Khimov
69176168c3 smartcontract: modernize Builder example
And make it a bit more useful.
2022-09-07 22:40:25 +03:00
Roman Khimov
aca8ce0d28 unwrap: provide ErrNoSessionID, add some explanations 2022-09-07 22:40:25 +03:00
Roman Khimov
457f904b1b
Merge pull request #2674 from nspcc-dev/update-linter-config
Update linter config
2022-09-02 20:17:58 +03:00
Roman Khimov
6c621066a7 circleci: update golangci-lint to current version 2022-09-02 18:36:26 +03:00
Roman Khimov
1895dfb2c1 golangci: enable some more linters
They have not found anything and maybe we better not have them find anything
in the future. Commented ones can be useful in future, but find too many
problems at the moment.
2022-09-02 18:36:26 +03:00
Roman Khimov
97193cf337 golangci: add predeclared linter
These can be confusing.
2022-09-02 18:36:26 +03:00
Roman Khimov
63f212f4b3 golangci: enable/fix misspell 2022-09-02 18:36:26 +03:00
Roman Khimov
4f3ffe7290 golangci: enable errorlint and fix everything it found 2022-09-02 18:36:23 +03:00
Roman Khimov
c703ac6805 golangci: enable contextcheck linter, fix WSClient
pkg/rpcclient/wsclient.go:93:30  contextcheck  Function `Dial` should pass the context parameter
2022-09-02 18:35:54 +03:00
Roman Khimov
3c009271f8 golangci: enable bodyclose checker and fix related code
It has found an issue in the oracle code, so I think it's worth doing.
2022-09-02 18:35:54 +03:00
Roman Khimov
df9a4fa7ce golangci: drop deprecated linters
WARN [runner] The linter 'varcheck' is deprecated (since v1.49.0) due to: The owner seems to have abandoned the linter.  Replaced by unused.
WARN [runner] The linter 'deadcode' is deprecated (since v1.49.0) due to: The owner seems to have abandoned the linter.  Replaced by unused.
WARN [runner] The linter 'structcheck' is deprecated (since v1.49.0) due to: The owner seems to have abandoned the linter.  Replaced by unused.
2022-09-02 18:35:54 +03:00
Roman Khimov
3da8b98fc3
Merge pull request #2672 from nspcc-dev/private-key-cleanup
Private key cleanup
2022-09-02 16:20:39 +03:00
Roman Khimov
eb67145f81 keys: check length first, then do things in WIFDecode
Otherwise we can easily panic there on bad input.
2022-09-02 14:44:32 +03:00
Roman Khimov
3c722a9498 keys: clean temporary data during key imports
Don't leak anything this way.
2022-09-02 14:44:32 +03:00
Roman Khimov
74bf4a8e3f slice: add Clean microfunction
To be used for various cleaning purposes, one line is better than three lines.
2022-09-02 14:44:32 +03:00
Roman Khimov
58dc8d0c9b *: always close the wallet after use
Fix #2631.
2022-09-02 14:44:32 +03:00
Roman Khimov
ee5f8b6c21 consensus: update dbft, drop marshaling from private key
dbft doesn not need this and we must not leak the key in any way.
2022-09-02 14:44:18 +03:00
Roman Khimov
cbc2299295 cli/wallet: add warning for dump and export commands 2022-09-02 14:44:18 +03:00
Roman Khimov
cad0d7f00d wallet: add some warnings to Decrypt and PrivateKey docs 2022-09-02 14:44:18 +03:00
Roman Khimov
e164625a7f wallet: provide (*Account).SignHashable API
Make PrivateKey() less used and less useful.
2022-09-02 14:44:01 +03:00
Roman Khimov
e569edc841 wallet: add ScriptHash() to Account
It allows to simplify a lot of code and avoid getting a PrivateKey in some
cases.
2022-09-02 14:43:34 +03:00
Roman Khimov
fd8da6fdb9 *: do not get private key from Account to check if it CanSign()
We have this API now to performs checks.
2022-09-02 14:43:34 +03:00
Roman Khimov
8d33206bb8 *: don't get private key from account if just public one is needed
Add PublicKey() API to the Account and use it as appropriate, avoid creating
additional references to the private key.
2022-09-02 14:43:28 +03:00
Roman Khimov
f79672c4c3
Merge pull request #2624 from nspcc-dev/optimize-unused-globals
compiler: do not emit initialisation code for unused global vars
2022-09-02 14:28:44 +03:00
Roman Khimov
62be6f959c keys/wallet: add Destroy/Close/Close
PrivateKey can be destroyed and Account/Wallet can be closed (destroying keys
in the process).
2022-09-01 17:07:00 +03:00
Roman Khimov
a30e73a0d7 wallet: drop publicKey from Account
It's not very useful and it's only available when we have a private key
anyway.
2022-09-01 17:07:00 +03:00
Roman Khimov
53edbd569f wallet: don't allow to ConvertMultisig a locked account
This stretched the definition of Locked somewhat, but still makes sense to
me, locked accounts better not be touched.
2022-09-01 17:07:00 +03:00
Roman Khimov
0090577446 wallet: don't permanently store wif in the Account
It's useless and it's just another copy of the key. If really needed, it can
be derived from the key.
2022-09-01 17:07:00 +03:00
Anna Shaleva
7f613e63aa compiler: add test for #2661 2022-09-01 13:39:22 +03:00
Anna Shaleva
800321db06 compiler: rename named unused global vars to "_"
So that (*codegen).Visit is able to omit code generation for these
unused global vars. The most tricky part is to detect unused global
variables, it is done in several steps:
1. Collect the set of named used/unused global vars.
2. Collect the set of globally declared expressions that contain
function calls.
3. Pick up global vars from the set made at step 2.
4. Traverse used functions and puck up those global vars that are used
from these functions.
5. Rename all globals that are presented in the set made at step 1
but are not presented in the set made on step 3 or step 4.
2022-09-01 13:39:19 +03:00
Anna Shaleva
1e6b70d570 compiler: adjust TestInline template
Move all auxiliary function declaration after Main, so that INITSLOT
instructions counter works properly. `vmAndCompileInterop` loads program
and moves nextIP to the Main function offset if there's no _init
function. If _init is there, then nextIP will be moved to the start of
_init. In TestInline we don't handle instructions properly (CALL/JMP
don't change nextIP), we just perform instruction traversal from the
start point via Next(), thus INITSLOT counter value depends on the
starting instruction, which depends on _init presence.
2022-09-01 09:19:20 +03:00
Anna Shaleva
91b36657d6 compiler: do not emit code for unnamed unused variables
If variable is unnamed and does not contain function call then it's
treated as unused and code generation may be omitted for it
initialization/declaration.
2022-09-01 09:18:56 +03:00
Anna Shaleva
1dcbdb011a compiler: emit code for unnamed global var decls more careful
In case if global var is unnamed (and, as a consequence, unused) and
contains a function call inside its value specification, we need to emit
code for this var to be able to call the function as it can have
side-effects. See the example:
```
package foo

import "github.com/nspcc-dev/neo-go/pkg/interop/runtime"

var A = f()

func Main() int {
   return 3
}

func f() int {
   runtime.Notify("Valuable notification", 1)
   return 2
}
```
2022-09-01 09:18:07 +03:00
729 changed files with 50679 additions and 14871 deletions

View file

@ -1,138 +0,0 @@
version: 2.1
executors:
go1_17:
docker:
- image: cimg/go:1.17
go1_18:
docker:
- image: cimg/go:1.18
go1_19:
docker:
- image: cimg/go:1.19
commands:
gomod:
steps:
- restore_cache:
keys: [deps-v2-]
- run:
name: Download go module dependencies
command: go mod download
- save_cache:
key: deps-v2-{{ checksum "go.sum" }}-{{ checksum "go.sum" }}
paths: [/home/circleci/go/pkg/mod]
jobs:
lint:
working_directory: /home/circleci/go/src/github.com/nspcc-dev/neo-go
# TODO: temp workaround, need to upgrade to go1_18 after https://github.com/golangci/golangci-lint/issues/2649 is resolved.
executor: go1_17
steps:
- checkout
- gomod
- run:
name: go-lint
command: |
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.44.2
make lint
test_1_17:
working_directory: /home/circleci/go/src/github.com/nspcc-dev/neo-go
executor: go1_17
steps:
- checkout
- run: git submodule sync
- run: git submodule update --init
- gomod
- run:
command: go test -v -race ./...
no_output_timeout: 15m
test_1_18:
working_directory: /home/circleci/go/src/github.com/nspcc-dev/neo-go
executor: go1_18
steps:
- checkout
- run: git submodule sync
- run: git submodule update --init
- gomod
- run:
command: go test -v -race ./...
no_output_timeout: 15m
test_1_19:
working_directory: /home/circleci/go/src/github.com/nspcc-dev/neo-go
executor: go1_19
steps:
- checkout
- run: git submodule sync
- run: git submodule update --init
- gomod
- run:
command: go test -v -race ./...
no_output_timeout: 15m
build_cli:
working_directory: /home/circleci/go/src/github.com/nspcc-dev/neo-go
executor: go1_19
steps:
- checkout
- gomod
- run: make build
- store_artifacts:
path: bin
destination: /
build_image:
working_directory: /home/circleci/go/src/github.com/nspcc-dev/neo-go
executor: go1_19
docker:
- image: golang:1-alpine
steps:
- run: apk update && apk add git make curl tar
- checkout
- gomod
- setup_remote_docker:
version: 20.10.6
- run:
name: Install Docker client
command: |
set -x
VER="20.10.6"
curl -L -o /tmp/docker-$VER.tgz https://download.docker.com/linux/static/stable/x86_64/docker-$VER.tgz
tar -xz -C /tmp -f /tmp/docker-$VER.tgz
mv /tmp/docker/* /usr/bin
- run: make image
workflows:
version: 2
workflow:
jobs:
- lint:
filters:
tags:
only: v/[0-9]+\.[0-9]+\.[0-9]+/
- test_1_17:
filters:
tags:
only: v/[0-9]+\.[0-9]+\.[0-9]+/
- test_1_18:
filters:
tags:
only: v/[0-9]+\.[0-9]+\.[0-9]+/
- test_1_19:
filters:
tags:
only: v/[0-9]+\.[0-9]+\.[0-9]+/
- build_cli:
filters:
tags:
only: v/[0-9]+\.[0-9]+\.[0-9]+/
- build_image:
requires:
- build_cli
filters:
tags:
only: v/[0-9]+\.[0-9]+\.[0-9]+/

View file

@ -16,7 +16,7 @@
"deployed": false
},
"lock": false,
"isdefault": false
"isDefault": false
},
{
"address": "NVTiAjNgagDkTr5HTzDmQP9kPwPHN5BgVq",
@ -41,7 +41,7 @@
"deployed": false
},
"lock": false,
"isdefault": false
"isDefault": false
}
],
"scrypt": {
@ -52,4 +52,4 @@
"extra": {
"Tokens": null
}
}
}

View file

@ -16,7 +16,7 @@
"deployed": false
},
"lock": false,
"isdefault": false
"isDefault": false
},
{
"address": "NVTiAjNgagDkTr5HTzDmQP9kPwPHN5BgVq",
@ -41,7 +41,7 @@
"deployed": false
},
"lock": false,
"isdefault": false
"isDefault": false
},
{
"address": "NfgHwwTi3wHAS8aFAN243C5vGbkYDpqLHP",
@ -58,7 +58,7 @@
"deployed": false
},
"lock": false,
"isdefault": false
"isDefault": false
}
],
"scrypt": {
@ -69,4 +69,4 @@
"extra": {
"Tokens": null
}
}
}

View file

@ -16,7 +16,7 @@
"deployed": false
},
"lock": false,
"isdefault": false
"isDefault": false
},
{
"address": "NVTiAjNgagDkTr5HTzDmQP9kPwPHN5BgVq",
@ -41,7 +41,7 @@
"deployed": false
},
"lock": false,
"isdefault": false
"isDefault": false
}
],
"scrypt": {
@ -52,4 +52,4 @@
"extra": {
"Tokens": null
}
}
}

View file

@ -16,7 +16,7 @@
"deployed": false
},
"lock": false,
"isdefault": false
"isDefault": false
},
{
"address": "NVTiAjNgagDkTr5HTzDmQP9kPwPHN5BgVq",
@ -41,7 +41,7 @@
"deployed": false
},
"lock": false,
"isdefault": false
"isDefault": false
}
],
"scrypt": {
@ -52,4 +52,4 @@
"extra": {
"Tokens": null
}
}
}

View file

@ -16,7 +16,7 @@
"deployed": false
},
"lock": false,
"isdefault": false
"isDefault": false
},
{
"address": "NVTiAjNgagDkTr5HTzDmQP9kPwPHN5BgVq",
@ -41,7 +41,7 @@
"deployed": false
},
"lock": false,
"isdefault": false
"isDefault": false
}
],
"scrypt": {
@ -52,4 +52,4 @@
"extra": {
"Tokens": null
}
}
}

1
.github/CODEOWNERS vendored Normal file
View file

@ -0,0 +1 @@
* @AnnaShaleva @roman-khimov

BIN
.github/logo_dark.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

View file

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 54 KiB

View file

@ -34,78 +34,83 @@ on:
jobs:
build_cli:
name: Build CLI
runs-on: ${{matrix.os}}
runs-on: ${{matrix.os.name}}
strategy:
matrix:
os: [ubuntu-20.04, windows-2022, macos-12]
os: [{ name: ubuntu-22.04, bin-name: linux }, { name: windows-2022, bin-name: windows }, { name: macos-12, bin-name: darwin }]
arch: [amd64, arm64]
exclude:
- os: windows-2022
- os: { name: windows-2022, bin-name: windows }
arch: 'arm64'
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
ref: ${{ github.event.inputs.ref }}
# Allows to fetch all history for all branches and tags. Need this for proper versioning.
fetch-depth: 0
- name: Set up Go
uses: actions/setup-go@v3
uses: actions/setup-go@v5
with:
go-version: 1.19
cache: true
- name: Update Go modules
run: go mod download -json
go-version: '1.22'
- name: Build CLI
run: make build
env:
GOARCH: ${{ matrix.arch }}
- name: Rename CLI binary
run: mv ./bin/neo-go* ./bin/neo-go-${{ matrix.os.bin-name }}-${{ matrix.arch }}${{ (matrix.os.bin-name == 'windows' && '.exe') || '' }}
- name: Upload artifact
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v4
with:
name: neo-go-${{ matrix.os }}-${{ matrix.arch }}
name: neo-go-${{ matrix.os.bin-name }}-${{ matrix.arch }}
path: ./bin/neo-go*
if-no-files-found: error
- name: Attach binary to the release as an asset
if: ${{ github.event_name == 'release' }}
run: gh release upload ${{ github.event.release.tag_name }} ./bin/neo-go-${{ matrix.os.bin-name }}-${{ matrix.arch }}${{ (matrix.os.bin-name == 'windows' && '.exe') || '' }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
build_image:
needs: build_cli
name: Build and push docker image
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
ref: ${{ github.event.inputs.ref }}
fetch-depth: 0
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
uses: docker/setup-buildx-action@v3
- name: Login to DockerHub
if: ${{ github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && github.event.inputs.push_image == 'true') }}
uses: docker/login-action@v2
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}
- name: Set vars
id: setvars
run: make gh-docker-vars
run: make gh-docker-vars >> $GITHUB_OUTPUT
- name: Set latest tag
id: setlatest
if: ${{ (github.event_name == 'release' && github.event.release.target_commitish == 'master') || (github.event_name == 'workflow_dispatch' && github.event.inputs.push_image == 'true' && github.event.inputs.use_latest_tag == 'true') }}
run: echo "::set-output name=latest::,${{ steps.setvars.outputs.repo }}:latest"
if: ${{ (github.event_name == 'release' && github.event.release.target_commitish == 'master') || (github.event_name == 'workflow_dispatch' && github.event.inputs.use_latest_tag == 'true') }}
run: echo "latest=,${{ steps.setvars.outputs.repo }}:latest" >> $GITHUB_OUTPUT
- name: Build and push
uses: docker/build-push-action@v3
uses: docker/build-push-action@v5
with:
context: .
push: ${{ github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && github.event.inputs.push_image == 'true') }}
@ -121,21 +126,20 @@ jobs:
runs-on: windows-2022
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
ref: ${{ github.event.inputs.ref }}
fetch-depth: 0
# For proper `deps` make target execution.
- name: Set up Go
uses: actions/setup-go@v3
uses: actions/setup-go@v5
with:
go-version: 1.19
cache: true
go-version: '1.22'
- name: Login to DockerHub
if: ${{ github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && github.event.inputs.push_image == 'true') }}
uses: docker/login-action@v2
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}

View file

@ -0,0 +1,11 @@
name: Contribution guidelines
on:
pull_request:
branches:
- master
jobs:
commits_check_job:
name: DCO check
uses: nspcc-dev/.github/.github/workflows/dco.yml@master

View file

@ -8,7 +8,7 @@ on:
- master
types: [opened, synchronize]
paths-ignore:
- 'scripts/**'
- 'scripts/*.sh'
- '**/*.md'
workflow_dispatch:
@ -18,26 +18,61 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/setup-go@v3
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: 1.19
- uses: actions/checkout@v3
go-version-file: 'go.mod'
- name: golangci-lint
uses: golangci/golangci-lint-action@v3
uses: golangci/golangci-lint-action@v4
with:
version: latest
skip-pkg-cache: true # golangci-lint can't work with this cache enabled, ref. https://github.com/golangci/golangci-lint-action/issues/135.
gomodcheck:
name: Check internal dependencies
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Check dependencies
run: |
./scripts/check_deps.sh
- name: Check go.mod is tidy
run: |
go mod tidy
if [[ $(git diff --name-only go.* | grep '' -c) != 0 ]]; then
echo "go mod tidy should be executed before the merge, following packages are unused or out of date:";
git diff go.*;
exit 1;
fi
codegencheck:
name: Check code generated with 'go generate' is up-to-date
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-go@v5
with:
go-version-file: 'go.mod'
- name: Install stringer
run: go install golang.org/x/tools/cmd/stringer@latest
- name: Run go generate
run: go generate ./...
- name: Check that autogenerated code is up-to-date
run: |
if [[ $(git diff --name-only | grep '' -c) != 0 ]]; then
echo "Fresh version of autogenerated code should be committed for the following files:";
git diff --name-only;
exit 1;
fi
codeql:
name: CodeQL
@ -53,11 +88,11 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v3
uses: actions/checkout@v4
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
@ -68,7 +103,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v2
uses: github/codeql-action/autobuild@v3
# Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
@ -82,41 +117,37 @@ jobs:
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
uses: github/codeql-action/analyze@v3
test_cover:
name: Coverage
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
env:
CGO_ENABLED: 0
GOEXPERIMENT: nocoverageredesign
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Sync VM submodule
run: |
git submodule sync
git submodule update --init
submodules: 'true'
- name: Set up Go
uses: actions/setup-go@v3
uses: actions/setup-go@v5
with:
go-version: 1.19
go-version: '1.22'
cache: true
- name: Update Go modules
run: go mod download -json
- name: Write coverage profile
run: go test -v ./... -coverprofile=./coverage.txt -covermode=atomic -coverpkg=./pkg...,./cli/...
run: go test -timeout 15m -v ./... -coverprofile=./coverage.txt -covermode=atomic -coverpkg=./pkg...,./cli/...
- name: Upload coverage results to Codecov
uses: codecov/codecov-action@v2
uses: codecov/codecov-action@v4
with:
fail_ci_if_error: true # if something is wrong on uploading codecov results, then this job will fail
files: ./coverage.txt
slug: nspcc-dev/neo-go
token: ${{ secrets.CODECOV_TOKEN }}
verbose: true
tests:
@ -124,40 +155,36 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-20.04, windows-2022, macos-12]
go_versions: [ '1.17', '1.18', '1.19' ]
os: [ubuntu-22.04, windows-2022, macos-12, macos-14]
go_versions: [ '1.20', '1.21', '1.22' ]
exclude:
# Only latest Go version for Windows and MacOS.
- os: windows-2022
go_versions: '1.17'
go_versions: '1.20'
- os: windows-2022
go_versions: '1.18'
go_versions: '1.21'
- os: macos-12
go_versions: '1.17'
go_versions: '1.20'
- os: macos-12
go_versions: '1.18'
go_versions: '1.21'
- os: macos-14
go_versions: '1.20'
- os: macos-14
go_versions: '1.21'
# Exclude latest Go version for Ubuntu as Coverage uses it.
- os: ubuntu-20.04
go_versions: '1.19'
- os: ubuntu-22.04
go_versions: '1.22'
fail-fast: false
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: 'true'
- name: Set up Go
uses: actions/setup-go@v3
uses: actions/setup-go@v5
with:
go-version: '${{ matrix.go_versions }}'
cache: true
- name: Update Go modules
run: go mod download -json
- name: Sync VM submodule
run: |
git submodule sync
git submodule update --init
- name: Run tests
run: go test -v -race ./...
run: go test -timeout 15m -v -race ./...

4
.gitignore vendored
View file

@ -7,9 +7,6 @@
# Test binary, build with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
# Added by CoZ developers
vendor/
bin/
@ -54,6 +51,7 @@ testdata/
!pkg/services/notary/testdata
!pkg/services/oracle/testdata
!pkg/smartcontract/testdata
!cli/smartcontract/testdata
pkg/vm/testdata/fuzz
!pkg/vm/testdata
!pkg/wallet/testdata

View file

@ -32,20 +32,32 @@ linters:
- revive
# some default golangci-lint linters
- deadcode
- errcheck
- gosimple
- godot
- ineffassign
- staticcheck
- structcheck
- typecheck
- unused
- varcheck
# extra linters
# - exhaustive
# - goconst
# - goerr113
# - gomnd
# - nonamedreturns
# - unparam
- bidichk
- bodyclose
- contextcheck
- decorder
- durationcheck
- errorlint
- exportloopref
- gofmt
- misspell
- predeclared
- reassign
- whitespace
- goimports
disable-all: true
@ -57,3 +69,7 @@ issues:
- EXC0003 # test/Test ... consider calling this
- EXC0004 # govet
- EXC0005 # C-style breaks
exclude-rules:
- linters:
- revive
text: "unused-parameter"

View file

@ -2,6 +2,942 @@
This document outlines major changes between releases.
## 0.106.1 "Implication" (3 Jun 2024)
An urgent release that fixes mainnet state difference at block 5462944 which halts
blocks processing starting from the height 5468658. This release requires full node
DB resynchronization for mainnet nodes. T5 testnet DB state is not affected by this
bug (at least up to the current 4087361 height). Thus, DB resynchronisation may be
skipped for testnet nodes. No configuration changes implied.
Bugs fixed:
* mainnet state difference at block 5462944 caused by runtime notification
permissions check against the updated contract state instead of executing state
(#3472)
* unused neofs-contract dependency in the node modules (#3458)
## 0.106.0 "Zephyranthes" (21 May 2024)
We're rolling out a large set of updates including all of Neo 3.7.4 protocol changes:
native contracts update functionality and extended native contract APIs united under
the upcoming Cockatrice hardfork. For smart contract developers an ability to
generate smart contract bindings with dynamic hash is supported as well as a number
of useful extensions for `unwrap` package, compatible NNS smart contract RPC binding
and a lot of other handy enhancements. This release also includes a couple of severe
regression bug fixes affecting the node state. As a bonus of fixing a wide range of
failing tests, we've refactored the node services start and shutdown procedures to
make it more stable. This version drops support for Go 1.19 and requires 1.20+ to
build (with Go 1.22 supported).
Notice that this release requires full node resynchronization for both mainnet
and testnet nodes. Please pay a special attention to the Cockatrice hardfork schedule
and check your configurations. It should be configured for 3967000 of T5 testnet and
5450000 of mainnet. To ensure compatibility your node must be configured
appropriately.
New features:
* native contracts update functionality bound to hardforks (#3402, #3444)
* Cockatrice hardfork planned for 5450000 block of mainnet and 3967000 block of T5
testnet (#3402, #3448, #3402, #3446)
* `CommitteeChanged` events are emitted by NeoToken native contract starting from
Cockatrice hardfork (#3351, #3448)
* `getCommitteeAddress` method of NeoToken native contract is available starting
from Cockatrice hardfork (#3362, #3402)
* `keccak256` method of CryptoLib native contract is available starting from
Cockatrice hardfork (#3301, #3402)
* dynamic contract hash support for smart contract bindings (#3405)
* support `StringCompressed` API for `crypto.PublicKey` (#3408)
* support `Copy` API for `transaction.Transaction` and `payload.P2PNotaryRequest`
(#3407)
* extend `verifyWithECDsa` method of native CryptoLib contract with Keccak256 hasher
starting from Cockatrice and add an example of custom Koblitz-based and
Keccak256-based transaction witness verification (#3425)
* autogenerated `nativehashes` package (#3402, #3431)
* introduce `unwrap.Exception` type for better RPC invocation result exceptions
detection (#3438)
Behavior changes:
* Neo Name Service smart contract RPC binding follows the official N3 implementation
(#3291)
* clear LastGasPerVote NeoToken account info on unvoting (#3349)
* return fault exception (if any) in `unwrap` RPC client helpers (#3356)
* move P2PNotary designation role out of P2PSigExtensions (#3452)
Improvements:
* support `smartcontract.Convertible` interface as RPC Actor and Invoker call
parameters (#3297)
* allow to import multisignature account into wallet without WIF and password
specified (#3293)
* upgrade go-ordered-json dependency to avoid possible node state incompatibility
issues caused by smart contract manifest marshalling (#3331, #3333)
* Go 1.22 support, bump minimum required Go version up to Go 1.20 (#3336)
* a number of dependent libraries are updated to the fresh versions (#3338, #3418)
* improve error message of `System.Crypto.CheckMultisig` interop API handler (#3374)
* upgrade dBFT library to v0.2.0 (#3371, #3413)
* increase `ValidUntilBlock` value for transactions generated by CLI commands
(#3376)
* documentation updates (#3375, #3382)
* let default Notary Actor options be customizable (#3394)
* extend `getversion` RPC response with RPC server settings (#3386)
* make errors related to wallet opening more detailed (#3389)
* adjust error messages of `setExecFeeFactor` and `setStoragePrice` methods of
native PolicyContract (#3406)
* make neotest chain constructor options customizable (#3404)
* format improvements for CLI commands description (#3410)
* make state dumps comparator script more verbose (#3411)
* refactor storage `Get` implementation for BoltDB (#3441)
* add `updatecounter` field to the resulting items of `getnativecontracts` RPC API
call (#3439)
Bugs fixed:
* node panic on committee missing from node configuration (#3294)
* autogenerated RPC bindings do not follow Go naming convention (#3299)
* a batch of failing tests is fixed (#3306, #3313, #3321, #3332, #3337, #3335,
#3344, #3340, #3350, #3355, #3364, #3368, #3377, #3393, #3397, #3392, #3398,
#3400)
* outdated minimum required Go version of boilerplate contract generated by
`neo-go contract init` (#3318)
* outdated address used as an example in RPC client documentation (#3327)
* ungraceful node services shutdown procedure (#3307)
* logging data race on node services shutdown (#3307)
* Map parameter support is missing from RPC server handlers (#3329)
* smart contract storage iterator prefix wasn't copied while iterating over values
(#3336)
* RPC error with -511 code (insufficient funds) returned on `sendrawtransaction` RPC
request should cover multiple cases of sender's insufficient funds (#3360, #3361)
* reentrancy possibility for Notary deposit withdrawal (#3357)
* null `findstorage` RPC response in case of missing storage items (#3385)
* uninitialized named return variables in compiler (#3401)
* wrong debug sequence points after `JUMP*` instructions shortening by compiler
(#3412)
* corrupted genesis block record and application log caused by improper Conflicts
attribute processing (#3437)
* false positive DB-based blocked accounts detection in native PolicyContract leaded
to invalid committee computations and reward distribution made by NeoToken (#3443)
## 0.105.1 "Enumeration" (12 Jan 2024)
This is another v3.6.2-compatible release that fixes mainnet state difference at
block 4688591. It is confirmed to have the same state up to 4723K height (which
is current), but to get proper mainnet state you need to resynchronize your node
from the genesis. T5 testnet state is not affected (at least up to the current
3323K height), thus DB resynchronisation may be skipped for testnet nodes.
Improvements:
* better network services logging (#3287, #3290)
Bugs fixed:
* state difference at block 4688591 of N3 mainnet caused by difference at
characters escaping during manifest's `Extra` field JSON serialisation (#3286)
## 0.105.0 "Designation" (29 Dec 2023)
We're rolling out an update for NeoGo nodes that contains a number of user-facing
API improvements for RPC web-socket notification subsystem, CLI utility, wallet
related packages and not only. Try out our new `--await` CLI option for those
commands that relay transactions to the network to automatically wait for the
on-chain transaction execution result. Subscribe for new block headers with
extended RPC notification subsystem interface. Use contract-based accounts
provided by `wallet` package and `neotest` framework to sign transactions. These
and a set of other improvements are available to our users while this release is
staying compatible with 3.6.2 version of C# node.
This version also delivers a bug fix for consensus node panic caused by improper
native NeoToken cache initialisation. Moreover, there's a set of RPC server side
improvements, thus, we recommend to upgrade both consensus and RPC nodes to
provide more stable consensus node functioning and extended user APIs functionality.
No database resynchronisation is needed.
New features:
* block headers RPC web-socket subscription (#3252)
* --await option to synchronize on transaction execution for CLI commands (#3265)
* partial session-based RPC iterator unwrapping (#3274)
* contract-based transaction signers in neotest framework (#3233)
* AMD64 release binaries for macOS (#3251)
* complex contract signature schemes in wallet.Account (#3256)
Behavior changes:
* basic RPC subscription filter validity checks are implemented on both RPC
client and RPC server sides (#3258)
* filter of notary request event RPC subscription is extended with `type` field
(#3236)
* if available, use block headers RPC web-socket subscription for transaction
awaiting via `waiter` package API (#3283)
Improvements:
* add smart contract storage limits to interop utilities (#3232)
* extend ZKP examples documentation with additional links to PoT ceremony
response files (#3234)
* support Go types in VM emitter API (#3237)
* documentation update (#3239, #3242, #3246)
* BoltDB (go.etcd.io/bbolt) dependency upgrade (#3250)
* CLI code refactoring (#2682)
* extend wallet package to work with byte slice based wallets (#3255)
* export RPC client side transaction awaiting functionality via `waiter` package
(#3265, #3283)
Bugs fixed:
* remove stale `updatehistory` section of `getnativecontracts` RPC response (#3240)
* immediately check RPC client initialisation on access to blocks RPC subscription
API (#3257, #3261)
* fix CN panic caused by unexpected call to native NeoToken cache (#3253)
* make "automatically generated" warning of all automatically generated files
follow the standard (#3280)
## 0.104.0 "Globalization" (27 Nov 2023)
We're updating NeoGo to push out a number of useful updates and protocol
extensions as well as make it compatible with 3.6.2 version of C# node. The most
invasive behaviour changes are VM-level protocol constraints imposed on the size
of serialized stackitems and `NativeActivation` node setting removal. This version
also delivers a set of smaller useful changes in the interoperability layer and
native contract functionality including System.Runtime.CurrentSigners interop,
`strLen` StdLib method and PolicyContract-based transaction attributes pricing
as far as a user-facing `canceltx` CLI command and community-requested
`--relative-path` CLI option.
Node operators must resynchronize their nodes to get fully compatible state
(which is confirmed to be compatible with 3.6.2 for current mainnet up to
block 4483627 and T5 testnet up to block 3078762). Please, ensure your node
configuration doesn't contain `NativeActivations` protocol configuration section
as this logic is hidden under Hardforks starting from the current release.
New features:
* System.Runtime.CurrentSigners interop allowing to get signers of the currently
loaded transaction (#3058)
* `strLen` method to native StdLib contract (#3208)
* transaction attributes pricing regulation via native PolicyContract (#3155)
* `canceltx` CLI command as an alternative to unsupported `canceltransaction` RPC
request (#3223, #3214)
Behaviour changes:
* reduce maximum allowed stackitem.Item size (#3185)
* restrict maximum allowed NEF file size and prohibit large contracts deployment (#3186)
* bind `NativeActivations` node setting to the `Hardforks` setting (#3212)
* introduce serialization limit to stackitem.Item and fail large contracts deploy
wrt this setting (#3218)
* add customizable `MaxRequestBodyBytes` and `MaxRequestHeaderBytes` RPC server
configuration setting (#3221)
Improvements:
* provide more detailed error on attempt to read non-existent service wallet
provided via node configuration file (#3210)
* optimize emit of imported code for autogenerated RPC bindings (#3215)
* documentation update (#3203, #3222)
* add `--relative-path` CLI flag allowing to override configuration-specific relative
paths (#3206)
* update code owners (#3216, @fyrchik will live in our hearts forever)
Bugs fixed:
* unify messages of RPC errors according to the RPC errors NEP (#3199)
* limit maximum allowed number ad depth of transaction signers and witnesses per
RPC request that accept transaction (#3207, #3221)
* forbid unknown fields usage in the node configuration file (#3209)
* enable hardfork-dependant code starting exactly from the block height specified
in the node configuration (#3211)
* require Notary native deposit to be valid for at least one subsequent block after
deposit transaction acceptance (#3211)
* deduplicate unnamed event types for autogenerated RPC bindings and make the
binding generation order strictly defined and stable (#3215, #3220)
* do not panic on trying to compile an import cycle (#3215)
* state difference at block 3002333 of T5 testnet caused by difference at characters
escaping during manifest's `Extra` field JSON serialisation (#3225)
* properly start node services that depend on native RoleManagement contract data
with genesis `Roles` protocol configuration setting specified (#3229)
## 0.103.1 "Verification" (09 Nov 2023)
An urgent 3.6.0-compatible version that contains a hotfix for the bug that
prevents node from starting from the existing database every new dBFT epoch.
Also, the release includes a bugfix that fails any non-zero NEO and GAS
roundtrips from accounts with zero balance.
Although the DB format and storage states were not affected by this release,
the node resynchronization is still recommended for those who want to keep
correct application logs. Resynchronization can be skipped if you're ok with
wrong application logs for some transactions (e.g. CN doesn't care, and RPC node
cares a lot).
Bugs fixed:
* properly initialize cache of native NeoToken contract every new dBFT epoch (#3187)
* forbid non-zero NEO and GAS roundtrips from accounts with zero balance (#3191)
## 0.103.0 "Backwardation" (20 Oct 2023)
A minor 3.6.0-compatible version of NeoGo with new salty ZKP-related
functionality, a large batch of deprecated APIs removal and an experimental
genesis block extension. Build Groth-16 circuits, generate proofs and deploy
verification contracts easily with the new end-to-end ZKP example and `zkpbinding`
NeoGo API. Setup node roles via the node configuration starting from the genesis
block without any painful multisignature transaction forming and invoke any
custom script in the genesis-level transaction with the new `Genesis` protocol
configuration extension. And don't forget to move from deprecated RPC client
APIs, as a lot of them have been removed.
New node configuration format is finally adapted and the deprecated configuration
sections are permanently removed according to the schedule. Pay attention to the
`SecondsPerBlock` protocol configuration section that was replaced by
`TimePerBlock`, a set of node and services address- and port- related configuration
section that were replaced by the new `Addresses` format, direct `UnlockWallet`
consensus configuration that was replaced by a separate `Consensus` section and
a set of node-specific protocol configurations that were moved under a separate
`P2P` section.
This release fixes a set of bugs including a vulnerability introduced by changes
in the transaction conflicts storage scheme implemented in #3061 (a part of
0.102.0 release). With the patch presented, it's impossible to uncontrollably
pollute the storage with malicious conflicting records.
This version is fully compatible with C# node 3.6.0. However, it requires
complete resynchronization on upgrade due to the database storage scheme changes.
New features:
* API for Groth-16 verification contracts autogeneration and end-to-end example for
proving and verifying statements on NeoGo (#3043, #3146)
* introduce genesis protocol extensions: default node roles designation and genesis
transactions (#3168)
Behaviour changes:
* a lot of deprecated functionality is dropped: RPC client old APIs, shared
Notifications channel of WebSocket client, SecondsPerBlock protocol
configuration, old way of services and node address and port configuration, old
P2P related application settings configuration, direct UnlockWallet consensus
configuration, direct node-specific protocol configuration (#3150)
* database scheme is changed by new way of storing the transaction conflicting
records (#3138)
Improvements:
* NeoFS SDK dependency upgrade (#3129)
* gnark and gnark-crypto dependencies upgrade (#3145, #3162, #3163)
* introduce timeout restriction for BoltDB opening (#3148)
* bump code coverage uploading action version (#3153)
* Go 1.21 support, bump minimum required Go version up to Go 1.19 (#3157)
* upgrade golang.org/x/net version (#3158)
* add protocol hardforks configuration to the `getversion` RPC response (#3160)
* format autogenerated smart contract bindings with accordance to standard `go fmt` rules (#3164)
* add "DO NOT EDIT" warning to the autogenerated smart contract bindings (#3167)
Bugs fixed:
* avoid race between `getnextblockvalidators` RPC call handler and blockchain's
block handler routine, significantly refactor native validators caching scheme
(#3110)
* do not panic on failed NeoFS oracle requests (#3129)
* enable Notary subsystem in NeoFS mainnet configuration (#3136)
* reorganize storage scheme for transaction conflicting records to avoid possible attack (#3138)
* properly deserialize wildcard trusts field of smart contract manifest (#3140)
* use more strict GAS limit for transaction network fee calculation via RPC call (#3141)
* avoid WebSocket client request blocking (#3142)
* properly emit big uint64 constants during smart contract compilation (#3147)
* avoid race access to the node version by tests (#3149)
* make FindStorage* RPC client APIs to be always compatible with NeoC# RPC server (#3166)
## 0.102.0 "Aberration" (06 Sep 2023)
Long-awaited feature-packed 3.6.0-compatible version of NeoGo with all the
appropriate protocol updates and a set of tasty improvements and bug
fixes. Groth16 ZKP proof checks are there for contract developers as well as
new opcodes. A huge number of improvements went into the RPC server and
client, new RPCs, improved contract binding generator and standardized
extended error codes make developing dApps much easier.
Users of smart contract utilities and RPC-related Prometheus metrics are
advised to take a look at the deprecated APIs removal schedule
(ROADMAP.md). This version was delayed for quite some time (waiting for 3.6),
so the next minor release (0.103.0) will remove a substantial amount of
compatibility code. It's expected to be released in November with 3.6 protocol
compatibility (3.7 cycle is likely to require more time).
This is also the first version that drops support for Go 1.17 and requires
1.18+ to build (with Go 1.20 supported). Using generics in smart contracts is
not supported yet, but some elements of this support can be implemented in
future versions.
Mainnet and testnet node operators, please pay attention to the Basilisk
hardfork schedule and check your configurations. It will happen at block
2680000 for T5 testnet and 4120000 for mainnet. To ensure compatibility your
node must be configured appropriately. This version requires DB
resynchronization, so schedule your updates accordingly.
New features:
* ZKP proof checking support via CryptoLib native contract (operations with
BLS12-381 curve points) (#2940, #3042)
* System.Storage.Find interop now support "Backwards" flag to iterate in the
opposite direction (#2952)
* `util ops` CLI utility that pretty-prints VM script (#2965)
* `notarypool_unsorted_tx` Prometheus metric for notary-enabled nodes (#2696)
* `CloseNotificationChannelIfFull` WSClient option allowing the client to
close notification channel on overflow (#2988)
* autogenerated RPC bindings for contract events and conversion code from
stackitem.Item to structure (#3008, #3035, #3036, #3087)
* event type inference from contract code (#3008)
* dynamic contract hashes support for RPC bindings (#3012)
* "Basilisk" protocol hardfork support (#3056, #3080, #3086, #3104)
* ABORTMSG and ASSERTMSG VM opcodes (#3066)
* standardized RPC error codes (#3063)
* `findstorage` and `findstoragehistoric` RPC support (#3099)
* `getstoragehistoric` RPC support (#3099)
* `getrawnotarypool` and `getrawnotarytransaction` RPC (#3098)
Behaviour changes:
* deprecated `FromAddress` smart contract helper is dropped from the `util`
interop package (#2941)
* a number of deprecated RPC-related Prometheus counters are permanently
removed (#2941)
* NEP-2 account label will be asked on account import via CLI (#2889)
* hashes and states of native contracts are now accessible via native
ContractManagement API (#2991)
* `serv_node_version` gauge Prometheus metric is marked as deprecated and
replaced by `neogo_version` and `server_id` (#3009)
* strict contract script check is back with Basilisk hardfork, it was
previously removed in 0.101.3 for 3.5 protocol compatibility (#3056)
* JSON number deserialization (via StdLib.jsonDeserialize) changes with
Basilisk hardfork allowing for more precision and handling more corner
cases (#3080)
* notification type errors are treated as fatal after Basilisk hardfork,
before it they're just logged (#3086)
* NULL and non-UTF8 items are not allowed for String event types (#3086)
* `Conflicts` and `NotValidBefore` transaction attributes are no longer NeoGo
extensions, they can be used on regular networks (#2962)
Improvements:
* documentation and example improvements (#2945, #2972, #2979, #3020, #3084,
#3099, #3114, #3116, #3119, #3121)
* `getproof` and `verifyproof` RPC API support in RPC client (#2942)
* Go 1.20 support, bump minimum required Go version up to Go 1.18 (#2908)
* faster state reset process (#2819)
* optimized voting data storage scheme for NEO contract (#2892, #2893)
* NeoFS SDK dependency upgrades (#2995, #3032)
* special exported error returned in case of WSClient disconnection (#3000)
* automatic guessing of contract and manifest filenames for `contract
compile` CLI command and `loadnef` VM CLI command (#3013)
* support for pushing stackitem.Convertible objects via VM script emitter (#3016)
* economic adjustment for ranking of transactions with `Conflicts` attribute (#3031)
* `google.golang.org/grpc` dependency upgrade fixing high severity security
vulnerability (#3055, gRPC is only used to communicate with NeoFS nodes in
the oracle service)
* enforce default RPC server values when it's used as an independent package
(not a part of node) (#3107)
* unwrap.Nothing function for RPC clients (#3117)
* address and reverse hash display in opcode dumps (#3115)
Bugs fixed:
* invalid peer port type returned by `getpeers` RPC response (#2914)
* invalid data source for `mempool_unsorted_tx` Prometheus metric (#2969)
* dBFT library upgrade fixing the ability of a single node to speed up the
process of new blocks creation for the whole network (#3018,
nspcc-dev/dbft#75)
* failing CALLT instructions in VM CLI for loaded NEF files (#3020)
* missing signers check for on-chain conflicting transactions (#3061)
* incorrect sequence point boundaries in debug data (#3074)
* compiler panic on encountering generic code (#3041)
* potential pooled fallback notary transaction changes (#3108)
* lost LastGasPerVote value on NEO state deserialization for non-voting
accounts (#3122)
## 0.101.4 "Yarborough" (01 Aug 2023)
Another one 3.5.0-compatible version that is aimed to fix T5 testnet state
difference that has happened at block 2336911 which leads to inability to process
new blocks since 2418703. The issue is fixed by allowing JSON numbers
unmarshalling from scientific notation to Integer stackitem. Maximum parsing
precision for such numbers is currently restricted by 53 bits. This is a
temporary C#-compatible solution that is likely to change in the future versions
when an appropriate C# node bug is fixed (neo-project/neo#2879).
A set of minor bug fixes is included as well to flush some of the long-awaited
changes that were blocked by the 0.102.0 release delay (caused by v3.6.0 C# node
release delay). In particular, invalid headers returned by an RPC server for
error responses, invalid format of incremental dumps created by CLI and deadlock
on unhealthy RPC server shutdown. Long-awaited `--config-file` CLI option to
start the node providing a single configuration file is added.
T5 testnet chain requires a complete resynchronization for this version. Mainnet
chain resynchronization is recommended, but not required.
New features:
* `--config-file` CLI option allowing to start the node with a single configuration file (#3014)
Improvements:
* blockchain Notary and Oracle services documentation improvement (#2972)
* BoltDB (`go.etcd.io/bbolt`) dependency upgrade that fixes a number of Windows-related issues (#3034)
Bugs fixed:
* panic on node start with invalid configuration (#2968)
* deadlock on unhealthy RPC server shutdown (#2966)
* improper WSClient notification channels managing after disconnection (#2980)
* missing Prometheus metric initialisation on node start (#2992)
* invalid initialisation of native contracts cache (#2994)
* incorrect way of incremental DB dumps creation (#3047)
* Notary contract is allowed to be a sender of main Notary request transaction (#3065)
* discrepancy in signer's witness scope parsing on the RPC server side (#3060)
* Invoker calling API isn't allowed to accept nil parameter (#3067)
* contract RPC Client unwrapper helper can't handle missing contract case (#3072)
* JSON numbers can't be unmarshalled to stackitem from scientific notation (#3073)
* invalid content-type header returned by RPC server on error responses (#3075)
## 0.101.3 "Yuckiness" (08 Jul 2023)
Yet another 3.5.0-compatible emergency version that removes scrupulous
instructions check of smart contract's script on contract deployment or update.
Presence of this check leads to the known T5 testnet state incompatibility
(since 1670095) which causes inability to process new blocks (since 2272533).
It should be noted that the corresponding check was accidentally removed from
the reference C# node implementation way back in neo-project/neo#2266 and added
again in neo-project/neo#2849 which is planned to be a part of the upcoming
3.6.0 C# node release. Thus, changes made in the presented 0.101.3 release will
be reverted afterwards and strict contract script check will be present in the
next 3.6.0-compatible version of NeoGo node.
T5 testnet chain requires a complete resynchronization for this version. Mainnet
chain resynchronization is recommended.
Bugs fixed:
* extra strict contract script check on contract deployment or update is
removed (#3052)
## 0.101.2 "Excavation" (29 Jun 2023)
One more (and unexpected one!) 3.5.0-compatible version that fixes a VM bug
leading to mainnet state incompatibility (since 3672783) which in turn leads
to inability to process new blocks (since 3682290).
Mainnet chain needs to be resynchronized for this version.
Improvements:
* documentation updates (#3029, #2990, #2981)
Bugs fixed:
* incorrect handling of empty Any-type parameter for RPC invocations (#2959)
* incorrect state rollbacks in case of exception during cross-contract call
when the call is made from non-TRYing context (#3046)
## 0.101.1 "Shallowness" (17 Mar 2023)
Another 3.5.0-compatible version that delivers important bug fixes and
provides a new API to be used by NeoFS. An upgrade is recommended, the DB
doesn't need to be resynchronized.
New features:
* internal RPC client for deeply integrated applications like NeoFS (#2916)
Improvements:
* documentation updates (#2879, #2880, #2893, #2917, #2920, #2936)
* code style, spelling and updated linter fixes (#2884, #2922, #2933)
* NEP-2 import password can be provided via config file now (#2887)
* custom stack item deserialization limit is available via public APIs now (#2904)
* RPC client endpoint can be retrieved via public API (#2915)
* dependency updates (#2919, #2929)
* WSClient now copies filter parameters to Subscribe* and Receive* methods
improving code safety (#2937)
Bugs fixed:
* name parameter ignored for wallet import command (#2887)
* incorrect RPC binding code generated for Any return type (#2918)
* memory leak on active peer disconnection (#2924)
* consensus process deadlock (#2930)
* dBFT deadlock in "committed at previous view" scenario (#2935)
* panic in RPC waiter code (#2938)
## 0.101.0 "Shortness" (13 Jan 2023)
This release delivers an important fix for block execution application logs
and requires a resynchronization, therefore it's 0.101.0 (even though it's
also 3.5.0-compatible). It fixes some other minor problems as well (the other
most notable change probably is in the compiler), so we recommend upgrading.
Improvements:
* updated golang.org/x/* dependencies (#2854)
* CLI help and required flags handling fixes (#2852)
* transfer data storage optimization (#2865)
* network's magic number is stored (and checked against the config on
startup) in the DB now, reducing potential for node operator errors (#2867)
Bugs fixed:
* in rare cases nodes could request an invalid number of blocks from peers
leading to disconnect (#2846)
* outdated documentation fixes (#2860, #2876)
* application logs for blocks that contained GAS spends for transaction fees
contained (and returned from getapplicationlog RPC) incorrect (off by one)
values for amount in Transfer events; transaction application logs were not
affected by this, but data returned to RPC event subscribers could
potentially be (#2865)
* findstates RPC returned an error instead of an empty data set for valid
contracts that have no data (unlike C# node, #2866)
* miscompiled shadowed range loop variable definition (#2871)
* missing (compared to C# node) explicit (even though null) 'exception' field
in the getapplicationlog RPC output from server (#2872)
## 0.100.1 "Chaptalization" (28 Dec 2022)
This is a tiny update that 99.99% of users can easily skip. The reason for
this release is the need to fix compatibility with the NeoFS mainnet
sidechain and have some stable version to be used there. In any other case it
can be ignored, but if you still decide to upgrade you don't need to
resynchronize.
Behaviour changes:
* Aspidochelone fork is made to include ContractManagement native contract
deploy/update methods call flags change, initially it was an unconditional
part of 0.99.0 NeoGo release (or 3.2.0 C# version), but this behavior is
incompatible with the NeoFS mainnet sidechain; the change to the fork logic
does not affect any other public networks (mainnet/testnet) and any new
networks that have Aspidochelone enabled since block 0 (#2848)
Improvements:
* more robust NEP-11 divisibility check in the RPC server code (#2841)
* microoptimization for some debug log messages (#2842)
* additional fuzz tests for integer serialization and script parsing code (#2851)
## 0.100.0 "Centuplication" (08 Dec 2022)
A 3.5.0-compatible version of NeoGo with all the appropriate protocol updates
and a number of other changes. The most notable ones are configuration
updates. New features and some long-standing inconsistencies required for some
changes and this release brings them with it. Old configurations are still
supported and will work the same way (except for one minor exception in
VerifyBlocks that is only supposed to be used for tests/development), but we'd
like to highlight that all of the old settings will be removed in ~6 months,
so please review these updates and update your configurations. For public
networks the best way to go is to take the new versions from the "config"
directory and then adjust for particular scenario if needed.
This release requires a complete resynchronization due to native contract
changes, so please schedule your updates appropriately.
New features:
* System.Runtime.LoadScript syscall (and appropriate smart contract interops)
allowing to load/run dynamic code (#2719)
* PUSHT/PUSHF VM instructions allowing for simpler/cheaper booleans (#2770)
* ContractManagement native contract was extended with ID->hash mappings and
`getContractById` and `getContractHashes` methods (#2702, #2837)
* LogLevel application configuration option that can be changed on SIGHUP
(#2831)
* additional type data generated by the compiler that then can be used by the
RPC bindings (SDK/contract wrapper) generator, this allows for complex
types (structures/arrays/maps) to be easily represented/handled in
contract-specific RPC code (#2828)
* multiaddress listeners for all services and P2P, this changes the old
Address/Port (and AnnouncedPort for P2P) configuration scheme to more
generic Addresses list, the old configuration is still supported, but is
deprecated and will be removed in future node versions (#2827, #2839)
Behaviour changes:
* Aspidochelone fork block for NeoFS sidechain mainnet configuration is
rescheduled again (#2823, #2830)
* Blockchain's GetHeaderHash() method now accepts uint32 for parameter
(#2814)
* pre-0.97.3 and pre-0.99.0 deprecated compatibility fields and logic were
dropped from the result.Version (`getversion` RPC result) structure (#2786)
* SecondsPerBlock protocol configuration variable was replaced with
TimePerBlock allowing for sub-second precision, SecondsPerBlock is still
supported, but will eventually be removed (#2829)
* AttemptConnPeers, BroadcastFactor, DialTimeout, ExtensiblePoolSize,
MaxPeers, MinPeers, PingInterval, PingTimeout, ProtoTickInterval settings
were moved into the new P2P section, timing parameters now use Duration
type allowing for more human-friendly values in many cases, old parameters
are still supported, but will eventually be removed (#2827)
* consensus (dBFT) is configured as a separate service now that can be
enabled/disabled (and can work in "watch only" mode without a wallet), the
old direct "UnlockWallet" specification in "ApplicationConfiguration" is
still supported, but is deprecated and will be removed in future versions
(#2832)
* GarbageCollectionPeriod, KeepOnlyLatestState, RemoveUntraceableBlocks,
SaveStorageBatch and VerifyBlocks settings were moved from
ProtocolConfiguration to ApplicationConfiguration; old configurations are
still supported, except for VerifyBlocks which is replaced by
SkipBlockVerification with inverted meaning (and hence an inverted default)
for security reasons; this also affects NewBlockchain and neotest APIs
(#2833)
Improvements:
* more user-friendly error and help messages in some cases (#2824, #2834)
* faster node startup time and smaller memory footprint for networks with
lots (1-2M+) of blocks (#2814)
* minor documentation fixes (#2834, #2838)
Bugs fixed:
* transactions with system fee or more than MaxBlockSystemFee are no longer
accepted into the mempool, preventing a form a network-wide DoS (#2826)
* deprecated WSClient subscription methods not working correctly when filters
are being used (#2836)
## 0.99.7 "Hyalinization" (23 Nov 2022)
Bugs, terrestrial arthropods with at least six legs. Sometimes we don't notice
them, sometimes we ignore them, but they do exist and there are times when
they need to be dealt with in one way or another. Most of the bugs fixed in
this release have a little less legs than proper insects, they're far from
being as critical as the ones fixed in the previous release and yet we
consider them annoying enough to warrant this new version of NeoGo to be
published. We don't want to see our users fighting these pesky creatures in
the wild, better update and have a troublefree experience.
If you're not affected by #2815 (requests for verbose transaction data and
application logs failed for some specific mainnet transaction(s)) you may
leave the DB as is with this upgrade, if you want it to be solved then please
resynchronize.
Behaviour changes:
* "loadtx" VM CLI command now uses transaction system fee value as the
default GAS limit for the context, unless --gas is used (previously it
wasn't limited, #2816)
* SendRawTransaction RPC client method will now always return transaction
hash, even if error occured, this also affects Actor APIs and allows to
handle some specific errors (like transaction already present in the
mempool) in more appropriate way (#2817)
* Actor and NotaryActor Wait() wrapper methods now handle "already exists"
and "already on chain" errors as non-errors, waiting (if needed) and
returning proper results (#2817)
Improvements:
* reworked network discoverer/connection manager that has a better picture of
the network (especially if it's a small one), doesn't try to make additional
connections (even when having less than MinPeers of them) when there are no
more real addresses to connect to, establishes stable connections faster in
containerized environments and does more connection attempts when MinPeers
setting is not satisfied, but there are potential candidates (#2811)
* VM invocation stack handling microoptimization (#2812)
* load* VM CLI commands now accept --gas parameter to set the amount of GAS
to be used in this context (#2816)
* better logging during state reset process (#2813)
* subscription-based transaction waiter now handles already accepted
transactions faster (~immediately vs waiting for block timeout previously,
#2817)
* WSClient can return more specific error on websocket handshake failure if
it's provided by server (#2821)
* new MaxWebSocketClients configuration option for the RPC server to control
the number of allowed websocket clients, missing or 0 value make the server
use the default of 64 which is compatible with the previous behavior (you
can use old configurations if you don't care about this option, #2821)
Bugs fixed:
* occasional "loadgo" VM CLI test failures because of timeout (#2810)
* websocket waiter test instability (#2809)
* websocket event unsubscriptions could lead to node deadlock in rare
circumstances (#2809)
* exception handler could use improper evaluation stack in some cases (#2812)
* pointer stack items were not handled correctly in "protected" serialization
mode leading to inability to deserialize these items back (#2816)
* state reset functionality not working for big chains like mainnet (#2813)
## 0.99.6 "Funambulation" (16 Nov 2022)
An emergency release fixing mainnet incompatibility at block 2504320 leading
to inability to process block 2504813. A couple of other less severe bugs got
fixed as well. Unfortunately, this release requires complete resynchronization
for mainnet, other networks can use old DBs.
Improvements:
* only transactions requested by the consensus process are forwarded to it
now slightly improving performance in some networked scenarios (#2788)
* a complete set of simple array unwrappers in the unwrap library (#2792)
* RPC binding generator can handle simple arrays now with configuration file
provided (#2792)
* more user-friendly error messages in some cases (#2797, #2802, #2804)
Bugs fixed:
* DB was not properly closed after state reset (#2791)
* VM stack handling problem leading to lost items after return from call to
another contract (#2800)
* "istack" command panic in the VM CLI (#2800)
* failure to decode incorrect contract from ContractManagement state leading
to failure to start the node, it'll be ignored now similar to how C# node
treats this (#2802)
* subscription to execution events failed if no "state" filter was used along
with "container" (#2804)
* Actor using WSClient could deadlock in the transaction waiter during
unsubscription (#2804)
## 0.99.5 "Underestimation" (11 Nov 2022)
It wasn't long since the previous release until a juicy set of features and
optimisations came on board. So we've decided to change our release plan and
supply one more 3.4.0 compatible version. It comes up with a massive suite
of network P2P and broadcast improvements. We've carefully investigated message
sending timeouts on benchmarks, reworked the broadcast logic and significantly
reduced delays in message sending and the amount of useless traffic between our
nodes. For smart-contract developers and RPC client users several new features
were added. These are automatic RPC bindings generator, poll-based and
websocket-based transactions awaiting and an extended websocket client
subscriptions interface. For better debugging experience we've improved state
related functionality of VM CLI and added an ability to reset chain state to a
particular height.
An important dBFT initialization bug that caused timestamp-related errors on
block addition was fixed. Also, those who use NeoGo node with
EnableCORSWorkaround setting may want to update the node to be able to handle
web-socket requests with Origin set in the header. The users of websocket RPC
client subscription mechanism are welcomed to move from deprecated subscriptions
API to the extended one. Finally, we are kindly asking our users to have a look
at our roadmap file where deprecated code removal schedule is attached.
This version is fully compatible with C# node 3.4.0 and does not require
resynchronization on upgrade. This time for sure, the next release is planned
to be compatible with 3.5.0.
New features:
* logarithmic gossip fan-out, new `BroadcastFactor` application setting and
adaptive peer requests are added to optimise broadcasting process (#608,
#2678, #2743)
* Prometheus histograms with handling time are added for P2P commands (#2750)
and RPC calls (#2784)
* transaction awaiting is added to RPC clients (#2740, #2749)
* RPC bindings generator (#2705) is added for both safe (#2766) and
state-changing (#2769, #2778) methods with initial iterator support (#2783)
* the ability to reset chain state to a particular height is added (#2576,
#2773)
Behaviour changes:
* Aspidochelone fork block for NeoFS sidechain mainnet configuration is
rescheduled (#2754, #2776)
* RPC server will now handle any Origin in websocket connection when
EnableCORSWorkaround setting is on (#2772, #2724)
* WS RPC client subscriptions API is extended to accept custom subscriber
channels, old subscriptions API is marked as deprecated (#2756, #2764)
Improvements:
* network code refactoring (#2742)
* network packets sending is now limited in time (#2738)
* broadcast messages will be sent concurrently to each peer (#2741)
* ping messages are broadcast using the common broadcast logic (#2742)
* transactions requested by dBFT will be accepted on demand only (#2746, #2748,
nspcc-dev/dbft#63)
* VM CLI's state-based functionality improvements (extended signers and
arguments parsing, enabled logging) and additional commands (`loadtx`,
`loaddeployed`, `jump`) (#2729, #2606, #2740)
* incoming P2P transactions are now processed concurrently and buffer for
inventory hashes is reusable (#2755)
* `GetData` and `GetBlocksByIndex` replies are now batched on a TCP-level
(#2757)
* optimisation of incoming P2P transactions and blocks filtering are introduced
(#2758, #2759)
* batch size of broadcast transactions hashes is adjusted (#2760)
* peer reconnections logic is improved, `GetAddr` messages are sent more
often (#2761, #2745)
* documentation for wallet configuration file is clarified (#2763)
* Koblitz curve implementation of btcd/btcec was replaced with decred/secp256k1
due to GitHub security warning (#2781)
* `NOT` opcode for Bool emission is now used to reduce resulting script
cost (#2762)
Bugs fixed:
* failing tests cleanup on Windows (#2736)
* race in CLI test (#2765)
* invalid conversion of PublicKey smart contract parameter to emitable (#2739)
* initialize dBFT's context with previous block's timestamp on view 0 (#2753,
#2752, nspcc-dev/dbft#64)
## 0.99.4 "Transliteration" (07 Oct 2022)
A small update mostly interesting for people building/testing smart contracts
with NeoGo. It contains long-awaited VM CLI update that allows to use
blockchain state and complete set of interops, additional helper functions for
smart contracts and notification checking code (for upcoming 3.5.0 protocol
changes). Node operators using EnableCORSWorkaround (that is still not
recommended, but available) also may want to update to be able to handle
pre-flight CORS requests.
This version is compatible with C# node 3.4.0 and does not require
resynchronization on upgrade. The next release is planned to be compatible
with 3.5.0.
New features:
* address conversion helpers for smart contracts (#2698)
* interop helper to call specific version of a contract (#2695)
* notifications are now checked for manifest compliance, a warning is logged
in case on detected inconsistencies (#2710)
* VM CLI can now use blockchain state DB (including historic states) to run
code with a complete set of interops and contracts available; additional
commands were added to it to inspect storage and generated events (#2723)
Behavior changes:
* type assertion with two return values in Go contracts can't be compiled now
(it never worked properly, #2718)
* RPC server will now handle pre-flight CORS requests (via OPTIONS methods)
when EnableCORSWorkaround setting is on (#2724)
* all transaction-generating CLI commands were unified to accept
gas/sysgas/out/force parameters, ask for confirmation and be able to save
transaction into a file; this affects wallet claim and candidate-related
commands mostly (#2731)
Improvements:
* smartcontract.Builder API was extended with Len method (#2691)
* NNS example contract adjustments for better DNS compatibility (#2679)
* documentation updates (#2708, #2722, #2726, #2728)
* compiler now emits code to explicitly cast runtime.Notify() parameters to
appropriate types (#2720)
* CLI tests repackaging (#2725)
* NeoFS sidechain configurations for mainnet and testnet (#2730)
Bugs fixed:
* panic on node shutdown (#2689)
* panic on inlined append() compilation (#2716)
## 0.99.3 "Simplification" (09 Sep 2022)
Version 0.99.3 brings with it most of the planned refactoring changes to the
RPC client. dApp backend code can be greatly simplified in many cases by
using new APIs (old ones are still available for transition period of about
one-two releases more). We also have some updates for CLI and compiler and a
number of bug fixes.
This version is compatible with C# node 3.4.0 and does not require
resynchronization on upgrade. The next release is planned to be compatible
with 3.5.0 (if it's to be released around currently planned dates).
New features:
* native contract RPC wrappers (#2643, #2646, #2650, #2666, #2665)
* NEP-11 RPC wrappers (#2651)
* invoker interface extension with session-based iterators support (#2650)
* notary Actor greatly simplifying creation of notary-assisted transactions
via RPC client (#2665)
* historic smart contract calls can now be made via CLI (#2683)
Behavior changes:
* calculatenetworkfee RPC can handle paid attributes (NeoGo extensions) and
invalid contract signatures now, it won't return an error for them (#2658)
* graceful node shutdown on SIGTERM (#2660)
* wallet balance commands now require at least 0.99.1 NeoGo version (or
compatible C# node) used by the RPC server (#2667)
Improvements:
* build system corrections (#2641, #2684)
* additional types in `unwrap` (#2650, #2651)
* session iterator consistency check in `unwrap` (#2650)
* multitransfers in NEP-17 RPC wrapper (#2653)
* extended transaction validity time in CLI wallet commands (#2653)
* reference counter optimization in VM (#2659)
* RPC Actor API can have default (used for all transactions) attributes and
callbacks now (#2665)
* neptoken RPC package can now provide wallet.Token data (#2667)
* NEP-11 balance commands can now work without direct token hash
specification or previous token import (#2667)
* support for offline signing in CLI (#2668)
* compiler can optimize out unused global variables now (#2624)
* private keys are now cleaned up from memory when they're no longer needed,
additional Account APIs added to reduce direct interactions with private
keys (#2672)
* updated linter settings, some code cleanup (#2674)
* more documentation and examples for new RPC APIs (#2681)
* refactored state-changing methods of NEP-11/NEP-17 RPC wrappers into a
separate structure to simplify reusing them in higher-level code (#2681)
* simplified rpcclient historic API (#2686)
Bugs fixed:
* compiler panic on empty package list (#2645)
* compiler not allowed to use unnamed parameters in exported methods (#2648)
* compiler allowed to export multireturn functions (#2648)
* compiler panic on nil method receiver in the compiled code (#2649)
* compiler panic on variable initialization from multireturn call (#2644)
* potential lockups or panics on node shutdown (#2652)
* contract manifest not checked for correctness in bindings generation CLI
command (#2656)
* SignTx wallet Account API could lead to inconsistent result in some cases
(#2665)
* wallet Account API allowed to sign with locked accounts (#2665)
* potential panic in keys.WIFDecode on some inputs (#2672)
## 0.99.2 "Recalibration" (12 Aug 2022)
This is a 3.4.0-compatible (tested for mainnet and testnet) update to NeoGo
@ -1673,7 +2609,7 @@ Behavior changes:
* contracts no longer have single entry point, rather they export a set of
methods with specific offsets. Go smart contract compiler has been changed
accordingly to add all exported (as in Go) methods to the manifest
(but with the first letter being lowercased to match NEP-5 expections,
(but with the first letter being lowercased to match NEP-5 expectations,
#1228). Please also refer to examples changes to better see how it affects
contracts, manifests and configuration files (#1296)
* native contracts are now called via Neo.Native.Call syscall (#1191)

View file

@ -1,6 +1,6 @@
# Builder image
# Keep go version in sync with Build GA job.
FROM golang:1.18-alpine as builder
FROM golang:1.22-alpine as builder
# Display go version for information purposes.
RUN go version

View file

@ -1,75 +1,6 @@
# Builder image
FROM mcr.microsoft.com/windows/servercore:ltsc2022 as builder
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop';", "$ProgressPreference = 'SilentlyContinue';"]
ENV GIT_VERSION=2.23.0
ENV GIT_TAG=v2.23.0.windows.1
ENV GIT_DOWNLOAD_URL=https://github.com/git-for-windows/git/releases/download/v2.23.0.windows.1/MinGit-2.23.0-64-bit.zip
ENV GIT_DOWNLOAD_SHA256=8f65208f92c0b4c3ae4c0cf02d4b5f6791d539cd1a07b2df62b7116467724735
RUN Write-Host ('Downloading {0} ...' -f $env:GIT_DOWNLOAD_URL); \
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; \
Invoke-WebRequest -Uri $env:GIT_DOWNLOAD_URL -OutFile 'git.zip'; \
\
Write-Host ('Verifying sha256 ({0}) ...' -f $env:GIT_DOWNLOAD_SHA256); \
if ((Get-FileHash git.zip -Algorithm sha256).Hash -ne $env:GIT_DOWNLOAD_SHA256) { \
Write-Host 'FAILED!'; \
exit 1; \
}; \
\
Write-Host 'Expanding ...'; \
Expand-Archive -Path git.zip -DestinationPath C:\git\.; \
\
Write-Host 'Removing ...'; \
Remove-Item git.zip -Force; \
\
Write-Host 'Updating PATH ...'; \
$env:PATH = 'C:\git\cmd;C:\git\mingw64\bin;C:\git\usr\bin;' + $env:PATH; \
[Environment]::SetEnvironmentVariable('PATH', $env:PATH, [EnvironmentVariableTarget]::Machine); \
\
Write-Host 'Verifying install ("git version") ...'; \
git version; \
\
Write-Host 'Complete.';
ENV GOPATH=C:\\go
RUN $newPath = ('{0}\bin;C:\Program Files\Go\bin;{1}' -f $env:GOPATH, $env:PATH); \
Write-Host ('Updating PATH: {0}' -f $newPath); \
[Environment]::SetEnvironmentVariable('PATH', $newPath, [EnvironmentVariableTarget]::Machine);
# Keep go version in sync with Build GA job.
ENV GOLANG_VERSION=1.19
RUN $url = 'https://go.dev/dl/go1.19.windows-amd64.zip'; \
Write-Host ('Downloading {0} ...' -f $url); \
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; \
Invoke-WebRequest -Uri $url -OutFile 'go.zip'; \
\
$sha256 = 'bcaaf966f91980d35ae93c37a8fe890e4ddfca19448c0d9f66c027d287e2823a'; \
Write-Host ('Verifying sha256 ({0}) ...' -f $sha256); \
if ((Get-FileHash go.zip -Algorithm sha256).Hash -ne $sha256) { \
Write-Host 'FAILED!'; \
exit 1; \
}; \
\
Write-Host 'Expanding ...'; \
Expand-Archive go.zip -DestinationPath C:\; \
\
Write-Host 'Moving ...'; \
Move-Item -Path C:\go -Destination 'C:\Program Files\Go'; \
\
Write-Host 'Removing ...'; \
Remove-Item go.zip -Force; \
\
Write-Host 'Verifying install ("go version") ...'; \
go version; \
\
Write-Host 'Complete.';
FROM golang:1.22.0-windowsservercore-ltsc2022 as builder
COPY . /neo-go

View file

@ -1,7 +1,6 @@
MIT License
Copyright (c) 2018-2022 Anthony De Meulemeester (@anthdm), City of Zion
community (@CityOfZion), NeoSPCC (@nspcc-dev)
Copyright (c) 2018-2023 NeoSPCC (@nspcc-dev), Anthony De Meulemeester (@anthdm), City of Zion community (@CityOfZion)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View file

@ -3,7 +3,7 @@ REPONAME = "neo-go"
NETMODE ?= "privnet"
BINARY=neo-go
BINARY_PATH=./bin/$(BINARY)$(shell go env GOEXE)
GO_VERSION ?= 1.18
GO_VERSION ?= 1.20
DESTDIR = ""
SYSCONFIGDIR = "/etc"
BINDIR = "/usr/bin"
@ -16,7 +16,7 @@ DC_FILE ?= ".docker/docker-compose.yml" # Single docker-compose for Ubuntu/WSC,
ENV_IMAGE_TAG="env_neo_go_image"
REPO ?= "$(shell go list -m)"
VERSION ?= "$(shell git describe --tags --match "v*" 2>/dev/null | sed 's/^v//')"
VERSION ?= "$(shell git describe --tags --match "v*" --abbrev=8 2>/dev/null | sed -r 's,^v([0-9]+\.[0-9]+)\.([0-9]+)(-.*)?$$,\1 \2 \3,' | while read mm patch suffix; do if [ -z "$$suffix" ]; then echo $$mm.$$patch; else patch=`expr $$patch + 1`; echo $$mm.$${patch}-pre$$suffix; fi; done)"
MODVERSION ?= "$(shell cat go.mod | cat go.mod | sed -r -n -e 's|.*pkg/interop (.*)|\1|p')"
BUILD_FLAGS = "-X '$(REPO)/pkg/config.Version=$(VERSION)' -X '$(REPO)/cli/smartcontract.ModVersion=$(MODVERSION)'"
@ -96,10 +96,10 @@ version:
@echo $(VERSION)
gh-docker-vars:
@echo "::set-output name=file::$(D_FILE)"
@echo "::set-output name=version::$(VERSION)"
@echo "::set-output name=repo::$(IMAGE_REPO)"
@echo "::set-output name=suffix::$(IMAGE_SUFFIX)"
@echo "file=$(D_FILE)"
@echo "version=$(VERSION)"
@echo "repo=$(IMAGE_REPO)"
@echo "suffix=$(IMAGE_SUFFIX)"
test:
@go test ./... -cover

View file

@ -1,5 +1,9 @@
<p align="center">
<img src="./.github/neo_color_dark_gopher.png" width="300px" alt="logo">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="./.github/logo_dark.png">
<source media="(prefers-color-scheme: light)" srcset="./.github/logo_light.png">
<img src="./.github/logo_light.png" width="300px" alt="NeoGo logo">
</picture>
</p>
<p align="center">
<b>Go</b> Node and SDK for the <a href="https://neo.org">Neo</a> blockchain.
@ -8,8 +12,7 @@
<hr />
[![codecov](https://codecov.io/gh/nspcc-dev/neo-go/branch/master/graph/badge.svg)](https://codecov.io/gh/nspcc-dev/neo-go)
[![CircleCI](https://circleci.com/gh/nspcc-dev/neo-go/tree/master.svg?style=shield)](https://circleci.com/gh/nspcc-dev/neo-go/tree/master)
[![GithubWorkflows Tests](https://github.com/nspcc-dev/neo-go/actions/workflows/run_tests.yml/badge.svg)](https://github.com/nspcc-dev/neo-go/actions/workflows/run_tests.yml)
[![GithubWorkflows Tests](https://github.com/nspcc-dev/neo-go/actions/workflows/tests.yml/badge.svg)](https://github.com/nspcc-dev/neo-go/actions/workflows/tests.yml)
[![Report](https://goreportcard.com/badge/github.com/nspcc-dev/neo-go)](https://goreportcard.com/report/github.com/nspcc-dev/neo-go)
[![GoDoc](https://godoc.org/github.com/nspcc-dev/neo-go?status.svg)](https://godoc.org/github.com/nspcc-dev/neo-go)
![GitHub release (latest SemVer)](https://img.shields.io/github/v/release/nspcc-dev/neo-go?sort=semver)
@ -17,20 +20,21 @@
# Overview
This project aims to be a full port of the original C# [Neo project](https://github.com/neo-project).
A complete toolkit for the NEO blockchain, including:
NeoGo is a complete platform for distributed application development built on
top of and compatible with the [Neo project](https://github.com/neo-project).
This includes, but not limited to (see documentation for more details):
- [Consensus node](docs/consensus.md)
- [RPC node & client](docs/rpc.md)
- [CLI tool](docs/cli.md)
- [Smart contract compiler](docs/compiler.md)
- [NEO virtual machine](docs/vm.md)
- [Neo virtual machine](docs/vm.md)
- [Smart contract examples](examples/README.md)
- [Oracle service](docs/oracle.md)
- [State validation service](docs/stateroots.md)
This branch (**master**) is Neo N3-compatible. For the current
Legacy-compatible version please refer to the [**master-2.x**
The protocol implemented here is Neo N3-compatible, however you can also find
an implementation of the Neo Legacy protocol in the [**master-2.x**
branch](https://github.com/nspcc-dev/neo-go/tree/master-2.x) and releases
before 0.80.0 (**0.7X.Y** track).
@ -47,13 +51,16 @@ NeoGo, `:latest` points to the latest release) or build yourself.
### Building
To build NeoGo you need Go 1.16+ and `make`:
Building NeoGo requires Go 1.20+ and `make`:
```
make build
make
```
The resulting binary is `bin/neo-go`.
The resulting binary is `bin/neo-go`. Notice that using some random revision
from the `master` branch is not recommended (it can have any number of
incompatibilities and bugs depending on the development stage), please use
tagged released versions.
#### Building on Windows
@ -61,13 +68,11 @@ To build NeoGo on Windows platform we recommend you to install `make` from [MinG
package](https://osdn.net/projects/mingw/). Then, you can build NeoGo with:
```
make build
make
```
The resulting binary is `bin/neo-go.exe`.
We also recommend you to switch the Windows Firewall off for further NeoGo node run.
## Running a node
A node needs to connect to some network, either local one (usually referred to
@ -96,6 +101,9 @@ Available network flags:
To run a consensus/committee node, refer to [consensus
documentation](docs/consensus.md).
If you're running a node on Windows, please turn off or configure Windows
Firewall appropriately (allowing inbound connections to the P2P port).
### Docker
By default, the `CMD` is set to run a node on `privnet`. So, to do this, simply run:
@ -126,37 +134,39 @@ Refer to [consensus node documentation](docs/consensus.md).
## Smart contract development
Please refer to [neo-go smart contract development
Please refer to [NeoGo smart contract development
workshop](https://github.com/nspcc-dev/neo-go-sc-wrkshp) that shows some
simple contracts that can be compiled/deployed/run using neo-go compiler, SDK
simple contracts that can be compiled/deployed/run using NeoGo compiler, SDK
and a private network. For details on how Go code is translated to Neo VM
bytecode and what you can and can not do in a smart contract, please refer to the
[compiler documentation](docs/compiler.md).
Refer to [examples](examples/README.md) for more NEO smart contract examples
Refer to [examples](examples/README.md) for more Neo smart contract examples
written in Go.
## Wallets
NeoGo differs substantially from C# implementation in its approach to
wallets. NeoGo wallet is just a
NeoGo wallet is just a
[NEP-6](https://github.com/neo-project/proposals/blob/68398d28b6932b8dd2b377d5d51bca7b0442f532/nep-6.mediawiki)
file that is used by CLI commands to sign various things. There is no database
behind it, the blockchain is the database and CLI commands use RPC to query
data from it. At the same time, it's not required to open a wallet on an RPC
node to perform various actions (unless your node provides some service
for the network like consensus or oracle nodes do).
file that is used by CLI commands to sign various things. CLI commands are not
a direct part of the node, but rather a part of the NeoGo binary, their
implementations use RPC to query data from the blockchain and perform any
required actions. It's not required to open a wallet on an RPC node (unless
your node provides some service for the network like consensus or oracle nodes
do).
# Developer notes
Nodes have such features as [Prometheus](https://prometheus.io/docs/guides/go-application) and
[Pprof](https://golang.org/pkg/net/http/pprof/) in order to have additional information about them for debugging.
## Monitoring
NeoGo provides [Prometheus](https://prometheus.io/docs/guides/go-application) and
[Pprof](https://golang.org/pkg/net/http/pprof/) services that can be enabled
in the node in order to provide additional monitoring and debugging data.
How to configure Prometheus or Pprof:
In `config/protocol.*.yml` there is
Configuring any of the two services is easy, add the following section (`Pprof`
instead of `Prometheus` if you need that) to the respective `config/protocol.*.yml`:
```
Prometheus:
Enabled: true
Port: 2112
Addresses:
- ":2112"
```
where you can switch on/off and define port. Prometheus is enabled and Pprof is disabled by default.
@ -170,10 +180,9 @@ describing the feature/topic you are going to implement.
# Contact
- [@roman-khimov](https://github.com/roman-khimov) on GitHub
- [@AnnaShaleva](https://github.com/AnnaShaleva) on GitHub
- [@fyrchik](https://github.com/fyrchik) on GitHub
- Reach out to us on the [NEO Discord](https://discordapp.com/invite/R8v48YA) channel
- [@roman-khimov](https://github.com/roman-khimov) on GitHub
- Reach out to us on the [Neo Discord](https://discordapp.com/invite/R8v48YA) channel
# License

View file

@ -7,10 +7,65 @@ functionality.
## Versions 0.7X.Y (as needed)
* Neo 2.0 support (bug fixes, minor functionality additions)
## Version 0.99.3 (September 2022)
* completely reworked RPC packages with all of the old functionality (but
keeping old APIs for this release as well)
* VM CLI improvements
## Version 0.107.0 (~Jun-Jul 2024)
* protocol updates
* bug fixes
* node resynchronisation from local DB
* CLI library upgrade
## Version 1.0 (2022, TBD)
* stable version with full Neo N3 support and useful extensions
## Version 1.0 (2024, TBD)
* stable version
# Deprecated functionality
As the node and the protocol evolve some external APIs can change. Usually we
try keeping backwards compatibility for some time (like half a year) unless
it's impossible to do for some reason. But eventually old
APIs/commands/configurations will be removed and here is a list of scheduled
breaking changes. Consider changing your code/scripts/configurations if you're
using anything mentioned here.
## GetPeers RPC server response type changes and RPC client support
GetPeers RPC command returns a list of Peers where the port type has changed from
string to uint16 to match C#. The RPC client currently supports unmarshalling both
formats.
Removal of Peer unmarshalling with string based ports is scheduled for Jun-Jul 2024
(~0.107.0 release).
## `NEOBalance` from stack item
We check struct items count before convert LastGasPerVote to let RPC client be compatible with
old versions.
Removal of this compatiblility code is scheduled for Jun-Jul 2024.
## `serv_node_version` Prometheus gauge metric
This metric is replaced by the new `neogo_version` and `server_id` Prometheus gauge
metrics with proper version formatting. `neogo_version` contains NeoGo version
hidden under `version` label and `server_id` contains network server ID hidden
under `server_id` label.
Removal of `serv_node_version` is scheduled for Jun-Jul 2024 (~0.107.0 release).
## RPC error codes returned by old versions and C#-nodes
NeoGo retains certain deprecated error codes: `neorpc.ErrCompatGeneric`,
`neorpc.ErrCompatNoOpenedWallet`. They returned by nodes not compliant with the
neo-project/proposals#156 (NeoGo pre-0.102.0 and all known C# versions).
Removal of the deprecated RPC error codes is planned for Jun-Jul 2024 (~0.107.0
release).
## Block based web-socket waiter transaction awaiting
Web-socket RPC based `waiter.EventWaiter` uses `header_of_added_block` notifications
subscription to manage transaction awaiting. To support old NeoGo RPC servers
(older than 0.105.0) that do not have block headers subscription ability,
event-based waiter fallbacks to the old way of block monitoring with
`block_added` notifications subscription.
Removal of stale RPC server compatibility code from `waiter.EventWaiter` is
scheduled for Jun-Jul 2024 (~0.107.0 release).

41
cli/app/app.go Normal file
View file

@ -0,0 +1,41 @@
package app
import (
"fmt"
"os"
"runtime"
"github.com/nspcc-dev/neo-go/cli/query"
"github.com/nspcc-dev/neo-go/cli/server"
"github.com/nspcc-dev/neo-go/cli/smartcontract"
"github.com/nspcc-dev/neo-go/cli/util"
"github.com/nspcc-dev/neo-go/cli/vm"
"github.com/nspcc-dev/neo-go/cli/wallet"
"github.com/nspcc-dev/neo-go/pkg/config"
"github.com/urfave/cli"
)
func versionPrinter(c *cli.Context) {
_, _ = fmt.Fprintf(c.App.Writer, "NeoGo\nVersion: %s\nGoVersion: %s\n",
config.Version,
runtime.Version(),
)
}
// New creates a NeoGo instance of [cli.App] with all commands included.
func New() *cli.App {
cli.VersionPrinter = versionPrinter
ctl := cli.NewApp()
ctl.Name = "neo-go"
ctl.Version = config.Version
ctl.Usage = "Official Go client for Neo"
ctl.ErrWriter = os.Stdout
ctl.Commands = append(ctl.Commands, server.NewCommands()...)
ctl.Commands = append(ctl.Commands, smartcontract.NewCommands()...)
ctl.Commands = append(ctl.Commands, wallet.NewCommands()...)
ctl.Commands = append(ctl.Commands, vm.NewCommands()...)
ctl.Commands = append(ctl.Commands, util.NewCommands()...)
ctl.Commands = append(ctl.Commands, query.NewCommands()...)
return ctl
}

19
cli/app/main_test.go Normal file
View file

@ -0,0 +1,19 @@
package app_test
import (
"testing"
"github.com/nspcc-dev/neo-go/internal/testcli"
"github.com/nspcc-dev/neo-go/internal/versionutil"
"github.com/nspcc-dev/neo-go/pkg/config"
)
func TestCLIVersion(t *testing.T) {
config.Version = versionutil.TestVersion // Zero-length version string disables '--version' completely.
e := testcli.NewExecutor(t, false)
e.Run(t, "neo-go", "--version")
e.CheckNextLine(t, "^NeoGo")
e.CheckNextLine(t, "^Version:")
e.CheckNextLine(t, "^GoVersion:")
e.CheckEOF(t)
}

View file

@ -1,155 +0,0 @@
package main
import (
"encoding/hex"
"math/big"
"strconv"
"testing"
"github.com/stretchr/testify/require"
)
// Register standby validator and vote for it.
// We don't create a new account here, because chain will
// stop working after validator will change.
func TestRegisterCandidate(t *testing.T) {
e := newExecutor(t, true)
validatorHex := hex.EncodeToString(validatorPriv.PublicKey().Bytes())
e.In.WriteString("one\r")
e.Run(t, "neo-go", "wallet", "nep17", "multitransfer",
"--rpc-endpoint", "http://"+e.RPC.Addr,
"--wallet", validatorWallet,
"--from", validatorAddr,
"--force",
"NEO:"+validatorPriv.Address()+":10",
"GAS:"+validatorPriv.Address()+":10000")
e.checkTxPersisted(t)
e.Run(t, "neo-go", "query", "committee",
"--rpc-endpoint", "http://"+e.RPC.Addr)
e.checkNextLine(t, "^\\s*"+validatorHex)
e.Run(t, "neo-go", "query", "candidates",
"--rpc-endpoint", "http://"+e.RPC.Addr)
e.checkNextLine(t, "^\\s*Key.+$") // Header.
e.checkEOF(t)
// missing address
e.RunWithError(t, "neo-go", "wallet", "candidate", "register",
"--rpc-endpoint", "http://"+e.RPC.Addr,
"--wallet", validatorWallet)
// additional parameter
e.RunWithError(t, "neo-go", "wallet", "candidate", "register",
"--rpc-endpoint", "http://"+e.RPC.Addr,
"--wallet", validatorWallet,
"--address", validatorPriv.Address(),
"error")
e.In.WriteString("one\r")
e.Run(t, "neo-go", "wallet", "candidate", "register",
"--rpc-endpoint", "http://"+e.RPC.Addr,
"--wallet", validatorWallet,
"--address", validatorPriv.Address())
e.checkTxPersisted(t)
vs, err := e.Chain.GetEnrollments()
require.NoError(t, err)
require.Equal(t, 1, len(vs))
require.Equal(t, validatorPriv.PublicKey(), vs[0].Key)
require.Equal(t, big.NewInt(0), vs[0].Votes)
t.Run("VoteUnvote", func(t *testing.T) {
// positional instead of a flag.
e.RunWithError(t, "neo-go", "wallet", "candidate", "vote",
"--rpc-endpoint", "http://"+e.RPC.Addr,
"--wallet", validatorWallet,
"--address", validatorPriv.Address(),
validatorHex) // not "--candidate hex", but "hex".
e.In.WriteString("one\r")
e.Run(t, "neo-go", "wallet", "candidate", "vote",
"--rpc-endpoint", "http://"+e.RPC.Addr,
"--wallet", validatorWallet,
"--address", validatorPriv.Address(),
"--candidate", validatorHex)
_, index := e.checkTxPersisted(t)
vs, err = e.Chain.GetEnrollments()
require.Equal(t, 1, len(vs))
require.Equal(t, validatorPriv.PublicKey(), vs[0].Key)
b, _ := e.Chain.GetGoverningTokenBalance(validatorPriv.GetScriptHash())
require.Equal(t, b, vs[0].Votes)
e.Run(t, "neo-go", "query", "committee",
"--rpc-endpoint", "http://"+e.RPC.Addr)
e.checkNextLine(t, "^\\s*"+validatorHex)
e.Run(t, "neo-go", "query", "candidates",
"--rpc-endpoint", "http://"+e.RPC.Addr)
e.checkNextLine(t, "^\\s*Key.+$") // Header.
e.checkNextLine(t, "^\\s*"+validatorHex+"\\s*"+b.String()+"\\s*true\\s*true$")
e.checkEOF(t)
// check state
e.Run(t, "neo-go", "query", "voter",
"--rpc-endpoint", "http://"+e.RPC.Addr,
validatorPriv.Address())
e.checkNextLine(t, "^\\s*Voted:\\s+"+validatorHex+"\\s+\\("+validatorPriv.Address()+"\\)$")
e.checkNextLine(t, "^\\s*Amount\\s*:\\s*"+b.String()+"$")
e.checkNextLine(t, "^\\s*Block\\s*:\\s*"+strconv.FormatUint(uint64(index), 10))
e.checkEOF(t)
// unvote
e.In.WriteString("one\r")
e.Run(t, "neo-go", "wallet", "candidate", "vote",
"--rpc-endpoint", "http://"+e.RPC.Addr,
"--wallet", validatorWallet,
"--address", validatorPriv.Address())
_, index = e.checkTxPersisted(t)
vs, err = e.Chain.GetEnrollments()
require.Equal(t, 1, len(vs))
require.Equal(t, validatorPriv.PublicKey(), vs[0].Key)
require.Equal(t, big.NewInt(0), vs[0].Votes)
// check state
e.Run(t, "neo-go", "query", "voter",
"--rpc-endpoint", "http://"+e.RPC.Addr,
validatorPriv.Address())
e.checkNextLine(t, "^\\s*Voted:\\s+"+"null") // no vote.
e.checkNextLine(t, "^\\s*Amount\\s*:\\s*"+b.String()+"$")
e.checkNextLine(t, "^\\s*Block\\s*:\\s*"+strconv.FormatUint(uint64(index), 10))
e.checkEOF(t)
})
// missing address
e.RunWithError(t, "neo-go", "wallet", "candidate", "unregister",
"--rpc-endpoint", "http://"+e.RPC.Addr,
"--wallet", validatorWallet)
// additional argument
e.RunWithError(t, "neo-go", "wallet", "candidate", "unregister",
"--rpc-endpoint", "http://"+e.RPC.Addr,
"--wallet", validatorWallet,
"--address", validatorPriv.Address(),
"argument")
e.In.WriteString("one\r")
e.Run(t, "neo-go", "wallet", "candidate", "unregister",
"--rpc-endpoint", "http://"+e.RPC.Addr,
"--wallet", validatorWallet,
"--address", validatorPriv.Address())
e.checkTxPersisted(t)
vs, err = e.Chain.GetEnrollments()
require.Equal(t, 0, len(vs))
// query voter: missing address
e.RunWithError(t, "neo-go", "query", "voter")
// Excessive parameters.
e.RunWithError(t, "neo-go", "query", "voter", "--rpc-endpoint", "http://"+e.RPC.Addr, validatorPriv.Address(), validatorPriv.Address())
e.RunWithError(t, "neo-go", "query", "committee", "--rpc-endpoint", "http://"+e.RPC.Addr, "something")
e.RunWithError(t, "neo-go", "query", "candidates", "--rpc-endpoint", "http://"+e.RPC.Addr, "something")
}

View file

@ -24,23 +24,148 @@ const (
ArrayEndSeparator = "]"
)
const (
// ParamsParsingDoc is a documentation for parameters parsing.
ParamsParsingDoc = ` Arguments always do have regular Neo smart contract parameter types, either
specified explicitly or being inferred from the value. To specify the type
manually use "type:value" syntax where the type is one of the following:
'signature', 'bool', 'int', 'hash160', 'hash256', 'bytes', 'key' or 'string'.
Array types are also supported: use special space-separated '[' and ']'
symbols around array values to denote array bounds. Nested arrays are also
supported. Null parameter is supported via 'nil' keyword without additional
type specification.
There is ability to provide an argument of 'bytearray' type via file. Use a
special 'filebytes' argument type for this with a filepath specified after
the colon, e.g. 'filebytes:my_file.txt'.
Given values are type-checked against given types with the following
restrictions applied:
* 'signature' type values should be hex-encoded and have a (decoded)
length of 64 bytes.
* 'bool' type values are 'true' and 'false'.
* 'int' values are decimal integers that can be successfully converted
from the string.
* 'hash160' values are Neo addresses and hex-encoded 20-bytes long (after
decoding) strings.
* 'hash256' type values should be hex-encoded and have a (decoded)
length of 32 bytes.
* 'bytes' type values are any hex-encoded things.
* 'filebytes' type values are filenames with the argument value inside.
* 'key' type values are hex-encoded marshalled public keys.
* 'string' type values are any valid UTF-8 strings. In the value's part of
the string the colon looses it's special meaning as a separator between
type and value and is taken literally.
If no type is explicitly specified, it is inferred from the value using the
following logic:
- anything that can be interpreted as a decimal integer gets
an 'int' type
- 'nil' string gets 'Any' NEP-14 parameter type and nil value which corresponds
to Null stackitem
- 'true' and 'false' strings get 'bool' type
- valid Neo addresses and 20 bytes long hex-encoded strings get 'hash160'
type
- valid hex-encoded public keys get 'key' type
- 32 bytes long hex-encoded values get 'hash256' type
- 64 bytes long hex-encoded values get 'signature' type
- any other valid hex-encoded values get 'bytes' type
- anything else is a 'string'
Backslash character is used as an escape character and allows to use colon in
an implicitly typed string. For any other characters it has no special
meaning, to get a literal backslash in the string use the '\\' sequence.
Examples:
* 'int:42' is an integer with a value of 42
* '42' is an integer with a value of 42
* 'nil' is a parameter with Any NEP-14 type and nil value (corresponds to Null stackitem)
* 'bad' is a string with a value of 'bad'
* 'dead' is a byte array with a value of 'dead'
* 'string:dead' is a string with a value of 'dead'
* 'filebytes:my_data.txt' is bytes decoded from a content of my_data.txt
* 'NSiVJYZej4XsxG5CUpdwn7VRQk8iiiDMPM' is a hash160 with a value
of '682cca3ebdc66210e5847d7f8115846586079d4a'
* '\4\2' is an integer with a value of 42
* '\\4\2' is a string with a value of '\42'
* 'string:string' is a string with a value of 'string'
* 'string\:string' is a string with a value of 'string:string'
* '03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c' is a
key with a value of '03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c'
* '[ a b c ]' is an array with strings values 'a', 'b' and 'c'
* '[ a b [ c d ] e ]' is an array with 4 values: string 'a', string 'b',
array of two strings 'c' and 'd', string 'e'
* '[ ]' is an empty array`
// SignersParsingDoc is a documentation for signers parsing.
SignersParsingDoc = ` Signers represent a set of Uint160 hashes with witness scopes and are used
to verify hashes in System.Runtime.CheckWitness syscall. First signer is treated
as a sender. To specify signers use signer[:scope] syntax where
* 'signer' is a signer's address (as Neo address or hex-encoded 160 bit (20 byte)
LE value with or without '0x' prefix).
* 'scope' is a comma-separated set of cosigner's scopes, which could be:
- 'None' - default witness scope which may be used for the sender
to only pay fee for the transaction.
- 'Global' - allows this witness in all contexts. This cannot be combined
with other flags.
- 'CalledByEntry' - means that this condition must hold: EntryScriptHash
== CallingScriptHash. The witness/permission/signature
given on first invocation will automatically expire if
entering deeper internal invokes. This can be default
safe choice for native NEO/GAS.
- 'CustomContracts' - define valid custom contract hashes for witness check.
Hashes are be provided as hex-encoded LE value string.
At lest one hash must be provided. Multiple hashes
are separated by ':'.
- 'CustomGroups' - define custom public keys for group members. Public keys are
provided as short-form (1-byte prefix + 32 bytes) hex-encoded
values. At least one key must be provided. Multiple keys
are separated by ':'.
If no scopes were specified, 'CalledByEntry' used as default. If no signers were
specified, no array is passed. Note that scopes are properly handled by
neo-go RPC server only. C# implementation does not support scopes capability.
Examples:
* 'NNQk4QXsxvsrr3GSozoWBUxEmfag7B6hz5'
* 'NVquyZHoPirw6zAEPvY1ZezxM493zMWQqs:Global'
* '0x0000000009070e030d0f0e020d0c06050e030c02'
* '0000000009070e030d0f0e020d0c06050e030c02:CalledByEntry,` +
`CustomGroups:0206d7495ceb34c197093b5fc1cccf1996ada05e69ef67e765462a7f5d88ee14d0'
* '0000000009070e030d0f0e020d0c06050e030c02:CalledByEntry,` +
`CustomContracts:1011120009070e030d0f0e020d0c06050e030c02:0x1211100009070e030d0f0e020d0c06050e030c02'`
)
// GetSignersFromContext returns signers parsed from context args starting
// from the specified offset.
func GetSignersFromContext(ctx *cli.Context, offset int) ([]transaction.Signer, *cli.ExitError) {
args := ctx.Args()
var signers []transaction.Signer
var (
signers []transaction.Signer
err error
)
if args.Present() && len(args) > offset {
for i, c := range args[offset:] {
cosigner, err := parseCosigner(c)
if err != nil {
return nil, cli.NewExitError(fmt.Errorf("failed to parse signer #%d: %w", i, err), 1)
}
signers = append(signers, cosigner)
signers, err = ParseSigners(args[offset:])
if err != nil {
return nil, cli.NewExitError(err, 1)
}
}
return signers, nil
}
// ParseSigners returns array of signers parsed from their string representation.
func ParseSigners(args []string) ([]transaction.Signer, error) {
var signers []transaction.Signer
for i, c := range args {
cosigner, err := parseCosigner(c)
if err != nil {
return nil, fmt.Errorf("failed to parse signer #%d: %w", i, err)
}
signers = append(signers, cosigner)
}
return signers, nil
}
func parseCosigner(c string) (transaction.Signer, error) {
var (
err error
@ -105,9 +230,9 @@ func parseCosigner(c string) (transaction.Signer, error) {
}
// GetDataFromContext returns data parameter from context args.
func GetDataFromContext(ctx *cli.Context) (int, interface{}, *cli.ExitError) {
func GetDataFromContext(ctx *cli.Context) (int, any, *cli.ExitError) {
var (
data interface{}
data any
offset int
params []smartcontract.Parameter
err error
@ -199,10 +324,7 @@ func ParseParams(args []string, calledFromMain bool) (int, []smartcontract.Param
// accounts from the provided wallet.
func GetSignersAccounts(senderAcc *wallet.Account, wall *wallet.Wallet, signers []transaction.Signer, accScope transaction.WitnessScope) ([]actor.SignerAccount, error) {
signersAccounts := make([]actor.SignerAccount, 0, len(signers)+1)
sender, err := address.StringToUint160(senderAcc.Address)
if err != nil {
return nil, err
}
sender := senderAcc.ScriptHash()
signersAccounts = append(signersAccounts, actor.SignerAccount{
Signer: transaction.Signer{
Account: sender,

View file

@ -1,7 +1,6 @@
package cmdargs
import (
"encoding/hex"
"strings"
"testing"
@ -45,7 +44,7 @@ func TestParseCosigner(t *testing.T) {
Scopes: transaction.CalledByEntry | transaction.CustomContracts,
AllowedContracts: []util.Uint160{c1, c2},
},
acc.StringLE() + ":CustomGroups:" + hex.EncodeToString(priv.PublicKey().Bytes()): {
acc.StringLE() + ":CustomGroups:" + priv.PublicKey().StringCompressed(): {
Account: acc,
Scopes: transaction.CustomGroups,
AllowedGroups: keys.PublicKeys{priv.PublicKey()},

View file

@ -1,48 +1,15 @@
package main
import (
"fmt"
"os"
"runtime"
"github.com/nspcc-dev/neo-go/cli/query"
"github.com/nspcc-dev/neo-go/cli/server"
"github.com/nspcc-dev/neo-go/cli/smartcontract"
"github.com/nspcc-dev/neo-go/cli/util"
"github.com/nspcc-dev/neo-go/cli/vm"
"github.com/nspcc-dev/neo-go/cli/wallet"
"github.com/nspcc-dev/neo-go/pkg/config"
"github.com/urfave/cli"
"github.com/nspcc-dev/neo-go/cli/app"
)
func main() {
ctl := newApp()
ctl := app.New()
if err := ctl.Run(os.Args); err != nil {
panic(err)
}
}
func versionPrinter(c *cli.Context) {
_, _ = fmt.Fprintf(c.App.Writer, "NeoGo\nVersion: %s\nGoVersion: %s\n",
config.Version,
runtime.Version(),
)
}
func newApp() *cli.App {
cli.VersionPrinter = versionPrinter
ctl := cli.NewApp()
ctl.Name = "neo-go"
ctl.Version = config.Version
ctl.Usage = "Official Go client for Neo"
ctl.ErrWriter = os.Stdout
ctl.Commands = append(ctl.Commands, server.NewCommands()...)
ctl.Commands = append(ctl.Commands, smartcontract.NewCommands()...)
ctl.Commands = append(ctl.Commands, wallet.NewCommands()...)
ctl.Commands = append(ctl.Commands, vm.NewCommands()...)
ctl.Commands = append(ctl.Commands, util.NewCommands()...)
ctl.Commands = append(ctl.Commands, query.NewCommands()...)
return ctl
}

View file

@ -1,14 +0,0 @@
package main
import (
"testing"
)
func TestCLIVersion(t *testing.T) {
e := newExecutor(t, false)
e.Run(t, "neo-go", "--version")
e.checkNextLine(t, "^NeoGo")
e.checkNextLine(t, "^Version:")
e.checkNextLine(t, "^GoVersion:")
e.checkEOF(t)
}

View file

@ -1,4 +1,4 @@
package main
package nep_test
import (
"bytes"
@ -13,6 +13,8 @@ import (
"strconv"
"testing"
"github.com/nspcc-dev/neo-go/internal/testcli"
"github.com/nspcc-dev/neo-go/internal/versionutil"
"github.com/nspcc-dev/neo-go/pkg/core/native/nativenames"
"github.com/nspcc-dev/neo-go/pkg/core/state"
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
@ -26,12 +28,15 @@ import (
const (
// nftOwnerAddr is the owner of NFT-ND HASHY token (../examples/nft-nd/nft.go).
nftOwnerAddr = "NbrUYaZgyhSkNoRo9ugRyEMdUZxrhkNaWB"
nftOwnerWallet = "../examples/my_wallet.json"
nftOwnerWallet = "../../examples/my_wallet.json"
nftOwnerPass = "qwerty"
// Keep contract NEFs consistent between runs.
_ = versionutil.TestVersion
)
func TestNEP11Import(t *testing.T) {
e := newExecutor(t, true)
e := testcli.NewExecutor(t, true)
tmpDir := t.TempDir()
walletPath := filepath.Join(tmpDir, "walletForImport.json")
@ -46,7 +51,7 @@ func TestNEP11Import(t *testing.T) {
args := []string{
"neo-go", "wallet", "nep11", "import",
"--rpc-endpoint", "http://" + e.RPC.Addr,
"--rpc-endpoint", "http://" + e.RPC.Addresses()[0],
"--wallet", walletPath,
}
// missing token hash
@ -68,12 +73,12 @@ func TestNEP11Import(t *testing.T) {
e.RunWithError(t, append(args, "--token", neoContractHash.StringLE())...)
checkInfo := func(t *testing.T, h util.Uint160, name string, symbol string, decimals int) {
e.checkNextLine(t, "^Name:\\s*"+name)
e.checkNextLine(t, "^Symbol:\\s*"+symbol)
e.checkNextLine(t, "^Hash:\\s*"+h.StringLE())
e.checkNextLine(t, "^Decimals:\\s*"+strconv.Itoa(decimals))
e.checkNextLine(t, "^Address:\\s*"+address.Uint160ToString(h))
e.checkNextLine(t, "^Standard:\\s*"+string(manifest.NEP11StandardName))
e.CheckNextLine(t, "^Name:\\s*"+name)
e.CheckNextLine(t, "^Symbol:\\s*"+symbol)
e.CheckNextLine(t, "^Hash:\\s*"+h.StringLE())
e.CheckNextLine(t, "^Decimals:\\s*"+strconv.Itoa(decimals))
e.CheckNextLine(t, "^Address:\\s*"+address.Uint160ToString(h))
e.CheckNextLine(t, "^Standard:\\s*"+string(manifest.NEP11StandardName))
}
t.Run("Info", func(t *testing.T) {
t.Run("excessive parameters", func(t *testing.T) {
@ -89,7 +94,7 @@ func TestNEP11Import(t *testing.T) {
e.Run(t, "neo-go", "wallet", "nep11", "info",
"--wallet", walletPath)
checkInfo(t, nnsContractHash, "NameService", "NNS", 0)
e.checkNextLine(t, "")
e.CheckNextLine(t, "")
checkInfo(t, nfsContractHash, "NeoFS Object NFT", "NFSO", 2)
})
})
@ -109,7 +114,7 @@ func TestNEP11Import(t *testing.T) {
}
func TestNEP11_ND_OwnerOf_BalanceOf_Transfer(t *testing.T) {
e := newExecutor(t, true)
e := testcli.NewExecutor(t, true)
tmpDir := t.TempDir()
// copy wallet to temp dir in order not to overwrite the original file
@ -122,14 +127,14 @@ func TestNEP11_ND_OwnerOf_BalanceOf_Transfer(t *testing.T) {
// transfer funds to contract owner
e.In.WriteString("one\r")
e.Run(t, "neo-go", "wallet", "nep17", "transfer",
"--rpc-endpoint", "http://"+e.RPC.Addr,
"--wallet", validatorWallet,
"--rpc-endpoint", "http://"+e.RPC.Addresses()[0],
"--wallet", testcli.ValidatorWallet,
"--to", nftOwnerAddr,
"--token", "GAS",
"--amount", "10000",
"--force",
"--from", validatorAddr)
e.checkTxPersisted(t)
"--from", testcli.ValidatorAddr)
e.CheckTxPersisted(t)
// deploy NFT HASHY contract
h := deployNFTContract(t, e)
@ -138,14 +143,14 @@ func TestNEP11_ND_OwnerOf_BalanceOf_Transfer(t *testing.T) {
// mint 1 HASHY token by transferring 10 GAS to HASHY contract
e.In.WriteString(nftOwnerPass + "\r")
e.Run(t, "neo-go", "wallet", "nep17", "transfer",
"--rpc-endpoint", "http://"+e.RPC.Addr,
"--rpc-endpoint", "http://"+e.RPC.Addresses()[0],
"--wallet", wall,
"--to", h.StringLE(),
"--token", "GAS",
"--amount", "10",
"--force",
"--from", nftOwnerAddr)
txMint, _ := e.checkTxPersisted(t)
txMint, _ := e.CheckTxPersisted(t)
// get NFT ID from AER
aer, err := e.Chain.GetAppExecResults(txMint.Hash(), trigger.Application)
@ -161,15 +166,16 @@ func TestNEP11_ND_OwnerOf_BalanceOf_Transfer(t *testing.T) {
}
tokenID := mint(t)
var hashBeforeTransfer = e.Chain.CurrentHeaderHash()
// check the balance
cmdCheckBalance := []string{"neo-go", "wallet", "nep11", "balance",
"--rpc-endpoint", "http://" + e.RPC.Addr,
"--rpc-endpoint", "http://" + e.RPC.Addresses()[0],
"--wallet", wall,
"--address", nftOwnerAddr}
checkBalanceResult := func(t *testing.T, acc string, ids ...[]byte) {
e.checkNextLine(t, "^\\s*Account\\s+"+acc)
e.checkNextLine(t, "^\\s*HASHY:\\s+HASHY NFT \\("+h.StringLE()+"\\)")
e.CheckNextLine(t, "^\\s*Account\\s+"+acc)
e.CheckNextLine(t, "^\\s*HASHY:\\s+HASHY NFT \\("+h.StringLE()+"\\)")
// Hashes can be ordered in any way, so make a regexp for them.
var tokstring = "("
@ -182,11 +188,11 @@ func TestNEP11_ND_OwnerOf_BalanceOf_Transfer(t *testing.T) {
tokstring += ")"
for range ids {
e.checkNextLine(t, "^\\s*Token: "+tokstring+"\\s*$")
e.checkNextLine(t, "^\\s*Amount: 1\\s*$")
e.checkNextLine(t, "^\\s*Updated: [0-9]+\\s*$")
e.CheckNextLine(t, "^\\s*Token: "+tokstring+"\\s*$")
e.CheckNextLine(t, "^\\s*Amount: 1\\s*$")
e.CheckNextLine(t, "^\\s*Updated: [0-9]+\\s*$")
}
e.checkEOF(t)
e.CheckEOF(t)
}
// balance check: by symbol, token is not imported
e.Run(t, append(cmdCheckBalance, "--token", "HASHY")...)
@ -199,7 +205,7 @@ func TestNEP11_ND_OwnerOf_BalanceOf_Transfer(t *testing.T) {
// import token
e.Run(t, "neo-go", "wallet", "nep11", "import",
"--rpc-endpoint", "http://"+e.RPC.Addr,
"--rpc-endpoint", "http://"+e.RPC.Addresses()[0],
"--wallet", wall,
"--token", h.StringLE())
@ -209,7 +215,7 @@ func TestNEP11_ND_OwnerOf_BalanceOf_Transfer(t *testing.T) {
// balance check: all accounts
e.Run(t, "neo-go", "wallet", "nep11", "balance",
"--rpc-endpoint", "http://"+e.RPC.Addr,
"--rpc-endpoint", "http://"+e.RPC.Addresses()[0],
"--wallet", wall,
"--token", h.StringLE())
checkBalanceResult(t, nftOwnerAddr, tokenID)
@ -221,7 +227,7 @@ func TestNEP11_ND_OwnerOf_BalanceOf_Transfer(t *testing.T) {
// ownerOf: missing contract hash
cmdOwnerOf := []string{"neo-go", "wallet", "nep11", "ownerOf",
"--rpc-endpoint", "http://" + e.RPC.Addr,
"--rpc-endpoint", "http://" + e.RPC.Addresses()[0],
}
e.RunWithError(t, cmdOwnerOf...)
cmdOwnerOf = append(cmdOwnerOf, "--token", h.StringLE())
@ -232,11 +238,11 @@ func TestNEP11_ND_OwnerOf_BalanceOf_Transfer(t *testing.T) {
// ownerOf: good
e.Run(t, cmdOwnerOf...)
e.checkNextLine(t, nftOwnerAddr)
e.CheckNextLine(t, nftOwnerAddr)
// tokensOf: missing contract hash
cmdTokensOf := []string{"neo-go", "wallet", "nep11", "tokensOf",
"--rpc-endpoint", "http://" + e.RPC.Addr,
"--rpc-endpoint", "http://" + e.RPC.Addresses()[0],
}
e.RunWithError(t, cmdTokensOf...)
cmdTokensOf = append(cmdTokensOf, "--token", h.StringLE())
@ -247,12 +253,12 @@ func TestNEP11_ND_OwnerOf_BalanceOf_Transfer(t *testing.T) {
// tokensOf: good
e.Run(t, cmdTokensOf...)
require.Equal(t, hex.EncodeToString(tokenID), e.getNextLine(t))
require.Equal(t, hex.EncodeToString(tokenID), e.GetNextLine(t))
// properties: no contract
cmdProperties := []string{
"neo-go", "wallet", "nep11", "properties",
"--rpc-endpoint", "http://" + e.RPC.Addr,
"--rpc-endpoint", "http://" + e.RPC.Addresses()[0],
}
e.RunWithError(t, cmdProperties...)
cmdProperties = append(cmdProperties, "--token", h.StringLE())
@ -263,7 +269,7 @@ func TestNEP11_ND_OwnerOf_BalanceOf_Transfer(t *testing.T) {
// properties: ok
e.Run(t, cmdProperties...)
require.Equal(t, fmt.Sprintf(`{"name":"HASHY %s"}`, base64.StdEncoding.EncodeToString(tokenID)), e.getNextLine(t))
require.Equal(t, fmt.Sprintf(`{"name":"HASHY %s"}`, base64.StdEncoding.EncodeToString(tokenID)), e.GetNextLine(t))
// tokensOf: good, several tokens
tokenID1 := mint(t)
@ -273,12 +279,12 @@ func TestNEP11_ND_OwnerOf_BalanceOf_Transfer(t *testing.T) {
fst, snd = snd, fst
}
require.Equal(t, hex.EncodeToString(fst), e.getNextLine(t))
require.Equal(t, hex.EncodeToString(snd), e.getNextLine(t))
require.Equal(t, hex.EncodeToString(fst), e.GetNextLine(t))
require.Equal(t, hex.EncodeToString(snd), e.GetNextLine(t))
// tokens: missing contract hash
cmdTokens := []string{"neo-go", "wallet", "nep11", "tokens",
"--rpc-endpoint", "http://" + e.RPC.Addr,
"--rpc-endpoint", "http://" + e.RPC.Addresses()[0],
}
e.RunWithError(t, cmdTokens...)
cmdTokens = append(cmdTokens, "--token", h.StringLE())
@ -287,8 +293,8 @@ func TestNEP11_ND_OwnerOf_BalanceOf_Transfer(t *testing.T) {
e.RunWithError(t, append(cmdTokens, "additional")...)
// tokens: good, several tokens
e.Run(t, cmdTokens...)
require.Equal(t, hex.EncodeToString(fst), e.getNextLine(t))
require.Equal(t, hex.EncodeToString(snd), e.getNextLine(t))
require.Equal(t, hex.EncodeToString(fst), e.GetNextLine(t))
require.Equal(t, hex.EncodeToString(snd), e.GetNextLine(t))
// balance check: several tokens, ok
e.Run(t, append(cmdCheckBalance, "--token", h.StringLE())...)
@ -296,9 +302,9 @@ func TestNEP11_ND_OwnerOf_BalanceOf_Transfer(t *testing.T) {
cmdTransfer := []string{
"neo-go", "wallet", "nep11", "transfer",
"--rpc-endpoint", "http://" + e.RPC.Addr,
"--rpc-endpoint", "http://" + e.RPC.Addresses()[0],
"--wallet", wall,
"--to", validatorAddr,
"--to", testcli.ValidatorAddr,
"--from", nftOwnerAddr,
"--force",
}
@ -316,17 +322,25 @@ func TestNEP11_ND_OwnerOf_BalanceOf_Transfer(t *testing.T) {
// transfer: good
e.In.WriteString(nftOwnerPass + "\r")
e.Run(t, append(cmdTransfer, "--id", hex.EncodeToString(tokenID))...)
e.checkTxPersisted(t)
e.CheckTxPersisted(t)
// check balance after transfer
e.Run(t, append(cmdCheckBalance, "--token", h.StringLE())...)
checkBalanceResult(t, nftOwnerAddr, tokenID1)
// check --await flag
tokenID2 := mint(t)
e.In.WriteString(nftOwnerPass + "\r")
e.Run(t, append(cmdTransfer, "--await", "--id", hex.EncodeToString(tokenID2))...)
e.CheckAwaitableTxPersisted(t)
e.Run(t, append(cmdCheckBalance, "--token", h.StringLE())...)
checkBalanceResult(t, nftOwnerAddr, tokenID1)
// transfer: good, to NEP-11-Payable contract, with data
verifyH := deployVerifyContract(t, e)
cmdTransfer = []string{
"neo-go", "wallet", "nep11", "transfer",
"--rpc-endpoint", "http://" + e.RPC.Addr,
"--rpc-endpoint", "http://" + e.RPC.Addresses()[0],
"--wallet", wall,
"--to", verifyH.StringLE(),
"--from", nftOwnerAddr,
@ -337,7 +351,7 @@ func TestNEP11_ND_OwnerOf_BalanceOf_Transfer(t *testing.T) {
}
e.In.WriteString(nftOwnerPass + "\r")
e.Run(t, cmdTransfer...)
tx, _ := e.checkTxPersisted(t)
tx, _ := e.CheckTxPersisted(t)
// check OnNEP11Payment event
aer, err := e.Chain.GetAppExecResults(tx.Hash(), trigger.Application)
require.NoError(t, err)
@ -358,14 +372,32 @@ func TestNEP11_ND_OwnerOf_BalanceOf_Transfer(t *testing.T) {
// check balance after transfer
e.Run(t, append(cmdCheckBalance, "--token", h.StringLE())...)
checkBalanceResult(t, nftOwnerAddr)
// historic calls still remember the good old days.
cmdOwnerOf = append(cmdOwnerOf, "--historic", hashBeforeTransfer.StringLE())
e.Run(t, cmdOwnerOf...)
e.CheckNextLine(t, nftOwnerAddr)
cmdTokensOf = append(cmdTokensOf, "--historic", hashBeforeTransfer.StringLE())
e.Run(t, cmdTokensOf...)
require.Equal(t, hex.EncodeToString(tokenID), e.GetNextLine(t))
cmdTokens = append(cmdTokens, "--historic", hashBeforeTransfer.StringLE())
e.Run(t, cmdTokens...)
require.Equal(t, hex.EncodeToString(tokenID), e.GetNextLine(t))
// this one is not affected by transfer, but anyway
cmdProperties = append(cmdProperties, "--historic", hashBeforeTransfer.StringLE())
e.Run(t, cmdProperties...)
require.Equal(t, fmt.Sprintf(`{"name":"HASHY %s"}`, base64.StdEncoding.EncodeToString(tokenID)), e.GetNextLine(t))
}
func TestNEP11_D_OwnerOf_BalanceOf_Transfer(t *testing.T) {
e := newExecutor(t, true)
e := testcli.NewExecutor(t, true)
tmpDir := t.TempDir()
// copy wallet to temp dir in order not to overwrite the original file
bytesRead, err := os.ReadFile(validatorWallet)
bytesRead, err := os.ReadFile(testcli.ValidatorWallet)
require.NoError(t, err)
wall := filepath.Join(tmpDir, "my_wallet.json")
err = os.WriteFile(wall, bytesRead, 0755)
@ -376,18 +408,18 @@ func TestNEP11_D_OwnerOf_BalanceOf_Transfer(t *testing.T) {
mint := func(t *testing.T, containerID, objectID util.Uint256) []byte {
// mint 1.00 NFSO token by transferring 10 GAS to NFSO contract
e.In.WriteString(validatorPass + "\r")
e.In.WriteString(testcli.ValidatorPass + "\r")
e.Run(t, "neo-go", "wallet", "nep17", "transfer",
"--rpc-endpoint", "http://"+e.RPC.Addr,
"--rpc-endpoint", "http://"+e.RPC.Addresses()[0],
"--wallet", wall,
"--to", h.StringLE(),
"--token", "GAS",
"--amount", "10",
"--force",
"--from", validatorAddr,
"--from", testcli.ValidatorAddr,
"--", "[", "hash256:"+containerID.StringLE(), "hash256:"+objectID.StringLE(), "]",
)
txMint, _ := e.checkTxPersisted(t)
txMint, _ := e.CheckTxPersisted(t)
// get NFT ID from AER
aer, err := e.Chain.GetAppExecResults(txMint.Hash(), trigger.Application)
@ -412,15 +444,15 @@ func TestNEP11_D_OwnerOf_BalanceOf_Transfer(t *testing.T) {
// check properties
e.Run(t, "neo-go", "wallet", "nep11", "properties",
"--rpc-endpoint", "http://"+e.RPC.Addr,
"--rpc-endpoint", "http://"+e.RPC.Addresses()[0],
"--token", h.StringLE(),
"--id", hex.EncodeToString(token1ID))
jProps := e.getNextLine(t)
jProps := e.GetNextLine(t)
props := make(map[string]string)
require.NoError(t, json.Unmarshal([]byte(jProps), &props))
require.Equal(t, base64.StdEncoding.EncodeToString(container1ID.BytesBE()), props["containerID"])
require.Equal(t, base64.StdEncoding.EncodeToString(object1ID.BytesBE()), props["objectID"])
e.checkEOF(t)
e.CheckEOF(t)
type idAmount struct {
id string
@ -429,19 +461,19 @@ func TestNEP11_D_OwnerOf_BalanceOf_Transfer(t *testing.T) {
// check the balance
cmdCheckBalance := []string{"neo-go", "wallet", "nep11", "balance",
"--rpc-endpoint", "http://" + e.RPC.Addr,
"--rpc-endpoint", "http://" + e.RPC.Addresses()[0],
"--wallet", wall,
"--address", validatorAddr}
"--address", testcli.ValidatorAddr}
checkBalanceResult := func(t *testing.T, acc string, objs ...idAmount) {
e.checkNextLine(t, "^\\s*Account\\s+"+acc)
e.checkNextLine(t, "^\\s*NFSO:\\s+NeoFS Object NFT \\("+h.StringLE()+"\\)")
e.CheckNextLine(t, "^\\s*Account\\s+"+acc)
e.CheckNextLine(t, "^\\s*NFSO:\\s+NeoFS Object NFT \\("+h.StringLE()+"\\)")
for _, o := range objs {
e.checkNextLine(t, "^\\s*Token: "+o.id+"\\s*$")
e.checkNextLine(t, "^\\s*Amount: "+o.amount+"\\s*$")
e.checkNextLine(t, "^\\s*Updated: [0-9]+\\s*$")
e.CheckNextLine(t, "^\\s*Token: "+o.id+"\\s*$")
e.CheckNextLine(t, "^\\s*Amount: "+o.amount+"\\s*$")
e.CheckNextLine(t, "^\\s*Updated: [0-9]+\\s*$")
}
e.checkEOF(t)
e.CheckEOF(t)
}
tokz := []idAmount{
{hex.EncodeToString(token1ID), "1"},
@ -449,29 +481,29 @@ func TestNEP11_D_OwnerOf_BalanceOf_Transfer(t *testing.T) {
}
// balance check: by symbol, token is not imported
e.Run(t, append(cmdCheckBalance, "--token", "NFSO")...)
checkBalanceResult(t, validatorAddr, tokz...)
checkBalanceResult(t, testcli.ValidatorAddr, tokz...)
// overall NFSO balance check: by hash, ok
e.Run(t, append(cmdCheckBalance, "--token", h.StringLE())...)
checkBalanceResult(t, validatorAddr, tokz...)
checkBalanceResult(t, testcli.ValidatorAddr, tokz...)
// particular NFSO balance check: by hash, ok
e.Run(t, append(cmdCheckBalance, "--token", h.StringLE(), "--id", hex.EncodeToString(token2ID))...)
checkBalanceResult(t, validatorAddr, tokz[1])
checkBalanceResult(t, testcli.ValidatorAddr, tokz[1])
// import token
e.Run(t, "neo-go", "wallet", "nep11", "import",
"--rpc-endpoint", "http://"+e.RPC.Addr,
"--rpc-endpoint", "http://"+e.RPC.Addresses()[0],
"--wallet", wall,
"--token", h.StringLE())
// overall balance check: by symbol, ok
e.Run(t, append(cmdCheckBalance, "--token", "NFSO")...)
checkBalanceResult(t, validatorAddr, tokz...)
checkBalanceResult(t, testcli.ValidatorAddr, tokz...)
// particular balance check: by symbol, ok
e.Run(t, append(cmdCheckBalance, "--token", "NFSO", "--id", hex.EncodeToString(token1ID))...)
checkBalanceResult(t, validatorAddr, tokz[0])
checkBalanceResult(t, testcli.ValidatorAddr, tokz[0])
// remove token from wallet
e.In.WriteString("y\r")
@ -480,7 +512,7 @@ func TestNEP11_D_OwnerOf_BalanceOf_Transfer(t *testing.T) {
// ownerOfD: missing contract hash
cmdOwnerOf := []string{"neo-go", "wallet", "nep11", "ownerOfD",
"--rpc-endpoint", "http://" + e.RPC.Addr,
"--rpc-endpoint", "http://" + e.RPC.Addresses()[0],
}
e.RunWithError(t, cmdOwnerOf...)
cmdOwnerOf = append(cmdOwnerOf, "--token", h.StringLE())
@ -491,29 +523,29 @@ func TestNEP11_D_OwnerOf_BalanceOf_Transfer(t *testing.T) {
// ownerOfD: good
e.Run(t, cmdOwnerOf...)
e.checkNextLine(t, validatorAddr)
e.CheckNextLine(t, testcli.ValidatorAddr)
// tokensOf: missing contract hash
cmdTokensOf := []string{"neo-go", "wallet", "nep11", "tokensOf",
"--rpc-endpoint", "http://" + e.RPC.Addr,
"--rpc-endpoint", "http://" + e.RPC.Addresses()[0],
}
e.RunWithError(t, cmdTokensOf...)
cmdTokensOf = append(cmdTokensOf, "--token", h.StringLE())
// tokensOf: missing owner address
e.RunWithError(t, cmdTokensOf...)
cmdTokensOf = append(cmdTokensOf, "--address", validatorAddr)
cmdTokensOf = append(cmdTokensOf, "--address", testcli.ValidatorAddr)
// tokensOf: good
e.Run(t, cmdTokensOf...)
require.Equal(t, hex.EncodeToString(token1ID), e.getNextLine(t))
require.Equal(t, hex.EncodeToString(token2ID), e.getNextLine(t))
e.checkEOF(t)
require.Equal(t, hex.EncodeToString(token1ID), e.GetNextLine(t))
require.Equal(t, hex.EncodeToString(token2ID), e.GetNextLine(t))
e.CheckEOF(t)
// properties: no contract
cmdProperties := []string{
"neo-go", "wallet", "nep11", "properties",
"--rpc-endpoint", "http://" + e.RPC.Addr,
"--rpc-endpoint", "http://" + e.RPC.Addresses()[0],
}
e.RunWithError(t, cmdProperties...)
cmdProperties = append(cmdProperties, "--token", h.StringLE())
@ -527,12 +559,12 @@ func TestNEP11_D_OwnerOf_BalanceOf_Transfer(t *testing.T) {
// properties: ok
e.Run(t, cmdProperties...)
jProps = e.getNextLine(t)
jProps = e.GetNextLine(t)
props = make(map[string]string)
require.NoError(t, json.Unmarshal([]byte(jProps), &props))
require.Equal(t, base64.StdEncoding.EncodeToString(container2ID.BytesBE()), props["containerID"])
require.Equal(t, base64.StdEncoding.EncodeToString(object2ID.BytesBE()), props["objectID"])
e.checkEOF(t)
e.CheckEOF(t)
// tokensOf: good, several tokens
e.Run(t, cmdTokensOf...)
@ -541,75 +573,75 @@ func TestNEP11_D_OwnerOf_BalanceOf_Transfer(t *testing.T) {
fst, snd = snd, fst
}
require.Equal(t, hex.EncodeToString(fst), e.getNextLine(t))
require.Equal(t, hex.EncodeToString(snd), e.getNextLine(t))
require.Equal(t, hex.EncodeToString(fst), e.GetNextLine(t))
require.Equal(t, hex.EncodeToString(snd), e.GetNextLine(t))
// tokens: missing contract hash
cmdTokens := []string{"neo-go", "wallet", "nep11", "tokens",
"--rpc-endpoint", "http://" + e.RPC.Addr,
"--rpc-endpoint", "http://" + e.RPC.Addresses()[0],
}
e.RunWithError(t, cmdTokens...)
cmdTokens = append(cmdTokens, "--token", h.StringLE())
// tokens: good, several tokens
e.Run(t, cmdTokens...)
require.Equal(t, hex.EncodeToString(fst), e.getNextLine(t))
require.Equal(t, hex.EncodeToString(snd), e.getNextLine(t))
require.Equal(t, hex.EncodeToString(fst), e.GetNextLine(t))
require.Equal(t, hex.EncodeToString(snd), e.GetNextLine(t))
// balance check: several tokens, ok
e.Run(t, append(cmdCheckBalance, "--token", h.StringLE())...)
checkBalanceResult(t, validatorAddr, tokz...)
checkBalanceResult(t, testcli.ValidatorAddr, tokz...)
cmdTransfer := []string{
"neo-go", "wallet", "nep11", "transfer",
"--rpc-endpoint", "http://" + e.RPC.Addr,
"--rpc-endpoint", "http://" + e.RPC.Addresses()[0],
"--wallet", wall,
"--to", nftOwnerAddr,
"--from", validatorAddr,
"--from", testcli.ValidatorAddr,
"--force",
}
// transfer: unimported token with symbol id specified
e.In.WriteString(validatorPass + "\r")
e.In.WriteString(testcli.ValidatorPass + "\r")
e.RunWithError(t, append(cmdTransfer,
"--token", "NFSO")...)
cmdTransfer = append(cmdTransfer, "--token", h.StringLE())
// transfer: no id specified
e.In.WriteString(validatorPass + "\r")
e.In.WriteString(testcli.ValidatorPass + "\r")
e.RunWithError(t, cmdTransfer...)
// transfer: good
e.In.WriteString(validatorPass + "\r")
e.In.WriteString(testcli.ValidatorPass + "\r")
e.Run(t, append(cmdTransfer, "--id", hex.EncodeToString(token1ID))...)
e.checkTxPersisted(t)
e.CheckTxPersisted(t)
// check balance after transfer
e.Run(t, append(cmdCheckBalance, "--token", h.StringLE())...)
checkBalanceResult(t, validatorAddr, tokz[1]) // only token2ID expected to be on the balance
checkBalanceResult(t, testcli.ValidatorAddr, tokz[1]) // only token2ID expected to be on the balance
// transfer: good, 1/4 of the balance, to NEP-11-Payable contract, with data
verifyH := deployVerifyContract(t, e)
cmdTransfer = []string{
"neo-go", "wallet", "nep11", "transfer",
"--rpc-endpoint", "http://" + e.RPC.Addr,
"--rpc-endpoint", "http://" + e.RPC.Addresses()[0],
"--wallet", wall,
"--to", verifyH.StringLE(),
"--from", validatorAddr,
"--from", testcli.ValidatorAddr,
"--token", h.StringLE(),
"--id", hex.EncodeToString(token2ID),
"--amount", "0.25",
"--force",
"string:some_data",
}
e.In.WriteString(validatorPass + "\r")
e.In.WriteString(testcli.ValidatorPass + "\r")
e.Run(t, cmdTransfer...)
tx, _ := e.checkTxPersisted(t)
tx, _ := e.CheckTxPersisted(t)
// check OnNEP11Payment event
aer, err := e.Chain.GetAppExecResults(tx.Hash(), trigger.Application)
require.NoError(t, err)
require.Equal(t, 2, len(aer[0].Events))
validatorHash, err := address.StringToUint160(validatorAddr)
validatorHash, err := address.StringToUint160(testcli.ValidatorAddr)
require.NoError(t, err)
require.Equal(t, state.NotificationEvent{
ScriptHash: verifyH,
@ -625,17 +657,21 @@ func TestNEP11_D_OwnerOf_BalanceOf_Transfer(t *testing.T) {
// check balance after transfer
e.Run(t, append(cmdCheckBalance, "--token", h.StringLE())...)
tokz[1].amount = "0.75"
checkBalanceResult(t, validatorAddr, tokz[1])
checkBalanceResult(t, testcli.ValidatorAddr, tokz[1])
}
func deployNFSContract(t *testing.T, e *executor) util.Uint160 {
return deployContract(t, e, "../examples/nft-d/nft.go", "../examples/nft-d/nft.yml", validatorWallet, validatorAddr, validatorPass)
func deployNFSContract(t *testing.T, e *testcli.Executor) util.Uint160 {
return testcli.DeployContract(t, e, "../../examples/nft-d/nft.go", "../../examples/nft-d/nft.yml", testcli.ValidatorWallet, testcli.ValidatorAddr, testcli.ValidatorPass)
}
func deployNFTContract(t *testing.T, e *executor) util.Uint160 {
return deployContract(t, e, "../examples/nft-nd/nft.go", "../examples/nft-nd/nft.yml", nftOwnerWallet, nftOwnerAddr, nftOwnerPass)
func deployNFTContract(t *testing.T, e *testcli.Executor) util.Uint160 {
return testcli.DeployContract(t, e, "../../examples/nft-nd/nft.go", "../../examples/nft-nd/nft.yml", nftOwnerWallet, nftOwnerAddr, nftOwnerPass)
}
func deployNNSContract(t *testing.T, e *executor) util.Uint160 {
return deployContract(t, e, "../examples/nft-nd-nns/", "../examples/nft-nd-nns/nns.yml", validatorWallet, validatorAddr, validatorPass)
func deployNNSContract(t *testing.T, e *testcli.Executor) util.Uint160 {
return testcli.DeployContract(t, e, "../../examples/nft-nd-nns/", "../../examples/nft-nd-nns/nns.yml", testcli.ValidatorWallet, testcli.ValidatorAddr, testcli.ValidatorPass)
}
func deployVerifyContract(t *testing.T, e *testcli.Executor) util.Uint160 {
return testcli.DeployContract(t, e, "../smartcontract/testdata/verify.go", "../smartcontract/testdata/verify.yml", testcli.ValidatorWallet, testcli.ValidatorAddr, testcli.ValidatorPass)
}

View file

@ -1,4 +1,4 @@
package main
package nep_test
import (
"io"
@ -8,6 +8,7 @@ import (
"strings"
"testing"
"github.com/nspcc-dev/neo-go/internal/testcli"
"github.com/nspcc-dev/neo-go/pkg/core/native/nativenames"
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
"github.com/nspcc-dev/neo-go/pkg/encoding/fixedn"
@ -17,24 +18,39 @@ import (
)
func TestNEP17Balance(t *testing.T) {
e := newExecutor(t, true)
e := testcli.NewExecutor(t, true)
args := []string{
"neo-go", "wallet", "nep17", "multitransfer",
"--rpc-endpoint", "http://" + e.RPC.Addresses()[0],
"--wallet", testcli.ValidatorWallet,
"--from", testcli.ValidatorAddr,
"GAS:" + testcli.TestWalletMultiAccount1 + ":1",
"NEO:" + testcli.TestWalletMultiAccount1 + ":10",
"GAS:" + testcli.TestWalletMultiAccount3 + ":3",
"--force",
}
e.In.WriteString("one\r")
e.Run(t, args...)
e.CheckTxPersisted(t)
cmdbalance := []string{"neo-go", "wallet", "nep17", "balance"}
cmdbase := append(cmdbalance,
"--rpc-endpoint", "http://"+e.RPC.Addr,
"--wallet", validatorWallet,
"--rpc-endpoint", "http://"+e.RPC.Addresses()[0],
"--wallet", testcli.TestWalletMultiPath,
)
cmd := append(cmdbase, "--address", validatorAddr)
cmd := append(cmdbase, "--address", testcli.TestWalletMultiAccount1)
t.Run("excessive parameters", func(t *testing.T) {
e.RunWithError(t, append(cmd, "--token", "NEO", "gas")...)
})
t.Run("NEO", func(t *testing.T) {
b, index := e.Chain.GetGoverningTokenBalance(validatorHash)
b, index := e.Chain.GetGoverningTokenBalance(testcli.TestWalletMultiAccount1Hash)
checkResult := func(t *testing.T) {
e.checkNextLine(t, "^\\s*Account\\s+"+validatorAddr)
e.checkNextLine(t, "^\\s*NEO:\\s+NeoToken \\("+e.Chain.GoverningTokenHash().StringLE()+"\\)")
e.checkNextLine(t, "^\\s*Amount\\s*:\\s*"+b.String()+"$")
e.checkNextLine(t, "^\\s*Updated\\s*:\\s*"+strconv.FormatUint(uint64(index), 10))
e.checkEOF(t)
e.CheckNextLine(t, "^\\s*Account\\s+"+testcli.TestWalletMultiAccount1)
e.CheckNextLine(t, "^\\s*NEO:\\s+NeoToken \\("+e.Chain.GoverningTokenHash().StringLE()+"\\)")
e.CheckNextLine(t, "^\\s*Amount\\s*:\\s*"+b.String()+"$")
e.CheckNextLine(t, "^\\s*Updated\\s*:\\s*"+strconv.FormatUint(uint64(index), 10))
e.CheckEOF(t)
}
t.Run("Alias", func(t *testing.T) {
e.Run(t, append(cmd, "--token", "NEO")...)
@ -47,67 +63,55 @@ func TestNEP17Balance(t *testing.T) {
})
t.Run("GAS", func(t *testing.T) {
e.Run(t, append(cmd, "--token", "GAS")...)
e.checkNextLine(t, "^\\s*Account\\s+"+validatorAddr)
e.checkNextLine(t, "^\\s*GAS:\\s+GasToken \\("+e.Chain.UtilityTokenHash().StringLE()+"\\)")
b := e.Chain.GetUtilityTokenBalance(validatorHash)
e.checkNextLine(t, "^\\s*Amount\\s*:\\s*"+fixedn.Fixed8(b.Int64()).String()+"$")
e.CheckNextLine(t, "^\\s*Account\\s+"+testcli.TestWalletMultiAccount1)
e.CheckNextLine(t, "^\\s*GAS:\\s+GasToken \\("+e.Chain.UtilityTokenHash().StringLE()+"\\)")
b := e.Chain.GetUtilityTokenBalance(testcli.TestWalletMultiAccount1Hash)
e.CheckNextLine(t, "^\\s*Amount\\s*:\\s*"+fixedn.Fixed8(b.Int64()).String()+"$")
})
t.Run("zero balance of known token", func(t *testing.T) {
e.Run(t, append(cmdbase, []string{"--token", "NEO"}...)...)
addr1, err := address.StringToUint160("Nhfg3TbpwogLvDGVvAvqyThbsHgoSUKwtn")
require.NoError(t, err)
e.checkNextLine(t, "^Account "+address.Uint160ToString(addr1))
e.checkNextLine(t, "^\\s*NEO:\\s+NeoToken \\("+e.Chain.GoverningTokenHash().StringLE()+"\\)")
e.checkNextLine(t, "^\\s*Amount\\s*:\\s*"+fixedn.Fixed8(0).String()+"$")
e.checkNextLine(t, "^\\s*Updated:")
e.checkNextLine(t, "^\\s*$")
e.Run(t, append(cmdbase, []string{"--token", "NEO", "--address", testcli.TestWalletMultiAccount2}...)...)
e.CheckNextLine(t, "^Account "+testcli.TestWalletMultiAccount2)
e.CheckNextLine(t, "^\\s*NEO:\\s+NeoToken \\("+e.Chain.GoverningTokenHash().StringLE()+"\\)")
e.CheckNextLine(t, "^\\s*Amount\\s*:\\s*"+fixedn.Fixed8(0).String()+"$")
e.CheckNextLine(t, "^\\s*Updated:")
e.CheckEOF(t)
})
t.Run("all accounts", func(t *testing.T) {
e.Run(t, cmdbase...)
addr1, err := address.StringToUint160("Nhfg3TbpwogLvDGVvAvqyThbsHgoSUKwtn")
require.NoError(t, err)
e.checkNextLine(t, "^Account "+address.Uint160ToString(addr1))
e.checkNextLine(t, "^\\s*GAS:\\s+GasToken \\("+e.Chain.UtilityTokenHash().StringLE()+"\\)")
balance := e.Chain.GetUtilityTokenBalance(addr1)
e.checkNextLine(t, "^\\s*Amount\\s*:\\s*"+fixedn.Fixed8(balance.Int64()).String()+"$")
e.checkNextLine(t, "^\\s*Updated:")
e.checkNextLine(t, "^\\s*$")
addr2, err := address.StringToUint160("NVTiAjNgagDkTr5HTzDmQP9kPwPHN5BgVq")
require.NoError(t, err)
e.checkNextLine(t, "^Account "+address.Uint160ToString(addr2))
e.checkNextLine(t, "^\\s*$")
addr3, err := address.StringToUint160("NfgHwwTi3wHAS8aFAN243C5vGbkYDpqLHP")
require.NoError(t, err)
e.checkNextLine(t, "^Account "+address.Uint160ToString(addr3))
e.CheckNextLine(t, "^Account "+testcli.TestWalletMultiAccount1)
// The order of assets is undefined.
for i := 0; i < 2; i++ {
line := e.getNextLine(t)
line := e.GetNextLine(t)
if strings.Contains(line, "GAS") {
e.checkLine(t, line, "^\\s*GAS:\\s+GasToken \\("+e.Chain.UtilityTokenHash().StringLE()+"\\)")
balance = e.Chain.GetUtilityTokenBalance(addr3)
e.checkNextLine(t, "^\\s*Amount\\s*:\\s*"+fixedn.Fixed8(balance.Int64()).String()+"$")
e.checkNextLine(t, "^\\s*Updated:")
e.CheckLine(t, line, "^\\s*GAS:\\s+GasToken \\("+e.Chain.UtilityTokenHash().StringLE()+"\\)")
balance := e.Chain.GetUtilityTokenBalance(testcli.TestWalletMultiAccount1Hash)
e.CheckNextLine(t, "^\\s*Amount\\s*:\\s*"+fixedn.Fixed8(balance.Int64()).String()+"$")
e.CheckNextLine(t, "^\\s*Updated:")
} else {
balance, index := e.Chain.GetGoverningTokenBalance(validatorHash)
e.checkLine(t, line, "^\\s*NEO:\\s+NeoToken \\("+e.Chain.GoverningTokenHash().StringLE()+"\\)")
e.checkNextLine(t, "^\\s*Amount\\s*:\\s*"+balance.String()+"$")
e.checkNextLine(t, "^\\s*Updated\\s*:\\s*"+strconv.FormatUint(uint64(index), 10))
balance, index := e.Chain.GetGoverningTokenBalance(testcli.TestWalletMultiAccount1Hash)
e.CheckLine(t, line, "^\\s*NEO:\\s+NeoToken \\("+e.Chain.GoverningTokenHash().StringLE()+"\\)")
e.CheckNextLine(t, "^\\s*Amount\\s*:\\s*"+balance.String()+"$")
e.CheckNextLine(t, "^\\s*Updated\\s*:\\s*"+strconv.FormatUint(uint64(index), 10))
}
}
e.CheckNextLine(t, "^\\s*$")
e.checkNextLine(t, "^\\s*$")
addr4, err := address.StringToUint160("NQ3nAdFQXzemHC9uvr4af2Ysap6aZJpqgN") // deployed verify.go contract
require.NoError(t, err)
e.checkNextLine(t, "^Account "+address.Uint160ToString(addr4))
e.checkEOF(t)
e.CheckNextLine(t, "^Account "+testcli.TestWalletMultiAccount2)
e.CheckNextLine(t, "^\\s*$")
e.CheckNextLine(t, "^Account "+testcli.TestWalletMultiAccount3)
e.CheckNextLine(t, "^\\s*GAS:\\s+GasToken \\("+e.Chain.UtilityTokenHash().StringLE()+"\\)")
balance := e.Chain.GetUtilityTokenBalance(testcli.TestWalletMultiAccount3Hash)
e.CheckNextLine(t, "^\\s*Amount\\s*:\\s*"+fixedn.Fixed8(balance.Int64()).String()+"$")
e.CheckNextLine(t, "^\\s*Updated:")
e.CheckEOF(t)
})
t.Run("Bad token", func(t *testing.T) {
e.Run(t, append(cmd, "--token", "kek")...)
e.checkNextLine(t, "^\\s*Account\\s+"+validatorAddr)
e.checkNextLine(t, `^\s*Can't find data for "kek" token\s*`)
e.checkEOF(t)
e.CheckNextLine(t, "^\\s*Account\\s+"+testcli.TestWalletMultiAccount1)
e.CheckNextLine(t, `^\s*Can't find data for "kek" token\s*`)
e.CheckEOF(t)
})
t.Run("Bad wallet", func(t *testing.T) {
e.RunWithError(t, append(cmdbalance, "--wallet", "/dev/null")...)
@ -115,18 +119,18 @@ func TestNEP17Balance(t *testing.T) {
}
func TestNEP17Transfer(t *testing.T) {
w, err := wallet.NewWalletFromFile("testdata/testwallet.json")
w, err := wallet.NewWalletFromFile("../testdata/testwallet.json")
require.NoError(t, err)
e := newExecutor(t, true)
e := testcli.NewExecutor(t, true)
args := []string{
"neo-go", "wallet", "nep17", "transfer",
"--rpc-endpoint", "http://" + e.RPC.Addr,
"--wallet", validatorWallet,
"--rpc-endpoint", "http://" + e.RPC.Addresses()[0],
"--wallet", testcli.ValidatorWallet,
"--to", w.Accounts[0].Address,
"--token", "NEO",
"--amount", "1",
"--from", validatorAddr,
"--from", testcli.ValidatorAddr,
}
t.Run("missing receiver", func(t *testing.T) {
@ -157,23 +161,20 @@ func TestNEP17Transfer(t *testing.T) {
e.In.WriteString("one\r")
e.In.WriteString("Y\r")
e.Run(t, args...)
e.checkNextLine(t, `^Network fee:\s*(\d|\.)+`)
e.checkNextLine(t, `^System fee:\s*(\d|\.)+`)
e.checkNextLine(t, `^Total fee:\s*(\d|\.)+`)
e.checkTxPersisted(t)
e.CheckNextLine(t, `^Network fee:\s*(\d|\.)+`)
e.CheckNextLine(t, `^System fee:\s*(\d|\.)+`)
e.CheckNextLine(t, `^Total fee:\s*(\d|\.)+`)
e.CheckTxPersisted(t)
sh, err := address.StringToUint160(w.Accounts[0].Address)
require.NoError(t, err)
sh := w.Accounts[0].ScriptHash()
b, _ := e.Chain.GetGoverningTokenBalance(sh)
require.Equal(t, big.NewInt(1), b)
t.Run("with force", func(t *testing.T) {
e.In.WriteString("one\r")
e.Run(t, append(args, "--force")...)
e.checkTxPersisted(t)
e.CheckTxPersisted(t)
sh, err := address.StringToUint160(w.Accounts[0].Address)
require.NoError(t, err)
b, _ := e.Chain.GetGoverningTokenBalance(sh)
require.Equal(t, big.NewInt(2), b)
})
@ -184,22 +185,20 @@ func TestNEP17Transfer(t *testing.T) {
t.Run("default address", func(t *testing.T) {
e.In.WriteString("one\r")
e.Run(t, "neo-go", "wallet", "nep17", "multitransfer",
"--rpc-endpoint", "http://"+e.RPC.Addr,
"--wallet", validatorWallet,
"--from", validatorAddr,
"--rpc-endpoint", "http://"+e.RPC.Addresses()[0],
"--wallet", testcli.ValidatorWallet,
"--from", testcli.ValidatorAddr,
"--force",
"NEO:"+validatorDefault+":42",
"GAS:"+validatorDefault+":7")
e.checkTxPersisted(t)
e.CheckTxPersisted(t)
args := args[:len(args)-2] // cut '--from' argument
args = append(args, "--force")
e.In.WriteString("one\r")
e.Run(t, args...)
e.checkTxPersisted(t)
e.CheckTxPersisted(t)
sh, err := address.StringToUint160(w.Accounts[0].Address)
require.NoError(t, err)
b, _ := e.Chain.GetGoverningTokenBalance(sh)
require.Equal(t, big.NewInt(3), b)
@ -212,63 +211,70 @@ func TestNEP17Transfer(t *testing.T) {
t.Run("with signers", func(t *testing.T) {
e.In.WriteString("one\r")
e.Run(t, "neo-go", "wallet", "nep17", "multitransfer",
"--rpc-endpoint", "http://"+e.RPC.Addr,
"--wallet", validatorWallet,
"--from", validatorAddr,
"--rpc-endpoint", "http://"+e.RPC.Addresses()[0],
"--wallet", testcli.ValidatorWallet,
"--from", testcli.ValidatorAddr,
"--force",
"NEO:"+validatorDefault+":42",
"GAS:"+validatorDefault+":7",
"--", validatorAddr+":Global")
e.checkTxPersisted(t)
"--", testcli.ValidatorAddr+":Global")
e.CheckTxPersisted(t)
})
validTil := e.Chain.BlockHeight() + 100
cmd := []string{
"neo-go", "wallet", "nep17", "transfer",
"--rpc-endpoint", "http://" + e.RPC.Addr,
"--wallet", validatorWallet,
"--to", address.Uint160ToString(e.Chain.GetNotaryContractScriptHash()),
"--rpc-endpoint", "http://" + e.RPC.Addresses()[0],
"--wallet", testcli.ValidatorWallet,
"--token", "GAS",
"--amount", "1",
"--from", validatorAddr,
"--force",
"[", validatorAddr, strconv.Itoa(int(validTil)), "]"}
"--from", testcli.ValidatorAddr}
t.Run("with await", func(t *testing.T) {
e.In.WriteString("one\r")
e.Run(t, append(cmd, "--to", nftOwnerAddr, "--await")...)
e.CheckAwaitableTxPersisted(t)
})
cmd = append(cmd, "--to", address.Uint160ToString(e.Chain.GetNotaryContractScriptHash()),
"[", testcli.ValidatorAddr, strconv.Itoa(int(validTil)), "]")
t.Run("with data", func(t *testing.T) {
e.In.WriteString("one\r")
e.Run(t, cmd...)
e.checkTxPersisted(t)
e.CheckTxPersisted(t)
})
t.Run("with data and signers", func(t *testing.T) {
t.Run("invalid sender's scope", func(t *testing.T) {
e.In.WriteString("one\r")
e.RunWithError(t, append(cmd, "--", validatorAddr+":None")...)
e.RunWithError(t, append(cmd, "--", testcli.ValidatorAddr+":None")...)
})
t.Run("good", func(t *testing.T) {
e.In.WriteString("one\r")
e.Run(t, append(cmd, "--", validatorAddr+":Global")...) // CalledByEntry is enough, but it's the default value, so check something else
e.checkTxPersisted(t)
e.Run(t, append(cmd, "--", testcli.ValidatorAddr+":Global")...) // CalledByEntry is enough, but it's the default value, so check something else
e.CheckTxPersisted(t)
})
t.Run("several signers", func(t *testing.T) {
e.In.WriteString("one\r")
e.Run(t, append(cmd, "--", validatorAddr, hVerify.StringLE())...)
e.checkTxPersisted(t)
e.Run(t, append(cmd, "--", testcli.ValidatorAddr, hVerify.StringLE())...)
e.CheckTxPersisted(t)
})
})
}
func TestNEP17MultiTransfer(t *testing.T) {
privs, _ := generateKeys(t, 3)
privs, _ := testcli.GenerateKeys(t, 3)
e := newExecutor(t, true)
e := testcli.NewExecutor(t, true)
neoContractHash, err := e.Chain.GetNativeContractScriptHash(nativenames.Neo)
require.NoError(t, err)
args := []string{
"neo-go", "wallet", "nep17", "multitransfer",
"--rpc-endpoint", "http://" + e.RPC.Addr,
"--wallet", validatorWallet,
"--from", validatorAddr,
"--rpc-endpoint", "http://" + e.RPC.Addresses()[0],
"--wallet", testcli.ValidatorWallet,
"--from", testcli.ValidatorAddr,
"--force",
"NEO:" + privs[0].Address() + ":42",
"GAS:" + privs[1].Address() + ":7",
@ -279,7 +285,7 @@ func TestNEP17MultiTransfer(t *testing.T) {
t.Run("no cosigners", func(t *testing.T) {
e.In.WriteString("one\r")
e.Run(t, args...)
e.checkTxPersisted(t)
e.CheckTxPersisted(t)
b, _ := e.Chain.GetGoverningTokenBalance(privs[0].GetScriptHash())
require.Equal(t, big.NewInt(42), b)
@ -292,24 +298,24 @@ func TestNEP17MultiTransfer(t *testing.T) {
t.Run("invalid sender scope", func(t *testing.T) {
e.In.WriteString("one\r")
e.RunWithError(t, append(args,
"--", validatorAddr+":None")...) // invalid sender scope
"--", testcli.ValidatorAddr+":None")...) // invalid sender scope
})
t.Run("Global sender scope", func(t *testing.T) {
e.In.WriteString("one\r")
e.Run(t, append(args,
"--", validatorAddr+":Global")...)
e.checkTxPersisted(t)
"--", testcli.ValidatorAddr+":Global")...)
e.CheckTxPersisted(t)
})
t.Run("Several cosigners", func(t *testing.T) {
e.In.WriteString("one\r")
e.Run(t, append(args,
"--", validatorAddr, hVerify.StringLE())...)
e.checkTxPersisted(t)
"--", testcli.ValidatorAddr, hVerify.StringLE())...)
e.CheckTxPersisted(t)
})
}
func TestNEP17ImportToken(t *testing.T) {
e := newExecutor(t, true)
e := testcli.NewExecutor(t, true)
tmpDir := t.TempDir()
walletPath := filepath.Join(tmpDir, "walletForImport.json")
@ -322,37 +328,37 @@ func TestNEP17ImportToken(t *testing.T) {
// missing token hash
e.RunWithError(t, "neo-go", "wallet", "nep17", "import",
"--rpc-endpoint", "http://"+e.RPC.Addr,
"--rpc-endpoint", "http://"+e.RPC.Addresses()[0],
"--wallet", walletPath)
// additional parameter
e.RunWithError(t, "neo-go", "wallet", "nep17", "import",
"--rpc-endpoint", "http://"+e.RPC.Addr,
"--rpc-endpoint", "http://"+e.RPC.Addresses()[0],
"--wallet", walletPath,
"--token", gasContractHash.StringLE(), "useless")
e.Run(t, "neo-go", "wallet", "nep17", "import",
"--rpc-endpoint", "http://"+e.RPC.Addr,
"--rpc-endpoint", "http://"+e.RPC.Addresses()[0],
"--wallet", walletPath,
"--token", gasContractHash.StringLE())
e.Run(t, "neo-go", "wallet", "nep17", "import",
"--rpc-endpoint", "http://"+e.RPC.Addr,
"--rpc-endpoint", "http://"+e.RPC.Addresses()[0],
"--wallet", walletPath,
"--token", address.Uint160ToString(neoContractHash)) // try address instead of sh
// not a NEP-17 token
e.RunWithError(t, "neo-go", "wallet", "nep17", "import",
"--rpc-endpoint", "http://"+e.RPC.Addr,
"--rpc-endpoint", "http://"+e.RPC.Addresses()[0],
"--wallet", walletPath,
"--token", nnsContractHash.StringLE())
t.Run("Info", func(t *testing.T) {
checkGASInfo := func(t *testing.T) {
e.checkNextLine(t, "^Name:\\s*GasToken")
e.checkNextLine(t, "^Symbol:\\s*GAS")
e.checkNextLine(t, "^Hash:\\s*"+gasContractHash.StringLE())
e.checkNextLine(t, "^Decimals:\\s*8")
e.checkNextLine(t, "^Address:\\s*"+address.Uint160ToString(gasContractHash))
e.checkNextLine(t, "^Standard:\\s*"+string(manifest.NEP17StandardName))
e.CheckNextLine(t, "^Name:\\s*GasToken")
e.CheckNextLine(t, "^Symbol:\\s*GAS")
e.CheckNextLine(t, "^Hash:\\s*"+gasContractHash.StringLE())
e.CheckNextLine(t, "^Decimals:\\s*8")
e.CheckNextLine(t, "^Address:\\s*"+address.Uint160ToString(gasContractHash))
e.CheckNextLine(t, "^Standard:\\s*"+string(manifest.NEP17StandardName))
}
t.Run("excessive parameters", func(t *testing.T) {
e.RunWithError(t, "neo-go", "wallet", "nep17", "info",
@ -369,12 +375,12 @@ func TestNEP17ImportToken(t *testing.T) {
checkGASInfo(t)
_, err := e.Out.ReadString('\n')
require.NoError(t, err)
e.checkNextLine(t, "^Name:\\s*NeoToken")
e.checkNextLine(t, "^Symbol:\\s*NEO")
e.checkNextLine(t, "^Hash:\\s*"+neoContractHash.StringLE())
e.checkNextLine(t, "^Decimals:\\s*0")
e.checkNextLine(t, "^Address:\\s*"+address.Uint160ToString(neoContractHash))
e.checkNextLine(t, "^Standard:\\s*"+string(manifest.NEP17StandardName))
e.CheckNextLine(t, "^Name:\\s*NeoToken")
e.CheckNextLine(t, "^Symbol:\\s*NEO")
e.CheckNextLine(t, "^Hash:\\s*"+neoContractHash.StringLE())
e.CheckNextLine(t, "^Decimals:\\s*0")
e.CheckNextLine(t, "^Address:\\s*"+address.Uint160ToString(neoContractHash))
e.CheckNextLine(t, "^Standard:\\s*"+string(manifest.NEP17StandardName))
})
t.Run("Remove", func(t *testing.T) {
e.RunWithError(t, "neo-go", "wallet", "nep17", "remove",

View file

@ -1,20 +1,22 @@
package main
package options_test
import (
"flag"
"testing"
"github.com/nspcc-dev/neo-go/cli/app"
"github.com/nspcc-dev/neo-go/cli/options"
"github.com/nspcc-dev/neo-go/internal/testcli"
"github.com/stretchr/testify/require"
"github.com/urfave/cli"
)
func TestGetRPCClient(t *testing.T) {
e := newExecutor(t, true)
e := testcli.NewExecutor(t, true)
t.Run("no endpoint", func(t *testing.T) {
set := flag.NewFlagSet("flagSet", flag.ExitOnError)
ctx := cli.NewContext(cli.NewApp(), set, nil)
ctx := cli.NewContext(app.New(), set, nil)
gctx, _ := options.GetTimeoutContext(ctx)
_, ec := options.GetRPCClient(gctx, ctx)
require.Equal(t, 1, ec.ExitCode())
@ -22,8 +24,8 @@ func TestGetRPCClient(t *testing.T) {
t.Run("success", func(t *testing.T) {
set := flag.NewFlagSet("flagSet", flag.ExitOnError)
set.String(options.RPCEndpointFlag, "http://"+e.RPC.Addr, "")
ctx := cli.NewContext(cli.NewApp(), set, nil)
set.String(options.RPCEndpointFlag, "http://"+e.RPC.Addresses()[0], "")
ctx := cli.NewContext(app.New(), set, nil)
gctx, _ := options.GetTimeoutContext(ctx)
_, ec := options.GetRPCClient(gctx, ctx)
require.Nil(t, ec)

View file

@ -0,0 +1,28 @@
package options
import "go.uber.org/zap/zapcore"
// FilteringCore is custom implementation of zapcore.Core that allows to filter
// log entries using custom filtering function.
type FilteringCore struct {
zapcore.Core
filter FilterFunc
}
// FilterFunc is the filter function that is called to check whether the given
// entry together with the associated fields is to be written to a core or not.
type FilterFunc func(zapcore.Entry) bool
// NewFilteringCore returns a core middleware that uses the given filter function
// to decide whether to log this message or not.
func NewFilteringCore(next zapcore.Core, filter FilterFunc) zapcore.Core {
return &FilteringCore{next, filter}
}
// Check implements zapcore.Core interface and performs log entries filtering.
func (c *FilteringCore) Check(e zapcore.Entry, ce *zapcore.CheckedEntry) *zapcore.CheckedEntry {
if c.filter(e) {
return c.Core.Check(e, ce)
}
return ce
}

View file

@ -6,26 +6,61 @@ package options
import (
"context"
"errors"
"fmt"
"net/url"
"os"
"runtime"
"strconv"
"strings"
"time"
"github.com/nspcc-dev/neo-go/cli/flags"
"github.com/nspcc-dev/neo-go/cli/input"
"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/transaction"
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
"github.com/nspcc-dev/neo-go/pkg/io"
"github.com/nspcc-dev/neo-go/pkg/rpcclient"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/actor"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker"
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/wallet"
"github.com/urfave/cli"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"golang.org/x/term"
"gopkg.in/yaml.v3"
)
// DefaultTimeout is the default timeout used for RPC requests.
const DefaultTimeout = 10 * time.Second
const (
// DefaultTimeout is the default timeout used for RPC requests.
DefaultTimeout = 10 * time.Second
// DefaultAwaitableTimeout is the default timeout used for RPC requests that
// require transaction awaiting. It is set to the approximate time of three
// Neo N3 mainnet blocks accepting.
DefaultAwaitableTimeout = 3 * 15 * time.Second
)
// RPCEndpointFlag is a long flag name for an RPC endpoint. It can be used to
// check for flag presence in the context.
const RPCEndpointFlag = "rpc-endpoint"
// Wallet is a set of flags used for wallet operations.
var Wallet = []cli.Flag{cli.StringFlag{
Name: "wallet, w",
Usage: "wallet to use to get the key for transaction signing; conflicts with --wallet-config flag",
}, cli.StringFlag{
Name: "wallet-config",
Usage: "path to wallet config to use to get the key for transaction signing; conflicts with --wallet flag"},
}
// Network is a set of flags for choosing the network to operate on
// (privnet/mainnet/testnet).
var Network = []cli.Flag{
cli.BoolFlag{Name: "privnet, p", Usage: "use private network configuration"},
cli.BoolFlag{Name: "mainnet, m", Usage: "use mainnet network configuration"},
cli.BoolFlag{Name: "testnet, t", Usage: "use testnet network configuration"},
cli.BoolFlag{Name: "privnet, p", Usage: "use private network configuration (if --config-file option is not specified)"},
cli.BoolFlag{Name: "mainnet, m", Usage: "use mainnet network configuration (if --config-file option is not specified)"},
cli.BoolFlag{Name: "testnet, t", Usage: "use testnet network configuration (if --config-file option is not specified)"},
cli.BoolFlag{Name: "unittest", Hidden: true},
}
@ -42,7 +77,42 @@ var RPC = []cli.Flag{
},
}
// Historic is a flag for commands that can perform historic invocations.
var Historic = cli.StringFlag{
Name: "historic",
Usage: "Use historic state (height, block hash or state root hash)",
}
// Config is a flag for commands that use node configuration.
var Config = cli.StringFlag{
Name: "config-path",
Usage: "path to directory with per-network configuration files (may be overridden by --config-file option for the configuration file)",
}
// ConfigFile is a flag for commands that use node configuration and provide
// path to the specific config file instead of config path.
var ConfigFile = cli.StringFlag{
Name: "config-file",
Usage: "path to the node configuration file (overrides --config-path option)",
}
// RelativePath is a flag for commands that use node configuration and provide
// a prefix to all relative paths in config files.
var RelativePath = cli.StringFlag{
Name: "relative-path",
Usage: "a prefix to all relative paths in the node configuration file",
}
// Debug is a flag for commands that allow node in debug mode usage.
var Debug = cli.BoolFlag{
Name: "debug, d",
Usage: "enable debug logging (LOTS of output, overrides configuration)",
}
var errNoEndpoint = errors.New("no RPC endpoint specified, use option '--" + RPCEndpointFlag + "' or '-r'")
var errInvalidHistoric = errors.New("invalid 'historic' parameter, neither a block number, nor a block/state hash")
var errNoWallet = errors.New("no wallet parameter found, specify it with the '--wallet' or '-w' flag or specify wallet config file with the '--wallet-config' flag")
var errConflictingWalletFlags = errors.New("--wallet flag conflicts with --wallet-config flag, please, provide one of them to specify wallet location")
// GetNetwork examines Context's flags and returns the appropriate network. It
// defaults to PrivNet if no flags are given.
@ -66,6 +136,9 @@ func GetTimeoutContext(ctx *cli.Context) (context.Context, func()) {
if dur == 0 {
dur = DefaultTimeout
}
if !ctx.IsSet("timeout") && ctx.Bool("await") {
dur = DefaultAwaitableTimeout
}
return context.WithTimeout(context.Background(), dur)
}
@ -85,3 +158,253 @@ func GetRPCClient(gctx context.Context, ctx *cli.Context) (*rpcclient.Client, cl
}
return c, nil
}
// GetInvoker returns an invoker using the given RPC client, context and signers.
// It parses "--historic" parameter to adjust it.
func GetInvoker(c *rpcclient.Client, ctx *cli.Context, signers []transaction.Signer) (*invoker.Invoker, cli.ExitCoder) {
historic := ctx.String("historic")
if historic == "" {
return invoker.New(c, signers), nil
}
if index, err := strconv.ParseUint(historic, 10, 32); err == nil {
return invoker.NewHistoricAtHeight(uint32(index), c, signers), nil
}
if u256, err := util.Uint256DecodeStringLE(historic); err == nil {
// Might as well be a block hash, but it makes no practical difference.
return invoker.NewHistoricWithState(u256, c, signers), nil
}
return nil, cli.NewExitError(errInvalidHistoric, 1)
}
// GetRPCWithInvoker combines GetRPCClient with GetInvoker for cases where it's
// appropriate to do so.
func GetRPCWithInvoker(gctx context.Context, ctx *cli.Context, signers []transaction.Signer) (*rpcclient.Client, *invoker.Invoker, cli.ExitCoder) {
c, err := GetRPCClient(gctx, ctx)
if err != nil {
return nil, nil, err
}
inv, err := GetInvoker(c, ctx, signers)
if err != nil {
c.Close()
return nil, nil, err
}
return c, inv, err
}
// GetConfigFromContext looks at the path and the mode flags in the given config and
// returns an appropriate config.
func GetConfigFromContext(ctx *cli.Context) (config.Config, error) {
var (
configFile = ctx.String("config-file")
relativePath = ctx.String("relative-path")
)
if len(configFile) != 0 {
return config.LoadFile(configFile, relativePath)
}
var configPath = "./config"
if argCp := ctx.String("config-path"); argCp != "" {
configPath = argCp
}
return config.Load(configPath, GetNetwork(ctx), relativePath)
}
var (
// _winfileSinkRegistered denotes whether zap has registered
// user-supplied factory for all sinks with `winfile`-prefixed scheme.
_winfileSinkRegistered bool
_winfileSinkCloser func() error
)
// HandleLoggingParams reads logging parameters.
// If a user selected debug level -- function enables it.
// If logPath is configured -- function creates a dir and a file for logging.
// If logPath is configured on Windows -- function returns closer to be
// able to close sink for the opened log output file.
// If the program is run in TTY then logger adds timestamp to its entries.
func HandleLoggingParams(debug bool, cfg config.ApplicationConfiguration) (*zap.Logger, *zap.AtomicLevel, func() error, error) {
var (
level = zapcore.InfoLevel
err error
)
if len(cfg.LogLevel) > 0 {
level, err = zapcore.ParseLevel(cfg.LogLevel)
if err != nil {
return nil, nil, nil, fmt.Errorf("log setting: %w", err)
}
}
if debug {
level = zapcore.DebugLevel
}
cc := zap.NewProductionConfig()
cc.DisableCaller = true
cc.DisableStacktrace = true
cc.EncoderConfig.EncodeDuration = zapcore.StringDurationEncoder
cc.EncoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder
if term.IsTerminal(int(os.Stdout.Fd())) {
cc.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
} else {
cc.EncoderConfig.EncodeTime = func(t time.Time, encoder zapcore.PrimitiveArrayEncoder) {}
}
cc.Encoding = "console"
cc.Level = zap.NewAtomicLevelAt(level)
cc.Sampling = nil
if logPath := cfg.LogPath; logPath != "" {
if err := io.MakeDirForFile(logPath, "logger"); err != nil {
return nil, nil, nil, err
}
if runtime.GOOS == "windows" {
if !_winfileSinkRegistered {
// See https://github.com/uber-go/zap/issues/621.
err := zap.RegisterSink("winfile", func(u *url.URL) (zap.Sink, error) {
if u.User != nil {
return nil, fmt.Errorf("user and password not allowed with file URLs: got %v", u)
}
if u.Fragment != "" {
return nil, fmt.Errorf("fragments not allowed with file URLs: got %v", u)
}
if u.RawQuery != "" {
return nil, fmt.Errorf("query parameters not allowed with file URLs: got %v", u)
}
// Error messages are better if we check hostname and port separately.
if u.Port() != "" {
return nil, fmt.Errorf("ports not allowed with file URLs: got %v", u)
}
if hn := u.Hostname(); hn != "" && hn != "localhost" {
return nil, fmt.Errorf("file URLs must leave host empty or use localhost: got %v", u)
}
switch u.Path {
case "stdout":
return os.Stdout, nil
case "stderr":
return os.Stderr, nil
}
f, err := os.OpenFile(u.Path[1:], // Remove leading slash left after url.Parse.
os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644)
_winfileSinkCloser = func() error {
_winfileSinkCloser = nil
return f.Close()
}
return f, err
})
if err != nil {
return nil, nil, nil, fmt.Errorf("failed to register windows-specific sinc: %w", err)
}
_winfileSinkRegistered = true
}
logPath = "winfile:///" + logPath
}
cc.OutputPaths = []string{logPath}
}
log, err := cc.Build()
return log, &cc.Level, _winfileSinkCloser, err
}
// GetRPCWithActor returns an RPC client instance and Actor instance for the given context.
func GetRPCWithActor(gctx context.Context, ctx *cli.Context, signers []actor.SignerAccount) (*rpcclient.Client, *actor.Actor, cli.ExitCoder) {
c, err := GetRPCClient(gctx, ctx)
if err != nil {
return nil, nil, err
}
a, actorErr := actor.New(c, signers)
if actorErr != nil {
c.Close()
return nil, nil, cli.NewExitError(fmt.Errorf("failed to create Actor: %w", actorErr), 1)
}
return c, a, nil
}
// GetAccFromContext returns account and wallet from context. If address is not set, default address is used.
func GetAccFromContext(ctx *cli.Context) (*wallet.Account, *wallet.Wallet, error) {
var addr util.Uint160
wPath := ctx.String("wallet")
walletConfigPath := ctx.String("wallet-config")
if len(wPath) != 0 && len(walletConfigPath) != 0 {
return nil, nil, errConflictingWalletFlags
}
if len(wPath) == 0 && len(walletConfigPath) == 0 {
return nil, nil, errNoWallet
}
var pass *string
if len(walletConfigPath) != 0 {
cfg, err := ReadWalletConfig(walletConfigPath)
if err != nil {
return nil, nil, err
}
wPath = cfg.Path
pass = &cfg.Password
}
wall, err := wallet.NewWalletFromFile(wPath)
if err != nil {
return nil, nil, err
}
addrFlag := ctx.Generic("address").(*flags.Address)
if addrFlag.IsSet {
addr = addrFlag.Uint160()
} else {
addr = wall.GetChangeAddress()
if addr.Equals(util.Uint160{}) {
return nil, wall, errors.New("can't get default address")
}
}
acc, err := GetUnlockedAccount(wall, addr, pass)
return acc, wall, err
}
// GetUnlockedAccount returns account from wallet, address and uses pass to unlock specified account if given.
// If the password is not given, then it is requested from user.
func GetUnlockedAccount(wall *wallet.Wallet, addr util.Uint160, pass *string) (*wallet.Account, error) {
acc := wall.GetAccount(addr)
if acc == nil {
return nil, fmt.Errorf("wallet contains no account for '%s'", address.Uint160ToString(addr))
}
if acc.CanSign() || acc.EncryptedWIF == "" {
return acc, nil
}
if pass == nil {
rawPass, err := input.ReadPassword(
fmt.Sprintf("Enter account %s password > ", address.Uint160ToString(addr)))
if err != nil {
return nil, fmt.Errorf("Error reading password: %w", err)
}
trimmed := strings.TrimRight(string(rawPass), "\n")
pass = &trimmed
}
err := acc.Decrypt(*pass, wall.Scrypt)
if err != nil {
return nil, err
}
return acc, nil
}
// ReadWalletConfig reads wallet config from the given path.
func ReadWalletConfig(configPath string) (*config.Wallet, error) {
file, err := os.Open(configPath)
if err != nil {
return nil, err
}
defer file.Close()
configData, err := os.ReadFile(configPath)
if err != nil {
return nil, fmt.Errorf("unable to read wallet config: %w", err)
}
cfg := &config.Wallet{}
err = yaml.Unmarshal(configData, &cfg)
if err != nil {
return nil, fmt.Errorf("failed to unmarshal wallet config YAML: %w", err)
}
return cfg, nil
}

View file

@ -7,7 +7,6 @@ import (
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/context"
"github.com/nspcc-dev/neo-go/pkg/wallet"
)
@ -16,16 +15,10 @@ import (
// as an input to `multisig sign`. If a wallet.Account is given and can sign,
// it's signed as well using it.
func InitAndSave(net netmode.Magic, tx *transaction.Transaction, acc *wallet.Account, filename string) error {
scCtx := context.NewParameterContext("Neo.Network.P2P.Payloads.Transaction", net, tx)
scCtx := context.NewParameterContext(context.TransactionType, net, tx)
if acc != nil && acc.CanSign() {
priv := acc.PrivateKey()
pub := priv.PublicKey()
sign := priv.SignHashable(uint32(net), tx)
h, err := address.StringToUint160(acc.Address)
if err != nil {
return fmt.Errorf("invalid address: %s", acc.Address)
}
if err := scCtx.AddSignature(h, acc.Contract, pub, sign); err != nil {
sign := acc.SignHashable(net, tx)
if err := scCtx.AddSignature(acc.ScriptHash(), acc.Contract, acc.PublicKey(), sign); err != nil {
return fmt.Errorf("can't add signature: %w", err)
}
}

View file

@ -3,7 +3,6 @@ package query
import (
"bytes"
"encoding/base64"
"encoding/hex"
"fmt"
"sort"
"strconv"
@ -111,7 +110,10 @@ func queryTx(ctx *cli.Context) error {
}
}
DumpApplicationLog(ctx, res, &txOut.Transaction, &txOut.TransactionMetadata, ctx.Bool("verbose"))
err = DumpApplicationLog(ctx, res, &txOut.Transaction, &txOut.TransactionMetadata, ctx.Bool("verbose"))
if err != nil {
return cli.NewExitError(err, 1)
}
return nil
}
@ -120,47 +122,49 @@ func DumpApplicationLog(
res *result.ApplicationLog,
tx *transaction.Transaction,
txMeta *result.TransactionMetadata,
verbose bool) {
buf := bytes.NewBuffer(nil)
verbose bool) error {
var buf []byte
// Ignore the errors below because `Write` to buffer doesn't return error.
tw := tabwriter.NewWriter(buf, 0, 4, 4, '\t', 0)
_, _ = tw.Write([]byte("Hash:\t" + tx.Hash().StringLE() + "\n"))
_, _ = tw.Write([]byte(fmt.Sprintf("OnChain:\t%t\n", res != nil)))
buf = fmt.Appendf(buf, "Hash:\t%s\n", tx.Hash().StringLE())
buf = fmt.Appendf(buf, "OnChain:\t%t\n", res != nil)
if res == nil {
_, _ = tw.Write([]byte("ValidUntil:\t" + strconv.FormatUint(uint64(tx.ValidUntilBlock), 10) + "\n"))
buf = fmt.Appendf(buf, "ValidUntil:\t%s\n", strconv.FormatUint(uint64(tx.ValidUntilBlock), 10))
} else {
if txMeta != nil {
_, _ = tw.Write([]byte("BlockHash:\t" + txMeta.Blockhash.StringLE() + "\n"))
buf = fmt.Appendf(buf, "BlockHash:\t%s\n", txMeta.Blockhash.StringLE())
}
if len(res.Executions) != 1 {
_, _ = tw.Write([]byte("Success:\tunknown (no execution data)\n"))
buf = fmt.Appendf(buf, "Success:\tunknown (no execution data)\n")
} else {
_, _ = tw.Write([]byte(fmt.Sprintf("Success:\t%t\n", res.Executions[0].VMState == vmstate.Halt)))
buf = fmt.Appendf(buf, "Success:\t%t\n", res.Executions[0].VMState == vmstate.Halt)
}
}
if verbose {
for _, sig := range tx.Signers {
_, _ = tw.Write([]byte(fmt.Sprintf("Signer:\t%s (%s)",
address.Uint160ToString(sig.Account),
sig.Scopes) + "\n"))
buf = fmt.Appendf(buf, "Signer:\t%s (%s)\n", address.Uint160ToString(sig.Account), sig.Scopes)
}
_, _ = tw.Write([]byte("SystemFee:\t" + fixedn.Fixed8(tx.SystemFee).String() + " GAS\n"))
_, _ = tw.Write([]byte("NetworkFee:\t" + fixedn.Fixed8(tx.NetworkFee).String() + " GAS\n"))
_, _ = tw.Write([]byte("Script:\t" + base64.StdEncoding.EncodeToString(tx.Script) + "\n"))
buf = fmt.Appendf(buf, "SystemFee:\t%s GAS\n", fixedn.Fixed8(tx.SystemFee).String())
buf = fmt.Appendf(buf, "NetworkFee:\t%s GAS\n", fixedn.Fixed8(tx.NetworkFee).String())
buf = fmt.Appendf(buf, "Script:\t%s\n", base64.StdEncoding.EncodeToString(tx.Script))
v := vm.New()
v.Load(tx.Script)
v.PrintOps(tw)
opts := bytes.NewBuffer(nil)
v.PrintOps(opts)
buf = append(buf, opts.Bytes()...)
if res != nil {
for _, e := range res.Executions {
if e.VMState != vmstate.Halt {
_, _ = tw.Write([]byte("Exception:\t" + e.FaultException + "\n"))
buf = fmt.Appendf(buf, "Exception:\t%s\n", e.FaultException)
}
}
}
}
_ = tw.Flush()
fmt.Fprint(ctx.App.Writer, buf.String())
tw := tabwriter.NewWriter(ctx.App.Writer, 0, 4, 4, '\t', 0)
_, err := tw.Write(buf)
if err != nil {
return err
}
return tw.Flush()
}
func queryCandidates(ctx *cli.Context) error {
@ -196,15 +200,17 @@ func queryCandidates(ctx *cli.Context) error {
}
return vals[i].PublicKey.Cmp(&vals[j].PublicKey) == -1
})
buf := bytes.NewBuffer(nil)
tw := tabwriter.NewWriter(buf, 0, 2, 2, ' ', 0)
_, _ = tw.Write([]byte("Key\tVotes\tCommittee\tConsensus\n"))
var res []byte
res = fmt.Appendf(res, "Key\tVotes\tCommittee\tConsensus\n")
for _, val := range vals {
_, _ = tw.Write([]byte(fmt.Sprintf("%s\t%d\t%t\t%t\n", hex.EncodeToString(val.PublicKey.Bytes()), val.Votes, comm.Contains(&val.PublicKey), val.Active)))
res = fmt.Appendf(res, "%s\t%d\t%t\t%t\n", val.PublicKey.StringCompressed(), val.Votes, comm.Contains(&val.PublicKey), val.Active)
}
_ = tw.Flush()
fmt.Fprint(ctx.App.Writer, buf.String())
return nil
tw := tabwriter.NewWriter(ctx.App.Writer, 0, 2, 2, ' ', 0)
_, err = tw.Write(res)
if err != nil {
return err
}
return tw.Flush()
}
func queryCommittee(ctx *cli.Context) error {
@ -228,7 +234,7 @@ func queryCommittee(ctx *cli.Context) error {
}
for _, k := range comm {
fmt.Fprintln(ctx.App.Writer, hex.EncodeToString(k.Bytes()))
fmt.Fprintln(ctx.App.Writer, k.StringCompressed())
}
return nil
}
@ -299,7 +305,7 @@ func queryVoter(ctx *cli.Context) error {
}
voted := "null"
if st.VoteTo != nil {
voted = fmt.Sprintf("%s (%s)", hex.EncodeToString(st.VoteTo.Bytes()), address.Uint160ToString(st.VoteTo.GetScriptHash()))
voted = fmt.Sprintf("%s (%s)", st.VoteTo.StringCompressed(), address.Uint160ToString(st.VoteTo.GetScriptHash()))
}
fmt.Fprintf(ctx.App.Writer, "\tVoted: %s\n", voted)
fmt.Fprintf(ctx.App.Writer, "\tAmount : %s\n", fixedn.ToString(&st.Balance, int(dec)))

View file

@ -1,4 +1,4 @@
package main
package query_test
import (
"encoding/base64"
@ -10,6 +10,7 @@ import (
"time"
"github.com/nspcc-dev/neo-go/internal/random"
"github.com/nspcc-dev/neo-go/internal/testcli"
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
"github.com/nspcc-dev/neo-go/pkg/encoding/fixedn"
@ -22,78 +23,76 @@ import (
)
func TestQueryTx(t *testing.T) {
e := newExecutorSuspended(t)
e := testcli.NewExecutorSuspended(t)
w, err := wallet.NewWalletFromFile("testdata/testwallet.json")
w, err := wallet.NewWalletFromFile("../testdata/testwallet.json")
require.NoError(t, err)
transferArgs := []string{
"neo-go", "wallet", "nep17", "transfer",
"--rpc-endpoint", "http://" + e.RPC.Addr,
"--wallet", validatorWallet,
"--rpc-endpoint", "http://" + e.RPC.Addresses()[0],
"--wallet", testcli.ValidatorWallet,
"--to", w.Accounts[0].Address,
"--token", "NEO",
"--from", validatorAddr,
"--from", testcli.ValidatorAddr,
"--force",
}
e.In.WriteString("one\r")
e.Run(t, append(transferArgs, "--amount", "1")...)
line := e.getNextLine(t)
line := e.GetNextLine(t)
txHash, err := util.Uint256DecodeStringLE(line)
require.NoError(t, err)
tx, ok := e.Chain.GetMemPool().TryGetValue(txHash)
require.True(t, ok)
args := []string{"neo-go", "query", "tx", "--rpc-endpoint", "http://" + e.RPC.Addr}
args := []string{"neo-go", "query", "tx", "--rpc-endpoint", "http://" + e.RPC.Addresses()[0]}
e.Run(t, append(args, txHash.StringLE())...)
e.checkNextLine(t, `Hash:\s+`+txHash.StringLE())
e.checkNextLine(t, `OnChain:\s+false`)
e.checkNextLine(t, `ValidUntil:\s+`+strconv.FormatUint(uint64(tx.ValidUntilBlock), 10))
e.checkEOF(t)
e.CheckNextLine(t, `Hash:\s+`+txHash.StringLE())
e.CheckNextLine(t, `OnChain:\s+false`)
e.CheckNextLine(t, `ValidUntil:\s+`+strconv.FormatUint(uint64(tx.ValidUntilBlock), 10))
e.CheckEOF(t)
height := e.Chain.BlockHeight()
go e.Chain.Run()
require.Eventually(t, func() bool { return e.Chain.BlockHeight() > height }, time.Second*2, time.Millisecond*50)
require.Eventually(t, func() bool { _, aerErr := e.Chain.GetAppExecResults(txHash, trigger.Application); return aerErr == nil }, time.Second*2, time.Millisecond*50)
e.Run(t, append(args, txHash.StringLE())...)
e.checkNextLine(t, `Hash:\s+`+txHash.StringLE())
e.checkNextLine(t, `OnChain:\s+true`)
e.CheckNextLine(t, `Hash:\s+`+txHash.StringLE())
e.CheckNextLine(t, `OnChain:\s+true`)
_, height, err = e.Chain.GetTransaction(txHash)
_, height, err := e.Chain.GetTransaction(txHash)
require.NoError(t, err)
e.checkNextLine(t, `BlockHash:\s+`+e.Chain.GetHeaderHash(int(height)).StringLE())
e.checkNextLine(t, `Success:\s+true`)
e.checkEOF(t)
e.CheckNextLine(t, `BlockHash:\s+`+e.Chain.GetHeaderHash(height).StringLE())
e.CheckNextLine(t, `Success:\s+true`)
e.CheckEOF(t)
t.Run("verbose", func(t *testing.T) {
e.Run(t, append(args, "--verbose", txHash.StringLE())...)
e.compareQueryTxVerbose(t, tx)
compareQueryTxVerbose(t, e, tx)
t.Run("FAULT", func(t *testing.T) {
e.In.WriteString("one\r")
e.Run(t, "neo-go", "contract", "invokefunction",
"--rpc-endpoint", "http://"+e.RPC.Addr,
"--wallet", validatorWallet,
"--address", validatorAddr,
"--rpc-endpoint", "http://"+e.RPC.Addresses()[0],
"--wallet", testcli.ValidatorWallet,
"--address", testcli.ValidatorAddr,
"--force",
random.Uint160().StringLE(),
"randomMethod")
e.checkNextLine(t, `Warning:`)
e.checkNextLine(t, "Sending transaction")
line := strings.TrimPrefix(e.getNextLine(t), "Sent invocation transaction ")
e.CheckNextLine(t, `Warning:`)
e.CheckNextLine(t, "Sending transaction")
line := strings.TrimPrefix(e.GetNextLine(t), "Sent invocation transaction ")
txHash, err := util.Uint256DecodeStringLE(line)
require.NoError(t, err)
height := e.Chain.BlockHeight()
require.Eventually(t, func() bool { return e.Chain.BlockHeight() > height }, time.Second*2, time.Millisecond*50)
require.Eventually(t, func() bool { _, aerErr := e.Chain.GetAppExecResults(txHash, trigger.Application); return aerErr == nil }, time.Second*2, time.Millisecond*50)
tx, _, err := e.Chain.GetTransaction(txHash)
require.NoError(t, err)
e.Run(t, append(args, "--verbose", txHash.StringLE())...)
e.compareQueryTxVerbose(t, tx)
compareQueryTxVerbose(t, e, tx)
})
})
@ -113,43 +112,43 @@ func TestQueryTx(t *testing.T) {
})
}
func (e *executor) compareQueryTxVerbose(t *testing.T, tx *transaction.Transaction) {
e.checkNextLine(t, `Hash:\s+`+tx.Hash().StringLE())
e.checkNextLine(t, `OnChain:\s+true`)
func compareQueryTxVerbose(t *testing.T, e *testcli.Executor, tx *transaction.Transaction) {
e.CheckNextLine(t, `Hash:\s+`+tx.Hash().StringLE())
e.CheckNextLine(t, `OnChain:\s+true`)
_, height, err := e.Chain.GetTransaction(tx.Hash())
require.NoError(t, err)
e.checkNextLine(t, `BlockHash:\s+`+e.Chain.GetHeaderHash(int(height)).StringLE())
e.CheckNextLine(t, `BlockHash:\s+`+e.Chain.GetHeaderHash(height).StringLE())
res, _ := e.Chain.GetAppExecResults(tx.Hash(), trigger.Application)
e.checkNextLine(t, fmt.Sprintf(`Success:\s+%t`, res[0].Execution.VMState == vmstate.Halt))
e.CheckNextLine(t, fmt.Sprintf(`Success:\s+%t`, res[0].Execution.VMState == vmstate.Halt))
for _, s := range tx.Signers {
e.checkNextLine(t, fmt.Sprintf(`Signer:\s+%s\s*\(%s\)`, address.Uint160ToString(s.Account), s.Scopes.String()))
e.CheckNextLine(t, fmt.Sprintf(`Signer:\s+%s\s*\(%s\)`, address.Uint160ToString(s.Account), s.Scopes.String()))
}
e.checkNextLine(t, `SystemFee:\s+`+fixedn.Fixed8(tx.SystemFee).String()+" GAS$")
e.checkNextLine(t, `NetworkFee:\s+`+fixedn.Fixed8(tx.NetworkFee).String()+" GAS$")
e.checkNextLine(t, `Script:\s+`+regexp.QuoteMeta(base64.StdEncoding.EncodeToString(tx.Script)))
e.CheckNextLine(t, `SystemFee:\s+`+fixedn.Fixed8(tx.SystemFee).String()+" GAS$")
e.CheckNextLine(t, `NetworkFee:\s+`+fixedn.Fixed8(tx.NetworkFee).String()+" GAS$")
e.CheckNextLine(t, `Script:\s+`+regexp.QuoteMeta(base64.StdEncoding.EncodeToString(tx.Script)))
c := vm.NewContext(tx.Script)
n := 0
for ; c.NextIP() < c.LenInstr(); _, _, err = c.Next() {
require.NoError(t, err)
n++
}
e.checkScriptDump(t, n)
e.CheckScriptDump(t, n)
if res[0].Execution.VMState != vmstate.Halt {
e.checkNextLine(t, `Exception:\s+`+regexp.QuoteMeta(res[0].Execution.FaultException))
e.CheckNextLine(t, `Exception:\s+`+regexp.QuoteMeta(res[0].Execution.FaultException))
}
e.checkEOF(t)
e.CheckEOF(t)
}
func TestQueryHeight(t *testing.T) {
e := newExecutor(t, true)
e := testcli.NewExecutor(t, true)
args := []string{"neo-go", "query", "height", "--rpc-endpoint", "http://" + e.RPC.Addr}
args := []string{"neo-go", "query", "height", "--rpc-endpoint", "http://" + e.RPC.Addresses()[0]}
e.Run(t, args...)
e.checkNextLine(t, `^Latest block: [0-9]+$`)
e.checkNextLine(t, `^Validated state: [0-9]+$`)
e.checkEOF(t)
e.CheckNextLine(t, `^Latest block: [0-9]+$`)
e.CheckNextLine(t, `^Validated state: [0-9]+$`)
e.CheckEOF(t)
t.Run("excessive arguments", func(t *testing.T) {
e.RunWithError(t, append(args, "something")...)
})

View file

@ -1,4 +1,4 @@
package main
package server_test
import (
"os"
@ -6,19 +6,24 @@ import (
"strconv"
"testing"
"github.com/nspcc-dev/neo-go/internal/testcli"
"github.com/nspcc-dev/neo-go/pkg/config"
"github.com/nspcc-dev/neo-go/pkg/core/storage/dbconfig"
"github.com/stretchr/testify/require"
"gopkg.in/yaml.v3"
)
// generated via `go run ./scripts/gendump/main.go --out ./cli/server/testdata/chain50x2.acc --blocks 50 --txs 2`.
const inDump = "./testdata/chain50x2.acc"
func TestDBRestoreDump(t *testing.T) {
tmpDir := t.TempDir()
loadConfig := func(t *testing.T) config.Config {
chainPath := filepath.Join(tmpDir, "neogotestchain")
cfg, err := config.LoadFile(filepath.Join("..", "config", "protocol.unit_testnet.yml"))
cfg, err := config.LoadFile(filepath.Join("..", "..", "config", "protocol.unit_testnet.yml"))
require.NoError(t, err, "could not load config")
cfg.ApplicationConfiguration.DBConfiguration.Type = "leveldb"
cfg.ApplicationConfiguration.DBConfiguration.Type = dbconfig.LevelDB
cfg.ApplicationConfiguration.DBConfiguration.LevelDBOptions.DataDirectoryPath = chainPath
return cfg
}
@ -30,9 +35,7 @@ func TestDBRestoreDump(t *testing.T) {
cfgPath := filepath.Join(tmpDir, "protocol.unit_testnet.yml")
require.NoError(t, os.WriteFile(cfgPath, out, os.ModePerm))
// generated via `go run ./scripts/gendump/main.go --out ./cli/testdata/chain50x2.acc --blocks 50 --txs 2`
const inDump = "./testdata/chain50x2.acc"
e := newExecutor(t, false)
e := testcli.NewExecutor(t, false)
stateDump := filepath.Join(tmpDir, "neogo.teststate")
baseArgs := []string{"neo-go", "db", "restore", "--unittest",
@ -109,3 +112,47 @@ func TestDBRestoreDump(t *testing.T) {
require.NoError(t, err)
require.Equal(t, d1, d2, "dumps differ")
}
func TestDBDumpRestoreIncremental(t *testing.T) {
tmpDir := t.TempDir()
chainPath := filepath.Join(tmpDir, "neogotestchain")
nonincDump := filepath.Join(tmpDir, "nonincDump.acc")
incDump := filepath.Join(tmpDir, "incDump.acc")
cfg, err := config.LoadFile(filepath.Join("..", "..", "config", "protocol.unit_testnet.yml"))
require.NoError(t, err, "could not load config")
cfg.ApplicationConfiguration.DBConfiguration.Type = dbconfig.LevelDB
cfg.ApplicationConfiguration.DBConfiguration.LevelDBOptions.DataDirectoryPath = chainPath
out, err := yaml.Marshal(cfg)
require.NoError(t, err)
cfgPath := filepath.Join(tmpDir, "protocol.unit_testnet.yml")
require.NoError(t, os.WriteFile(cfgPath, out, os.ModePerm))
e := testcli.NewExecutor(t, false)
// Create DB from dump.
e.Run(t, "neo-go", "db", "restore", "--unittest", "--config-path", tmpDir, "--in", inDump)
// Create two dumps: non-incremental and incremental.
dumpBaseArgs := []string{"neo-go", "db", "dump", "--unittest",
"--config-path", tmpDir}
// Dump first 15 blocks to a non-incremental dump.
e.Run(t, append(dumpBaseArgs, "--out", nonincDump, "--count", "15")...)
// Dump second 15 blocks to an incremental dump.
e.Run(t, append(dumpBaseArgs, "--out", incDump, "--start", "15", "--count", "15")...)
// Clean the DB.
require.NoError(t, os.RemoveAll(chainPath))
// Restore chain from two dumps.
restoreBaseArgs := []string{"neo-go", "db", "restore", "--unittest", "--config-path", tmpDir}
// Restore first 15 blocks from non-incremental dump.
e.Run(t, append(restoreBaseArgs, "--in", nonincDump)...)
// Restore second 15 blocks from incremental dump.
e.Run(t, append(restoreBaseArgs, "--in", incDump, "-n", "--count", "15")...)
}

View file

@ -1,6 +1,7 @@
package main
package server_test
import (
"errors"
"io"
"os"
"path/filepath"
@ -10,20 +11,22 @@ import (
"time"
"github.com/nspcc-dev/neo-go/cli/server"
"github.com/nspcc-dev/neo-go/internal/testcli"
"github.com/nspcc-dev/neo-go/pkg/config"
"github.com/nspcc-dev/neo-go/pkg/core/storage/dbconfig"
"github.com/stretchr/testify/require"
"gopkg.in/yaml.v3"
)
func TestServerStart(t *testing.T) {
tmpDir := t.TempDir()
goodCfg, err := config.LoadFile(filepath.Join("..", "config", "protocol.unit_testnet.yml"))
goodCfg, err := config.LoadFile(filepath.Join("..", "..", "config", "protocol.unit_testnet.yml"))
require.NoError(t, err, "could not load config")
ptr := &goodCfg
saveCfg := func(t *testing.T, f func(cfg *config.Config)) string {
cfg := *ptr
chainPath := filepath.Join(t.TempDir(), "neogotestchain")
cfg.ApplicationConfiguration.DBConfiguration.Type = "leveldb"
cfg.ApplicationConfiguration.DBConfiguration.Type = dbconfig.LevelDB
cfg.ApplicationConfiguration.DBConfiguration.LevelDBOptions.DataDirectoryPath = chainPath
f(&cfg)
out, err := yaml.Marshal(cfg)
@ -38,7 +41,7 @@ func TestServerStart(t *testing.T) {
}
baseCmd := []string{"neo-go", "node", "--unittest", "--config-path", tmpDir}
e := newExecutor(t, false)
e := testcli.NewExecutor(t, false)
t.Run("invalid config path", func(t *testing.T) {
e.RunWithError(t, baseCmd...)
@ -74,7 +77,8 @@ func TestServerStart(t *testing.T) {
})
t.Run("invalid consensus config", func(t *testing.T) {
saveCfg(t, func(cfg *config.Config) {
cfg.ApplicationConfiguration.UnlockWallet.Path = "bad_consensus_wallet.json"
cfg.ApplicationConfiguration.Consensus.Enabled = true
cfg.ApplicationConfiguration.Consensus.UnlockWallet.Path = "bad_consensus_wallet.json"
})
e.RunWithError(t, baseCmd...)
})
@ -110,7 +114,7 @@ func TestServerStart(t *testing.T) {
var line string
require.Eventually(t, func() bool {
line, err = e.Out.ReadString('\n')
if err != nil && err != io.EOF {
if err != nil && !errors.Is(err, io.EOF) {
t.Fatalf("unexpected error while reading CLI output: %s", err)
}
return err == nil
@ -119,11 +123,11 @@ func TestServerStart(t *testing.T) {
for _, expected := range lines {
// It should be regexp, so escape all backslashes.
expected = strings.ReplaceAll(expected, `\`, `\\`)
e.checkLine(t, line, expected)
line = e.getNextLine(t)
e.CheckLine(t, line, expected)
line = e.GetNextLine(t)
}
e.checkNextLine(t, "")
e.checkEOF(t)
e.CheckNextLine(t, "")
e.CheckEOF(t)
})
}
}

View file

@ -4,10 +4,8 @@ import (
"context"
"errors"
"fmt"
"net/url"
"os"
"os/signal"
"runtime"
"syscall"
"time"
@ -34,22 +32,13 @@ import (
"go.uber.org/zap/zapcore"
)
var (
// _winfileSinkRegistered denotes whether zap has registered
// user-supplied factory for all sinks with `winfile`-prefixed scheme.
_winfileSinkRegistered bool
_winfileSinkCloser func() error
)
// NewCommands returns 'node' command.
func NewCommands() []cli.Command {
var cfgFlags = []cli.Flag{
cli.StringFlag{Name: "config-path", Usage: "path to directory with configuration files"},
}
cfgFlags := []cli.Flag{options.Config, options.ConfigFile, options.RelativePath}
cfgFlags = append(cfgFlags, options.Network...)
var cfgWithCountFlags = make([]cli.Flag, len(cfgFlags))
copy(cfgWithCountFlags, cfgFlags)
cfgFlags = append(cfgFlags, cli.BoolFlag{Name: "debug, d", Usage: "enable debug logging (LOTS of output)"})
cfgFlags = append(cfgFlags, options.Debug)
cfgWithCountFlags = append(cfgWithCountFlags,
cli.UintFlag{
@ -85,11 +74,18 @@ func NewCommands() []cli.Command {
Usage: "use if dump is incremental",
},
)
var cfgHeightFlags = make([]cli.Flag, len(cfgFlags)+1)
copy(cfgHeightFlags, cfgFlags)
cfgHeightFlags[len(cfgHeightFlags)-1] = cli.UintFlag{
Name: "height",
Usage: "Height of the state to reset DB to",
Required: true,
}
return []cli.Command{
{
Name: "node",
Usage: "start a NEO node",
UsageText: "neo-go node [--config-path path] [-d] [-p/-m/-t]",
Usage: "start a NeoGo node",
UsageText: "neo-go node [--config-path path] [-d] [-p/-m/-t] [--config-file file]",
Action: startServer,
Flags: cfgFlags,
},
@ -100,17 +96,24 @@ func NewCommands() []cli.Command {
{
Name: "dump",
Usage: "dump blocks (starting with block #1) to the file",
UsageText: "neo-go db dump -o file [-s start] [-c count] [--config-path path] [-p/-m/-t]",
UsageText: "neo-go db dump -o file [-s start] [-c count] [--config-path path] [-p/-m/-t] [--config-file file]",
Action: dumpDB,
Flags: cfgCountOutFlags,
},
{
Name: "restore",
Usage: "restore blocks from the file",
UsageText: "neo-go db restore -i file [--dump] [-n] [-c count] [--config-path path] [-p/-m/-t]",
UsageText: "neo-go db restore -i file [--dump] [-n] [-c count] [--config-path path] [-p/-m/-t] [--config-file file]",
Action: restoreDB,
Flags: cfgCountInFlags,
},
{
Name: "reset",
Usage: "reset database to the previous state",
UsageText: "neo-go db reset --height height [--config-path path] [-p/-m/-t] [--config-file file]",
Action: resetDB,
Flags: cfgHeightFlags,
},
},
},
}
@ -128,103 +131,23 @@ func newGraceContext() context.Context {
return ctx
}
// getConfigFromContext looks at the path and the mode flags in the given config and
// returns an appropriate config.
func getConfigFromContext(ctx *cli.Context) (config.Config, error) {
configPath := "./config"
if argCp := ctx.String("config-path"); argCp != "" {
configPath = argCp
}
return config.Load(configPath, options.GetNetwork(ctx))
}
// handleLoggingParams reads logging parameters.
// If a user selected debug level -- function enables it.
// If logPath is configured -- function creates a dir and a file for logging.
// If logPath is configured on Windows -- function returns closer to be
// able to close sink for the opened log output file.
func handleLoggingParams(ctx *cli.Context, cfg config.ApplicationConfiguration) (*zap.Logger, func() error, error) {
level := zapcore.InfoLevel
if ctx.Bool("debug") {
level = zapcore.DebugLevel
}
cc := zap.NewProductionConfig()
cc.DisableCaller = true
cc.DisableStacktrace = true
cc.EncoderConfig.EncodeDuration = zapcore.StringDurationEncoder
cc.EncoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder
cc.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
cc.Encoding = "console"
cc.Level = zap.NewAtomicLevelAt(level)
cc.Sampling = nil
if logPath := cfg.LogPath; logPath != "" {
if err := io.MakeDirForFile(logPath, "logger"); err != nil {
return nil, nil, err
}
if runtime.GOOS == "windows" {
if !_winfileSinkRegistered {
// See https://github.com/uber-go/zap/issues/621.
err := zap.RegisterSink("winfile", func(u *url.URL) (zap.Sink, error) {
if u.User != nil {
return nil, fmt.Errorf("user and password not allowed with file URLs: got %v", u)
}
if u.Fragment != "" {
return nil, fmt.Errorf("fragments not allowed with file URLs: got %v", u)
}
if u.RawQuery != "" {
return nil, fmt.Errorf("query parameters not allowed with file URLs: got %v", u)
}
// Error messages are better if we check hostname and port separately.
if u.Port() != "" {
return nil, fmt.Errorf("ports not allowed with file URLs: got %v", u)
}
if hn := u.Hostname(); hn != "" && hn != "localhost" {
return nil, fmt.Errorf("file URLs must leave host empty or use localhost: got %v", u)
}
switch u.Path {
case "stdout":
return os.Stdout, nil
case "stderr":
return os.Stderr, nil
}
f, err := os.OpenFile(u.Path[1:], // Remove leading slash left after url.Parse.
os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644)
_winfileSinkCloser = func() error {
_winfileSinkCloser = nil
return f.Close()
}
return f, err
})
if err != nil {
return nil, nil, fmt.Errorf("failed to register windows-specific sinc: %w", err)
}
_winfileSinkRegistered = true
}
logPath = "winfile:///" + logPath
}
cc.OutputPaths = []string{logPath}
}
log, err := cc.Build()
return log, _winfileSinkCloser, err
}
func initBCWithMetrics(cfg config.Config, log *zap.Logger) (*core.Blockchain, *metrics.Service, *metrics.Service, error) {
chain, err := initBlockChain(cfg, log)
chain, _, err := initBlockChain(cfg, log)
if err != nil {
return nil, nil, nil, cli.NewExitError(err, 1)
}
configureAddresses(&cfg.ApplicationConfiguration)
prometheus := metrics.NewPrometheusService(cfg.ApplicationConfiguration.Prometheus, log)
pprof := metrics.NewPprofService(cfg.ApplicationConfiguration.Pprof, log)
go chain.Run()
go prometheus.Start()
go pprof.Start()
err = prometheus.Start()
if err != nil {
return nil, nil, nil, cli.NewExitError(fmt.Errorf("failed to start Prometheus service: %w", err), 1)
}
err = pprof.Start()
if err != nil {
return nil, nil, nil, cli.NewExitError(fmt.Errorf("failed to start Pprof service: %w", err), 1)
}
return chain, prometheus, pprof, nil
}
@ -233,11 +156,11 @@ func dumpDB(ctx *cli.Context) error {
if err := cmdargs.EnsureNone(ctx); err != nil {
return err
}
cfg, err := getConfigFromContext(ctx)
cfg, err := options.GetConfigFromContext(ctx)
if err != nil {
return cli.NewExitError(err, 1)
}
log, logCloser, err := handleLoggingParams(ctx, cfg.ApplicationConfiguration)
log, _, logCloser, err := options.HandleLoggingParams(ctx.Bool("debug"), cfg.ApplicationConfiguration)
if err != nil {
return cli.NewExitError(err, 1)
}
@ -274,6 +197,9 @@ func dumpDB(ctx *cli.Context) error {
if count == 0 {
count = chainCount - start
}
if start != 0 {
writer.WriteU32LE(start)
}
writer.WriteU32LE(count)
err = chaindump.Dump(chain, writer, start, count)
if err != nil {
@ -286,11 +212,11 @@ func restoreDB(ctx *cli.Context) error {
if err := cmdargs.EnsureNone(ctx); err != nil {
return err
}
cfg, err := getConfigFromContext(ctx)
cfg, err := options.GetConfigFromContext(ctx)
if err != nil {
return err
}
log, logCloser, err := handleLoggingParams(ctx, cfg.ApplicationConfiguration)
log, _, logCloser, err := options.HandleLoggingParams(ctx.Bool("debug"), cfg.ApplicationConfiguration)
if err != nil {
return cli.NewExitError(err, 1)
}
@ -311,7 +237,7 @@ func restoreDB(ctx *cli.Context) error {
dumpDir := ctx.String("dump")
if dumpDir != "" {
cfg.ProtocolConfiguration.SaveStorageBatch = true
cfg.ApplicationConfiguration.SaveStorageBatch = true
}
chain, prometheus, pprof, err := initBCWithMetrics(cfg, log)
@ -399,7 +325,47 @@ func restoreDB(ctx *cli.Context) error {
return nil
}
func mkOracle(config config.OracleConfiguration, magic netmode.Magic, chain *core.Blockchain, serv *network.Server, log *zap.Logger) (*oracle.Oracle, error) {
func resetDB(ctx *cli.Context) error {
if err := cmdargs.EnsureNone(ctx); err != nil {
return err
}
cfg, err := options.GetConfigFromContext(ctx)
if err != nil {
return cli.NewExitError(err, 1)
}
h := uint32(ctx.Uint("height"))
log, _, logCloser, err := options.HandleLoggingParams(ctx.Bool("debug"), cfg.ApplicationConfiguration)
if err != nil {
return cli.NewExitError(err, 1)
}
if logCloser != nil {
defer func() { _ = logCloser() }()
}
chain, store, err := initBlockChain(cfg, log)
if err != nil {
return cli.NewExitError(fmt.Errorf("failed to create Blockchain instance: %w", err), 1)
}
err = chain.Reset(h)
if err != nil {
return cli.NewExitError(fmt.Errorf("failed to reset chain state to height %d: %w", h, err), 1)
}
err = store.Close()
if err != nil {
return cli.NewExitError(fmt.Errorf("failed to close the DB: %w", err), 1)
}
return nil
}
// oracleService is an interface representing Oracle service with network.Service
// capabilities and ability to submit oracle responses.
type oracleService interface {
rpcsrv.OracleHandler
network.Service
}
func mkOracle(config config.OracleConfiguration, magic netmode.Magic, chain *core.Blockchain, serv *network.Server, log *zap.Logger) (oracleService, error) {
if !config.Enabled {
return nil, nil
}
@ -419,17 +385,19 @@ func mkOracle(config config.OracleConfiguration, magic netmode.Magic, chain *cor
return orc, nil
}
func mkConsensus(config config.Wallet, tpb time.Duration, chain *core.Blockchain, serv *network.Server, log *zap.Logger) (consensus.Service, error) {
if len(config.Path) == 0 {
func mkConsensus(config config.Consensus, tpb time.Duration, chain *core.Blockchain, serv *network.Server, log *zap.Logger) (consensus.Service, error) {
if !config.Enabled {
return nil, nil
}
srv, err := consensus.NewService(consensus.Config{
Logger: log,
Broadcast: serv.BroadcastExtensible,
Chain: chain,
ProtocolConfiguration: chain.GetConfig(),
BlockQueue: serv.GetBlockQueue(),
ProtocolConfiguration: chain.GetConfig().ProtocolConfiguration,
RequestTx: serv.RequestTx,
Wallet: &config,
StopTxFlow: serv.StopTxFlow,
Wallet: config.UnlockWallet,
TimePerBlock: tpb,
})
if err != nil {
@ -454,7 +422,7 @@ func mkP2PNotary(config config.P2PNotary, chain *core.Blockchain, serv *network.
}
n, err := notary.NewNotary(cfg, serv.Net, serv.GetNotaryPool(), func(tx *transaction.Transaction) error {
err := serv.RelayTxn(tx)
if err != nil && !errors.Is(err, core.ErrAlreadyExists) {
if err != nil && !errors.Is(err, core.ErrAlreadyExists) && !errors.Is(err, core.ErrAlreadyInPool) {
return fmt.Errorf("can't relay completed notary transaction: hash %s, error: %w", tx.Hash().StringLE(), err)
}
return nil
@ -472,11 +440,12 @@ func startServer(ctx *cli.Context) error {
return err
}
cfg, err := getConfigFromContext(ctx)
cfg, err := options.GetConfigFromContext(ctx)
if err != nil {
return cli.NewExitError(err, 1)
}
log, logCloser, err := handleLoggingParams(ctx, cfg.ApplicationConfiguration)
var logDebug = ctx.Bool("debug")
log, logLevel, logCloser, err := options.HandleLoggingParams(logDebug, cfg.ApplicationConfiguration)
if err != nil {
return cli.NewExitError(err, 1)
}
@ -487,7 +456,10 @@ func startServer(ctx *cli.Context) error {
grace, cancel := context.WithCancel(newGraceContext())
defer cancel()
serverConfig := network.NewServerConfig(cfg)
serverConfig, err := network.NewServerConfig(cfg)
if err != nil {
return cli.NewExitError(err, 1)
}
chain, prometheus, pprof, err := initBCWithMetrics(cfg, log)
if err != nil {
@ -514,7 +486,7 @@ func startServer(ctx *cli.Context) error {
if err != nil {
return cli.NewExitError(err, 1)
}
dbftSrv, err := mkConsensus(cfg.ApplicationConfiguration.UnlockWallet, serverConfig.TimePerBlock, chain, serv, log)
dbftSrv, err := mkConsensus(cfg.ApplicationConfiguration.Consensus, serverConfig.TimePerBlock, chain, serv, log)
if err != nil {
return cli.NewExitError(err, 1)
}
@ -526,9 +498,12 @@ func startServer(ctx *cli.Context) error {
rpcServer := rpcsrv.New(chain, cfg.ApplicationConfiguration.RPC, serv, oracleSrv, log, errChan)
serv.AddService(&rpcServer)
go serv.Start(errChan)
serv.Start()
if !cfg.ApplicationConfiguration.RPC.StartWhenSynchronized {
rpcServer.Start()
// Run RPC server in a separate routine. This is necessary to avoid a potential
// deadlock: Start() can write errors to errChan which is not yet read in the
// current execution context (see for-loop below).
go rpcServer.Start()
}
sigCh := make(chan os.Signal, 1)
@ -548,8 +523,10 @@ Main:
shutdownErr = fmt.Errorf("server error: %w", err)
cancel()
case sig := <-sigCh:
var newLogLevel = zapcore.InvalidLevel
log.Info("signal received", zap.Stringer("name", sig))
cfgnew, err := getConfigFromContext(ctx)
cfgnew, err := options.GetConfigFromContext(ctx)
if err != nil {
log.Warn("can't reread the config file, signal ignored", zap.Error(err))
break // Continue working.
@ -562,22 +539,41 @@ Main:
log.Warn("ApplicationConfiguration changed in incompatible way, signal ignored")
break // Continue working.
}
configureAddresses(&cfgnew.ApplicationConfiguration)
if !logDebug && cfgnew.ApplicationConfiguration.LogLevel != cfg.ApplicationConfiguration.LogLevel {
newLogLevel, err = zapcore.ParseLevel(cfgnew.ApplicationConfiguration.LogLevel)
if err != nil {
log.Warn("wrong LogLevel in ApplicationConfiguration, signal ignored", zap.Error(err))
break // Continue working.
}
}
switch sig {
case sighup:
if newLogLevel != zapcore.InvalidLevel {
logLevel.SetLevel(newLogLevel)
log.Warn("using new logging level", zap.Stringer("level", newLogLevel))
}
serv.DelService(&rpcServer)
rpcServer.Shutdown()
rpcServer = rpcsrv.New(chain, cfgnew.ApplicationConfiguration.RPC, serv, oracleSrv, log, errChan)
serv.AddService(&rpcServer)
if !cfgnew.ApplicationConfiguration.RPC.StartWhenSynchronized || serv.IsInSync() {
rpcServer.Start()
// Here similar to the initial run (see above for-loop), so async.
go rpcServer.Start()
}
pprof.ShutDown()
pprof = metrics.NewPprofService(cfgnew.ApplicationConfiguration.Pprof, log)
go pprof.Start()
err = pprof.Start()
if err != nil {
shutdownErr = fmt.Errorf("failed to start Pprof service: %w", err)
cancel() // Fatal error, like for RPC server.
}
prometheus.ShutDown()
prometheus = metrics.NewPrometheusService(cfgnew.ApplicationConfiguration.Prometheus, log)
go prometheus.Start()
err = prometheus.Start()
if err != nil {
shutdownErr = fmt.Errorf("failed to start Prometheus service: %w", err)
cancel() // Fatal error, like for RPC server.
}
case sigusr1:
if oracleSrv != nil {
serv.DelService(oracleSrv)
@ -626,7 +622,7 @@ Main:
serv.DelConsensusService(dbftSrv)
dbftSrv.Shutdown()
}
dbftSrv, err = mkConsensus(cfgnew.ApplicationConfiguration.UnlockWallet, serverConfig.TimePerBlock, chain, serv, log)
dbftSrv, err = mkConsensus(cfgnew.ApplicationConfiguration.Consensus, serverConfig.TimePerBlock, chain, serv, log)
if err != nil {
log.Error("failed to create consensus service", zap.Error(err))
break // Whatever happens, I'll leave it all to chance.
@ -650,39 +646,29 @@ Main:
return nil
}
// configureAddresses sets up addresses for RPC, Prometheus and Pprof depending from the provided config.
// In case RPC or Prometheus or Pprof Address provided each of them will use it.
// In case global Address (of the node) provided and RPC/Prometheus/Pprof don't have configured addresses they will
// use global one. So Node and RPC and Prometheus and Pprof will run on one address.
func configureAddresses(cfg *config.ApplicationConfiguration) {
if cfg.Address != "" {
if cfg.RPC.Address == "" {
cfg.RPC.Address = cfg.Address
}
if cfg.Prometheus.Address == "" {
cfg.Prometheus.Address = cfg.Address
}
if cfg.Pprof.Address == "" {
cfg.Pprof.Address = cfg.Address
}
}
}
// initBlockChain initializes BlockChain with preselected DB.
func initBlockChain(cfg config.Config, log *zap.Logger) (*core.Blockchain, error) {
func initBlockChain(cfg config.Config, log *zap.Logger) (*core.Blockchain, storage.Store, error) {
store, err := storage.NewStore(cfg.ApplicationConfiguration.DBConfiguration)
if err != nil {
return nil, cli.NewExitError(fmt.Errorf("could not initialize storage: %w", err), 1)
return nil, nil, cli.NewExitError(fmt.Errorf("could not initialize storage: %w", err), 1)
}
chain, err := core.NewBlockchain(store, cfg.ProtocolConfiguration, log)
chain, err := core.NewBlockchain(store, cfg.Blockchain(), log)
if err != nil {
return nil, cli.NewExitError(fmt.Errorf("could not initialize blockchain: %w", err), 1)
errText := "could not initialize blockchain: %w"
errArgs := []any{err}
closeErr := store.Close()
if closeErr != nil {
errText += "; failed to close the DB: %w"
errArgs = append(errArgs, closeErr)
}
return nil, nil, cli.NewExitError(fmt.Errorf(errText, errArgs...), 1)
}
return chain, nil
return chain, store, nil
}
// Logo returns Neo-Go logo.
// Logo returns NeoGo logo.
func Logo() string {
return `
_ ____________ __________

View file

@ -5,14 +5,17 @@ import (
"flag"
"os"
"path/filepath"
"runtime"
"testing"
"go.uber.org/zap/zapcore"
"github.com/nspcc-dev/neo-go/cli/options"
"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/storage/dbconfig"
"github.com/stretchr/testify/require"
"github.com/urfave/cli"
"go.uber.org/zap"
"gopkg.in/yaml.v3"
)
@ -28,13 +31,58 @@ func init() {
}
func TestGetConfigFromContext(t *testing.T) {
set := flag.NewFlagSet("flagSet", flag.ExitOnError)
set.String("config-path", "../../config", "")
set.Bool("testnet", true, "")
ctx := cli.NewContext(cli.NewApp(), set, nil)
cfg, err := getConfigFromContext(ctx)
require.NoError(t, err)
require.Equal(t, netmode.TestNet, cfg.ProtocolConfiguration.Magic)
t.Run("config-path", func(t *testing.T) {
set := flag.NewFlagSet("flagSet", flag.ExitOnError)
set.String("config-path", "../../config", "")
set.Bool("testnet", true, "")
ctx := cli.NewContext(cli.NewApp(), set, nil)
cfg, err := options.GetConfigFromContext(ctx)
require.NoError(t, err)
require.Equal(t, netmode.TestNet, cfg.ProtocolConfiguration.Magic)
})
t.Run("config-file", func(t *testing.T) {
set := flag.NewFlagSet("flagSet", flag.ExitOnError)
set.String("config-path", "../../config", "")
set.Bool("testnet", true, "")
set.String("config-file", "../../config/protocol.testnet.yml", "")
ctx := cli.NewContext(cli.NewApp(), set, nil)
cfg, err := options.GetConfigFromContext(ctx)
require.NoError(t, err)
require.Equal(t, netmode.TestNet, cfg.ProtocolConfiguration.Magic)
})
t.Run("relative-path windows", func(t *testing.T) {
if runtime.GOOS != "windows" {
t.Skip("skipping Windows specific test")
}
set := flag.NewFlagSet("flagSet", flag.ExitOnError)
set.String("relative-path", "..\\..\\config", "")
set.Bool("testnet", true, "")
set.String("config-file", ".\\testdata\\protocol.testnet.windows.yml", "")
ctx := cli.NewContext(cli.NewApp(), set, nil)
cfg, err := options.GetConfigFromContext(ctx)
require.NoError(t, err)
require.Equal(t, filepath.Join("..", "..", "config", "chains", "testnet"), cfg.ApplicationConfiguration.DBConfiguration.LevelDBOptions.DataDirectoryPath)
require.Equal(t, "C:\\someFolder\\cn_wallet.json", cfg.ApplicationConfiguration.Consensus.UnlockWallet.Path)
require.Equal(t, "C:\\someFolder\\notary_wallet.json", cfg.ApplicationConfiguration.P2PNotary.UnlockWallet.Path)
})
t.Run("relative-path non-windows", func(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skip("skipping non-Windows specific test")
}
set := flag.NewFlagSet("flagSet", flag.ExitOnError)
set.String("relative-path", "../../config", "")
set.Bool("testnet", true, "")
set.String("config-file", "../../config/protocol.testnet.yml", "")
ctx := cli.NewContext(cli.NewApp(), set, nil)
cfg, err := options.GetConfigFromContext(ctx)
require.NoError(t, err)
require.Equal(t, filepath.Join("..", "..", "config", "chains", "testnet"), cfg.ApplicationConfiguration.DBConfiguration.LevelDBOptions.DataDirectoryPath)
require.Equal(t, "/cn_wallet.json", cfg.ApplicationConfiguration.Consensus.UnlockWallet.Path)
require.Equal(t, "/notary_wallet.json", cfg.ApplicationConfiguration.P2PNotary.UnlockWallet.Path)
})
}
func TestHandleLoggingParams(t *testing.T) {
@ -44,49 +92,74 @@ func TestHandleLoggingParams(t *testing.T) {
t.Run("logdir is a file", func(t *testing.T) {
logfile := filepath.Join(d, "logdir")
require.NoError(t, os.WriteFile(logfile, []byte{1, 2, 3}, os.ModePerm))
set := flag.NewFlagSet("flagSet", flag.ExitOnError)
ctx := cli.NewContext(cli.NewApp(), set, nil)
cfg := config.ApplicationConfiguration{
LogPath: filepath.Join(logfile, "file.log"),
}
_, closer, err := handleLoggingParams(ctx, cfg)
_, lvl, closer, err := options.HandleLoggingParams(false, cfg)
require.Error(t, err)
require.Nil(t, lvl)
require.Nil(t, closer)
})
t.Run("broken level", func(t *testing.T) {
cfg := config.ApplicationConfiguration{
LogPath: testLog,
LogLevel: "qwerty",
}
_, lvl, closer, err := options.HandleLoggingParams(false, cfg)
require.Error(t, err)
require.Nil(t, lvl)
require.Nil(t, closer)
})
t.Run("default", func(t *testing.T) {
set := flag.NewFlagSet("flagSet", flag.ExitOnError)
ctx := cli.NewContext(cli.NewApp(), set, nil)
cfg := config.ApplicationConfiguration{
LogPath: testLog,
}
logger, closer, err := handleLoggingParams(ctx, cfg)
logger, lvl, closer, err := options.HandleLoggingParams(false, cfg)
require.NotNil(t, lvl)
require.NoError(t, err)
t.Cleanup(func() {
if closer != nil {
require.NoError(t, closer())
}
})
require.True(t, logger.Core().Enabled(zap.InfoLevel))
require.False(t, logger.Core().Enabled(zap.DebugLevel))
require.Equal(t, zapcore.InfoLevel, lvl.Level())
require.True(t, logger.Core().Enabled(zapcore.InfoLevel))
require.False(t, logger.Core().Enabled(zapcore.DebugLevel))
})
t.Run("warn", func(t *testing.T) {
cfg := config.ApplicationConfiguration{
LogPath: testLog,
LogLevel: "warn",
}
logger, lvl, closer, err := options.HandleLoggingParams(false, cfg)
require.NoError(t, err)
t.Cleanup(func() {
if closer != nil {
require.NoError(t, closer())
}
})
require.Equal(t, zapcore.WarnLevel, lvl.Level())
require.True(t, logger.Core().Enabled(zapcore.WarnLevel))
require.False(t, logger.Core().Enabled(zapcore.InfoLevel))
})
t.Run("debug", func(t *testing.T) {
set := flag.NewFlagSet("flagSet", flag.ExitOnError)
set.Bool("debug", true, "")
ctx := cli.NewContext(cli.NewApp(), set, nil)
cfg := config.ApplicationConfiguration{
LogPath: testLog,
}
logger, closer, err := handleLoggingParams(ctx, cfg)
logger, lvl, closer, err := options.HandleLoggingParams(true, cfg)
require.NoError(t, err)
t.Cleanup(func() {
if closer != nil {
require.NoError(t, closer())
}
})
require.True(t, logger.Core().Enabled(zap.InfoLevel))
require.True(t, logger.Core().Enabled(zap.DebugLevel))
require.Equal(t, zapcore.DebugLevel, lvl.Level())
require.True(t, logger.Core().Enabled(zapcore.InfoLevel))
require.True(t, logger.Core().Enabled(zapcore.DebugLevel))
})
}
@ -101,9 +174,9 @@ func TestInitBCWithMetrics(t *testing.T) {
set.Bool("testnet", true, "")
set.Bool("debug", true, "")
ctx := cli.NewContext(cli.NewApp(), set, nil)
cfg, err := getConfigFromContext(ctx)
cfg, err := options.GetConfigFromContext(ctx)
require.NoError(t, err)
logger, closer, err := handleLoggingParams(ctx, cfg.ApplicationConfiguration)
logger, _, closer, err := options.HandleLoggingParams(true, cfg.ApplicationConfiguration)
require.NoError(t, err)
t.Cleanup(func() {
if closer != nil {
@ -285,74 +358,35 @@ func TestRestoreDB(t *testing.T) {
require.NoError(t, restoreDB(ctx))
}
func TestConfigureAddresses(t *testing.T) {
defaultAddress := "http://localhost:10333"
customAddress := "http://localhost:10334"
t.Run("default addresses", func(t *testing.T) {
cfg := &config.ApplicationConfiguration{
Address: defaultAddress,
}
configureAddresses(cfg)
require.Equal(t, defaultAddress, cfg.RPC.Address)
require.Equal(t, defaultAddress, cfg.Prometheus.Address)
require.Equal(t, defaultAddress, cfg.Pprof.Address)
})
t.Run("custom RPC address", func(t *testing.T) {
cfg := &config.ApplicationConfiguration{
Address: defaultAddress,
RPC: config.RPC{
Address: customAddress,
},
}
configureAddresses(cfg)
require.Equal(t, cfg.RPC.Address, customAddress)
require.Equal(t, cfg.Prometheus.Address, defaultAddress)
require.Equal(t, cfg.Pprof.Address, defaultAddress)
})
t.Run("custom Pprof address", func(t *testing.T) {
cfg := &config.ApplicationConfiguration{
Address: defaultAddress,
Pprof: config.BasicService{
Address: customAddress,
},
}
configureAddresses(cfg)
require.Equal(t, cfg.RPC.Address, defaultAddress)
require.Equal(t, cfg.Prometheus.Address, defaultAddress)
require.Equal(t, cfg.Pprof.Address, customAddress)
})
t.Run("custom Prometheus address", func(t *testing.T) {
cfg := &config.ApplicationConfiguration{
Address: defaultAddress,
Prometheus: config.BasicService{
Address: customAddress,
},
}
configureAddresses(cfg)
require.Equal(t, cfg.RPC.Address, defaultAddress)
require.Equal(t, cfg.Prometheus.Address, customAddress)
require.Equal(t, cfg.Pprof.Address, defaultAddress)
})
}
func TestInitBlockChain(t *testing.T) {
t.Run("bad storage", func(t *testing.T) {
_, err := initBlockChain(config.Config{}, nil)
_, _, err := initBlockChain(config.Config{}, nil)
require.Error(t, err)
})
t.Run("empty logger", func(t *testing.T) {
_, err := initBlockChain(config.Config{
_, _, err := initBlockChain(config.Config{
ApplicationConfiguration: config.ApplicationConfiguration{
DBConfiguration: dbconfig.DBConfiguration{
Type: "inmemory",
Type: dbconfig.InMemoryDB,
},
},
}, nil)
require.Error(t, err)
})
}
func TestResetDB(t *testing.T) {
d := t.TempDir()
err := os.Chdir(d)
require.NoError(t, err)
t.Cleanup(func() { require.NoError(t, os.Chdir(serverTestWD)) })
set := flag.NewFlagSet("flagSet", flag.ExitOnError)
set.String("config-path", filepath.Join(serverTestWD, "..", "..", "config"), "")
set.Bool("privnet", true, "")
set.Bool("debug", true, "")
set.Int("height", 0, "")
ctx := cli.NewContext(cli.NewApp(), set, nil)
err = resetDB(ctx)
require.NoError(t, err)
}

View file

@ -0,0 +1,96 @@
ProtocolConfiguration:
Magic: 894710606
MaxBlockSize: 2097152
MaxBlockSystemFee: 150000000000
MaxTraceableBlocks: 2102400
MaxTransactionsPerBlock: 5000
InitialGASSupply: 52000000
TimePerBlock: 15s
MemPoolSize: 50000
StandbyCommittee:
- 023e9b32ea89b94d066e649b124fd50e396ee91369e8e2a6ae1b11c170d022256d
- 03009b7540e10f2562e5fd8fac9eaec25166a58b26e412348ff5a86927bfac22a2
- 02ba2c70f5996f357a43198705859fae2cfea13e1172962800772b3d588a9d4abd
- 03408dcd416396f64783ac587ea1e1593c57d9fea880c8a6a1920e92a259477806
- 02a7834be9b32e2981d157cb5bbd3acb42cfd11ea5c3b10224d7a44e98c5910f1b
- 0214baf0ceea3a66f17e7e1e839ea25fd8bed6cd82e6bb6e68250189065f44ff01
- 030205e9cefaea5a1dfc580af20c8d5aa2468bb0148f1a5e4605fc622c80e604ba
- 025831cee3708e87d78211bec0d1bfee9f4c85ae784762f042e7f31c0d40c329b8
- 02cf9dc6e85d581480d91e88e8cbeaa0c153a046e89ded08b4cefd851e1d7325b5
- 03840415b0a0fcf066bcc3dc92d8349ebd33a6ab1402ef649bae00e5d9f5840828
- 026328aae34f149853430f526ecaa9cf9c8d78a4ea82d08bdf63dd03c4d0693be6
- 02c69a8d084ee7319cfecf5161ff257aa2d1f53e79bf6c6f164cff5d94675c38b3
- 0207da870cedb777fceff948641021714ec815110ca111ccc7a54c168e065bda70
- 035056669864feea401d8c31e447fb82dd29f342a9476cfd449584ce2a6165e4d7
- 0370c75c54445565df62cfe2e76fbec4ba00d1298867972213530cae6d418da636
- 03957af9e77282ae3263544b7b2458903624adc3f5dee303957cb6570524a5f254
- 03d84d22b8753cf225d263a3a782a4e16ca72ef323cfde04977c74f14873ab1e4c
- 02147c1b1d5728e1954958daff2f88ee2fa50a06890a8a9db3fa9e972b66ae559f
- 03c609bea5a4825908027e4ab217e7efc06e311f19ecad9d417089f14927a173d5
- 0231edee3978d46c335e851c76059166eb8878516f459e085c0dd092f0f1d51c21
- 03184b018d6b2bc093e535519732b3fd3f7551c8cffaf4621dd5a0b89482ca66c9
ValidatorsCount: 7
SeedList:
- seed1t5.neo.org:20333
- seed2t5.neo.org:20333
- seed3t5.neo.org:20333
- seed4t5.neo.org:20333
- seed5t5.neo.org:20333
VerifyTransactions: false
P2PSigExtensions: false
Hardforks:
Aspidochelone: 210000
Basilisk: 2680000
ApplicationConfiguration:
SkipBlockVerification: false
DBConfiguration:
Type: "leveldb" #other options: 'inmemory','boltdb'
# DB type options. Uncomment those you need in case you want to switch DB type.
LevelDBOptions:
DataDirectoryPath: ".\\chains\\testnet"
P2P:
Addresses:
- ":20333" # in form of "[host]:[port][:announcedPort]"
DialTimeout: 3s
ProtoTickInterval: 2s
PingInterval: 30s
PingTimeout: 90s
MaxPeers: 100
AttemptConnPeers: 20
MinPeers: 10
Relay: true
Consensus:
Enabled: false
UnlockWallet:
Path: "C:\\someFolder\\cn_wallet.json"
Password: "pass"
Oracle:
Enabled: false
AllowedContentTypes:
- application/json
P2PNotary:
Enabled: false
UnlockWallet:
Path: "C:\\someFolder\\notary_wallet.json"
Password: "pass"
RPC:
Enabled: true
Addresses:
- ":20332"
MaxGasInvoke: 15
EnableCORSWorkaround: false
TLSConfig:
Enabled: false
Addresses:
- ":20331"
CertFile: serv.crt
KeyFile: serv.key
Prometheus:
Enabled: true
Addresses:
- ":2112"
Pprof:
Enabled: false
Addresses:
- ":2113"

View file

@ -1,9 +1,10 @@
package main
package smartcontract_test
import (
"bytes"
"encoding/hex"
"encoding/json"
"fmt"
"os"
"path/filepath"
"strconv"
@ -12,6 +13,8 @@ import (
"github.com/nspcc-dev/neo-go/cli/smartcontract"
"github.com/nspcc-dev/neo-go/internal/random"
"github.com/nspcc-dev/neo-go/internal/testcli"
"github.com/nspcc-dev/neo-go/internal/versionutil"
"github.com/nspcc-dev/neo-go/pkg/config"
"github.com/nspcc-dev/neo-go/pkg/core/interop/storage"
"github.com/nspcc-dev/neo-go/pkg/core/state"
@ -22,6 +25,7 @@ import (
"github.com/nspcc-dev/neo-go/pkg/neorpc/result"
"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/smartcontract/trigger"
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
"github.com/nspcc-dev/neo-go/pkg/vm/vmstate"
@ -30,9 +34,12 @@ import (
"gopkg.in/yaml.v3"
)
// Keep contract NEFs consistent between runs.
const _ = versionutil.TestVersion
func TestCalcHash(t *testing.T) {
tmpDir := t.TempDir()
e := newExecutor(t, false)
e := testcli.NewExecutor(t, false)
nefPath := "./testdata/verify.nef"
src, err := os.ReadFile(nefPath)
@ -83,27 +90,24 @@ func TestCalcHash(t *testing.T) {
})
t.Run("valid, uint160", func(t *testing.T) {
e.Run(t, append(cmd, "--sender", sender.StringLE())...)
e.checkNextLine(t, expected.StringLE())
e.CheckNextLine(t, expected.StringLE())
})
t.Run("valid, uint160 with 0x", func(t *testing.T) {
e.Run(t, append(cmd, "--sender", "0x"+sender.StringLE())...)
e.checkNextLine(t, expected.StringLE())
e.CheckNextLine(t, expected.StringLE())
})
t.Run("valid, address", func(t *testing.T) {
e.Run(t, append(cmd, "--sender", address.Uint160ToString(sender))...)
e.checkNextLine(t, expected.StringLE())
e.CheckNextLine(t, expected.StringLE())
})
}
func TestContractBindings(t *testing.T) {
// For proper nef generation.
config.Version = "v0.98.1-test"
// For proper contract init. The actual version as it will be replaced.
smartcontract.ModVersion = "v0.0.0"
tmpDir := t.TempDir()
e := newExecutor(t, false)
e := testcli.NewExecutor(t, false)
ctrPath := filepath.Join(tmpDir, "testcontract")
e.Run(t, "neo-go", "contract", "init", "--name", ctrPath)
@ -142,18 +146,7 @@ func Blocks() []*alias.Block {
cmd = append(cmd, "--in", ctrPath, "--bindings", bindingsPath)
// Replace `pkg/interop` in go.mod to avoid getting an actual module version.
goMod := filepath.Join(ctrPath, "go.mod")
data, err := os.ReadFile(goMod)
require.NoError(t, err)
i := bytes.IndexByte(data, '\n')
data = append([]byte("module myimport.com/testcontract"), data[i:]...)
wd, err := os.Getwd()
require.NoError(t, err)
data = append(data, "\nreplace github.com/nspcc-dev/neo-go/pkg/interop => "...)
data = append(data, filepath.Join(wd, "../pkg/interop")...)
require.NoError(t, os.WriteFile(goMod, data, os.ModePerm))
require.NoError(t, updateGoMod(ctrPath, "myimport.com/testcontract", "../../pkg/interop"))
cmd = append(cmd, "--config", cfgPath,
"--out", filepath.Join(tmpDir, "out.nef"),
@ -163,7 +156,7 @@ func Blocks() []*alias.Block {
e.RunWithError(t, append(cmd, "something")...)
})
e.Run(t, cmd...)
e.checkEOF(t)
e.CheckEOF(t)
require.FileExists(t, bindingsPath)
outPath := filepath.Join(t.TempDir(), "binding.go")
@ -173,7 +166,9 @@ func Blocks() []*alias.Block {
bs, err := os.ReadFile(outPath)
require.NoError(t, err)
require.Equal(t, `// Package testcontract contains wrappers for testcontract contract.
require.Equal(t, `// Code generated by neo-go contract generate-wrapper --manifest <file.json> --out <file.go> [--hash <hash>] [--config <config>]; DO NOT EDIT.
// Package testcontract contains wrappers for testcontract contract.
package testcontract
import (
@ -208,15 +203,90 @@ func ToMap(a []testcontract.MyPair) map[int]string {
`, string(bs))
}
func TestContractInitAndCompile(t *testing.T) {
// For proper nef generation.
config.Version = "v0.98.1-test"
// updateGoMod updates the go.mod file located in the specified directory.
// It sets the module name and replaces the neo-go interop package path with
// the provided one to avoid getting an actual module version.
func updateGoMod(dir, moduleName, neoGoPath string) error {
goModPath := filepath.Join(dir, "go.mod")
data, err := os.ReadFile(goModPath)
if err != nil {
return fmt.Errorf("failed to read go.mod: %w", err)
}
i := bytes.IndexByte(data, '\n')
if i == -1 {
return fmt.Errorf("unexpected go.mod format")
}
updatedData := append([]byte("module "+moduleName), data[i:]...)
wd, err := os.Getwd()
if err != nil {
return fmt.Errorf("failed to get working directory: %w", err)
}
replacementPath := filepath.Join(wd, neoGoPath)
updatedData = append(updatedData, "\nreplace github.com/nspcc-dev/neo-go/pkg/interop => "+replacementPath+" \n"...)
if err := os.WriteFile(goModPath, updatedData, os.ModePerm); err != nil {
return fmt.Errorf("failed to write updated go.mod: %w", err)
}
return nil
}
func TestDynamicWrapper(t *testing.T) {
// For proper contract init. The actual version as it will be replaced.
smartcontract.ModVersion = "v0.0.0"
tmpDir := t.TempDir()
e := newExecutor(t, false)
e := testcli.NewExecutor(t, true)
ctrPath := "../smartcontract/testdata"
verifyHash := testcli.DeployContract(t, e, filepath.Join(ctrPath, "verify.go"), filepath.Join(ctrPath, "verify.yml"), testcli.ValidatorWallet, testcli.ValidatorAddr, testcli.ValidatorPass)
helperContract := `package testcontract
import (
"github.com/nspcc-dev/neo-go/pkg/interop"
verify "myimport.com/testcontract/bindings"
)
func CallVerifyContract(h interop.Hash160) bool{
contractInstance := verify.NewContract(h)
return contractInstance.Verify()
}`
helperDir := filepath.Join(tmpDir, "helper")
e.Run(t, "neo-go", "contract", "init", "--name", helperDir)
require.NoError(t, updateGoMod(helperDir, "myimport.com/testcontract", "../../pkg/interop"))
require.NoError(t, os.WriteFile(filepath.Join(helperDir, "main.go"), []byte(helperContract), os.ModePerm))
require.NoError(t, os.Mkdir(filepath.Join(helperDir, "bindings"), os.ModePerm))
e.Run(t, "neo-go", "contract", "generate-wrapper",
"--config", filepath.Join(ctrPath, "verify.bindings.yml"), "--manifest", filepath.Join(ctrPath, "verify.manifest.json"),
"--out", filepath.Join(helperDir, "bindings", "testdata.go"))
e.Run(t, "neo-go", "contract", "compile", "--in", filepath.Join(helperDir, "main.go"), "--config", filepath.Join(helperDir, "neo-go.yml"))
helperHash := testcli.DeployContract(t, e, filepath.Join(helperDir, "main.go"), filepath.Join(helperDir, "neo-go.yml"), testcli.ValidatorWallet, testcli.ValidatorAddr, testcli.ValidatorPass)
e.In.WriteString("one\r")
e.Run(t, "neo-go", "contract", "invokefunction",
"--rpc-endpoint", "http://"+e.RPC.Addresses()[0],
"--wallet", testcli.ValidatorWallet, "--address", testcli.ValidatorAddr, "--force", "--await", helperHash.StringLE(), "callVerifyContract", verifyHash.StringLE())
tx, _ := e.CheckTxPersisted(t, "Sent invocation transaction ")
aer, err := e.Chain.GetAppExecResults(tx.Hash(), trigger.Application)
require.NoError(t, err)
require.Equal(t, aer[0].Stack[0].Value().(bool), true)
}
func TestContractInitAndCompile(t *testing.T) {
// For proper contract init. The actual version as it will be replaced.
smartcontract.ModVersion = "v0.0.0"
tmpDir := t.TempDir()
e := testcli.NewExecutor(t, false)
t.Run("no path is provided", func(t *testing.T) {
e.RunWithError(t, "neo-go", "contract", "init")
@ -236,7 +306,8 @@ func TestContractInitAndCompile(t *testing.T) {
e.RunWithError(t, "neo-go", "contract", "init", "--name", ctrPath)
})
srcPath := filepath.Join(ctrPath, "main.go")
ctrRootPath := filepath.Join(ctrPath, "main")
srcPath := ctrRootPath + ".go"
cfgPath := filepath.Join(ctrPath, "neo-go.yml")
nefPath := filepath.Join(tmpDir, "testcontract.nef")
manifestPath := filepath.Join(tmpDir, "testcontract.manifest.json")
@ -262,15 +333,7 @@ func TestContractInitAndCompile(t *testing.T) {
})
// Replace `pkg/interop` in go.mod to avoid getting an actual module version.
goMod := filepath.Join(ctrPath, "go.mod")
data, err := os.ReadFile(goMod)
require.NoError(t, err)
wd, err := os.Getwd()
require.NoError(t, err)
data = append(data, "\nreplace github.com/nspcc-dev/neo-go/pkg/interop => "...)
data = append(data, filepath.Join(wd, "../pkg/interop")...)
require.NoError(t, os.WriteFile(goMod, data, os.ModePerm))
require.NoError(t, updateGoMod(ctrPath, "myimport.com/testcontract", "../../pkg/interop"))
cmd = append(cmd, "--config", cfgPath)
@ -279,25 +342,35 @@ func TestContractInitAndCompile(t *testing.T) {
})
e.Run(t, cmd...)
e.checkEOF(t)
e.CheckEOF(t)
require.FileExists(t, nefPath)
require.FileExists(t, manifestPath)
t.Run("output hex script with --verbose", func(t *testing.T) {
e.Run(t, append(cmd, "--verbose")...)
e.checkNextLine(t, "^[0-9a-hA-H]+$")
e.CheckNextLine(t, "^[0-9a-hA-H]+$")
})
t.Run("autocomplete outputs", func(t *testing.T) {
cfg, err := os.ReadFile(cfgPath)
require.NoError(t, err)
require.NoError(t, os.WriteFile(filepath.Join(ctrPath, "main.yml"), cfg, os.ModePerm))
e.Run(t, "neo-go", "contract", "compile", "--in", srcPath)
defaultNefPath := ctrRootPath + ".nef"
defaultManifestPath := ctrRootPath + ".manifest.json"
defaultBindingsPath := ctrRootPath + ".bindings.yml"
require.FileExists(t, defaultNefPath)
require.FileExists(t, defaultManifestPath)
require.FileExists(t, defaultBindingsPath)
})
}
// Checks that error is returned if GAS available for test-invoke exceeds
// GAS needed to be consumed.
func TestDeployBigContract(t *testing.T) {
e := newExecutorWithConfig(t, true, true, func(c *config.Config) {
e := testcli.NewExecutorWithConfig(t, true, true, func(c *config.Config) {
c.ApplicationConfiguration.RPC.MaxGasInvoke = fixedn.Fixed8(1)
})
// For proper nef generation.
config.Version = "0.90.0-test"
tmpDir := t.TempDir()
nefName := filepath.Join(tmpDir, "deploy.nef")
@ -307,18 +380,15 @@ func TestDeployBigContract(t *testing.T) {
"--config", "testdata/deploy/neo-go.yml",
"--out", nefName, "--manifest", manifestName)
e.In.WriteString("one\r")
e.In.WriteString(testcli.ValidatorPass + "\r")
e.RunWithError(t, "neo-go", "contract", "deploy",
"--rpc-endpoint", "http://"+e.RPC.Addr,
"--wallet", validatorWallet, "--address", validatorAddr,
"--rpc-endpoint", "http://"+e.RPC.Addresses()[0],
"--wallet", testcli.ValidatorWallet, "--address", testcli.ValidatorAddr,
"--in", nefName, "--manifest", manifestName)
}
func TestContractDeployWithData(t *testing.T) {
eCompile := newExecutor(t, false)
// For proper nef generation.
config.Version = "0.90.0-test"
eCompile := testcli.NewExecutor(t, false)
tmpDir := t.TempDir()
nefName := filepath.Join(tmpDir, "deploy.nef")
@ -328,28 +398,36 @@ func TestContractDeployWithData(t *testing.T) {
"--config", "testdata/deploy/neo-go.yml",
"--out", nefName, "--manifest", manifestName)
deployContract := func(t *testing.T, haveData bool, scope string) {
e := newExecutor(t, true)
deployContract := func(t *testing.T, haveData bool, scope string, await bool) {
e := testcli.NewExecutor(t, true)
cmd := []string{
"neo-go", "contract", "deploy",
"--rpc-endpoint", "http://" + e.RPC.Addr,
"--wallet", validatorWallet, "--address", validatorAddr,
"--rpc-endpoint", "http://" + e.RPC.Addresses()[0],
"--wallet", testcli.ValidatorWallet, "--address", testcli.ValidatorAddr,
"--in", nefName, "--manifest", manifestName,
"--force",
}
if await {
cmd = append(cmd, "--await")
}
if haveData {
cmd = append(cmd, "[", "key1", "12", "key2", "take_me_to_church", "]")
}
if scope != "" {
cmd = append(cmd, "--", validatorAddr+":"+scope)
cmd = append(cmd, "--", testcli.ValidatorAddr+":"+scope)
} else {
scope = "CalledByEntry"
}
e.In.WriteString("one\r")
e.In.WriteString(testcli.ValidatorPass + "\r")
e.Run(t, cmd...)
var tx *transaction.Transaction
if await {
tx, _ = e.CheckAwaitableTxPersisted(t)
} else {
tx, _ = e.CheckTxPersisted(t)
}
tx, _ := e.checkTxPersisted(t, "Sent invocation transaction ")
require.Equal(t, scope, tx.Signers[0].Scopes.String())
if !haveData {
return
@ -362,7 +440,7 @@ func TestContractDeployWithData(t *testing.T) {
require.NoError(t, err)
e.Run(t, "neo-go", "contract", "testinvokefunction",
"--rpc-endpoint", "http://"+e.RPC.Addr,
"--rpc-endpoint", "http://"+e.RPC.Addresses()[0],
h.StringLE(),
"getValueWithKey", "key1",
)
@ -374,7 +452,7 @@ func TestContractDeployWithData(t *testing.T) {
require.Equal(t, []byte{12}, res.Stack[0].Value())
e.Run(t, "neo-go", "contract", "testinvokefunction",
"--rpc-endpoint", "http://"+e.RPC.Addr,
"--rpc-endpoint", "http://"+e.RPC.Addresses()[0],
h.StringLE(),
"getValueWithKey", "key2",
)
@ -386,16 +464,16 @@ func TestContractDeployWithData(t *testing.T) {
require.Equal(t, []byte("take_me_to_church"), res.Stack[0].Value())
}
deployContract(t, true, "")
deployContract(t, false, "Global")
deployContract(t, true, "Global")
deployContract(t, true, "", false)
deployContract(t, false, "Global", false)
deployContract(t, true, "Global", false)
deployContract(t, false, "", true)
deployContract(t, true, "Global", true)
deployContract(t, true, "", true)
}
func TestDeployWithSigners(t *testing.T) {
e := newExecutor(t, true)
// For proper nef generation.
config.Version = "0.90.0-test"
e := testcli.NewExecutor(t, true)
tmpDir := t.TempDir()
nefName := filepath.Join(tmpDir, "deploy.nef")
@ -407,62 +485,59 @@ func TestDeployWithSigners(t *testing.T) {
t.Run("missing nef", func(t *testing.T) {
e.RunWithError(t, "neo-go", "contract", "deploy",
"--rpc-endpoint", "http://"+e.RPC.Addr,
"--wallet", validatorWallet, "--address", validatorAddr,
"--rpc-endpoint", "http://"+e.RPC.Addresses()[0],
"--wallet", testcli.ValidatorWallet, "--address", testcli.ValidatorAddr,
"--in", "", "--manifest", manifestName)
})
t.Run("missing manifest", func(t *testing.T) {
e.RunWithError(t, "neo-go", "contract", "deploy",
"--rpc-endpoint", "http://"+e.RPC.Addr,
"--wallet", validatorWallet, "--address", validatorAddr,
"--rpc-endpoint", "http://"+e.RPC.Addresses()[0],
"--wallet", testcli.ValidatorWallet, "--address", testcli.ValidatorAddr,
"--in", nefName, "--manifest", "")
})
t.Run("corrupted data", func(t *testing.T) {
e.RunWithError(t, "neo-go", "contract", "deploy",
"--rpc-endpoint", "http://"+e.RPC.Addr,
"--wallet", validatorWallet, "--address", validatorAddr,
"--rpc-endpoint", "http://"+e.RPC.Addresses()[0],
"--wallet", testcli.ValidatorWallet, "--address", testcli.ValidatorAddr,
"--in", nefName, "--manifest", manifestName,
"[", "str1")
})
t.Run("invalid data", func(t *testing.T) {
e.RunWithError(t, "neo-go", "contract", "deploy",
"--rpc-endpoint", "http://"+e.RPC.Addr,
"--wallet", validatorWallet, "--address", validatorAddr,
"--rpc-endpoint", "http://"+e.RPC.Addresses()[0],
"--wallet", testcli.ValidatorWallet, "--address", testcli.ValidatorAddr,
"--in", nefName, "--manifest", manifestName,
"str1", "str2")
})
t.Run("missing wallet", func(t *testing.T) {
e.RunWithError(t, "neo-go", "contract", "deploy",
"--rpc-endpoint", "http://"+e.RPC.Addr,
"--address", validatorAddr,
"--rpc-endpoint", "http://"+e.RPC.Addresses()[0],
"--address", testcli.ValidatorAddr,
"--in", nefName, "--manifest", manifestName,
"[", "str1", "str2", "]")
})
t.Run("missing RPC", func(t *testing.T) {
e.RunWithError(t, "neo-go", "contract", "deploy",
"--wallet", validatorWallet, "--address", validatorAddr,
"--wallet", testcli.ValidatorWallet, "--address", testcli.ValidatorAddr,
"--in", nefName, "--manifest", manifestName,
"[", "str1", "str2", "]")
})
e.In.WriteString("one\r")
e.In.WriteString(testcli.ValidatorPass + "\r")
e.Run(t, "neo-go", "contract", "deploy",
"--rpc-endpoint", "http://"+e.RPC.Addr,
"--wallet", validatorWallet, "--address", validatorAddr,
"--rpc-endpoint", "http://"+e.RPC.Addresses()[0],
"--wallet", testcli.ValidatorWallet, "--address", testcli.ValidatorAddr,
"--in", nefName, "--manifest", manifestName,
"--force",
"--", validatorAddr+":Global")
tx, _ := e.checkTxPersisted(t, "Sent invocation transaction ")
"--", testcli.ValidatorAddr+":Global")
tx, _ := e.CheckTxPersisted(t, "Sent invocation transaction ")
require.Equal(t, transaction.Global, tx.Signers[0].Scopes)
}
func TestContractManifestGroups(t *testing.T) {
e := newExecutor(t, true)
// For proper nef generation.
config.Version = "0.90.0-test"
e := testcli.NewExecutor(t, true)
tmpDir := t.TempDir()
_, err := wallet.NewWalletFromFile(testWalletPath)
_, err := wallet.NewWalletFromFile(testcli.TestWalletPath)
require.NoError(t, err)
nefName := filepath.Join(tmpDir, "deploy.nef")
@ -481,93 +556,70 @@ func TestContractManifestGroups(t *testing.T) {
})
t.Run("invalid sender", func(t *testing.T) {
e.RunWithError(t, "neo-go", "contract", "manifest", "add-group",
"--wallet", testWalletPath, "--address", testWalletAccount,
"--wallet", testcli.TestWalletPath, "--address", testcli.TestWalletAccount,
"--sender", "not-a-sender")
})
t.Run("invalid NEF file", func(t *testing.T) {
e.RunWithError(t, "neo-go", "contract", "manifest", "add-group",
"--wallet", testWalletPath, "--address", testWalletAccount,
"--sender", testWalletAccount, "--nef", tmpDir)
"--wallet", testcli.TestWalletPath, "--address", testcli.TestWalletAccount,
"--sender", testcli.TestWalletAccount, "--nef", tmpDir)
})
t.Run("corrupted NEF file", func(t *testing.T) {
f := filepath.Join(tmpDir, "invalid.nef")
require.NoError(t, os.WriteFile(f, []byte{1, 2, 3}, os.ModePerm))
e.RunWithError(t, "neo-go", "contract", "manifest", "add-group",
"--wallet", testWalletPath, "--address", testWalletAccount,
"--sender", testWalletAccount, "--nef", f)
"--wallet", testcli.TestWalletPath, "--address", testcli.TestWalletAccount,
"--sender", testcli.TestWalletAccount, "--nef", f)
})
t.Run("invalid manifest file", func(t *testing.T) {
e.RunWithError(t, "neo-go", "contract", "manifest", "add-group",
"--wallet", testWalletPath, "--address", testWalletAccount,
"--sender", testWalletAccount, "--nef", nefName,
"--wallet", testcli.TestWalletPath, "--address", testcli.TestWalletAccount,
"--sender", testcli.TestWalletAccount, "--nef", nefName,
"--manifest", tmpDir)
})
t.Run("corrupted manifest file", func(t *testing.T) {
f := filepath.Join(tmpDir, "invalid.manifest.json")
require.NoError(t, os.WriteFile(f, []byte{1, 2, 3}, os.ModePerm))
e.RunWithError(t, "neo-go", "contract", "manifest", "add-group",
"--wallet", testWalletPath, "--address", testWalletAccount,
"--sender", testWalletAccount, "--nef", nefName,
"--wallet", testcli.TestWalletPath, "--address", testcli.TestWalletAccount,
"--sender", testcli.TestWalletAccount, "--nef", nefName,
"--manifest", f)
})
t.Run("unknown account", func(t *testing.T) {
e.RunWithError(t, "neo-go", "contract", "manifest", "add-group",
"--wallet", testWalletPath, "--address", util.Uint160{}.StringLE(),
"--sender", testWalletAccount, "--nef", nefName,
"--wallet", testcli.TestWalletPath, "--address", util.Uint160{}.StringLE(),
"--sender", testcli.TestWalletAccount, "--nef", nefName,
"--manifest", manifestName)
})
cmd := []string{"neo-go", "contract", "manifest", "add-group",
"--nef", nefName, "--manifest", manifestName}
t.Run("excessive parameters", func(t *testing.T) {
e.RunWithError(t, append(cmd, "--wallet", testWalletPath,
"--sender", testWalletAccount, "--address", testWalletAccount, "something")...)
e.RunWithError(t, append(cmd, "--wallet", testcli.TestWalletPath,
"--sender", testcli.TestWalletAccount, "--address", testcli.TestWalletAccount, "something")...)
})
e.In.WriteString("testpass\r")
e.Run(t, append(cmd, "--wallet", testWalletPath,
"--sender", testWalletAccount, "--address", testWalletAccount)...)
e.Run(t, append(cmd, "--wallet", testcli.TestWalletPath,
"--sender", testcli.TestWalletAccount, "--address", testcli.TestWalletAccount)...)
e.In.WriteString("testpass\r") // should override signature with the previous sender
e.Run(t, append(cmd, "--wallet", testWalletPath,
"--sender", validatorAddr, "--address", testWalletAccount)...)
e.Run(t, append(cmd, "--wallet", testcli.TestWalletPath,
"--sender", testcli.ValidatorAddr, "--address", testcli.TestWalletAccount)...)
e.In.WriteString("one\r")
e.In.WriteString(testcli.ValidatorPass + "\r")
e.Run(t, "neo-go", "contract", "deploy",
"--rpc-endpoint", "http://"+e.RPC.Addr,
"--rpc-endpoint", "http://"+e.RPC.Addresses()[0],
"--in", nefName, "--manifest", manifestName,
"--force",
"--wallet", validatorWallet, "--address", validatorAddr)
"--wallet", testcli.ValidatorWallet, "--address", testcli.ValidatorAddr)
}
func deployVerifyContract(t *testing.T, e *executor) util.Uint160 {
return deployContract(t, e, "testdata/verify.go", "testdata/verify.yml", validatorWallet, validatorAddr, "one")
}
func deployContract(t *testing.T, e *executor, inPath, configPath, wallet, address, pass string) util.Uint160 {
tmpDir := t.TempDir()
nefName := filepath.Join(tmpDir, "contract.nef")
manifestName := filepath.Join(tmpDir, "contract.manifest.json")
e.Run(t, "neo-go", "contract", "compile",
"--in", inPath,
"--config", configPath,
"--out", nefName, "--manifest", manifestName)
e.In.WriteString(pass + "\r")
e.Run(t, "neo-go", "contract", "deploy",
"--rpc-endpoint", "http://"+e.RPC.Addr,
"--wallet", wallet, "--address", address,
"--force",
"--in", nefName, "--manifest", manifestName)
e.checkTxPersisted(t, "Sent invocation transaction ")
line, err := e.Out.ReadString('\n')
require.NoError(t, err)
line = strings.TrimSpace(strings.TrimPrefix(line, "Contract: "))
h, err := util.Uint160DecodeStringLE(line)
require.NoError(t, err)
return h
func deployVerifyContract(t *testing.T, e *testcli.Executor) util.Uint160 {
return testcli.DeployContract(t, e, "testdata/verify.go", "testdata/verify.yml", testcli.ValidatorWallet, testcli.ValidatorAddr, testcli.ValidatorPass)
}
func TestContract_TestInvokeScript(t *testing.T) {
e := newExecutor(t, true)
e := testcli.NewExecutor(t, true)
tmpDir := t.TempDir()
badNef := filepath.Join(tmpDir, "invalid.nef")
goodNef := filepath.Join(tmpDir, "deploy.nef")
@ -579,22 +631,22 @@ func TestContract_TestInvokeScript(t *testing.T) {
t.Run("missing in", func(t *testing.T) {
e.RunWithError(t, "neo-go", "contract", "testinvokescript",
"--rpc-endpoint", "http://"+e.RPC.Addr)
"--rpc-endpoint", "http://"+e.RPC.Addresses()[0])
})
t.Run("unexisting in", func(t *testing.T) {
e.RunWithError(t, "neo-go", "contract", "testinvokescript",
"--rpc-endpoint", "http://"+e.RPC.Addr,
"--rpc-endpoint", "http://"+e.RPC.Addresses()[0],
"--in", badNef)
})
t.Run("invalid nef", func(t *testing.T) {
require.NoError(t, os.WriteFile(badNef, []byte("qwer"), os.ModePerm))
e.RunWithError(t, "neo-go", "contract", "testinvokescript",
"--rpc-endpoint", "http://"+e.RPC.Addr,
"--rpc-endpoint", "http://"+e.RPC.Addresses()[0],
"--in", badNef)
})
t.Run("invalid signers", func(t *testing.T) {
e.RunWithError(t, "neo-go", "contract", "testinvokescript",
"--rpc-endpoint", "http://"+e.RPC.Addr,
"--rpc-endpoint", "http://"+e.RPC.Addresses()[0],
"--in", goodNef, "--", "not-a-valid-signer")
})
t.Run("no RPC endpoint", func(t *testing.T) {
@ -602,13 +654,43 @@ func TestContract_TestInvokeScript(t *testing.T) {
"--rpc-endpoint", "http://123456789",
"--in", goodNef)
})
t.Run("good", func(t *testing.T) {
e.Run(t, "neo-go", "contract", "testinvokescript",
"--rpc-endpoint", "http://"+e.RPC.Addresses()[0],
"--in", goodNef)
})
t.Run("good with hashed signer", func(t *testing.T) {
e.Run(t, "neo-go", "contract", "testinvokescript",
"--rpc-endpoint", "http://"+e.RPC.Addresses()[0],
"--in", goodNef, "--", util.Uint160{1, 2, 3}.StringLE())
})
t.Run("good with addressed signer", func(t *testing.T) {
e.Run(t, "neo-go", "contract", "testinvokescript",
"--rpc-endpoint", "http://"+e.RPC.Addresses()[0],
"--in", goodNef, "--", address.Uint160ToString(util.Uint160{1, 2, 3}))
})
t.Run("historic, invalid", func(t *testing.T) {
e.RunWithError(t, "neo-go", "contract", "testinvokescript",
"--rpc-endpoint", "http://"+e.RPC.Addresses()[0],
"--historic", "bad",
"--in", goodNef)
})
t.Run("historic, index", func(t *testing.T) {
e.Run(t, "neo-go", "contract", "testinvokescript",
"--rpc-endpoint", "http://"+e.RPC.Addresses()[0],
"--historic", "0",
"--in", goodNef)
})
t.Run("historic, hash", func(t *testing.T) {
e.Run(t, "neo-go", "contract", "testinvokescript",
"--rpc-endpoint", "http://"+e.RPC.Addresses()[0],
"--historic", e.Chain.GetHeaderHash(0).StringLE(),
"--in", goodNef)
})
}
func TestComlileAndInvokeFunction(t *testing.T) {
e := newExecutor(t, true)
// For proper nef generation.
config.Version = "0.90.0-test"
e := testcli.NewExecutor(t, true)
tmpDir := t.TempDir()
nefName := filepath.Join(tmpDir, "deploy.nef")
@ -618,31 +700,21 @@ func TestComlileAndInvokeFunction(t *testing.T) {
"--config", "testdata/deploy/neo-go.yml",
"--out", nefName, "--manifest", manifestName)
// Check that it is possible to invoke before deploy.
// This doesn't make much sense, because every method has an offset
// which is contained in the manifest. This should be either removed or refactored.
e.Run(t, "neo-go", "contract", "testinvokescript",
"--rpc-endpoint", "http://"+e.RPC.Addr,
"--in", nefName, "--", util.Uint160{1, 2, 3}.StringLE())
e.Run(t, "neo-go", "contract", "testinvokescript",
"--rpc-endpoint", "http://"+e.RPC.Addr,
"--in", nefName, "--", address.Uint160ToString(util.Uint160{1, 2, 3}))
tmp := t.TempDir()
configPath := filepath.Join(tmp, "config.yaml")
cfg := config.Wallet{
Path: validatorWallet,
Password: "one",
Path: testcli.ValidatorWallet,
Password: testcli.ValidatorPass,
}
yml, err := yaml.Marshal(cfg)
require.NoError(t, err)
require.NoError(t, os.WriteFile(configPath, yml, 0666))
e.Run(t, "neo-go", "contract", "deploy",
"--rpc-endpoint", "http://"+e.RPC.Addr, "--force",
"--wallet-config", configPath, "--address", validatorAddr,
"--rpc-endpoint", "http://"+e.RPC.Addresses()[0], "--force",
"--wallet-config", configPath, "--address", testcli.ValidatorAddr,
"--in", nefName, "--manifest", manifestName)
e.checkTxPersisted(t, "Sent invocation transaction ")
e.CheckTxPersisted(t, "Sent invocation transaction ")
line, err := e.Out.ReadString('\n')
require.NoError(t, err)
line = strings.TrimSpace(strings.TrimPrefix(line, "Contract: "))
@ -656,13 +728,13 @@ func TestComlileAndInvokeFunction(t *testing.T) {
"--manifest", manifestName)
e.Run(t, "neo-go", "contract", "calc-hash",
"--sender", validatorAddr, "--in", nefName,
"--sender", testcli.ValidatorAddr, "--in", nefName,
"--manifest", manifestName)
e.checkNextLine(t, h.StringLE())
e.CheckNextLine(t, h.StringLE())
})
cmd := []string{"neo-go", "contract", "testinvokefunction",
"--rpc-endpoint", "http://" + e.RPC.Addr}
"--rpc-endpoint", "http://" + e.RPC.Addresses()[0]}
t.Run("missing hash", func(t *testing.T) {
e.RunWithError(t, cmd...)
})
@ -689,18 +761,21 @@ func TestComlileAndInvokeFunction(t *testing.T) {
e.Run(t, cmd...)
res := new(result.Invoke)
require.NoError(t, json.Unmarshal(e.Out.Bytes(), res))
require.Equal(t, vmstate.Halt.String(), res.State, res.FaultException)
require.Len(t, res.Stack, 1)
require.Equal(t, []byte("on create|sub create"), res.Stack[0].Value())
checkGetValueOut := func(str string) {
res := new(result.Invoke)
require.NoError(t, json.Unmarshal(e.Out.Bytes(), res))
require.Equal(t, vmstate.Halt.String(), res.State, res.FaultException)
require.Len(t, res.Stack, 1)
require.Equal(t, []byte(str), res.Stack[0].Value())
}
checkGetValueOut("on create|sub create")
// deploy verification contract
hVerify := deployVerifyContract(t, e)
t.Run("real invoke", func(t *testing.T) {
cmd := []string{"neo-go", "contract", "invokefunction",
"--rpc-endpoint", "http://" + e.RPC.Addr}
"--rpc-endpoint", "http://" + e.RPC.Addresses()[0]}
t.Run("missing wallet", func(t *testing.T) {
cmd := append(cmd, h.StringLE(), "getValue")
e.RunWithError(t, cmd...)
@ -720,28 +795,28 @@ func TestComlileAndInvokeFunction(t *testing.T) {
e.RunWithError(t, cmd...)
})
t.Run("non-existent address", func(t *testing.T) {
cmd := append(cmd, "--wallet", validatorWallet,
cmd := append(cmd, "--wallet", testcli.ValidatorWallet,
"--address", random.Uint160().StringLE(),
h.StringLE(), "getValue")
e.RunWithError(t, cmd...)
})
t.Run("invalid password", func(t *testing.T) {
e.In.WriteString("invalid_password\r")
cmd := append(cmd, "--wallet", validatorWallet,
cmd := append(cmd, "--wallet", testcli.ValidatorWallet,
h.StringLE(), "getValue")
e.RunWithError(t, cmd...)
})
t.Run("good: default address", func(t *testing.T) {
e.In.WriteString("one\r")
e.In.WriteString("y\r")
e.Run(t, append(cmd, "--wallet", validatorWallet, h.StringLE(), "getValue")...)
e.Run(t, append(cmd, "--wallet", testcli.ValidatorWallet, h.StringLE(), "getValue")...)
})
t.Run("good: from wallet config", func(t *testing.T) {
e.In.WriteString("y\r")
e.Run(t, append(cmd, "--wallet-config", configPath, h.StringLE(), "getValue")...)
})
cmd = append(cmd, "--wallet", validatorWallet, "--address", validatorAddr)
cmd = append(cmd, "--wallet", testcli.ValidatorWallet, "--address", testcli.ValidatorAddr)
t.Run("cancelled", func(t *testing.T) {
e.In.WriteString("one\r")
e.In.WriteString("n\r")
@ -766,7 +841,13 @@ func TestComlileAndInvokeFunction(t *testing.T) {
e.In.WriteString("one\r")
e.In.WriteString("y\r")
e.Run(t, append(cmd, h.StringLE(), "getValue",
"--", validatorAddr, hVerify.StringLE())...)
"--", testcli.ValidatorAddr, hVerify.StringLE())...)
})
t.Run("with await", func(t *testing.T) {
e.In.WriteString("one\r")
e.Run(t, append(cmd, "--force", "--await", h.StringLE(), "getValue")...)
e.CheckAwaitableTxPersisted(t)
})
})
@ -774,9 +855,9 @@ func TestComlileAndInvokeFunction(t *testing.T) {
txout := filepath.Join(tmpDir, "test_contract_tx.json")
cmd = []string{"neo-go", "contract", "invokefunction",
"--rpc-endpoint", "http://" + e.RPC.Addr,
"--rpc-endpoint", "http://" + e.RPC.Addresses()[0],
"--out", txout,
"--wallet", validatorWallet, "--address", validatorAddr,
"--wallet", testcli.ValidatorWallet, "--address", testcli.ValidatorAddr,
}
t.Run("without cosigner", func(t *testing.T) {
@ -787,22 +868,22 @@ func TestComlileAndInvokeFunction(t *testing.T) {
t.Run("with cosigner", func(t *testing.T) {
t.Run("cosigner is sender (none)", func(t *testing.T) {
e.In.WriteString("one\r")
e.RunWithError(t, append(cmd, h.StringLE(), "checkSenderWitness", "--", validatorAddr+":None")...)
e.RunWithError(t, append(cmd, h.StringLE(), "checkSenderWitness", "--", testcli.ValidatorAddr+":None")...)
})
t.Run("cosigner is sender (customcontract)", func(t *testing.T) {
e.In.WriteString("one\r")
e.Run(t, append(cmd, h.StringLE(), "checkSenderWitness", "--", validatorAddr+":CustomContracts:"+h.StringLE())...)
e.Run(t, append(cmd, h.StringLE(), "checkSenderWitness", "--", testcli.ValidatorAddr+":CustomContracts:"+h.StringLE())...)
})
t.Run("cosigner is sender (global)", func(t *testing.T) {
e.In.WriteString("one\r")
e.Run(t, append(cmd, h.StringLE(), "checkSenderWitness", "--", validatorAddr+":Global")...)
e.Run(t, append(cmd, h.StringLE(), "checkSenderWitness", "--", testcli.ValidatorAddr+":Global")...)
})
acc, err := wallet.NewAccount()
require.NoError(t, err)
pk, err := keys.NewPrivateKey()
require.NoError(t, err)
err = acc.ConvertMultisig(2, keys.PublicKeys{acc.PrivateKey().PublicKey(), pk.PublicKey()})
err = acc.ConvertMultisig(2, keys.PublicKeys{acc.PublicKey(), pk.PublicKey()})
require.NoError(t, err)
t.Run("cosigner is multisig account", func(t *testing.T) {
@ -813,7 +894,7 @@ func TestComlileAndInvokeFunction(t *testing.T) {
t.Run("good", func(t *testing.T) {
e.In.WriteString("one\r")
e.Run(t, append(cmd, hVerify.StringLE(), "verify", "--", multisigAddr)...)
e.Run(t, append(cmd, hVerify.StringLE(), "verify", "--", testcli.MultisigAddr)...)
})
})
@ -833,7 +914,7 @@ func TestComlileAndInvokeFunction(t *testing.T) {
t.Run("test Storage.Find", func(t *testing.T) {
cmd := []string{"neo-go", "contract", "testinvokefunction",
"--rpc-endpoint", "http://" + e.RPC.Addr,
"--rpc-endpoint", "http://" + e.RPC.Addresses()[0],
h.StringLE(), "testFind"}
t.Run("keys only", func(t *testing.T) {
@ -866,6 +947,12 @@ func TestComlileAndInvokeFunction(t *testing.T) {
})
})
var (
hashBeforeUpdate util.Uint256
indexBeforeUpdate uint32
indexAfterUpdate uint32
stateBeforeUpdate util.Uint256
)
t.Run("Update", func(t *testing.T) {
nefName := filepath.Join(tmpDir, "updated.nef")
manifestName := filepath.Join(tmpDir, "updated.manifest.json")
@ -884,35 +971,61 @@ func TestComlileAndInvokeFunction(t *testing.T) {
rawManifest, err := os.ReadFile(manifestName)
require.NoError(t, err)
indexBeforeUpdate = e.Chain.BlockHeight()
hashBeforeUpdate = e.Chain.CurrentHeaderHash()
mptBeforeUpdate, err := e.Chain.GetStateRoot(indexBeforeUpdate)
require.NoError(t, err)
stateBeforeUpdate = mptBeforeUpdate.Root
e.In.WriteString("one\r")
e.Run(t, "neo-go", "contract", "invokefunction",
"--rpc-endpoint", "http://"+e.RPC.Addr,
"--wallet", validatorWallet, "--address", validatorAddr,
"--rpc-endpoint", "http://"+e.RPC.Addresses()[0],
"--wallet", testcli.ValidatorWallet, "--address", testcli.ValidatorAddr,
"--force",
h.StringLE(), "update",
"bytes:"+hex.EncodeToString(rawNef),
"bytes:"+hex.EncodeToString(rawManifest),
)
e.checkTxPersisted(t, "Sent invocation transaction ")
e.CheckTxPersisted(t, "Sent invocation transaction ")
indexAfterUpdate = e.Chain.BlockHeight()
e.In.WriteString("one\r")
e.Run(t, "neo-go", "contract", "testinvokefunction",
"--rpc-endpoint", "http://"+e.RPC.Addr,
"--rpc-endpoint", "http://"+e.RPC.Addresses()[0],
h.StringLE(), "getValue")
res := new(result.Invoke)
require.NoError(t, json.Unmarshal(e.Out.Bytes(), res))
require.Equal(t, vmstate.Halt.String(), res.State)
require.Len(t, res.Stack, 1)
require.Equal(t, []byte("on update|sub update"), res.Stack[0].Value())
checkGetValueOut("on update|sub update")
})
t.Run("historic", func(t *testing.T) {
t.Run("bad ref", func(t *testing.T) {
e.RunWithError(t, "neo-go", "contract", "testinvokefunction",
"--rpc-endpoint", "http://"+e.RPC.Addresses()[0],
"--historic", "bad",
h.StringLE(), "getValue")
})
for name, ref := range map[string]string{
"by index": strconv.FormatUint(uint64(indexBeforeUpdate), 10),
"by block hash": hashBeforeUpdate.StringLE(),
"by state hash": stateBeforeUpdate.StringLE(),
} {
t.Run(name, func(t *testing.T) {
e.Run(t, "neo-go", "contract", "testinvokefunction",
"--rpc-endpoint", "http://"+e.RPC.Addresses()[0],
"--historic", ref,
h.StringLE(), "getValue")
})
checkGetValueOut("on create|sub create")
}
t.Run("updated historic", func(t *testing.T) {
e.Run(t, "neo-go", "contract", "testinvokefunction",
"--rpc-endpoint", "http://"+e.RPC.Addresses()[0],
"--historic", strconv.FormatUint(uint64(indexAfterUpdate), 10),
h.StringLE(), "getValue")
checkGetValueOut("on update|sub update")
})
})
}
func TestContractInspect(t *testing.T) {
e := newExecutor(t, false)
// For proper nef generation.
config.Version = "0.90.0-test"
e := testcli.NewExecutor(t, false)
const srcPath = "testdata/deploy/main.go"
tmpDir := t.TempDir()
@ -943,14 +1056,11 @@ func TestContractInspect(t *testing.T) {
func TestCompileExamples(t *testing.T) {
tmpDir := t.TempDir()
const examplePath = "../examples"
const examplePath = "../../examples"
infos, err := os.ReadDir(examplePath)
require.NoError(t, err)
// For proper nef generation.
config.Version = "0.90.0-test"
e := newExecutor(t, false)
e := testcli.NewExecutor(t, false)
for _, info := range infos {
if !info.IsDir() {
@ -958,6 +1068,10 @@ func TestCompileExamples(t *testing.T) {
// there are also a couple of files inside the `/examples` which doesn't need to be compiled
continue
}
if info.Name() == "zkp" {
// A set of special ZKP-related examples, they have their own tests.
continue
}
t.Run(info.Name(), func(t *testing.T) {
infos, err := os.ReadDir(filepath.Join(examplePath, info.Name()))
require.NoError(t, err)
@ -965,6 +1079,9 @@ func TestCompileExamples(t *testing.T) {
outF := filepath.Join(tmpDir, info.Name()+".nef")
manifestF := filepath.Join(tmpDir, info.Name()+".manifest.json")
bindingF := filepath.Join(tmpDir, info.Name()+".binding.yml")
wrapperF := filepath.Join(tmpDir, info.Name()+".go")
rpcWrapperF := filepath.Join(tmpDir, info.Name()+".rpc.go")
cfgName := filterFilename(infos, ".yml")
opts := []string{
@ -973,6 +1090,7 @@ func TestCompileExamples(t *testing.T) {
"--out", outF,
"--manifest", manifestF,
"--config", filepath.Join(examplePath, info.Name(), cfgName),
"--bindings", bindingF,
}
e.Run(t, opts...)
@ -991,6 +1109,16 @@ func TestCompileExamples(t *testing.T) {
require.NotNil(t, m.ABI.GetMethod("put", 1))
require.NotNil(t, m.ABI.GetMethod("put", 2))
}
e.Run(t, "neo-go", "contract", "generate-wrapper",
"--manifest", manifestF,
"--config", bindingF,
"--out", wrapperF,
"--hash", "0x00112233445566778899aabbccddeeff00112233")
e.Run(t, "neo-go", "contract", "generate-rpcwrapper",
"--manifest", manifestF,
"--config", bindingF,
"--out", rpcWrapperF,
"--hash", "0x00112233445566778899aabbccddeeff00112233")
})
}
@ -1020,3 +1148,27 @@ func filterFilename(infos []os.DirEntry, ext string) string {
}
return ""
}
func TestContractCompile_NEFSizeCheck(t *testing.T) {
tmpDir := t.TempDir()
e := testcli.NewExecutor(t, false)
src := `package nefconstraints
var data = "%s"
func Main() string {
return data
}`
data := make([]byte, stackitem.MaxSize-10)
for i := range data {
data[i] = byte('a')
}
in := filepath.Join(tmpDir, "main.go")
cfg := filepath.Join(tmpDir, "main.yml")
require.NoError(t, os.WriteFile(cfg, []byte("name: main"), os.ModePerm))
require.NoError(t, os.WriteFile(in, []byte(fmt.Sprintf(src, data)), os.ModePerm))
e.RunWithError(t, "neo-go", "contract", "compile", "--in", in)
require.NoFileExists(t, filepath.Join(tmpDir, "main.nef"))
}

View file

@ -7,45 +7,77 @@ import (
"github.com/nspcc-dev/neo-go/cli/cmdargs"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/binding"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/rpcbinding"
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/urfave/cli"
"gopkg.in/yaml.v3"
)
var generateWrapperCmd = cli.Command{
Name: "generate-wrapper",
Usage: "generate wrapper to use in other contracts",
UsageText: "neo-go contract generate-wrapper --manifest <file.json> --out <file.go> --hash <hash>",
Description: ``,
Action: contractGenerateWrapper,
Flags: []cli.Flag{
cli.StringFlag{
Name: "config, c",
Usage: "Configuration file to use",
},
cli.StringFlag{
Name: "manifest, m",
Usage: "Read contract manifest (*.manifest.json) file",
},
cli.StringFlag{
Name: "out, o",
Usage: "Output of the compiled contract",
},
cli.StringFlag{
Name: "hash",
Usage: "Smart-contract hash",
},
var generatorFlags = []cli.Flag{
cli.StringFlag{
Name: "config, c",
Usage: "Configuration file to use",
},
cli.StringFlag{
Name: "manifest, m",
Required: true,
Usage: "Read contract manifest (*.manifest.json) file",
},
cli.StringFlag{
Name: "out, o",
Required: true,
Usage: "Output of the compiled wrapper",
},
cli.StringFlag{
Name: "hash",
Usage: "Smart-contract hash. If not passed, the wrapper will be designed for dynamic hash usage",
},
}
// contractGenerateWrapper deploys contract.
var generateWrapperCmd = cli.Command{
Name: "generate-wrapper",
Usage: "generate wrapper to use in other contracts",
UsageText: "neo-go contract generate-wrapper --manifest <file.json> --out <file.go> [--hash <hash>] [--config <config>]",
Description: `Generates a Go wrapper to use it in other smart contracts. If the
--hash flag is provided, CALLT instruction is used for the target contract
invocation as an optimization of the wrapper contract code. If omitted, the
generated wrapper will be designed for dynamic hash usage, allowing
the hash to be specified at runtime.
`,
Action: contractGenerateWrapper,
Flags: generatorFlags,
}
var generateRPCWrapperCmd = cli.Command{
Name: "generate-rpcwrapper",
Usage: "generate RPC wrapper to use for data reads",
UsageText: "neo-go contract generate-rpcwrapper --manifest <file.json> --out <file.go> [--hash <hash>] [--config <config>]",
Action: contractGenerateRPCWrapper,
Flags: generatorFlags,
}
func contractGenerateWrapper(ctx *cli.Context) error {
return contractGenerateSomething(ctx, binding.Generate)
}
func contractGenerateRPCWrapper(ctx *cli.Context) error {
return contractGenerateSomething(ctx, rpcbinding.Generate)
}
// contractGenerateSomething reads generator parameters and calls the given callback.
func contractGenerateSomething(ctx *cli.Context, cb func(binding.Config) error) error {
if err := cmdargs.EnsureNone(ctx); err != nil {
return err
}
h, err := util.Uint160DecodeStringLE(strings.TrimPrefix(ctx.String("hash"), "0x"))
if err != nil {
return cli.NewExitError(fmt.Errorf("invalid contract hash: %w", err), 1)
var (
h util.Uint160
err error
)
if hStr := ctx.String("hash"); len(hStr) != 0 {
h, err = util.Uint160DecodeStringLE(strings.TrimPrefix(hStr, "0x"))
if err != nil {
return cli.NewExitError(fmt.Errorf("invalid contract hash: %w", err), 1)
}
}
m, _, err := readManifest(ctx.String("manifest"), h)
if err != nil {
@ -74,7 +106,7 @@ func contractGenerateWrapper(ctx *cli.Context) error {
cfg.Output = f
err = binding.Generate(cfg)
err = cb(cfg)
if err != nil {
return cli.NewExitError(fmt.Errorf("error during generation: %w", err), 1)
}

View file

@ -1,7 +1,9 @@
package smartcontract
import (
"bytes"
"encoding/json"
"fmt"
"os"
"path/filepath"
"strings"
@ -44,6 +46,15 @@ func TestGenerate(t *testing.T) {
ReturnType: smartcontract.IntegerType,
Safe: true,
},
manifest.Method{
Name: "zum",
Parameters: []manifest.Parameter{
manifest.NewParameter("type", smartcontract.IntegerType),
manifest.NewParameter("typev", smartcontract.IntegerType),
manifest.NewParameter("func", smartcontract.IntegerType),
},
ReturnType: smartcontract.IntegerType,
},
manifest.Method{
Name: "justExecute",
Parameters: []manifest.Parameter{
@ -140,7 +151,9 @@ callflags:
"--hash", h.StringLE(),
}))
const expected = `// Package wrapper contains wrappers for MyContract contract.
const expected = `// Code generated by neo-go contract generate-wrapper --manifest <file.json> --out <file.go> [--hash <hash>] [--config <config>]; DO NOT EDIT.
// Package wrapper contains wrappers for MyContract contract.
package wrapper
import (
@ -161,8 +174,8 @@ func Sum(first int, second int) int {
return neogointernal.CallWithToken(Hash, "sum", int(contract.All), first, second).(int)
}
// Sum_3 invokes ` + "`sum`" + ` method of contract.
func Sum_3(first int, second int, third int) int {
// Sum2 invokes ` + "`sum`" + ` method of contract.
func Sum2(first int, second int, third int) int {
return neogointernal.CallWithToken(Hash, "sum", int(contract.All), first, second, third).(int)
}
@ -171,8 +184,13 @@ func Sum3() int {
return neogointernal.CallWithToken(Hash, "sum3", int(contract.ReadOnly)).(int)
}
// Zum invokes ` + "`zum`" + ` method of contract.
func Zum(typev int, typev_ int, funcv int) int {
return neogointernal.CallWithToken(Hash, "zum", int(contract.All), typev, typev_, funcv).(int)
}
// JustExecute invokes ` + "`justExecute`" + ` method of contract.
func JustExecute(arr []interface{}) {
func JustExecute(arr []any) {
neogointernal.CallWithTokenNoRet(Hash, "justExecute", int(contract.All), arr)
}
@ -182,7 +200,7 @@ func GetPublicKey() interop.PublicKey {
}
// OtherTypes invokes ` + "`otherTypes`" + ` method of contract.
func OtherTypes(ctr interop.Hash160, tx interop.Hash256, sig interop.Signature, data interface{}) bool {
func OtherTypes(ctr interop.Hash160, tx interop.Hash256, sig interop.Signature, data any) bool {
return neogointernal.CallWithToken(Hash, "otherTypes", int(contract.All), ctr, tx, sig, data).(bool)
}
@ -197,8 +215,8 @@ func GetFromMap(intMap map[string]int, indices []string) []int {
}
// DoSomething invokes ` + "`doSomething`" + ` method of contract.
func DoSomething(bytes []byte, str string) interface{} {
return neogointernal.CallWithToken(Hash, "doSomething", int(contract.ReadStates), bytes, str).(interface{})
func DoSomething(bytes []byte, str string) any {
return neogointernal.CallWithToken(Hash, "doSomething", int(contract.ReadStates), bytes, str).(any)
}
// GetBlockWrapper invokes ` + "`getBlockWrapper`" + ` method of contract.
@ -215,6 +233,99 @@ func MyFunc(in map[int]mycontract.Input) []mycontract.Output {
data, err := os.ReadFile(outFile)
require.NoError(t, err)
require.Equal(t, expected, string(data))
require.NoError(t, app.Run([]string{"", "generate-wrapper",
"--manifest", manifestFile,
"--config", cfgPath,
"--out", outFile,
}))
expectedWithDynamicHash := `// Code generated by neo-go contract generate-wrapper --manifest <file.json> --out <file.go> [--hash <hash>] [--config <config>]; DO NOT EDIT.
// Package wrapper contains wrappers for MyContract contract.
package wrapper
import (
"github.com/heyitsme/mycontract"
"github.com/nspcc-dev/neo-go/pkg/interop"
"github.com/nspcc-dev/neo-go/pkg/interop/contract"
"github.com/nspcc-dev/neo-go/pkg/interop/iterator"
"github.com/nspcc-dev/neo-go/pkg/interop/native/ledger"
"github.com/nspcc-dev/neo-go/pkg/interop/storage"
)
// Contract represents the MyContract smart contract.
type Contract struct {
Hash interop.Hash160
}
// NewContract returns a new Contract instance with the specified hash.
func NewContract(hash interop.Hash160) Contract {
return Contract{Hash: hash}
}
// Sum invokes ` + "`sum`" + ` method of contract.
func (c Contract) Sum(first int, second int) int {
return contract.Call(c.Hash, "sum", contract.All, first, second).(int)
}
// Sum2 invokes ` + "`sum`" + ` method of contract.
func (c Contract) Sum2(first int, second int, third int) int {
return contract.Call(c.Hash, "sum", contract.All, first, second, third).(int)
}
// Sum3 invokes ` + "`sum3`" + ` method of contract.
func (c Contract) Sum3() int {
return contract.Call(c.Hash, "sum3", contract.ReadOnly).(int)
}
// Zum invokes ` + "`zum`" + ` method of contract.
func (c Contract) Zum(typev int, typev_ int, funcv int) int {
return contract.Call(c.Hash, "zum", contract.All, typev, typev_, funcv).(int)
}
// JustExecute invokes ` + "`justExecute`" + ` method of contract.
func (c Contract) JustExecute(arr []any) {
contract.Call(c.Hash, "justExecute", contract.All, arr)
}
// GetPublicKey invokes ` + "`getPublicKey`" + ` method of contract.
func (c Contract) GetPublicKey() interop.PublicKey {
return contract.Call(c.Hash, "getPublicKey", contract.All).(interop.PublicKey)
}
// OtherTypes invokes ` + "`otherTypes`" + ` method of contract.
func (c Contract) OtherTypes(ctr interop.Hash160, tx interop.Hash256, sig interop.Signature, data any) bool {
return contract.Call(c.Hash, "otherTypes", contract.All, ctr, tx, sig, data).(bool)
}
// SearchStorage invokes ` + "`searchStorage`" + ` method of contract.
func (c Contract) SearchStorage(ctx storage.Context) iterator.Iterator {
return contract.Call(c.Hash, "searchStorage", contract.All, ctx).(iterator.Iterator)
}
// GetFromMap invokes ` + "`getFromMap`" + ` method of contract.
func (c Contract) GetFromMap(intMap map[string]int, indices []string) []int {
return contract.Call(c.Hash, "getFromMap", contract.All, intMap, indices).([]int)
}
// DoSomething invokes ` + "`doSomething`" + ` method of contract.
func (c Contract) DoSomething(bytes []byte, str string) any {
return contract.Call(c.Hash, "doSomething", contract.ReadStates, bytes, str).(any)
}
// GetBlockWrapper invokes ` + "`getBlockWrapper`" + ` method of contract.
func (c Contract) GetBlockWrapper() ledger.Block {
return contract.Call(c.Hash, "getBlockWrapper", contract.All).(ledger.Block)
}
// MyFunc invokes ` + "`myFunc`" + ` method of contract.
func (c Contract) MyFunc(in map[int]mycontract.Input) []mycontract.Output {
return contract.Call(c.Hash, "myFunc", contract.All, in).([]mycontract.Output)
}
`
data, err = os.ReadFile(outFile)
require.NoError(t, err)
require.Equal(t, expectedWithDynamicHash, string(data))
}
func TestGenerateValidPackageName(t *testing.T) {
@ -224,6 +335,7 @@ func TestGenerateValidPackageName(t *testing.T) {
Name: "get",
Parameters: []manifest.Parameter{},
ReturnType: smartcontract.IntegerType,
Safe: true,
},
)
@ -239,7 +351,7 @@ func TestGenerateValidPackageName(t *testing.T) {
0xCA, 0xFE, 0xBA, 0xBE, 0xDE, 0xAD, 0xBE, 0xEF, 0x03, 0x04,
}
app := cli.NewApp()
app.Commands = []cli.Command{generateWrapperCmd}
app.Commands = []cli.Command{generateWrapperCmd, generateRPCWrapperCmd}
require.NoError(t, app.Run([]string{"", "generate-wrapper",
"--manifest", manifestFile,
"--out", outFile,
@ -248,7 +360,9 @@ func TestGenerateValidPackageName(t *testing.T) {
data, err := os.ReadFile(outFile)
require.NoError(t, err)
require.Equal(t, `// Package myspacecontract contains wrappers for My space contract contract.
require.Equal(t, `// Code generated by neo-go contract generate-wrapper --manifest <file.json> --out <file.go> [--hash <hash>] [--config <config>]; DO NOT EDIT.
// Package myspacecontract contains wrappers for My space contract contract.
package myspacecontract
import (
@ -261,9 +375,176 @@ const Hash = "\x04\x08\x15\x16\x23\x42\x43\x44\x00\x01\xca\xfe\xba\xbe\xde\xad\x
// Get invokes `+"`get`"+` method of contract.
func Get() int {
return neogointernal.CallWithToken(Hash, "get", int(contract.All)).(int)
return neogointernal.CallWithToken(Hash, "get", int(contract.ReadOnly)).(int)
}
`, string(data))
require.NoError(t, app.Run([]string{"", "generate-rpcwrapper",
"--manifest", manifestFile,
"--out", outFile,
"--hash", "0x" + h.StringLE(),
}))
data, err = os.ReadFile(outFile)
require.NoError(t, err)
require.Equal(t, `// Code generated by neo-go contract generate-rpcwrapper --manifest <file.json> --out <file.go> [--hash <hash>] [--config <config>]; DO NOT EDIT.
// Package myspacecontract contains RPC wrappers for My space contract contract.
package myspacecontract
import (
"github.com/nspcc-dev/neo-go/pkg/neorpc/result"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap"
"github.com/nspcc-dev/neo-go/pkg/util"
"math/big"
)
// Hash contains contract hash.
var Hash = util.Uint160{0x4, 0x8, 0x15, 0x16, 0x23, 0x42, 0x43, 0x44, 0x0, 0x1, 0xca, 0xfe, 0xba, 0xbe, 0xde, 0xad, 0xbe, 0xef, 0x3, 0x4}
// Invoker is used by ContractReader to call various safe methods.
type Invoker interface {
Call(contract util.Uint160, operation string, params ...any) (*result.Invoke, error)
}
// ContractReader implements safe contract methods.
type ContractReader struct {
invoker Invoker
hash util.Uint160
}
// NewReader creates an instance of ContractReader using Hash and the given Invoker.
func NewReader(invoker Invoker) *ContractReader {
var hash = Hash
return &ContractReader{invoker, hash}
}
// Get invokes `+"`get`"+` method of contract.
func (c *ContractReader) Get() (*big.Int, error) {
return unwrap.BigInt(c.invoker.Call(c.hash, "get"))
}
`, string(data))
}
// rewriteExpectedOutputs denotes whether expected output files should be rewritten
// for TestGenerateRPCBindings and TestAssistedRPCBindings.
const rewriteExpectedOutputs = false
func TestGenerateRPCBindings(t *testing.T) {
tmpDir := t.TempDir()
app := cli.NewApp()
app.Commands = []cli.Command{generateWrapperCmd, generateRPCWrapperCmd}
var checkBinding = func(manifest string, hash string, good string) {
t.Run(manifest, func(t *testing.T) {
outFile := filepath.Join(tmpDir, "out.go")
require.NoError(t, app.Run([]string{"", "generate-rpcwrapper",
"--manifest", manifest,
"--out", outFile,
"--hash", hash,
}))
data, err := os.ReadFile(outFile)
require.NoError(t, err)
data = bytes.ReplaceAll(data, []byte("\r"), []byte{}) // Windows.
if rewriteExpectedOutputs {
require.NoError(t, os.WriteFile(good, data, os.ModePerm))
} else {
expected, err := os.ReadFile(good)
require.NoError(t, err)
expected = bytes.ReplaceAll(expected, []byte("\r"), []byte{}) // Windows.
require.Equal(t, string(expected), string(data))
}
})
}
checkBinding(filepath.Join("testdata", "nex", "nex.manifest.json"),
"0xa2a67f09e8cf22c6bfd5cea24adc0f4bf0a11aa8",
filepath.Join("testdata", "nex", "nex.go"))
checkBinding(filepath.Join("testdata", "nameservice", "nns.manifest.json"),
"0x50ac1c37690cc2cfc594472833cf57505d5f46de",
filepath.Join("testdata", "nameservice", "nns.go"))
checkBinding(filepath.Join("testdata", "gas", "gas.manifest.json"),
"0xd2a4cff31913016155e38e474a2c06d08be276cf",
filepath.Join("testdata", "gas", "gas.go"))
checkBinding(filepath.Join("testdata", "verifyrpc", "verify.manifest.json"),
"0x00112233445566778899aabbccddeeff00112233",
filepath.Join("testdata", "verifyrpc", "verify.go"))
checkBinding(filepath.Join("testdata", "nonepiter", "iter.manifest.json"),
"0x00112233445566778899aabbccddeeff00112233",
filepath.Join("testdata", "nonepiter", "iter.go"))
require.False(t, rewriteExpectedOutputs)
}
func TestAssistedRPCBindings(t *testing.T) {
tmpDir := t.TempDir()
app := cli.NewApp()
app.Commands = NewCommands()
var checkBinding = func(source string, hasDefinedHash bool, guessEventTypes bool, suffix ...string) {
testName := source
if len(suffix) != 0 {
testName += suffix[0]
}
testName += fmt.Sprintf(", predefined hash: %t", hasDefinedHash)
t.Run(testName, func(t *testing.T) {
outFile := filepath.Join(tmpDir, "out.go")
configFile := filepath.Join(source, "config.yml")
expectedFile := filepath.Join(source, "rpcbindings.out")
if len(suffix) != 0 {
configFile = filepath.Join(source, "config"+suffix[0]+".yml")
expectedFile = filepath.Join(source, "rpcbindings"+suffix[0]+".out")
} else if !hasDefinedHash {
expectedFile = filepath.Join(source, "rpcbindings_dynamic_hash.out")
}
manifestF := filepath.Join(tmpDir, "manifest.json")
bindingF := filepath.Join(tmpDir, "binding.yml")
nefF := filepath.Join(tmpDir, "out.nef")
cmd := []string{"", "contract", "compile",
"--in", source,
"--config", configFile,
"--manifest", manifestF,
"--bindings", bindingF,
"--out", nefF,
}
if guessEventTypes {
cmd = append(cmd, "--guess-eventtypes")
}
require.NoError(t, app.Run(cmd))
cmds := []string{"", "contract", "generate-rpcwrapper",
"--config", bindingF,
"--manifest", manifestF,
"--out", outFile,
}
if hasDefinedHash {
cmds = append(cmds, "--hash", "0x00112233445566778899aabbccddeeff00112233")
}
require.NoError(t, app.Run(cmds))
data, err := os.ReadFile(outFile)
require.NoError(t, err)
data = bytes.ReplaceAll(data, []byte("\r"), []byte{}) // Windows.
if rewriteExpectedOutputs {
require.NoError(t, os.WriteFile(expectedFile, data, os.ModePerm))
} else {
expected, err := os.ReadFile(expectedFile)
require.NoError(t, err)
expected = bytes.ReplaceAll(expected, []byte("\r"), []byte{}) // Windows.
require.Equal(t, string(expected), string(data))
}
})
}
for _, hasDefinedHash := range []bool{true, false} {
checkBinding(filepath.Join("testdata", "rpcbindings", "types"), hasDefinedHash, false)
checkBinding(filepath.Join("testdata", "rpcbindings", "structs"), hasDefinedHash, false)
}
checkBinding(filepath.Join("testdata", "rpcbindings", "notifications"), true, false)
checkBinding(filepath.Join("testdata", "rpcbindings", "notifications"), true, false, "_extended")
checkBinding(filepath.Join("testdata", "rpcbindings", "notifications"), true, true, "_guessed")
require.False(t, rewriteExpectedOutputs)
}
func TestGenerate_Errors(t *testing.T) {
@ -277,18 +558,18 @@ func TestGenerate_Errors(t *testing.T) {
require.True(t, strings.Contains(err.Error(), msg), "got: %v", err)
}
t.Run("invalid hash", func(t *testing.T) {
checkError(t, "invalid contract hash", "--hash", "xxx")
checkError(t, "invalid contract hash", "--hash", "xxx", "--manifest", "yyy", "--out", "zzz")
})
t.Run("missing manifest argument", func(t *testing.T) {
checkError(t, errNoManifestFile.Error(), "--hash", util.Uint160{}.StringLE())
checkError(t, "Required flag \"manifest\" not set", "--hash", util.Uint160{}.StringLE(), "--out", "zzz")
})
t.Run("missing manifest file", func(t *testing.T) {
checkError(t, "can't read contract manifest", "--manifest", "notexists", "--hash", util.Uint160{}.StringLE())
checkError(t, "can't read contract manifest", "--manifest", "notexists", "--hash", util.Uint160{}.StringLE(), "--out", "zzz")
})
t.Run("empty manifest", func(t *testing.T) {
manifestFile := filepath.Join(t.TempDir(), "invalid.json")
require.NoError(t, os.WriteFile(manifestFile, []byte("[]"), os.ModePerm))
checkError(t, "json: cannot unmarshal array into Go value of type manifest.Manifest", "--manifest", manifestFile, "--hash", util.Uint160{}.StringLE())
checkError(t, "json: cannot unmarshal array into Go value of type manifest.Manifest", "--manifest", manifestFile, "--hash", util.Uint160{}.StringLE(), "--out", "zzz")
})
t.Run("invalid manifest", func(t *testing.T) {
manifestFile := filepath.Join(t.TempDir(), "invalid.json")
@ -296,7 +577,7 @@ func TestGenerate_Errors(t *testing.T) {
rawManifest, err := json.Marshal(m)
require.NoError(t, err)
require.NoError(t, os.WriteFile(manifestFile, rawManifest, os.ModePerm))
checkError(t, "ABI: no methods", "--manifest", manifestFile, "--hash", util.Uint160{}.StringLE())
checkError(t, "ABI: no methods", "--manifest", manifestFile, "--hash", util.Uint160{}.StringLE(), "--out", "zzz")
})
manifestFile := filepath.Join(t.TempDir(), "manifest.json")
@ -314,7 +595,7 @@ func TestGenerate_Errors(t *testing.T) {
t.Run("missing config", func(t *testing.T) {
checkError(t, "can't read config file",
"--manifest", manifestFile, "--hash", util.Uint160{}.StringLE(),
"--config", filepath.Join(t.TempDir(), "not.exists.yml"))
"--config", filepath.Join(t.TempDir(), "not.exists.yml"), "--out", "zzz")
})
t.Run("invalid config", func(t *testing.T) {
rawCfg := `package: wrapper
@ -326,6 +607,106 @@ callflags:
checkError(t, "can't parse config file",
"--manifest", manifestFile, "--hash", util.Uint160{}.StringLE(),
"--config", cfgPath)
"--config", cfgPath, "--out", "zzz")
})
}
func TestCompile_GuessEventTypes(t *testing.T) {
app := cli.NewApp()
app.Commands = NewCommands()
app.ExitErrHandler = func(*cli.Context, error) {}
checkError := func(t *testing.T, msg string, args ...string) {
// cli.ExitError doesn't implement wraping properly, so we check for an error message.
err := app.Run(args)
require.Error(t, err)
require.True(t, strings.Contains(err.Error(), msg), "got: %v", err)
}
check := func(t *testing.T, source string, expectedErrText string) {
tmpDir := t.TempDir()
configFile := filepath.Join(source, "invalid.yml")
manifestF := filepath.Join(tmpDir, "invalid.manifest.json")
bindingF := filepath.Join(tmpDir, "invalid.binding.yml")
nefF := filepath.Join(tmpDir, "invalid.out.nef")
cmd := []string{"", "contract", "compile",
"--in", source,
"--config", configFile,
"--manifest", manifestF,
"--bindings", bindingF,
"--out", nefF,
"--guess-eventtypes",
}
checkError(t, expectedErrText, cmd...)
}
t.Run("not declared in manifest", func(t *testing.T) {
check(t, filepath.Join("testdata", "rpcbindings", "invalid1"), "inconsistent usages of event `Non declared event`: not declared in the contract config")
})
t.Run("invalid number of params", func(t *testing.T) {
check(t, filepath.Join("testdata", "rpcbindings", "invalid2"), "inconsistent usages of event `SomeEvent` against config: number of params mismatch: 2 vs 1")
})
/*
// TODO: this on is a controversial one. If event information is provided in the config file, then conversion code
// will be emitted by the compiler according to the parameter type provided via config. Thus, we can be sure that
// either event parameter has the type specified in the config file or the execution of the contract will fail.
// Thus, this testcase is always failing (no compilation error occures).
// Question: do we want to compare `RealType` of the emitted parameter with the one expected in the manifest?
t.Run("SC parameter type mismatch", func(t *testing.T) {
check(t, filepath.Join("testdata", "rpcbindings", "invalid3"), "inconsistent usages of event `SomeEvent` against config: number of params mismatch: 2 vs 1")
})
*/
t.Run("extended types mismatch", func(t *testing.T) {
check(t, filepath.Join("testdata", "rpcbindings", "invalid4"), "inconsistent usages of event `SomeEvent`: extended type of param #0 mismatch")
})
t.Run("named types redeclare", func(t *testing.T) {
check(t, filepath.Join("testdata", "rpcbindings", "invalid5"), "configured declared named type intersects with the contract's one: `invalid5.NamedStruct`")
})
}
func TestGenerateRPCBindings_Errors(t *testing.T) {
app := cli.NewApp()
app.Commands = NewCommands()
app.ExitErrHandler = func(*cli.Context, error) {}
t.Run("duplicating resulting fields", func(t *testing.T) {
check := func(t *testing.T, packageName string, autogen bool, expectedError string) {
tmpDir := t.TempDir()
source := filepath.Join("testdata", "rpcbindings", packageName)
configFile := filepath.Join(source, "invalid.yml")
out := filepath.Join(tmpDir, "rpcbindings.out")
manifestF := filepath.Join(tmpDir, "manifest.json")
bindingF := filepath.Join(tmpDir, "binding.yml")
nefF := filepath.Join(tmpDir, "out.nef")
cmd := []string{"", "contract", "compile",
"--in", source,
"--config", configFile,
"--manifest", manifestF,
"--bindings", bindingF,
"--out", nefF,
}
if autogen {
cmd = append(cmd, "--guess-eventtypes")
}
require.NoError(t, app.Run(cmd))
cmds := []string{"", "contract", "generate-rpcwrapper",
"--config", bindingF,
"--manifest", manifestF,
"--out", out,
}
err := app.Run(cmds)
require.Error(t, err)
require.True(t, strings.Contains(err.Error(), expectedError), err.Error())
}
t.Run("event", func(t *testing.T) {
check(t, "invalid6", false, "error during generation: named type `SomeStruct` has two fields with identical resulting binding name `Field`")
})
t.Run("autogen event", func(t *testing.T) {
check(t, "invalid7", true, "error during generation: named type `invalid7.SomeStruct` has two fields with identical resulting binding name `Field`")
})
t.Run("struct", func(t *testing.T) {
check(t, "invalid8", false, "error during generation: named type `invalid8.SomeStruct` has two fields with identical resulting binding name `Field`")
})
})
}

View file

@ -8,6 +8,7 @@ import (
"github.com/nspcc-dev/neo-go/cli/cmdargs"
"github.com/nspcc-dev/neo-go/cli/flags"
"github.com/nspcc-dev/neo-go/cli/options"
"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"
@ -37,15 +38,16 @@ func manifestAddGroup(ctx *cli.Context) error {
h := state.CreateContractHash(sender, nf.Checksum, m.Name)
gAcc, _, err := getAccFromContext(ctx)
gAcc, w, err := options.GetAccFromContext(ctx)
if err != nil {
return cli.NewExitError(fmt.Errorf("can't get account to sign group with: %w", err), 1)
}
defer w.Close()
var found bool
sig := gAcc.PrivateKey().Sign(h.BytesBE())
pub := gAcc.PrivateKey().PublicKey()
pub := gAcc.PublicKey()
for i := range m.Groups {
if m.Groups[i].PublicKey.Equal(pub) {
m.Groups[i].Signature = sig
@ -108,7 +110,7 @@ func readManifest(filename string, hash util.Uint160) (*manifest.Manifest, []byt
if err != nil {
return nil, nil, err
}
if err := m.IsValid(hash); err != nil {
if err := m.IsValid(hash, true); err != nil {
return nil, nil, fmt.Errorf("manifest is invalid: %w", err)
}
return m, manifestBytes, nil

View file

@ -1,7 +1,6 @@
package smartcontract
import (
"encoding/hex"
"errors"
"fmt"
@ -19,7 +18,7 @@ const (
permMethodKey = "methods"
)
func (p permission) MarshalYAML() (interface{}, error) {
func (p permission) MarshalYAML() (any, error) {
m := yaml.Node{Kind: yaml.MappingNode}
switch p.Contract.Type {
case manifest.PermissionWildcard:
@ -28,15 +27,14 @@ func (p permission) MarshalYAML() (interface{}, error) {
&yaml.Node{Kind: yaml.ScalarNode, Value: permHashKey},
&yaml.Node{Kind: yaml.ScalarNode, Value: p.Contract.Value.(util.Uint160).StringLE()})
case manifest.PermissionGroup:
bs := p.Contract.Value.(*keys.PublicKey).Bytes()
m.Content = append(m.Content,
&yaml.Node{Kind: yaml.ScalarNode, Value: permGroupKey},
&yaml.Node{Kind: yaml.ScalarNode, Value: hex.EncodeToString(bs)})
&yaml.Node{Kind: yaml.ScalarNode, Value: p.Contract.Value.(*keys.PublicKey).StringCompressed()})
default:
return nil, fmt.Errorf("invalid permission type: %d", p.Contract.Type)
}
var val interface{} = "*"
var val any = "*"
if !p.Methods.IsWildcard() {
val = p.Methods.Value
}
@ -53,8 +51,8 @@ func (p permission) MarshalYAML() (interface{}, error) {
return m, nil
}
func (p *permission) UnmarshalYAML(unmarshal func(interface{}) error) error {
var m map[string]interface{}
func (p *permission) UnmarshalYAML(unmarshal func(any) error) error {
var m map[string]any
if err := unmarshal(&m); err != nil {
return err
}
@ -66,7 +64,7 @@ func (p *permission) UnmarshalYAML(unmarshal func(interface{}) error) error {
return p.fillMethods(m)
}
func (p *permission) fillType(m map[string]interface{}) error {
func (p *permission) fillType(m map[string]any) error {
vh, ok1 := m[permHashKey]
vg, ok2 := m[permGroupKey]
switch {
@ -104,7 +102,7 @@ func (p *permission) fillType(m map[string]interface{}) error {
return nil
}
func (p *permission) fillMethods(m map[string]interface{}) error {
func (p *permission) fillMethods(m map[string]any) error {
methods, ok := m[permMethodKey]
if !ok {
return errors.New("'methods' field is missing from permission")
@ -116,7 +114,7 @@ func (p *permission) fillMethods(m map[string]interface{}) error {
p.Methods.Value = nil
return nil
}
case []interface{}:
case []any:
ms := make([]string, len(mt))
for i := range mt {
ms[i], ok = mt[i].(string)

View file

@ -8,23 +8,20 @@ import (
"os"
"path/filepath"
"strings"
"time"
"github.com/nspcc-dev/neo-go/cli/cmdargs"
"github.com/nspcc-dev/neo-go/cli/flags"
"github.com/nspcc-dev/neo-go/cli/input"
"github.com/nspcc-dev/neo-go/cli/options"
"github.com/nspcc-dev/neo-go/cli/paramcontext"
cliwallet "github.com/nspcc-dev/neo-go/cli/wallet"
"github.com/nspcc-dev/neo-go/cli/txctx"
"github.com/nspcc-dev/neo-go/pkg/compiler"
"github.com/nspcc-dev/neo-go/pkg/core/state"
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
"github.com/nspcc-dev/neo-go/pkg/encoding/fixedn"
"github.com/nspcc-dev/neo-go/pkg/neorpc/result"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/actor"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/management"
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/binding"
"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"
@ -39,44 +36,17 @@ import (
const addressFlagName = "address, a"
var (
errNoInput = errors.New("no input file was found, specify an input file with the '--in or -i' flag")
errNoConfFile = errors.New("no config file was found, specify a config file with the '--config' or '-c' flag")
errNoManifestFile = errors.New("no manifest file was found, specify manifest file with '--manifest' or '-m' flag")
errNoMethod = errors.New("no method specified for function invocation command")
errNoWallet = errors.New("no wallet parameter found, specify it with the '--wallet' or '-w' flag or specify wallet config file with the '--wallet-config' flag")
errConflictingWalletFlags = errors.New("--wallet flag conflicts with --wallet-config flag, please, provide one of them to specify wallet location")
errNoScriptHash = errors.New("no smart contract hash was provided, specify one as the first argument")
errNoSmartContractName = errors.New("no name was provided, specify the '--name or -n' flag")
errFileExist = errors.New("A file with given smart-contract name already exists")
walletFlag = cli.StringFlag{
Name: "wallet, w",
Usage: "wallet to use to get the key for transaction signing; conflicts with --wallet-config flag",
}
walletConfigFlag = cli.StringFlag{
Name: "wallet-config",
Usage: "path to wallet config to use to get the key for transaction signing; conflicts with --wallet flag",
}
addressFlag = flags.AddressFlag{
errNoInput = errors.New("no input file was found, specify an input file with the '--in or -i' flag")
errNoConfFile = errors.New("no config file was found, specify a config file with the '--config' or '-c' flag")
errNoManifestFile = errors.New("no manifest file was found, specify manifest file with '--manifest' or '-m' flag")
errNoMethod = errors.New("no method specified for function invocation command")
errNoScriptHash = errors.New("no smart contract hash was provided, specify one as the first argument")
errNoSmartContractName = errors.New("no name was provided, specify the '--name or -n' flag")
errFileExist = errors.New("A file with given smart-contract name already exists")
addressFlag = flags.AddressFlag{
Name: addressFlagName,
Usage: "address to use as transaction signee (and gas source)",
}
gasFlag = flags.Fixed8Flag{
Name: "gas, g",
Usage: "network fee to add to the transaction (prioritizing it)",
}
sysGasFlag = flags.Fixed8Flag{
Name: "sysgas, e",
Usage: "system fee to add to transaction (compensating for execution)",
}
outFlag = cli.StringFlag{
Name: "out",
Usage: "file to put JSON transaction to",
}
forceFlag = cli.BoolFlag{
Name: "force",
Usage: "force-push the transaction in case of bad VM state after test script invocation",
}
)
// ModVersion contains `pkg/interop` module version
@ -98,7 +68,7 @@ func init() {
}
// RuntimeNotify sends runtime notification with "Hello world!" name
func RuntimeNotify(args []interface{}) {
func RuntimeNotify(args []any) {
runtime.Notify(notificationName, args)
}`
)
@ -110,17 +80,20 @@ func NewCommands() []cli.Command {
Name: "in, i",
Usage: "Input location of the .nef file that needs to be invoked",
},
options.Historic,
}
testInvokeScriptFlags = append(testInvokeScriptFlags, options.RPC...)
testInvokeFunctionFlags := []cli.Flag{options.Historic}
testInvokeFunctionFlags = append(testInvokeFunctionFlags, options.RPC...)
invokeFunctionFlags := []cli.Flag{
walletFlag,
walletConfigFlag,
addressFlag,
gasFlag,
sysGasFlag,
outFlag,
forceFlag,
txctx.GasFlag,
txctx.SysGasFlag,
txctx.OutFlag,
txctx.ForceFlag,
txctx.AwaitFlag,
}
invokeFunctionFlags = append(invokeFunctionFlags, options.Wallet...)
invokeFunctionFlags = append(invokeFunctionFlags, options.RPC...)
deployFlags := append(invokeFunctionFlags, []cli.Flag{
cli.StringFlag{
@ -132,6 +105,24 @@ func NewCommands() []cli.Command {
Usage: "Manifest input file (*.manifest.json)",
},
}...)
manifestAddGroupFlags := append([]cli.Flag{
cli.StringFlag{
Name: "sender, s",
Usage: "deploy transaction sender",
},
flags.AddressFlag{
Name: addressFlagName, // use the same name for handler code unification.
Usage: "account to sign group with",
},
cli.StringFlag{
Name: "nef, n",
Usage: "path to the NEF file",
},
cli.StringFlag{
Name: "manifest, m",
Usage: "path to the manifest",
},
}, options.Wallet...)
return []cli.Command{{
Name: "contract",
Usage: "compile - debug - deploy smart contracts",
@ -139,12 +130,20 @@ func NewCommands() []cli.Command {
{
Name: "compile",
Usage: "compile a smart contract to a .nef file",
UsageText: "neo-go contract compile -i path [-o nef] [-v] [-d] [-m manifest] [-c yaml] [--bindings file] [--no-standards] [--no-events] [--no-permissions]",
Action: contractCompile,
UsageText: "neo-go contract compile -i path [-o nef] [-v] [-d] [-m manifest] [-c yaml] [--bindings file] [--no-standards] [--no-events] [--no-permissions] [--guess-eventtypes]",
Description: `Compiles given smart contract to a .nef file and emits other associated
information (manifest, bindings configuration, debug information files) if
asked to. If none of --out, --manifest, --config, --bindings flags are specified,
then the output filenames for these flags will be guessed using the contract
name or path provided via --in option by trimming/adding corresponding suffixes
to the common part of the path. In the latter case the configuration filepath
will be guessed from the --in option using the same rule.
`,
Action: contractCompile,
Flags: []cli.Flag{
cli.StringFlag{
Name: "in, i",
Usage: "Input file for the smart contract to be compiled",
Usage: "Input file for the smart contract to be compiled (*.go file or directory)",
},
cli.StringFlag{
Name: "out, o",
@ -178,6 +177,10 @@ func NewCommands() []cli.Command {
Name: "no-permissions",
Usage: "do not check if invoked contracts are allowed in manifest",
},
cli.BoolFlag{
Name: "guess-eventtypes",
Usage: "guess event types for smart-contract bindings configuration from the code usages",
},
cli.StringFlag{
Name: "bindings",
Usage: "output file for smart-contract bindings configuration",
@ -187,25 +190,29 @@ func NewCommands() []cli.Command {
{
Name: "deploy",
Usage: "deploy a smart contract (.nef with description)",
UsageText: "neo-go contract deploy -r endpoint -w wallet [-a address] [-g gas] [-e sysgas] --in contract.nef --manifest contract.manifest.json [--out file] [--force] [data]",
UsageText: "neo-go contract deploy -r endpoint -w wallet [-a address] [-g gas] [-e sysgas] --in contract.nef --manifest contract.manifest.json [--out file] [--force] [--await] [data]",
Description: `Deploys given contract into the chain. The gas parameter is for additional
gas to be added as a network fee to prioritize the transaction. The data
parameter is an optional parameter to be passed to '_deploy' method.
parameter is an optional parameter to be passed to '_deploy' method. When
--await flag is specified, it waits for the transaction to be included
in a block.
`,
Action: contractDeploy,
Flags: deployFlags,
},
generateWrapperCmd,
generateRPCWrapperCmd,
{
Name: "invokefunction",
Usage: "invoke deployed contract on the blockchain",
UsageText: "neo-go contract invokefunction -r endpoint -w wallet [-a address] [-g gas] [-e sysgas] [--out file] [--force] scripthash [method] [arguments...] [--] [signers...]",
UsageText: "neo-go contract invokefunction -r endpoint -w wallet [-a address] [-g gas] [-e sysgas] [--out file] [--force] [--await] scripthash [method] [arguments...] [--] [signers...]",
Description: `Executes given (as a script hash) deployed script with the given method,
arguments and signers. Sender is included in the list of signers by default
with None witness scope. If you'd like to change default sender's scope,
specify it via signers parameter. See testinvokefunction documentation for
the details about parameters. It differs from testinvokefunction in that this
command sends an invocation transaction to the network.
command sends an invocation transaction to the network. When --await flag is
specified, it waits for the transaction to be included in a block.
`,
Action: invokeFunction,
Flags: invokeFunctionFlags,
@ -213,7 +220,7 @@ func NewCommands() []cli.Command {
{
Name: "testinvokefunction",
Usage: "invoke deployed contract on the blockchain (test mode)",
UsageText: "neo-go contract testinvokefunction -r endpoint scripthash [method] [arguments...] [--] [signers...]",
UsageText: "neo-go contract testinvokefunction -r endpoint [--historic index/hash] scripthash [method] [arguments...] [--] [signers...]",
Description: `Executes given (as a script hash) deployed script with the given method,
arguments and signers (sender is not included by default). If no method is given
"" is passed to the script, if no arguments are given, an empty array is
@ -223,117 +230,17 @@ func NewCommands() []cli.Command {
follow the regular convention of smart contract arguments (method string and
an array of other arguments).
Arguments always do have regular Neo smart contract parameter types, either
specified explicitly or being inferred from the value. To specify the type
manually use "type:value" syntax where the type is one of the following:
'signature', 'bool', 'int', 'hash160', 'hash256', 'bytes', 'key' or 'string'.
Array types are also supported: use special space-separated '[' and ']'
symbols around array values to denote array bounds. Nested arrays are also
supported.
` + cmdargs.ParamsParsingDoc + `
There is ability to provide an argument of 'bytearray' type via file. Use a
special 'filebytes' argument type for this with a filepath specified after
the colon, e.g. 'filebytes:my_file.txt'.
Given values are type-checked against given types with the following
restrictions applied:
* 'signature' type values should be hex-encoded and have a (decoded)
length of 64 bytes.
* 'bool' type values are 'true' and 'false'.
* 'int' values are decimal integers that can be successfully converted
from the string.
* 'hash160' values are Neo addresses and hex-encoded 20-bytes long (after
decoding) strings.
* 'hash256' type values should be hex-encoded and have a (decoded)
length of 32 bytes.
* 'bytes' type values are any hex-encoded things.
* 'filebytes' type values are filenames with the argument value inside.
* 'key' type values are hex-encoded marshalled public keys.
* 'string' type values are any valid UTF-8 strings. In the value's part of
the string the colon looses it's special meaning as a separator between
type and value and is taken literally.
If no type is explicitly specified, it is inferred from the value using the
following logic:
- anything that can be interpreted as a decimal integer gets
an 'int' type
- 'true' and 'false' strings get 'bool' type
- valid Neo addresses and 20 bytes long hex-encoded strings get 'hash160'
type
- valid hex-encoded public keys get 'key' type
- 32 bytes long hex-encoded values get 'hash256' type
- 64 bytes long hex-encoded values get 'signature' type
- any other valid hex-encoded values get 'bytes' type
- anything else is a 'string'
Backslash character is used as an escape character and allows to use colon in
an implicitly typed string. For any other characters it has no special
meaning, to get a literal backslash in the string use the '\\' sequence.
Examples:
* 'int:42' is an integer with a value of 42
* '42' is an integer with a value of 42
* 'bad' is a string with a value of 'bad'
* 'dead' is a byte array with a value of 'dead'
* 'string:dead' is a string with a value of 'dead'
* 'filebytes:my_data.txt' is bytes decoded from a content of my_data.txt
* 'AK2nJJpJr6o664CWJKi1QRXjqeic2zRp8y' is a hash160 with a value
of '23ba2703c53263e8d6e522dc32203339dcd8eee9'
* '\4\2' is an integer with a value of 42
* '\\4\2' is a string with a value of '\42'
* 'string:string' is a string with a value of 'string'
* 'string\:string' is a string with a value of 'string:string'
* '03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c' is a
key with a value of '03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c'
* '[ a b c ]' is an array with strings values 'a', 'b' and 'c'
* '[ a b [ c d ] e ]' is an array with 4 values: string 'a', string 'b',
array of two strings 'c' and 'd', string 'e'
* '[ ]' is an empty array
Signers represent a set of Uint160 hashes with witness scopes and are used
to verify hashes in System.Runtime.CheckWitness syscall. First signer is treated
as a sender. To specify signers use signer[:scope] syntax where
* 'signer' is a signer's address (as Neo address or hex-encoded 160 bit (20 byte)
LE value with or without '0x' prefix).
* 'scope' is a comma-separated set of cosigner's scopes, which could be:
- 'None' - default witness scope which may be used for the sender
to only pay fee for the transaction.
- 'Global' - allows this witness in all contexts. This cannot be combined
with other flags.
- 'CalledByEntry' - means that this condition must hold: EntryScriptHash
== CallingScriptHash. The witness/permission/signature
given on first invocation will automatically expire if
entering deeper internal invokes. This can be default
safe choice for native NEO/GAS.
- 'CustomContracts' - define valid custom contract hashes for witness check.
Hashes are be provided as hex-encoded LE value string.
At lest one hash must be provided. Multiple hashes
are separated by ':'.
- 'CustomGroups' - define custom public keys for group members. Public keys are
provided as short-form (1-byte prefix + 32 bytes) hex-encoded
values. At least one key must be provided. Multiple keys
are separated by ':'.
If no scopes were specified, 'CalledByEntry' used as default. If no signers were
specified, no array is passed. Note that scopes are properly handled by
neo-go RPC server only. C# implementation does not support scopes capability.
Examples:
* 'NNQk4QXsxvsrr3GSozoWBUxEmfag7B6hz5'
* 'NVquyZHoPirw6zAEPvY1ZezxM493zMWQqs:Global'
* '0x0000000009070e030d0f0e020d0c06050e030c02'
* '0000000009070e030d0f0e020d0c06050e030c02:CalledByEntry,` +
`CustomGroups:0206d7495ceb34c197093b5fc1cccf1996ada05e69ef67e765462a7f5d88ee14d0'
* '0000000009070e030d0f0e020d0c06050e030c02:CalledByEntry,` +
`CustomContracts:1011120009070e030d0f0e020d0c06050e030c02:0x1211100009070e030d0f0e020d0c06050e030c02'
` + cmdargs.SignersParsingDoc + `
`,
Action: testInvokeFunction,
Flags: options.RPC,
Flags: testInvokeFunctionFlags,
},
{
Name: "testinvokescript",
Usage: "Invoke compiled AVM code in NEF format on the blockchain (test mode, not creating a transaction for it)",
UsageText: "neo-go contract testinvokescript -r endpoint -i input.nef [signers...]",
UsageText: "neo-go contract testinvokescript -r endpoint -i input.nef [--historic index/hash] [signers...]",
Description: `Executes given compiled AVM instructions in NEF format with the given set of
signers not included sender by default. See testinvokefunction documentation
for the details about parameters.
@ -402,26 +309,7 @@ func NewCommands() []cli.Command {
Usage: "adds group to the manifest",
UsageText: "neo-go contract manifest add-group -w wallet [--wallet-config path] -n nef -m manifest -a address -s address",
Action: manifestAddGroup,
Flags: []cli.Flag{
walletFlag,
walletConfigFlag,
cli.StringFlag{
Name: "sender, s",
Usage: "deploy transaction sender",
},
flags.AddressFlag{
Name: addressFlagName, // use the same name for handler code unification.
Usage: "account to sign group with",
},
cli.StringFlag{
Name: "nef, n",
Usage: "path to the NEF file",
},
cli.StringFlag{
Name: "manifest, m",
Usage: "path to the manifest",
},
},
Flags: manifestAddGroupFlags,
},
},
},
@ -458,13 +346,15 @@ func initSmartContract(ctx *cli.Context) error {
SourceURL: "http://example.com/",
SupportedStandards: []string{},
SafeMethods: []string{},
Events: []manifest.Event{
Events: []compiler.HybridEvent{
{
Name: "Hello world!",
Parameters: []manifest.Parameter{
Parameters: []compiler.HybridParameter{
{
Name: "args",
Type: smartcontract.ArrayType,
Parameter: manifest.Parameter{
Name: "args",
Type: smartcontract.ArrayType,
},
},
},
},
@ -485,6 +375,9 @@ func initSmartContract(ctx *cli.Context) error {
}
gm := []byte("module " + contractName + `
go 1.20
require (
github.com/nspcc-dev/neo-go/pkg/interop ` + ver + `
)`)
@ -513,20 +406,48 @@ func contractCompile(ctx *cli.Context) error {
manifestFile := ctx.String("manifest")
confFile := ctx.String("config")
debugFile := ctx.String("debug")
if len(confFile) == 0 && (len(manifestFile) != 0 || len(debugFile) != 0) {
out := ctx.String("out")
bindings := ctx.String("bindings")
if len(confFile) == 0 && (len(manifestFile) != 0 || len(debugFile) != 0 || len(bindings) != 0) {
return cli.NewExitError(errNoConfFile, 1)
}
autocomplete := len(manifestFile) == 0 &&
len(confFile) == 0 &&
len(out) == 0 &&
len(bindings) == 0
if autocomplete {
var root string
fileInfo, err := os.Stat(src)
if err != nil {
return cli.NewExitError(fmt.Errorf("failed to stat source file or directory: %w", err), 1)
}
if fileInfo.IsDir() {
base := filepath.Base(fileInfo.Name())
if base == string(filepath.Separator) {
base = "contract"
}
root = filepath.Join(src, base)
} else {
root = strings.TrimSuffix(src, ".go")
}
manifestFile = root + ".manifest.json"
confFile = root + ".yml"
out = root + ".nef"
bindings = root + ".bindings.yml"
}
o := &compiler.Options{
Outfile: ctx.String("out"),
Outfile: out,
DebugInfo: debugFile,
ManifestFile: manifestFile,
BindingsFile: ctx.String("bindings"),
BindingsFile: bindings,
NoStandardCheck: ctx.Bool("no-standards"),
NoEventsCheck: ctx.Bool("no-events"),
NoPermissionsCheck: ctx.Bool("no-permissions"),
GuessEventTypes: ctx.Bool("guess-eventtypes"),
}
if len(confFile) != 0 {
@ -537,6 +458,7 @@ func contractCompile(ctx *cli.Context) error {
o.Name = conf.Name
o.SourceURL = conf.SourceURL
o.ContractEvents = conf.Events
o.DeclaredNamedTypes = conf.NamedTypes
o.ContractSupportedStandards = conf.SupportedStandards
o.Permissions = make([]manifest.Permission, len(conf.Permissions))
for i := range conf.Permissions {
@ -608,8 +530,9 @@ func invokeInternal(ctx *cli.Context, signAndPush bool) error {
err error
exitErr *cli.ExitError
operation string
params = make([]smartcontract.Parameter, 0)
params []any
paramsStart = 1
scParams []smartcontract.Parameter
cosigners []transaction.Signer
cosignersOffset = 0
)
@ -629,10 +552,14 @@ func invokeInternal(ctx *cli.Context, signAndPush bool) error {
paramsStart++
if len(args) > paramsStart {
cosignersOffset, params, err = cmdargs.ParseParams(args[paramsStart:], true)
cosignersOffset, scParams, err = cmdargs.ParseParams(args[paramsStart:], true)
if err != nil {
return cli.NewExitError(err, 1)
}
params = make([]any, len(scParams))
for i := range scParams {
params[i] = scParams[i]
}
}
cosignersStart := paramsStart + cosignersOffset
@ -646,60 +573,54 @@ func invokeInternal(ctx *cli.Context, signAndPush bool) error {
w *wallet.Wallet
)
if signAndPush {
acc, w, err = getAccFromContext(ctx)
acc, w, err = options.GetAccFromContext(ctx)
if err != nil {
return cli.NewExitError(err, 1)
}
defer w.Close()
}
_, err = invokeWithArgs(ctx, acc, w, script, operation, params, cosigners)
return err
return invokeWithArgs(ctx, acc, w, script, operation, params, cosigners)
}
func invokeWithArgs(ctx *cli.Context, acc *wallet.Account, wall *wallet.Wallet, script util.Uint160, operation string, params []smartcontract.Parameter, cosigners []transaction.Signer) (util.Uint160, error) {
func invokeWithArgs(ctx *cli.Context, acc *wallet.Account, wall *wallet.Wallet, script util.Uint160, operation string, params []any, cosigners []transaction.Signer) error {
var (
err error
gas, sysgas fixedn.Fixed8
signersAccounts []actor.SignerAccount
resp *result.Invoke
sender util.Uint160
signAndPush = acc != nil
inv *invoker.Invoker
act *actor.Actor
)
if signAndPush {
gas = flags.Fixed8FromContext(ctx, "gas")
sysgas = flags.Fixed8FromContext(ctx, "sysgas")
signersAccounts, err = cmdargs.GetSignersAccounts(acc, wall, cosigners, transaction.None)
if err != nil {
return sender, cli.NewExitError(fmt.Errorf("invalid signers: %w", err), 1)
return cli.NewExitError(fmt.Errorf("invalid signers: %w", err), 1)
}
sender = signersAccounts[0].Signer.Account
}
gctx, cancel := options.GetTimeoutContext(ctx)
defer cancel()
c, err := options.GetRPCClient(gctx, ctx)
if err != nil {
return sender, err
}
if signAndPush {
act, err = actor.New(c, signersAccounts)
_, act, err = options.GetRPCWithActor(gctx, ctx, signersAccounts)
if err != nil {
return sender, cli.NewExitError(fmt.Errorf("failed to create RPC actor: %w", err), 1)
return err
}
inv = &act.Invoker
} else {
_, inv, err = options.GetRPCWithInvoker(gctx, ctx, cosigners)
if err != nil {
return err
}
}
out := ctx.String("out")
// It's a bit easier to keep this as is (not using invoker.Invoker)
// during transition period. Mostly because of the need to convert params
// to []interface{}.
resp, err = c.InvokeFunction(script, operation, params, cosigners)
resp, err = inv.Call(script, operation, params...)
if err != nil {
return sender, cli.NewExitError(err, 1)
return cli.NewExitError(err, 1)
}
if resp.State != "HALT" {
errText := fmt.Sprintf("Warning: %s VM state returned from the RPC node: %s", resp.State, resp.FaultException)
if !signAndPush {
return sender, cli.NewExitError(errText, 1)
return cli.NewExitError(errText, 1)
}
action := "send"
@ -709,55 +630,27 @@ func invokeWithArgs(ctx *cli.Context, acc *wallet.Account, wall *wallet.Wallet,
process = "Saving"
}
if !ctx.Bool("force") {
return sender, cli.NewExitError(errText+".\nUse --force flag to "+action+" the transaction anyway.", 1)
return cli.NewExitError(errText+".\nUse --force flag to "+action+" the transaction anyway.", 1)
}
fmt.Fprintln(ctx.App.Writer, errText+".\n"+process+" transaction...")
}
if !signAndPush {
b, err := json.MarshalIndent(resp, "", " ")
if err != nil {
return sender, cli.NewExitError(err, 1)
return cli.NewExitError(err, 1)
}
fmt.Fprintln(ctx.App.Writer, string(b))
} else {
if len(resp.Script) == 0 {
return sender, cli.NewExitError(errors.New("no script returned from the RPC node"), 1)
}
ver := act.GetVersion()
tx, err := act.MakeUnsignedUncheckedRun(resp.Script, resp.GasConsumed+int64(sysgas), nil)
if err != nil {
return sender, cli.NewExitError(fmt.Errorf("failed to create tx: %w", err), 1)
}
tx.NetworkFee += int64(gas)
if out != "" {
// Make a long-lived transaction, it's to be signed manually.
tx.ValidUntilBlock += (ver.Protocol.MaxValidUntilBlockIncrement - uint32(ver.Protocol.ValidatorsCount)) - 2
m := act.GetNetwork()
if err := paramcontext.InitAndSave(m, tx, acc, out); err != nil {
return sender, cli.NewExitError(err, 1)
}
fmt.Fprintln(ctx.App.Writer, tx.Hash().StringLE())
} else {
if !ctx.Bool("force") {
promptTime := time.Now()
err := input.ConfirmTx(ctx.App.Writer, tx)
if err != nil {
return sender, cli.NewExitError(err, 1)
}
waitTime := time.Since(promptTime)
// Compensate for confirmation waiting.
tx.ValidUntilBlock += uint32((waitTime.Milliseconds() / int64(ver.Protocol.MillisecondsPerBlock))) + 1
}
txHash, _, err := act.SignAndSend(tx)
if err != nil {
return sender, cli.NewExitError(fmt.Errorf("failed to push invocation tx: %w", err), 1)
}
fmt.Fprintf(ctx.App.Writer, "Sent invocation transaction %s\n", txHash.StringLE())
}
return nil
}
return sender, nil
if len(resp.Script) == 0 {
return cli.NewExitError(errors.New("no script returned from the RPC node"), 1)
}
tx, err := act.MakeUnsignedUncheckedRun(resp.Script, resp.GasConsumed, nil)
if err != nil {
return cli.NewExitError(fmt.Errorf("failed to create tx: %w", err), 1)
}
return txctx.SignAndSend(ctx, act, acc, tx)
}
func testInvokeScript(ctx *cli.Context) error {
@ -783,12 +676,12 @@ func testInvokeScript(ctx *cli.Context) error {
gctx, cancel := options.GetTimeoutContext(ctx)
defer cancel()
c, err := options.GetRPCClient(gctx, ctx)
_, inv, err := options.GetRPCWithInvoker(gctx, ctx, signers)
if err != nil {
return err
}
resp, err := c.InvokeScript(nefFile.Script, signers)
resp, err := inv.Run(nefFile.Script)
if err != nil {
return cli.NewExitError(err, 1)
}
@ -809,9 +702,10 @@ type ProjectConfig struct {
SourceURL string
SafeMethods []string
SupportedStandards []string
Events []manifest.Event
Events []compiler.HybridEvent
Permissions []permission
Overloads map[string]string `yaml:"overloads,omitempty"`
Overloads map[string]string `yaml:"overloads,omitempty"`
NamedTypes map[string]binding.ExtendedType `yaml:"namedtypes,omitempty"`
}
func inspect(ctx *cli.Context) error {
@ -850,68 +744,6 @@ func inspect(ctx *cli.Context) error {
return nil
}
func getAccFromContext(ctx *cli.Context) (*wallet.Account, *wallet.Wallet, error) {
var addr util.Uint160
wPath := ctx.String("wallet")
walletConfigPath := ctx.String("wallet-config")
if len(wPath) != 0 && len(walletConfigPath) != 0 {
return nil, nil, errConflictingWalletFlags
}
if len(wPath) == 0 && len(walletConfigPath) == 0 {
return nil, nil, errNoWallet
}
var pass *string
if len(walletConfigPath) != 0 {
cfg, err := cliwallet.ReadWalletConfig(walletConfigPath)
if err != nil {
return nil, nil, err
}
wPath = cfg.Path
pass = &cfg.Password
}
wall, err := wallet.NewWalletFromFile(wPath)
if err != nil {
return nil, nil, err
}
addrFlag := ctx.Generic("address").(*flags.Address)
if addrFlag.IsSet {
addr = addrFlag.Uint160()
} else {
addr = wall.GetChangeAddress()
}
acc, err := getUnlockedAccount(wall, addr, pass)
return acc, wall, err
}
func getUnlockedAccount(wall *wallet.Wallet, addr util.Uint160, pass *string) (*wallet.Account, error) {
acc := wall.GetAccount(addr)
if acc == nil {
return nil, fmt.Errorf("wallet contains no account for '%s'", address.Uint160ToString(addr))
}
if acc.PrivateKey() != nil {
return acc, nil
}
if pass == nil {
rawPass, err := input.ReadPassword(
fmt.Sprintf("Enter account %s password > ", address.Uint160ToString(addr)))
if err != nil {
return nil, fmt.Errorf("Error reading password: %w", err)
}
trimmed := strings.TrimRight(string(rawPass), "\n")
pass = &trimmed
}
err := acc.Decrypt(*pass, wall.Scrypt)
if err != nil {
return nil, err
}
return acc, nil
}
// contractDeploy deploys contract.
func contractDeploy(ctx *cli.Context) error {
nefFile, f, err := readNEFFile(ctx.String("in"))
@ -924,16 +756,8 @@ func contractDeploy(ctx *cli.Context) error {
return cli.NewExitError(fmt.Errorf("failed to read manifest file: %w", err), 1)
}
appCallParams := []smartcontract.Parameter{
{
Type: smartcontract.ByteArrayType,
Value: f,
},
{
Type: smartcontract.ByteArrayType,
Value: manifestBytes,
},
}
var appCallParams = []any{f, manifestBytes}
signOffset, data, err := cmdargs.ParseParams(ctx.Args(), true)
if err != nil {
return cli.NewExitError(fmt.Errorf("unable to parse 'data' parameter: %w", err), 1)
@ -945,10 +769,12 @@ func contractDeploy(ctx *cli.Context) error {
appCallParams = append(appCallParams, data[0])
}
acc, w, err := getAccFromContext(ctx)
acc, w, err := options.GetAccFromContext(ctx)
if err != nil {
return cli.NewExitError(fmt.Errorf("can't get sender address: %w", err), 1)
}
defer w.Close()
sender := acc.ScriptHash()
cosigners, sgnErr := cmdargs.GetSignersFromContext(ctx, signOffset)
if sgnErr != nil {
@ -960,7 +786,7 @@ func contractDeploy(ctx *cli.Context) error {
}}
}
sender, extErr := invokeWithArgs(ctx, acc, w, management.Hash, "deploy", appCallParams, cosigners)
extErr := invokeWithArgs(ctx, acc, w, management.Hash, "deploy", appCallParams, cosigners)
if extErr != nil {
return extErr
}

View file

@ -1,7 +1,6 @@
package smartcontract
import (
"encoding/hex"
"flag"
"os"
"testing"
@ -51,7 +50,7 @@ func init() {
}
// RuntimeNotify sends runtime notification with "Hello world!" name
func RuntimeNotify(args []interface{}) {
func RuntimeNotify(args []any) {
runtime.Notify(notificationName, args)
}`, string(main))
@ -109,7 +108,7 @@ func TestPermissionMarshal(t *testing.T) {
p.Methods.Add("abc")
p.Methods.Add("lamao")
testPermissionMarshal(t, p,
"group: "+hex.EncodeToString(priv.PublicKey().Bytes())+"\n"+
"group: "+priv.PublicKey().StringCompressed()+"\n"+
"methods:\n - abc\n - lamao\n")
})
}
@ -118,7 +117,7 @@ func TestPermissionUnmarshalInvalid(t *testing.T) {
priv, err := keys.NewPrivateKey()
require.NoError(t, err)
pub := hex.EncodeToString(priv.PublicKey().Bytes())
pub := priv.PublicKey().StringCompressed()
u160 := random.Uint160().StringLE()
testCases := []string{
"hash: []\nmethods: '*'\n", // invalid hash type

View file

@ -1,7 +1,7 @@
package deploy
import (
"github.com/nspcc-dev/neo-go/cli/testdata/deploy/sub"
"github.com/nspcc-dev/neo-go/cli/smartcontract/testdata/deploy/sub"
"github.com/nspcc-dev/neo-go/pkg/interop"
"github.com/nspcc-dev/neo-go/pkg/interop/contract"
"github.com/nspcc-dev/neo-go/pkg/interop/iterator"
@ -13,7 +13,7 @@ var key = "key"
const mgmtKey = "mgmt"
func _deploy(data interface{}, isUpdate bool) {
func _deploy(data any, isUpdate bool) {
var value string
ctx := storage.GetContext()
@ -25,7 +25,7 @@ func _deploy(data interface{}, isUpdate bool) {
storage.Put(ctx, mgmtKey, sh)
if data != nil {
arr := data.([]interface{})
arr := data.([]any)
for i := 0; i < len(arr)-1; i += 2 {
storage.Put(ctx, arr[i], arr[i+1])
}
@ -70,12 +70,12 @@ func GetValueWithKey(key string) string {
}
// TestFind finds items with the specified prefix.
func TestFind(f storage.FindFlags) []interface{} {
func TestFind(f storage.FindFlags) []any {
ctx := storage.GetContext()
storage.Put(ctx, "findkey1", "value1")
storage.Put(ctx, "findkey2", "value2")
var result []interface{}
var result []any
iter := storage.Find(ctx, "findkey", f)
for iterator.Next(iter) {
result = append(result, iterator.Value(iter))

View file

@ -4,7 +4,7 @@ import "github.com/nspcc-dev/neo-go/pkg/interop/storage"
var Key = "sub"
func _deploy(data interface{}, isUpdate bool) {
func _deploy(data any, isUpdate bool) {
ctx := storage.GetContext()
value := "sub create"
if isUpdate {

52
cli/smartcontract/testdata/gas/gas.go vendored Normal file
View file

@ -0,0 +1,52 @@
// Code generated by neo-go contract generate-rpcwrapper --manifest <file.json> --out <file.go> [--hash <hash>] [--config <config>]; DO NOT EDIT.
// Package gastoken contains RPC wrappers for GasToken contract.
package gastoken
import (
"github.com/nspcc-dev/neo-go/pkg/rpcclient/nep17"
"github.com/nspcc-dev/neo-go/pkg/util"
)
// Hash contains contract hash.
var Hash = util.Uint160{0xcf, 0x76, 0xe2, 0x8b, 0xd0, 0x6, 0x2c, 0x4a, 0x47, 0x8e, 0xe3, 0x55, 0x61, 0x1, 0x13, 0x19, 0xf3, 0xcf, 0xa4, 0xd2}
// Invoker is used by ContractReader to call various safe methods.
type Invoker interface {
nep17.Invoker
}
// Actor is used by Contract to call state-changing methods.
type Actor interface {
Invoker
nep17.Actor
}
// ContractReader implements safe contract methods.
type ContractReader struct {
nep17.TokenReader
invoker Invoker
hash util.Uint160
}
// Contract implements all contract methods.
type Contract struct {
ContractReader
nep17.TokenWriter
actor Actor
hash util.Uint160
}
// NewReader creates an instance of ContractReader using Hash and the given Invoker.
func NewReader(invoker Invoker) *ContractReader {
var hash = Hash
return &ContractReader{*nep17.NewReader(invoker, hash), invoker, hash}
}
// New creates an instance of Contract using Hash and the given Actor.
func New(actor Actor) *Contract {
var hash = Hash
var nep17t = nep17.New(actor, hash)
return &Contract{ContractReader{nep17t.TokenReader, actor, hash}, nep17t.TokenWriter, actor, hash}
}

View file

@ -0,0 +1 @@
{"name":"GasToken","groups":[],"features":{},"supportedstandards":["NEP-17"],"abi":{"methods":[{"name":"balanceOf","parameters":[{"name":"account","type":"Hash160"}],"returntype":"Integer","offset":0,"safe":true},{"name":"decimals","parameters":[],"returntype":"Integer","offset":7,"safe":true},{"name":"symbol","parameters":[],"returntype":"String","offset":14,"safe":true},{"name":"totalSupply","parameters":[],"returntype":"Integer","offset":21,"safe":true},{"name":"transfer","parameters":[{"name":"from","type":"Hash160"},{"name":"to","type":"Hash160"},{"name":"amount","type":"Integer"},{"name":"data","type":"Any"}],"returntype":"Boolean","offset":28,"safe":false}],"events":[{"name":"Transfer","parameters":[{"name":"from","type":"Hash160"},{"name":"to","type":"Hash160"},{"name":"amount","type":"Integer"}]}]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"extra":null}

View file

@ -0,0 +1,511 @@
// Code generated by neo-go contract generate-rpcwrapper --manifest <file.json> --out <file.go> [--hash <hash>] [--config <config>]; DO NOT EDIT.
// Package nameservice contains RPC wrappers for NameService contract.
package nameservice
import (
"errors"
"fmt"
"github.com/google/uuid"
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
"github.com/nspcc-dev/neo-go/pkg/neorpc/result"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/nep11"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap"
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
"math/big"
"unicode/utf8"
)
// Hash contains contract hash.
var Hash = util.Uint160{0xde, 0x46, 0x5f, 0x5d, 0x50, 0x57, 0xcf, 0x33, 0x28, 0x47, 0x94, 0xc5, 0xcf, 0xc2, 0xc, 0x69, 0x37, 0x1c, 0xac, 0x50}
// SetAdminEvent represents "SetAdmin" event emitted by the contract.
type SetAdminEvent struct {
Name string
OldAdmin util.Uint160
NewAdmin util.Uint160
}
// RenewEvent represents "Renew" event emitted by the contract.
type RenewEvent struct {
Name string
OldExpiration *big.Int
NewExpiration *big.Int
}
// Invoker is used by ContractReader to call various safe methods.
type Invoker interface {
nep11.Invoker
}
// Actor is used by Contract to call state-changing methods.
type Actor interface {
Invoker
nep11.Actor
MakeCall(contract util.Uint160, method string, params ...any) (*transaction.Transaction, error)
MakeRun(script []byte) (*transaction.Transaction, error)
MakeUnsignedCall(contract util.Uint160, method string, attrs []transaction.Attribute, params ...any) (*transaction.Transaction, error)
MakeUnsignedRun(script []byte, attrs []transaction.Attribute) (*transaction.Transaction, error)
SendCall(contract util.Uint160, method string, params ...any) (util.Uint256, uint32, error)
SendRun(script []byte) (util.Uint256, uint32, error)
}
// ContractReader implements safe contract methods.
type ContractReader struct {
nep11.NonDivisibleReader
invoker Invoker
hash util.Uint160
}
// Contract implements all contract methods.
type Contract struct {
ContractReader
nep11.BaseWriter
actor Actor
hash util.Uint160
}
// NewReader creates an instance of ContractReader using Hash and the given Invoker.
func NewReader(invoker Invoker) *ContractReader {
var hash = Hash
return &ContractReader{*nep11.NewNonDivisibleReader(invoker, hash), invoker, hash}
}
// New creates an instance of Contract using Hash and the given Actor.
func New(actor Actor) *Contract {
var hash = Hash
var nep11ndt = nep11.NewNonDivisible(actor, hash)
return &Contract{ContractReader{nep11ndt.NonDivisibleReader, actor, hash}, nep11ndt.BaseWriter, actor, hash}
}
// Roots invokes `roots` method of contract.
func (c *ContractReader) Roots() (uuid.UUID, result.Iterator, error) {
return unwrap.SessionIterator(c.invoker.Call(c.hash, "roots"))
}
// RootsExpanded is similar to Roots (uses the same contract
// method), but can be useful if the server used doesn't support sessions and
// doesn't expand iterators. It creates a script that will get the specified
// number of result items from the iterator right in the VM and return them to
// you. It's only limited by VM stack and GAS available for RPC invocations.
func (c *ContractReader) RootsExpanded(_numOfIteratorItems int) ([]stackitem.Item, error) {
return unwrap.Array(c.invoker.CallAndExpandIterator(c.hash, "roots", _numOfIteratorItems))
}
// GetPrice invokes `getPrice` method of contract.
func (c *ContractReader) GetPrice(length *big.Int) (*big.Int, error) {
return unwrap.BigInt(c.invoker.Call(c.hash, "getPrice", length))
}
// IsAvailable invokes `isAvailable` method of contract.
func (c *ContractReader) IsAvailable(name string) (bool, error) {
return unwrap.Bool(c.invoker.Call(c.hash, "isAvailable", name))
}
// GetRecord invokes `getRecord` method of contract.
func (c *ContractReader) GetRecord(name string, typev *big.Int) (string, error) {
return unwrap.UTF8String(c.invoker.Call(c.hash, "getRecord", name, typev))
}
// GetAllRecords invokes `getAllRecords` method of contract.
func (c *ContractReader) GetAllRecords(name string) (uuid.UUID, result.Iterator, error) {
return unwrap.SessionIterator(c.invoker.Call(c.hash, "getAllRecords", name))
}
// GetAllRecordsExpanded is similar to GetAllRecords (uses the same contract
// method), but can be useful if the server used doesn't support sessions and
// doesn't expand iterators. It creates a script that will get the specified
// number of result items from the iterator right in the VM and return them to
// you. It's only limited by VM stack and GAS available for RPC invocations.
func (c *ContractReader) GetAllRecordsExpanded(name string, _numOfIteratorItems int) ([]stackitem.Item, error) {
return unwrap.Array(c.invoker.CallAndExpandIterator(c.hash, "getAllRecords", _numOfIteratorItems, name))
}
// Resolve invokes `resolve` method of contract.
func (c *ContractReader) Resolve(name string, typev *big.Int) (string, error) {
return unwrap.UTF8String(c.invoker.Call(c.hash, "resolve", name, typev))
}
// Update creates a transaction invoking `update` method of the contract.
// This transaction is signed and immediately sent to the network.
// The values returned are its hash, ValidUntilBlock value and error if any.
func (c *Contract) Update(nef []byte, manifest string) (util.Uint256, uint32, error) {
return c.actor.SendCall(c.hash, "update", nef, manifest)
}
// UpdateTransaction creates a transaction invoking `update` method of the contract.
// This transaction is signed, but not sent to the network, instead it's
// returned to the caller.
func (c *Contract) UpdateTransaction(nef []byte, manifest string) (*transaction.Transaction, error) {
return c.actor.MakeCall(c.hash, "update", nef, manifest)
}
// UpdateUnsigned creates a transaction invoking `update` method of the contract.
// This transaction is not signed, it's simply returned to the caller.
// Any fields of it that do not affect fees can be changed (ValidUntilBlock,
// Nonce), fee values (NetworkFee, SystemFee) can be increased as well.
func (c *Contract) UpdateUnsigned(nef []byte, manifest string) (*transaction.Transaction, error) {
return c.actor.MakeUnsignedCall(c.hash, "update", nil, nef, manifest)
}
// AddRoot creates a transaction invoking `addRoot` method of the contract.
// This transaction is signed and immediately sent to the network.
// The values returned are its hash, ValidUntilBlock value and error if any.
func (c *Contract) AddRoot(root string) (util.Uint256, uint32, error) {
return c.actor.SendCall(c.hash, "addRoot", root)
}
// AddRootTransaction creates a transaction invoking `addRoot` method of the contract.
// This transaction is signed, but not sent to the network, instead it's
// returned to the caller.
func (c *Contract) AddRootTransaction(root string) (*transaction.Transaction, error) {
return c.actor.MakeCall(c.hash, "addRoot", root)
}
// AddRootUnsigned creates a transaction invoking `addRoot` method of the contract.
// This transaction is not signed, it's simply returned to the caller.
// Any fields of it that do not affect fees can be changed (ValidUntilBlock,
// Nonce), fee values (NetworkFee, SystemFee) can be increased as well.
func (c *Contract) AddRootUnsigned(root string) (*transaction.Transaction, error) {
return c.actor.MakeUnsignedCall(c.hash, "addRoot", nil, root)
}
// SetPrice creates a transaction invoking `setPrice` method of the contract.
// This transaction is signed and immediately sent to the network.
// The values returned are its hash, ValidUntilBlock value and error if any.
func (c *Contract) SetPrice(priceList []any) (util.Uint256, uint32, error) {
return c.actor.SendCall(c.hash, "setPrice", priceList)
}
// SetPriceTransaction creates a transaction invoking `setPrice` method of the contract.
// This transaction is signed, but not sent to the network, instead it's
// returned to the caller.
func (c *Contract) SetPriceTransaction(priceList []any) (*transaction.Transaction, error) {
return c.actor.MakeCall(c.hash, "setPrice", priceList)
}
// SetPriceUnsigned creates a transaction invoking `setPrice` method of the contract.
// This transaction is not signed, it's simply returned to the caller.
// Any fields of it that do not affect fees can be changed (ValidUntilBlock,
// Nonce), fee values (NetworkFee, SystemFee) can be increased as well.
func (c *Contract) SetPriceUnsigned(priceList []any) (*transaction.Transaction, error) {
return c.actor.MakeUnsignedCall(c.hash, "setPrice", nil, priceList)
}
func (c *Contract) scriptForRegister(name string, owner util.Uint160) ([]byte, error) {
return smartcontract.CreateCallWithAssertScript(c.hash, "register", name, owner)
}
// Register creates a transaction invoking `register` method of the contract.
// This transaction is signed and immediately sent to the network.
// The values returned are its hash, ValidUntilBlock value and error if any.
func (c *Contract) Register(name string, owner util.Uint160) (util.Uint256, uint32, error) {
script, err := c.scriptForRegister(name, owner)
if err != nil {
return util.Uint256{}, 0, err
}
return c.actor.SendRun(script)
}
// RegisterTransaction creates a transaction invoking `register` method of the contract.
// This transaction is signed, but not sent to the network, instead it's
// returned to the caller.
func (c *Contract) RegisterTransaction(name string, owner util.Uint160) (*transaction.Transaction, error) {
script, err := c.scriptForRegister(name, owner)
if err != nil {
return nil, err
}
return c.actor.MakeRun(script)
}
// RegisterUnsigned creates a transaction invoking `register` method of the contract.
// This transaction is not signed, it's simply returned to the caller.
// Any fields of it that do not affect fees can be changed (ValidUntilBlock,
// Nonce), fee values (NetworkFee, SystemFee) can be increased as well.
func (c *Contract) RegisterUnsigned(name string, owner util.Uint160) (*transaction.Transaction, error) {
script, err := c.scriptForRegister(name, owner)
if err != nil {
return nil, err
}
return c.actor.MakeUnsignedRun(script, nil)
}
// Renew creates a transaction invoking `renew` method of the contract.
// This transaction is signed and immediately sent to the network.
// The values returned are its hash, ValidUntilBlock value and error if any.
func (c *Contract) Renew(name string) (util.Uint256, uint32, error) {
return c.actor.SendCall(c.hash, "renew", name)
}
// RenewTransaction creates a transaction invoking `renew` method of the contract.
// This transaction is signed, but not sent to the network, instead it's
// returned to the caller.
func (c *Contract) RenewTransaction(name string) (*transaction.Transaction, error) {
return c.actor.MakeCall(c.hash, "renew", name)
}
// RenewUnsigned creates a transaction invoking `renew` method of the contract.
// This transaction is not signed, it's simply returned to the caller.
// Any fields of it that do not affect fees can be changed (ValidUntilBlock,
// Nonce), fee values (NetworkFee, SystemFee) can be increased as well.
func (c *Contract) RenewUnsigned(name string) (*transaction.Transaction, error) {
return c.actor.MakeUnsignedCall(c.hash, "renew", nil, name)
}
// Renew2 creates a transaction invoking `renew` method of the contract.
// This transaction is signed and immediately sent to the network.
// The values returned are its hash, ValidUntilBlock value and error if any.
func (c *Contract) Renew2(name string, years *big.Int) (util.Uint256, uint32, error) {
return c.actor.SendCall(c.hash, "renew", name, years)
}
// Renew2Transaction creates a transaction invoking `renew` method of the contract.
// This transaction is signed, but not sent to the network, instead it's
// returned to the caller.
func (c *Contract) Renew2Transaction(name string, years *big.Int) (*transaction.Transaction, error) {
return c.actor.MakeCall(c.hash, "renew", name, years)
}
// Renew2Unsigned creates a transaction invoking `renew` method of the contract.
// This transaction is not signed, it's simply returned to the caller.
// Any fields of it that do not affect fees can be changed (ValidUntilBlock,
// Nonce), fee values (NetworkFee, SystemFee) can be increased as well.
func (c *Contract) Renew2Unsigned(name string, years *big.Int) (*transaction.Transaction, error) {
return c.actor.MakeUnsignedCall(c.hash, "renew", nil, name, years)
}
// SetAdmin creates a transaction invoking `setAdmin` method of the contract.
// This transaction is signed and immediately sent to the network.
// The values returned are its hash, ValidUntilBlock value and error if any.
func (c *Contract) SetAdmin(name string, admin util.Uint160) (util.Uint256, uint32, error) {
return c.actor.SendCall(c.hash, "setAdmin", name, admin)
}
// SetAdminTransaction creates a transaction invoking `setAdmin` method of the contract.
// This transaction is signed, but not sent to the network, instead it's
// returned to the caller.
func (c *Contract) SetAdminTransaction(name string, admin util.Uint160) (*transaction.Transaction, error) {
return c.actor.MakeCall(c.hash, "setAdmin", name, admin)
}
// SetAdminUnsigned creates a transaction invoking `setAdmin` method of the contract.
// This transaction is not signed, it's simply returned to the caller.
// Any fields of it that do not affect fees can be changed (ValidUntilBlock,
// Nonce), fee values (NetworkFee, SystemFee) can be increased as well.
func (c *Contract) SetAdminUnsigned(name string, admin util.Uint160) (*transaction.Transaction, error) {
return c.actor.MakeUnsignedCall(c.hash, "setAdmin", nil, name, admin)
}
// SetRecord creates a transaction invoking `setRecord` method of the contract.
// This transaction is signed and immediately sent to the network.
// The values returned are its hash, ValidUntilBlock value and error if any.
func (c *Contract) SetRecord(name string, typev *big.Int, data string) (util.Uint256, uint32, error) {
return c.actor.SendCall(c.hash, "setRecord", name, typev, data)
}
// SetRecordTransaction creates a transaction invoking `setRecord` method of the contract.
// This transaction is signed, but not sent to the network, instead it's
// returned to the caller.
func (c *Contract) SetRecordTransaction(name string, typev *big.Int, data string) (*transaction.Transaction, error) {
return c.actor.MakeCall(c.hash, "setRecord", name, typev, data)
}
// SetRecordUnsigned creates a transaction invoking `setRecord` method of the contract.
// This transaction is not signed, it's simply returned to the caller.
// Any fields of it that do not affect fees can be changed (ValidUntilBlock,
// Nonce), fee values (NetworkFee, SystemFee) can be increased as well.
func (c *Contract) SetRecordUnsigned(name string, typev *big.Int, data string) (*transaction.Transaction, error) {
return c.actor.MakeUnsignedCall(c.hash, "setRecord", nil, name, typev, data)
}
// DeleteRecord creates a transaction invoking `deleteRecord` method of the contract.
// This transaction is signed and immediately sent to the network.
// The values returned are its hash, ValidUntilBlock value and error if any.
func (c *Contract) DeleteRecord(name string, typev *big.Int) (util.Uint256, uint32, error) {
return c.actor.SendCall(c.hash, "deleteRecord", name, typev)
}
// DeleteRecordTransaction creates a transaction invoking `deleteRecord` method of the contract.
// This transaction is signed, but not sent to the network, instead it's
// returned to the caller.
func (c *Contract) DeleteRecordTransaction(name string, typev *big.Int) (*transaction.Transaction, error) {
return c.actor.MakeCall(c.hash, "deleteRecord", name, typev)
}
// DeleteRecordUnsigned creates a transaction invoking `deleteRecord` method of the contract.
// This transaction is not signed, it's simply returned to the caller.
// Any fields of it that do not affect fees can be changed (ValidUntilBlock,
// Nonce), fee values (NetworkFee, SystemFee) can be increased as well.
func (c *Contract) DeleteRecordUnsigned(name string, typev *big.Int) (*transaction.Transaction, error) {
return c.actor.MakeUnsignedCall(c.hash, "deleteRecord", nil, name, typev)
}
// SetAdminEventsFromApplicationLog retrieves a set of all emitted events
// with "SetAdmin" name from the provided [result.ApplicationLog].
func SetAdminEventsFromApplicationLog(log *result.ApplicationLog) ([]*SetAdminEvent, error) {
if log == nil {
return nil, errors.New("nil application log")
}
var res []*SetAdminEvent
for i, ex := range log.Executions {
for j, e := range ex.Events {
if e.Name != "SetAdmin" {
continue
}
event := new(SetAdminEvent)
err := event.FromStackItem(e.Item)
if err != nil {
return nil, fmt.Errorf("failed to deserialize SetAdminEvent from stackitem (execution #%d, event #%d): %w", i, j, err)
}
res = append(res, event)
}
}
return res, nil
}
// FromStackItem converts provided [stackitem.Array] to SetAdminEvent or
// returns an error if it's not possible to do to so.
func (e *SetAdminEvent) FromStackItem(item *stackitem.Array) error {
if item == nil {
return errors.New("nil item")
}
arr, ok := item.Value().([]stackitem.Item)
if !ok {
return errors.New("not an array")
}
if len(arr) != 3 {
return errors.New("wrong number of structure elements")
}
var (
index = -1
err error
)
index++
e.Name, err = func(item stackitem.Item) (string, error) {
b, err := item.TryBytes()
if err != nil {
return "", err
}
if !utf8.Valid(b) {
return "", errors.New("not a UTF-8 string")
}
return string(b), nil
}(arr[index])
if err != nil {
return fmt.Errorf("field Name: %w", err)
}
index++
e.OldAdmin, err = func(item stackitem.Item) (util.Uint160, error) {
b, err := item.TryBytes()
if err != nil {
return util.Uint160{}, err
}
u, err := util.Uint160DecodeBytesBE(b)
if err != nil {
return util.Uint160{}, err
}
return u, nil
}(arr[index])
if err != nil {
return fmt.Errorf("field OldAdmin: %w", err)
}
index++
e.NewAdmin, err = func(item stackitem.Item) (util.Uint160, error) {
b, err := item.TryBytes()
if err != nil {
return util.Uint160{}, err
}
u, err := util.Uint160DecodeBytesBE(b)
if err != nil {
return util.Uint160{}, err
}
return u, nil
}(arr[index])
if err != nil {
return fmt.Errorf("field NewAdmin: %w", err)
}
return nil
}
// RenewEventsFromApplicationLog retrieves a set of all emitted events
// with "Renew" name from the provided [result.ApplicationLog].
func RenewEventsFromApplicationLog(log *result.ApplicationLog) ([]*RenewEvent, error) {
if log == nil {
return nil, errors.New("nil application log")
}
var res []*RenewEvent
for i, ex := range log.Executions {
for j, e := range ex.Events {
if e.Name != "Renew" {
continue
}
event := new(RenewEvent)
err := event.FromStackItem(e.Item)
if err != nil {
return nil, fmt.Errorf("failed to deserialize RenewEvent from stackitem (execution #%d, event #%d): %w", i, j, err)
}
res = append(res, event)
}
}
return res, nil
}
// FromStackItem converts provided [stackitem.Array] to RenewEvent or
// returns an error if it's not possible to do to so.
func (e *RenewEvent) FromStackItem(item *stackitem.Array) error {
if item == nil {
return errors.New("nil item")
}
arr, ok := item.Value().([]stackitem.Item)
if !ok {
return errors.New("not an array")
}
if len(arr) != 3 {
return errors.New("wrong number of structure elements")
}
var (
index = -1
err error
)
index++
e.Name, err = func(item stackitem.Item) (string, error) {
b, err := item.TryBytes()
if err != nil {
return "", err
}
if !utf8.Valid(b) {
return "", errors.New("not a UTF-8 string")
}
return string(b), nil
}(arr[index])
if err != nil {
return fmt.Errorf("field Name: %w", err)
}
index++
e.OldExpiration, err = arr[index].TryInteger()
if err != nil {
return fmt.Errorf("field OldExpiration: %w", err)
}
index++
e.NewExpiration, err = arr[index].TryInteger()
if err != nil {
return fmt.Errorf("field NewExpiration: %w", err)
}
return nil
}

View file

@ -0,0 +1,441 @@
{
"abi" : {
"events" : [
{
"parameters" : [
{
"name" : "from",
"type" : "Hash160"
},
{
"name" : "to",
"type" : "Hash160"
},
{
"name" : "amount",
"type" : "Integer"
},
{
"type" : "ByteArray",
"name" : "tokenId"
}
],
"name" : "Transfer"
},
{
"parameters" : [
{
"type" : "String",
"name" : "name"
},
{
"type" : "Hash160",
"name" : "oldAdmin"
},
{
"type" : "Hash160",
"name" : "newAdmin"
}
],
"name" : "SetAdmin"
},
{
"name" : "Renew",
"parameters" : [
{
"name" : "name",
"type" : "String"
},
{
"type" : "Integer",
"name" : "oldExpiration"
},
{
"name" : "newExpiration",
"type" : "Integer"
}
]
}
],
"methods" : [
{
"safe" : true,
"parameters" : [],
"name" : "symbol",
"returntype" : "String",
"offset" : 0
},
{
"parameters" : [],
"name" : "decimals",
"returntype" : "Integer",
"safe" : true,
"offset" : 6
},
{
"offset" : 8,
"returntype" : "Integer",
"name" : "totalSupply",
"parameters" : [],
"safe" : true
},
{
"offset" : 53,
"safe" : true,
"parameters" : [
{
"type" : "ByteArray",
"name" : "tokenId"
}
],
"name" : "ownerOf",
"returntype" : "Hash160"
},
{
"safe" : true,
"name" : "properties",
"returntype" : "Map",
"parameters" : [
{
"type" : "ByteArray",
"name" : "tokenId"
}
],
"offset" : 184
},
{
"safe" : true,
"returntype" : "Integer",
"name" : "balanceOf",
"parameters" : [
{
"name" : "owner",
"type" : "Hash160"
}
],
"offset" : 341
},
{
"safe" : true,
"returntype" : "InteropInterface",
"name" : "tokens",
"parameters" : [],
"offset" : 453
},
{
"safe" : true,
"name" : "tokensOf",
"returntype" : "InteropInterface",
"parameters" : [
{
"name" : "owner",
"type" : "Hash160"
}
],
"offset" : 494
},
{
"offset" : 600,
"safe" : false,
"parameters" : [
{
"type" : "Hash160",
"name" : "to"
},
{
"name" : "tokenId",
"type" : "ByteArray"
},
{
"name" : "data",
"type" : "Any"
}
],
"name" : "transfer",
"returntype" : "Boolean"
},
{
"name" : "update",
"returntype" : "Void",
"parameters" : [
{
"type" : "ByteArray",
"name" : "nef"
},
{
"name" : "manifest",
"type" : "String"
}
],
"safe" : false,
"offset" : 1121
},
{
"offset" : 1291,
"returntype" : "Void",
"name" : "addRoot",
"parameters" : [
{
"name" : "root",
"type" : "String"
}
],
"safe" : false
},
{
"offset" : 1725,
"safe" : true,
"parameters" : [],
"returntype" : "InteropInterface",
"name" : "roots"
},
{
"offset" : 1757,
"parameters" : [
{
"type" : "Array",
"name" : "priceList"
}
],
"name" : "setPrice",
"returntype" : "Void",
"safe" : false
},
{
"offset" : 1952,
"safe" : true,
"parameters" : [
{
"name" : "length",
"type" : "Integer"
}
],
"name" : "getPrice",
"returntype" : "Integer"
},
{
"offset" : 2017,
"safe" : true,
"parameters" : [
{
"type" : "String",
"name" : "name"
}
],
"name" : "isAvailable",
"returntype" : "Boolean"
},
{
"offset" : 2405,
"parameters" : [
{
"type" : "String",
"name" : "name"
},
{
"type" : "Hash160",
"name" : "owner"
}
],
"name" : "register",
"returntype" : "Boolean",
"safe" : false
},
{
"name" : "renew",
"returntype" : "Integer",
"parameters" : [
{
"type" : "String",
"name" : "name"
}
],
"safe" : false,
"offset" : 3113
},
{
"offset" : 3123,
"safe" : false,
"parameters" : [
{
"name" : "name",
"type" : "String"
},
{
"name" : "years",
"type" : "Integer"
}
],
"name" : "renew",
"returntype" : "Integer"
},
{
"offset" : 3697,
"parameters" : [
{
"type" : "String",
"name" : "name"
},
{
"name" : "admin",
"type" : "Hash160"
}
],
"name" : "setAdmin",
"returntype" : "Void",
"safe" : false
},
{
"safe" : false,
"returntype" : "Void",
"name" : "setRecord",
"parameters" : [
{
"name" : "name",
"type" : "String"
},
{
"type" : "Integer",
"name" : "type"
},
{
"name" : "data",
"type" : "String"
}
],
"offset" : 3921
},
{
"name" : "getRecord",
"returntype" : "String",
"parameters" : [
{
"name" : "name",
"type" : "String"
},
{
"type" : "Integer",
"name" : "type"
}
],
"safe" : true,
"offset" : 5877
},
{
"returntype" : "InteropInterface",
"name" : "getAllRecords",
"parameters" : [
{
"name" : "name",
"type" : "String"
}
],
"safe" : true,
"offset" : 6201
},
{
"safe" : false,
"returntype" : "Void",
"name" : "deleteRecord",
"parameters" : [
{
"name" : "name",
"type" : "String"
},
{
"type" : "Integer",
"name" : "type"
}
],
"offset" : 6281
},
{
"offset" : 6565,
"name" : "resolve",
"returntype" : "String",
"parameters" : [
{
"name" : "name",
"type" : "String"
},
{
"type" : "Integer",
"name" : "type"
}
],
"safe" : true
},
{
"safe" : false,
"parameters" : [
{
"name" : "data",
"type" : "Any"
},
{
"name" : "update",
"type" : "Boolean"
}
],
"name" : "_deploy",
"returntype" : "Void",
"offset" : 7152
},
{
"offset" : 7514,
"parameters" : [],
"returntype" : "Void",
"name" : "_initialize",
"safe" : false
}
]
},
"supportedstandards" : [
"NEP-11"
],
"permissions" : [
{
"contract" : "0x726cb6e0cd8628a1350a611384688911ab75f51b",
"methods" : [
"ripemd160"
]
},
{
"contract" : "0xacce6fd80d44e1796aa0c2c625e9e4e0ce39efc0",
"methods" : [
"atoi",
"deserialize",
"serialize",
"stringSplit"
]
},
{
"contract" : "0xef4073a0f2b305a38ec4050e4d3d28bc40ea63f5",
"methods" : [
"getCommittee"
]
},
{
"contract" : "0xfffdc93764dbaddd97c48f252a53ea4643faa3fd",
"methods" : [
"getContract",
"update"
]
},
{
"methods" : [
"onNEP11Payment"
],
"contract" : "*"
}
],
"features" : {},
"name" : "NameService",
"trusts" : [],
"extra" : {
"Author" : "The Neo Project",
"Description" : "Neo Name Service",
"Email" : "dev@neo.org"
},
"groups" : []
}

339
cli/smartcontract/testdata/nex/nex.go vendored Normal file
View file

@ -0,0 +1,339 @@
// Code generated by neo-go contract generate-rpcwrapper --manifest <file.json> --out <file.go> [--hash <hash>] [--config <config>]; DO NOT EDIT.
// Package nextoken contains RPC wrappers for NEX Token contract.
package nextoken
import (
"errors"
"fmt"
"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/neorpc/result"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/nep17"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap"
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
"math/big"
)
// Hash contains contract hash.
var Hash = util.Uint160{0xa8, 0x1a, 0xa1, 0xf0, 0x4b, 0xf, 0xdc, 0x4a, 0xa2, 0xce, 0xd5, 0xbf, 0xc6, 0x22, 0xcf, 0xe8, 0x9, 0x7f, 0xa6, 0xa2}
// OnMintEvent represents "OnMint" event emitted by the contract.
type OnMintEvent struct {
From util.Uint160
To util.Uint160
Amount *big.Int
SwapId *big.Int
}
// Invoker is used by ContractReader to call various safe methods.
type Invoker interface {
nep17.Invoker
}
// Actor is used by Contract to call state-changing methods.
type Actor interface {
Invoker
nep17.Actor
MakeCall(contract util.Uint160, method string, params ...any) (*transaction.Transaction, error)
MakeRun(script []byte) (*transaction.Transaction, error)
MakeUnsignedCall(contract util.Uint160, method string, attrs []transaction.Attribute, params ...any) (*transaction.Transaction, error)
MakeUnsignedRun(script []byte, attrs []transaction.Attribute) (*transaction.Transaction, error)
SendCall(contract util.Uint160, method string, params ...any) (util.Uint256, uint32, error)
SendRun(script []byte) (util.Uint256, uint32, error)
}
// ContractReader implements safe contract methods.
type ContractReader struct {
nep17.TokenReader
invoker Invoker
hash util.Uint160
}
// Contract implements all contract methods.
type Contract struct {
ContractReader
nep17.TokenWriter
actor Actor
hash util.Uint160
}
// NewReader creates an instance of ContractReader using Hash and the given Invoker.
func NewReader(invoker Invoker) *ContractReader {
var hash = Hash
return &ContractReader{*nep17.NewReader(invoker, hash), invoker, hash}
}
// New creates an instance of Contract using Hash and the given Actor.
func New(actor Actor) *Contract {
var hash = Hash
var nep17t = nep17.New(actor, hash)
return &Contract{ContractReader{nep17t.TokenReader, actor, hash}, nep17t.TokenWriter, actor, hash}
}
// Cap invokes `cap` method of contract.
func (c *ContractReader) Cap() (*big.Int, error) {
return unwrap.BigInt(c.invoker.Call(c.hash, "cap"))
}
// GetMinter invokes `getMinter` method of contract.
func (c *ContractReader) GetMinter() (*keys.PublicKey, error) {
return unwrap.PublicKey(c.invoker.Call(c.hash, "getMinter"))
}
// GetOwner invokes `getOwner` method of contract.
func (c *ContractReader) GetOwner() (util.Uint160, error) {
return unwrap.Uint160(c.invoker.Call(c.hash, "getOwner"))
}
// TotalMinted invokes `totalMinted` method of contract.
func (c *ContractReader) TotalMinted() (*big.Int, error) {
return unwrap.BigInt(c.invoker.Call(c.hash, "totalMinted"))
}
// ChangeMinter creates a transaction invoking `changeMinter` method of the contract.
// This transaction is signed and immediately sent to the network.
// The values returned are its hash, ValidUntilBlock value and error if any.
func (c *Contract) ChangeMinter(newMinter *keys.PublicKey) (util.Uint256, uint32, error) {
return c.actor.SendCall(c.hash, "changeMinter", newMinter)
}
// ChangeMinterTransaction creates a transaction invoking `changeMinter` method of the contract.
// This transaction is signed, but not sent to the network, instead it's
// returned to the caller.
func (c *Contract) ChangeMinterTransaction(newMinter *keys.PublicKey) (*transaction.Transaction, error) {
return c.actor.MakeCall(c.hash, "changeMinter", newMinter)
}
// ChangeMinterUnsigned creates a transaction invoking `changeMinter` method of the contract.
// This transaction is not signed, it's simply returned to the caller.
// Any fields of it that do not affect fees can be changed (ValidUntilBlock,
// Nonce), fee values (NetworkFee, SystemFee) can be increased as well.
func (c *Contract) ChangeMinterUnsigned(newMinter *keys.PublicKey) (*transaction.Transaction, error) {
return c.actor.MakeUnsignedCall(c.hash, "changeMinter", nil, newMinter)
}
// ChangeOwner creates a transaction invoking `changeOwner` method of the contract.
// This transaction is signed and immediately sent to the network.
// The values returned are its hash, ValidUntilBlock value and error if any.
func (c *Contract) ChangeOwner(newOwner util.Uint160) (util.Uint256, uint32, error) {
return c.actor.SendCall(c.hash, "changeOwner", newOwner)
}
// ChangeOwnerTransaction creates a transaction invoking `changeOwner` method of the contract.
// This transaction is signed, but not sent to the network, instead it's
// returned to the caller.
func (c *Contract) ChangeOwnerTransaction(newOwner util.Uint160) (*transaction.Transaction, error) {
return c.actor.MakeCall(c.hash, "changeOwner", newOwner)
}
// ChangeOwnerUnsigned creates a transaction invoking `changeOwner` method of the contract.
// This transaction is not signed, it's simply returned to the caller.
// Any fields of it that do not affect fees can be changed (ValidUntilBlock,
// Nonce), fee values (NetworkFee, SystemFee) can be increased as well.
func (c *Contract) ChangeOwnerUnsigned(newOwner util.Uint160) (*transaction.Transaction, error) {
return c.actor.MakeUnsignedCall(c.hash, "changeOwner", nil, newOwner)
}
// Destroy creates a transaction invoking `destroy` method of the contract.
// This transaction is signed and immediately sent to the network.
// The values returned are its hash, ValidUntilBlock value and error if any.
func (c *Contract) Destroy() (util.Uint256, uint32, error) {
return c.actor.SendCall(c.hash, "destroy")
}
// DestroyTransaction creates a transaction invoking `destroy` method of the contract.
// This transaction is signed, but not sent to the network, instead it's
// returned to the caller.
func (c *Contract) DestroyTransaction() (*transaction.Transaction, error) {
return c.actor.MakeCall(c.hash, "destroy")
}
// DestroyUnsigned creates a transaction invoking `destroy` method of the contract.
// This transaction is not signed, it's simply returned to the caller.
// Any fields of it that do not affect fees can be changed (ValidUntilBlock,
// Nonce), fee values (NetworkFee, SystemFee) can be increased as well.
func (c *Contract) DestroyUnsigned() (*transaction.Transaction, error) {
return c.actor.MakeUnsignedCall(c.hash, "destroy", nil)
}
// MaxSupply creates a transaction invoking `maxSupply` method of the contract.
// This transaction is signed and immediately sent to the network.
// The values returned are its hash, ValidUntilBlock value and error if any.
func (c *Contract) MaxSupply() (util.Uint256, uint32, error) {
return c.actor.SendCall(c.hash, "maxSupply")
}
// MaxSupplyTransaction creates a transaction invoking `maxSupply` method of the contract.
// This transaction is signed, but not sent to the network, instead it's
// returned to the caller.
func (c *Contract) MaxSupplyTransaction() (*transaction.Transaction, error) {
return c.actor.MakeCall(c.hash, "maxSupply")
}
// MaxSupplyUnsigned creates a transaction invoking `maxSupply` method of the contract.
// This transaction is not signed, it's simply returned to the caller.
// Any fields of it that do not affect fees can be changed (ValidUntilBlock,
// Nonce), fee values (NetworkFee, SystemFee) can be increased as well.
func (c *Contract) MaxSupplyUnsigned() (*transaction.Transaction, error) {
return c.actor.MakeUnsignedCall(c.hash, "maxSupply", nil)
}
// Mint creates a transaction invoking `mint` method of the contract.
// This transaction is signed and immediately sent to the network.
// The values returned are its hash, ValidUntilBlock value and error if any.
func (c *Contract) Mint(from util.Uint160, to util.Uint160, amount *big.Int, swapId *big.Int, signature []byte, data any) (util.Uint256, uint32, error) {
return c.actor.SendCall(c.hash, "mint", from, to, amount, swapId, signature, data)
}
// MintTransaction creates a transaction invoking `mint` method of the contract.
// This transaction is signed, but not sent to the network, instead it's
// returned to the caller.
func (c *Contract) MintTransaction(from util.Uint160, to util.Uint160, amount *big.Int, swapId *big.Int, signature []byte, data any) (*transaction.Transaction, error) {
return c.actor.MakeCall(c.hash, "mint", from, to, amount, swapId, signature, data)
}
// MintUnsigned creates a transaction invoking `mint` method of the contract.
// This transaction is not signed, it's simply returned to the caller.
// Any fields of it that do not affect fees can be changed (ValidUntilBlock,
// Nonce), fee values (NetworkFee, SystemFee) can be increased as well.
func (c *Contract) MintUnsigned(from util.Uint160, to util.Uint160, amount *big.Int, swapId *big.Int, signature []byte, data any) (*transaction.Transaction, error) {
return c.actor.MakeUnsignedCall(c.hash, "mint", nil, from, to, amount, swapId, signature, data)
}
// Update creates a transaction invoking `update` method of the contract.
// This transaction is signed and immediately sent to the network.
// The values returned are its hash, ValidUntilBlock value and error if any.
func (c *Contract) Update(nef []byte, manifest []byte) (util.Uint256, uint32, error) {
return c.actor.SendCall(c.hash, "update", nef, manifest)
}
// UpdateTransaction creates a transaction invoking `update` method of the contract.
// This transaction is signed, but not sent to the network, instead it's
// returned to the caller.
func (c *Contract) UpdateTransaction(nef []byte, manifest []byte) (*transaction.Transaction, error) {
return c.actor.MakeCall(c.hash, "update", nef, manifest)
}
// UpdateUnsigned creates a transaction invoking `update` method of the contract.
// This transaction is not signed, it's simply returned to the caller.
// Any fields of it that do not affect fees can be changed (ValidUntilBlock,
// Nonce), fee values (NetworkFee, SystemFee) can be increased as well.
func (c *Contract) UpdateUnsigned(nef []byte, manifest []byte) (*transaction.Transaction, error) {
return c.actor.MakeUnsignedCall(c.hash, "update", nil, nef, manifest)
}
// UpdateCap creates a transaction invoking `updateCap` method of the contract.
// This transaction is signed and immediately sent to the network.
// The values returned are its hash, ValidUntilBlock value and error if any.
func (c *Contract) UpdateCap(newCap *big.Int) (util.Uint256, uint32, error) {
return c.actor.SendCall(c.hash, "updateCap", newCap)
}
// UpdateCapTransaction creates a transaction invoking `updateCap` method of the contract.
// This transaction is signed, but not sent to the network, instead it's
// returned to the caller.
func (c *Contract) UpdateCapTransaction(newCap *big.Int) (*transaction.Transaction, error) {
return c.actor.MakeCall(c.hash, "updateCap", newCap)
}
// UpdateCapUnsigned creates a transaction invoking `updateCap` method of the contract.
// This transaction is not signed, it's simply returned to the caller.
// Any fields of it that do not affect fees can be changed (ValidUntilBlock,
// Nonce), fee values (NetworkFee, SystemFee) can be increased as well.
func (c *Contract) UpdateCapUnsigned(newCap *big.Int) (*transaction.Transaction, error) {
return c.actor.MakeUnsignedCall(c.hash, "updateCap", nil, newCap)
}
// OnMintEventsFromApplicationLog retrieves a set of all emitted events
// with "OnMint" name from the provided [result.ApplicationLog].
func OnMintEventsFromApplicationLog(log *result.ApplicationLog) ([]*OnMintEvent, error) {
if log == nil {
return nil, errors.New("nil application log")
}
var res []*OnMintEvent
for i, ex := range log.Executions {
for j, e := range ex.Events {
if e.Name != "OnMint" {
continue
}
event := new(OnMintEvent)
err := event.FromStackItem(e.Item)
if err != nil {
return nil, fmt.Errorf("failed to deserialize OnMintEvent from stackitem (execution #%d, event #%d): %w", i, j, err)
}
res = append(res, event)
}
}
return res, nil
}
// FromStackItem converts provided [stackitem.Array] to OnMintEvent or
// returns an error if it's not possible to do to so.
func (e *OnMintEvent) FromStackItem(item *stackitem.Array) error {
if item == nil {
return errors.New("nil item")
}
arr, ok := item.Value().([]stackitem.Item)
if !ok {
return errors.New("not an array")
}
if len(arr) != 4 {
return errors.New("wrong number of structure elements")
}
var (
index = -1
err error
)
index++
e.From, err = func(item stackitem.Item) (util.Uint160, error) {
b, err := item.TryBytes()
if err != nil {
return util.Uint160{}, err
}
u, err := util.Uint160DecodeBytesBE(b)
if err != nil {
return util.Uint160{}, err
}
return u, nil
}(arr[index])
if err != nil {
return fmt.Errorf("field From: %w", err)
}
index++
e.To, err = func(item stackitem.Item) (util.Uint160, error) {
b, err := item.TryBytes()
if err != nil {
return util.Uint160{}, err
}
u, err := util.Uint160DecodeBytesBE(b)
if err != nil {
return util.Uint160{}, err
}
return u, nil
}(arr[index])
if err != nil {
return fmt.Errorf("field To: %w", err)
}
index++
e.Amount, err = arr[index].TryInteger()
if err != nil {
return fmt.Errorf("field Amount: %w", err)
}
index++
e.SwapId, err = arr[index].TryInteger()
if err != nil {
return fmt.Errorf("field SwapId: %w", err)
}
return nil
}

View file

@ -0,0 +1,275 @@
{
"name" : "NEX Token",
"abi" : {
"events" : [
{
"parameters" : [
{
"type" : "Hash160",
"name" : "from"
},
{
"name" : "to",
"type" : "Hash160"
},
{
"name" : "amount",
"type" : "Integer"
}
],
"name" : "Transfer"
},
{
"name" : "OnMint",
"parameters" : [
{
"name" : "from",
"type" : "Hash160"
},
{
"type" : "Hash160",
"name" : "to"
},
{
"type" : "Integer",
"name" : "amount"
},
{
"name" : "swapId",
"type" : "Integer"
}
]
}
],
"methods" : [
{
"parameters" : [],
"offset" : 0,
"name" : "_initialize",
"safe" : false,
"returntype" : "Void"
},
{
"parameters" : [
{
"type" : "Any",
"name" : "data"
},
{
"name" : "isUpdate",
"type" : "Boolean"
}
],
"offset" : 3,
"name" : "_deploy",
"safe" : false,
"returntype" : "Void"
},
{
"parameters" : [
{
"type" : "Hash160",
"name" : "holder"
}
],
"offset" : 484,
"returntype" : "Integer",
"safe" : true,
"name" : "balanceOf"
},
{
"safe" : true,
"returntype" : "Integer",
"name" : "cap",
"offset" : 1881,
"parameters" : []
},
{
"name" : "changeMinter",
"safe" : false,
"returntype" : "Void",
"parameters" : [
{
"name" : "newMinter",
"type" : "PublicKey"
}
],
"offset" : 1678
},
{
"parameters" : [
{
"type" : "Hash160",
"name" : "newOwner"
}
],
"offset" : 1659,
"name" : "changeOwner",
"safe" : false,
"returntype" : "Void"
},
{
"offset" : 466,
"parameters" : [],
"safe" : true,
"name" : "decimals",
"returntype" : "Integer"
},
{
"returntype" : "Void",
"safe" : false,
"name" : "destroy",
"parameters" : [],
"offset" : 1194
},
{
"safe" : true,
"returntype" : "PublicKey",
"name" : "getMinter",
"offset" : 1671,
"parameters" : []
},
{
"parameters" : [],
"offset" : 1652,
"name" : "getOwner",
"safe" : true,
"returntype" : "Hash160"
},
{
"name" : "maxSupply",
"safe" : false,
"returntype" : "Integer",
"parameters" : [],
"offset" : 468
},
{
"offset" : 1222,
"parameters" : [
{
"name" : "from",
"type" : "Hash160"
},
{
"name" : "to",
"type" : "Hash160"
},
{
"type" : "Integer",
"name" : "amount"
},
{
"name" : "swapId",
"type" : "Integer"
},
{
"name" : "signature",
"type" : "Signature"
},
{
"name" : "data",
"type" : "Any"
}
],
"safe" : false,
"name" : "mint",
"returntype" : "Void"
},
{
"safe" : true,
"name" : "symbol",
"returntype" : "String",
"parameters" : [],
"offset" : 460
},
{
"offset" : 1854,
"parameters" : [],
"name" : "totalMinted",
"safe" : true,
"returntype" : "Integer"
},
{
"offset" : 478,
"parameters" : [],
"name" : "totalSupply",
"safe" : true,
"returntype" : "Integer"
},
{
"offset" : 543,
"parameters" : [
{
"name" : "from",
"type" : "Hash160"
},
{
"name" : "to",
"type" : "Hash160"
},
{
"type" : "Integer",
"name" : "amount"
},
{
"name" : "data",
"type" : "Any"
}
],
"name" : "transfer",
"safe" : false,
"returntype" : "Boolean"
},
{
"offset" : 1205,
"parameters" : [
{
"type" : "ByteArray",
"name" : "nef"
},
{
"name" : "manifest",
"type" : "ByteArray"
}
],
"safe" : false,
"returntype" : "Void",
"name" : "update"
},
{
"offset" : 1717,
"parameters" : [
{
"type" : "Integer",
"name" : "newCap"
}
],
"returntype" : "Void",
"safe" : false,
"name" : "updateCap"
}
]
},
"supportedstandards" : [
"NEP-17"
],
"extra" : null,
"trusts" : [],
"features" : {},
"groups" : [],
"permissions" : [
{
"methods" : [
"onNEP17Payment"
],
"contract" : "*"
},
{
"methods" : [
"update",
"destroy"
],
"contract" : "0xfffdc93764dbaddd97c48f252a53ea4643faa3fd"
}
]
}

View file

@ -0,0 +1,63 @@
// Code generated by neo-go contract generate-rpcwrapper --manifest <file.json> --out <file.go> [--hash <hash>] [--config <config>]; DO NOT EDIT.
// Package nonnepxxcontractwithiterators contains RPC wrappers for Non-NEPXX contract with iterators contract.
package nonnepxxcontractwithiterators
import (
"github.com/google/uuid"
"github.com/nspcc-dev/neo-go/pkg/neorpc/result"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap"
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
)
// Hash contains contract hash.
var Hash = util.Uint160{0x33, 0x22, 0x11, 0x0, 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x0}
// Invoker is used by ContractReader to call various safe methods.
type Invoker interface {
Call(contract util.Uint160, operation string, params ...any) (*result.Invoke, error)
CallAndExpandIterator(contract util.Uint160, method string, maxItems int, params ...any) (*result.Invoke, error)
TerminateSession(sessionID uuid.UUID) error
TraverseIterator(sessionID uuid.UUID, iterator *result.Iterator, num int) ([]stackitem.Item, error)
}
// ContractReader implements safe contract methods.
type ContractReader struct {
invoker Invoker
hash util.Uint160
}
// NewReader creates an instance of ContractReader using Hash and the given Invoker.
func NewReader(invoker Invoker) *ContractReader {
var hash = Hash
return &ContractReader{invoker, hash}
}
// Tokens invokes `tokens` method of contract.
func (c *ContractReader) Tokens() (uuid.UUID, result.Iterator, error) {
return unwrap.SessionIterator(c.invoker.Call(c.hash, "tokens"))
}
// TokensExpanded is similar to Tokens (uses the same contract
// method), but can be useful if the server used doesn't support sessions and
// doesn't expand iterators. It creates a script that will get the specified
// number of result items from the iterator right in the VM and return them to
// you. It's only limited by VM stack and GAS available for RPC invocations.
func (c *ContractReader) TokensExpanded(_numOfIteratorItems int) ([]stackitem.Item, error) {
return unwrap.Array(c.invoker.CallAndExpandIterator(c.hash, "tokens", _numOfIteratorItems))
}
// GetAllRecords invokes `getAllRecords` method of contract.
func (c *ContractReader) GetAllRecords(name string) (uuid.UUID, result.Iterator, error) {
return unwrap.SessionIterator(c.invoker.Call(c.hash, "getAllRecords", name))
}
// GetAllRecordsExpanded is similar to GetAllRecords (uses the same contract
// method), but can be useful if the server used doesn't support sessions and
// doesn't expand iterators. It creates a script that will get the specified
// number of result items from the iterator right in the VM and return them to
// you. It's only limited by VM stack and GAS available for RPC invocations.
func (c *ContractReader) GetAllRecordsExpanded(name string, _numOfIteratorItems int) ([]stackitem.Item, error) {
return unwrap.Array(c.invoker.CallAndExpandIterator(c.hash, "getAllRecords", _numOfIteratorItems, name))
}

View file

@ -0,0 +1,33 @@
{
"groups" : [],
"abi" : {
"events" : [],
"methods" : [
{
"parameters" : [],
"safe" : true,
"name" : "tokens",
"offset" : 0,
"returntype" : "InteropInterface"
},
{
"offset" : 1,
"returntype" : "InteropInterface",
"safe" : true,
"parameters" : [
{
"type" : "String",
"name" : "name"
}
],
"name" : "getAllRecords"
}
]
},
"supportedstandards" : [],
"trusts" : [],
"extra" : {},
"permissions" : [],
"name" : "Non-NEPXX contract with iterators",
"features" : {}
}

View file

@ -0,0 +1,7 @@
package invalid1
import "github.com/nspcc-dev/neo-go/pkg/interop/runtime"
func Main() {
runtime.Notify("Non declared event")
}

View file

@ -0,0 +1 @@
name: Test undeclared event

View file

@ -0,0 +1,7 @@
package invalid2
import "github.com/nspcc-dev/neo-go/pkg/interop/runtime"
func Main() {
runtime.Notify("SomeEvent", "p1", "p2")
}

View file

@ -0,0 +1,6 @@
name: Test undeclared event
events:
- name: SomeEvent
parameters:
- name: p1
type: String

View file

@ -0,0 +1,7 @@
package invalid3
import "github.com/nspcc-dev/neo-go/pkg/interop/runtime"
func Main() {
runtime.Notify("SomeEvent", "p1", 5)
}

View file

@ -0,0 +1,8 @@
name: Test undeclared event
events:
- name: SomeEvent
parameters:
- name: p1
type: String
- name: p2
type: String

View file

@ -0,0 +1,17 @@
package invalid4
import "github.com/nspcc-dev/neo-go/pkg/interop/runtime"
type SomeStruct1 struct {
Field1 int
}
type SomeStruct2 struct {
Field2 string
}
func Main() {
// Inconsistent event params usages (different named types throughout the usages).
runtime.Notify("SomeEvent", SomeStruct1{Field1: 123})
runtime.Notify("SomeEvent", SomeStruct2{Field2: "str"})
}

View file

@ -0,0 +1,6 @@
name: Test undeclared event
events:
- name: SomeEvent
parameters:
- name: p1
type: Array

View file

@ -0,0 +1,12 @@
package invalid5
import "github.com/nspcc-dev/neo-go/pkg/interop/runtime"
type NamedStruct struct {
SomeInt int
}
func Main() NamedStruct {
runtime.Notify("SomeEvent", []interface{}{123})
return NamedStruct{SomeInt: 123}
}

View file

@ -0,0 +1,16 @@
name: Test undeclared event
events:
- name: SomeEvent
parameters:
- name: p1
type: Array
extendedtype:
base: Array
name: invalid5.NamedStruct
namedtypes:
invalid5.NamedStruct:
base: Array
name: invalid5.NamedStruct
fields:
- field: SomeInt
base: Integer

View file

@ -0,0 +1,14 @@
package invalid6
import "github.com/nspcc-dev/neo-go/pkg/interop/runtime"
type SomeStruct struct {
Field int
// RPC binding generator will convert this field into exported, which matches
// exactly the existing Field.
field int
}
func Main() {
runtime.Notify("SomeEvent", SomeStruct{Field: 123, field: 123})
}

View file

@ -0,0 +1,18 @@
name: Test duplicating event fields
events:
- name: SomeEvent
parameters:
- name: p1
type: Struct
extendedtype:
base: Struct
name: SomeStruct
namedtypes:
SomeStruct:
base: Struct
name: SomeStruct
fields:
- field: Field
base: Integer
- field: field
base: Integer

View file

@ -0,0 +1,14 @@
package invalid7
import "github.com/nspcc-dev/neo-go/pkg/interop/runtime"
type SomeStruct struct {
Field int
// RPC binding generator will convert this field into exported, which matches
// exactly the existing Field.
field int
}
func Main() {
runtime.Notify("SomeEvent", SomeStruct{Field: 123, field: 123})
}

View file

@ -0,0 +1,6 @@
name: Test duplicating autogenerated event fields
events:
- name: SomeEvent
parameters:
- name: p1
type: Struct

View file

@ -0,0 +1,16 @@
package invalid8
type SomeStruct struct {
Field int
// RPC binding generator will convert this field into exported, which matches
// exactly the existing Field.
field int
}
func Main() SomeStruct {
s := SomeStruct{
Field: 1,
field: 2,
}
return s
}

View file

@ -0,0 +1 @@
name: Test duplicating struct fields

View file

@ -0,0 +1,23 @@
name: "Notifications"
sourceurl: https://github.com/nspcc-dev/neo-go/
events:
- name: "! complicated name %$#"
parameters:
- name: ! complicated param @#$%
type: String
- name: "SomeMap"
parameters:
- name: m
type: Map
- name: "SomeStruct"
parameters:
- name: s
type: Struct
- name: "SomeArray"
parameters:
- name: a
type: Array
- name: "SomeUnexportedField"
parameters:
- name: s
type: Struct

View file

@ -0,0 +1,60 @@
name: "Notifications"
sourceurl: https://github.com/nspcc-dev/neo-go/
events:
- name: "! complicated name %$#"
parameters:
- name: ! complicated param @#$%
type: String
- name: "SomeMap"
parameters:
- name: m
type: Map
extendedtype:
base: Map
key: Integer
value:
base: Map
key: String
value:
base: Array
value:
base: Hash160
- name: "SomeStruct"
parameters:
- name: s
type: Struct
extendedtype:
base: Struct
name: crazyStruct
- name: "SomeArray"
parameters:
- name: a
type: Array
extendedtype:
base: Array
value:
base: Array
value:
base: Integer
- name: "SomeUnexportedField"
parameters:
- name: s
type: Struct
extendedtype:
base: Struct
name: simpleStruct
namedtypes:
crazyStruct:
base: Struct
name: crazyStruct
fields:
- field: I
base: Integer
- field: B
base: Boolean
simpleStruct:
base: Struct
name: simpleStruct
fields:
- field: i
base: Integer

View file

@ -0,0 +1,23 @@
name: "Notifications"
sourceurl: https://github.com/nspcc-dev/neo-go/
events:
- name: "! complicated name %$#"
parameters:
- name: ! complicated param @#$%
type: String
- name: "SomeMap"
parameters:
- name: m
type: Map
- name: "SomeStruct"
parameters:
- name: s
type: Struct
- name: "SomeArray"
parameters:
- name: a
type: Array
- name: "SomeUnexportedField"
parameters:
- name: s
type: Struct

View file

@ -0,0 +1,33 @@
package structs
import (
"github.com/nspcc-dev/neo-go/pkg/interop"
"github.com/nspcc-dev/neo-go/pkg/interop/runtime"
)
func Main() {
runtime.Notify("! complicated name %$#", "str1")
}
func CrazyMap() {
runtime.Notify("SomeMap", map[int][]map[string][]interop.Hash160{})
}
func Struct() {
runtime.Notify("SomeStruct", struct {
I int
B bool
}{I: 123, B: true})
}
func Array() {
runtime.Notify("SomeArray", [][]int{})
}
// UnexportedField emits notification with unexported field that must be converted
// to exported in the resulting RPC binding.
func UnexportedField() {
runtime.Notify("SomeUnexportedField", struct {
i int
}{i: 123})
}

View file

@ -0,0 +1,500 @@
// Code generated by neo-go contract generate-rpcwrapper --manifest <file.json> --out <file.go> [--hash <hash>] [--config <config>]; DO NOT EDIT.
// Package structs contains RPC wrappers for Notifications contract.
package structs
import (
"errors"
"fmt"
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
"github.com/nspcc-dev/neo-go/pkg/neorpc/result"
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
"unicode/utf8"
)
// Hash contains contract hash.
var Hash = util.Uint160{0x33, 0x22, 0x11, 0x0, 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x0}
// ComplicatedNameEvent represents "! complicated name %$#" event emitted by the contract.
type ComplicatedNameEvent struct {
ComplicatedParam string
}
// SomeMapEvent represents "SomeMap" event emitted by the contract.
type SomeMapEvent struct {
M map[any]any
}
// SomeStructEvent represents "SomeStruct" event emitted by the contract.
type SomeStructEvent struct {
S []any
}
// SomeArrayEvent represents "SomeArray" event emitted by the contract.
type SomeArrayEvent struct {
A []any
}
// SomeUnexportedFieldEvent represents "SomeUnexportedField" event emitted by the contract.
type SomeUnexportedFieldEvent struct {
S []any
}
// Actor is used by Contract to call state-changing methods.
type Actor interface {
MakeCall(contract util.Uint160, method string, params ...any) (*transaction.Transaction, error)
MakeRun(script []byte) (*transaction.Transaction, error)
MakeUnsignedCall(contract util.Uint160, method string, attrs []transaction.Attribute, params ...any) (*transaction.Transaction, error)
MakeUnsignedRun(script []byte, attrs []transaction.Attribute) (*transaction.Transaction, error)
SendCall(contract util.Uint160, method string, params ...any) (util.Uint256, uint32, error)
SendRun(script []byte) (util.Uint256, uint32, error)
}
// Contract implements all contract methods.
type Contract struct {
actor Actor
hash util.Uint160
}
// New creates an instance of Contract using Hash and the given Actor.
func New(actor Actor) *Contract {
var hash = Hash
return &Contract{actor, hash}
}
// Array creates a transaction invoking `array` method of the contract.
// This transaction is signed and immediately sent to the network.
// The values returned are its hash, ValidUntilBlock value and error if any.
func (c *Contract) Array() (util.Uint256, uint32, error) {
return c.actor.SendCall(c.hash, "array")
}
// ArrayTransaction creates a transaction invoking `array` method of the contract.
// This transaction is signed, but not sent to the network, instead it's
// returned to the caller.
func (c *Contract) ArrayTransaction() (*transaction.Transaction, error) {
return c.actor.MakeCall(c.hash, "array")
}
// ArrayUnsigned creates a transaction invoking `array` method of the contract.
// This transaction is not signed, it's simply returned to the caller.
// Any fields of it that do not affect fees can be changed (ValidUntilBlock,
// Nonce), fee values (NetworkFee, SystemFee) can be increased as well.
func (c *Contract) ArrayUnsigned() (*transaction.Transaction, error) {
return c.actor.MakeUnsignedCall(c.hash, "array", nil)
}
// CrazyMap creates a transaction invoking `crazyMap` method of the contract.
// This transaction is signed and immediately sent to the network.
// The values returned are its hash, ValidUntilBlock value and error if any.
func (c *Contract) CrazyMap() (util.Uint256, uint32, error) {
return c.actor.SendCall(c.hash, "crazyMap")
}
// CrazyMapTransaction creates a transaction invoking `crazyMap` method of the contract.
// This transaction is signed, but not sent to the network, instead it's
// returned to the caller.
func (c *Contract) CrazyMapTransaction() (*transaction.Transaction, error) {
return c.actor.MakeCall(c.hash, "crazyMap")
}
// CrazyMapUnsigned creates a transaction invoking `crazyMap` method of the contract.
// This transaction is not signed, it's simply returned to the caller.
// Any fields of it that do not affect fees can be changed (ValidUntilBlock,
// Nonce), fee values (NetworkFee, SystemFee) can be increased as well.
func (c *Contract) CrazyMapUnsigned() (*transaction.Transaction, error) {
return c.actor.MakeUnsignedCall(c.hash, "crazyMap", nil)
}
// Main creates a transaction invoking `main` method of the contract.
// This transaction is signed and immediately sent to the network.
// The values returned are its hash, ValidUntilBlock value and error if any.
func (c *Contract) Main() (util.Uint256, uint32, error) {
return c.actor.SendCall(c.hash, "main")
}
// MainTransaction creates a transaction invoking `main` method of the contract.
// This transaction is signed, but not sent to the network, instead it's
// returned to the caller.
func (c *Contract) MainTransaction() (*transaction.Transaction, error) {
return c.actor.MakeCall(c.hash, "main")
}
// MainUnsigned creates a transaction invoking `main` method of the contract.
// This transaction is not signed, it's simply returned to the caller.
// Any fields of it that do not affect fees can be changed (ValidUntilBlock,
// Nonce), fee values (NetworkFee, SystemFee) can be increased as well.
func (c *Contract) MainUnsigned() (*transaction.Transaction, error) {
return c.actor.MakeUnsignedCall(c.hash, "main", nil)
}
// Struct creates a transaction invoking `struct` method of the contract.
// This transaction is signed and immediately sent to the network.
// The values returned are its hash, ValidUntilBlock value and error if any.
func (c *Contract) Struct() (util.Uint256, uint32, error) {
return c.actor.SendCall(c.hash, "struct")
}
// StructTransaction creates a transaction invoking `struct` method of the contract.
// This transaction is signed, but not sent to the network, instead it's
// returned to the caller.
func (c *Contract) StructTransaction() (*transaction.Transaction, error) {
return c.actor.MakeCall(c.hash, "struct")
}
// StructUnsigned creates a transaction invoking `struct` method of the contract.
// This transaction is not signed, it's simply returned to the caller.
// Any fields of it that do not affect fees can be changed (ValidUntilBlock,
// Nonce), fee values (NetworkFee, SystemFee) can be increased as well.
func (c *Contract) StructUnsigned() (*transaction.Transaction, error) {
return c.actor.MakeUnsignedCall(c.hash, "struct", nil)
}
// UnexportedField creates a transaction invoking `unexportedField` method of the contract.
// This transaction is signed and immediately sent to the network.
// The values returned are its hash, ValidUntilBlock value and error if any.
func (c *Contract) UnexportedField() (util.Uint256, uint32, error) {
return c.actor.SendCall(c.hash, "unexportedField")
}
// UnexportedFieldTransaction creates a transaction invoking `unexportedField` method of the contract.
// This transaction is signed, but not sent to the network, instead it's
// returned to the caller.
func (c *Contract) UnexportedFieldTransaction() (*transaction.Transaction, error) {
return c.actor.MakeCall(c.hash, "unexportedField")
}
// UnexportedFieldUnsigned creates a transaction invoking `unexportedField` method of the contract.
// This transaction is not signed, it's simply returned to the caller.
// Any fields of it that do not affect fees can be changed (ValidUntilBlock,
// Nonce), fee values (NetworkFee, SystemFee) can be increased as well.
func (c *Contract) UnexportedFieldUnsigned() (*transaction.Transaction, error) {
return c.actor.MakeUnsignedCall(c.hash, "unexportedField", nil)
}
// ComplicatedNameEventsFromApplicationLog retrieves a set of all emitted events
// with "! complicated name %$#" name from the provided [result.ApplicationLog].
func ComplicatedNameEventsFromApplicationLog(log *result.ApplicationLog) ([]*ComplicatedNameEvent, error) {
if log == nil {
return nil, errors.New("nil application log")
}
var res []*ComplicatedNameEvent
for i, ex := range log.Executions {
for j, e := range ex.Events {
if e.Name != "! complicated name %$#" {
continue
}
event := new(ComplicatedNameEvent)
err := event.FromStackItem(e.Item)
if err != nil {
return nil, fmt.Errorf("failed to deserialize ComplicatedNameEvent from stackitem (execution #%d, event #%d): %w", i, j, err)
}
res = append(res, event)
}
}
return res, nil
}
// FromStackItem converts provided [stackitem.Array] to ComplicatedNameEvent or
// returns an error if it's not possible to do to so.
func (e *ComplicatedNameEvent) FromStackItem(item *stackitem.Array) error {
if item == nil {
return errors.New("nil item")
}
arr, ok := item.Value().([]stackitem.Item)
if !ok {
return errors.New("not an array")
}
if len(arr) != 1 {
return errors.New("wrong number of structure elements")
}
var (
index = -1
err error
)
index++
e.ComplicatedParam, err = func(item stackitem.Item) (string, error) {
b, err := item.TryBytes()
if err != nil {
return "", err
}
if !utf8.Valid(b) {
return "", errors.New("not a UTF-8 string")
}
return string(b), nil
}(arr[index])
if err != nil {
return fmt.Errorf("field ComplicatedParam: %w", err)
}
return nil
}
// SomeMapEventsFromApplicationLog retrieves a set of all emitted events
// with "SomeMap" name from the provided [result.ApplicationLog].
func SomeMapEventsFromApplicationLog(log *result.ApplicationLog) ([]*SomeMapEvent, error) {
if log == nil {
return nil, errors.New("nil application log")
}
var res []*SomeMapEvent
for i, ex := range log.Executions {
for j, e := range ex.Events {
if e.Name != "SomeMap" {
continue
}
event := new(SomeMapEvent)
err := event.FromStackItem(e.Item)
if err != nil {
return nil, fmt.Errorf("failed to deserialize SomeMapEvent from stackitem (execution #%d, event #%d): %w", i, j, err)
}
res = append(res, event)
}
}
return res, nil
}
// FromStackItem converts provided [stackitem.Array] to SomeMapEvent or
// returns an error if it's not possible to do to so.
func (e *SomeMapEvent) FromStackItem(item *stackitem.Array) error {
if item == nil {
return errors.New("nil item")
}
arr, ok := item.Value().([]stackitem.Item)
if !ok {
return errors.New("not an array")
}
if len(arr) != 1 {
return errors.New("wrong number of structure elements")
}
var (
index = -1
err error
)
index++
e.M, err = func(item stackitem.Item) (map[any]any, error) {
m, ok := item.Value().([]stackitem.MapElement)
if !ok {
return nil, fmt.Errorf("%s is not a map", item.Type().String())
}
res := make(map[any]any)
for i := range m {
k, err := m[i].Key.Value(), error(nil)
if err != nil {
return nil, fmt.Errorf("key %d: %w", i, err)
}
v, err := m[i].Value.Value(), error(nil)
if err != nil {
return nil, fmt.Errorf("value %d: %w", i, err)
}
res[k] = v
}
return res, nil
}(arr[index])
if err != nil {
return fmt.Errorf("field M: %w", err)
}
return nil
}
// SomeStructEventsFromApplicationLog retrieves a set of all emitted events
// with "SomeStruct" name from the provided [result.ApplicationLog].
func SomeStructEventsFromApplicationLog(log *result.ApplicationLog) ([]*SomeStructEvent, error) {
if log == nil {
return nil, errors.New("nil application log")
}
var res []*SomeStructEvent
for i, ex := range log.Executions {
for j, e := range ex.Events {
if e.Name != "SomeStruct" {
continue
}
event := new(SomeStructEvent)
err := event.FromStackItem(e.Item)
if err != nil {
return nil, fmt.Errorf("failed to deserialize SomeStructEvent from stackitem (execution #%d, event #%d): %w", i, j, err)
}
res = append(res, event)
}
}
return res, nil
}
// FromStackItem converts provided [stackitem.Array] to SomeStructEvent or
// returns an error if it's not possible to do to so.
func (e *SomeStructEvent) FromStackItem(item *stackitem.Array) error {
if item == nil {
return errors.New("nil item")
}
arr, ok := item.Value().([]stackitem.Item)
if !ok {
return errors.New("not an array")
}
if len(arr) != 1 {
return errors.New("wrong number of structure elements")
}
var (
index = -1
err error
)
index++
e.S, err = func(item stackitem.Item) ([]any, error) {
arr, ok := item.Value().([]stackitem.Item)
if !ok {
return nil, errors.New("not an array")
}
res := make([]any, len(arr))
for i := range res {
res[i], err = arr[i].Value(), error(nil)
if err != nil {
return nil, fmt.Errorf("item %d: %w", i, err)
}
}
return res, nil
}(arr[index])
if err != nil {
return fmt.Errorf("field S: %w", err)
}
return nil
}
// SomeArrayEventsFromApplicationLog retrieves a set of all emitted events
// with "SomeArray" name from the provided [result.ApplicationLog].
func SomeArrayEventsFromApplicationLog(log *result.ApplicationLog) ([]*SomeArrayEvent, error) {
if log == nil {
return nil, errors.New("nil application log")
}
var res []*SomeArrayEvent
for i, ex := range log.Executions {
for j, e := range ex.Events {
if e.Name != "SomeArray" {
continue
}
event := new(SomeArrayEvent)
err := event.FromStackItem(e.Item)
if err != nil {
return nil, fmt.Errorf("failed to deserialize SomeArrayEvent from stackitem (execution #%d, event #%d): %w", i, j, err)
}
res = append(res, event)
}
}
return res, nil
}
// FromStackItem converts provided [stackitem.Array] to SomeArrayEvent or
// returns an error if it's not possible to do to so.
func (e *SomeArrayEvent) FromStackItem(item *stackitem.Array) error {
if item == nil {
return errors.New("nil item")
}
arr, ok := item.Value().([]stackitem.Item)
if !ok {
return errors.New("not an array")
}
if len(arr) != 1 {
return errors.New("wrong number of structure elements")
}
var (
index = -1
err error
)
index++
e.A, err = func(item stackitem.Item) ([]any, error) {
arr, ok := item.Value().([]stackitem.Item)
if !ok {
return nil, errors.New("not an array")
}
res := make([]any, len(arr))
for i := range res {
res[i], err = arr[i].Value(), error(nil)
if err != nil {
return nil, fmt.Errorf("item %d: %w", i, err)
}
}
return res, nil
}(arr[index])
if err != nil {
return fmt.Errorf("field A: %w", err)
}
return nil
}
// SomeUnexportedFieldEventsFromApplicationLog retrieves a set of all emitted events
// with "SomeUnexportedField" name from the provided [result.ApplicationLog].
func SomeUnexportedFieldEventsFromApplicationLog(log *result.ApplicationLog) ([]*SomeUnexportedFieldEvent, error) {
if log == nil {
return nil, errors.New("nil application log")
}
var res []*SomeUnexportedFieldEvent
for i, ex := range log.Executions {
for j, e := range ex.Events {
if e.Name != "SomeUnexportedField" {
continue
}
event := new(SomeUnexportedFieldEvent)
err := event.FromStackItem(e.Item)
if err != nil {
return nil, fmt.Errorf("failed to deserialize SomeUnexportedFieldEvent from stackitem (execution #%d, event #%d): %w", i, j, err)
}
res = append(res, event)
}
}
return res, nil
}
// FromStackItem converts provided [stackitem.Array] to SomeUnexportedFieldEvent or
// returns an error if it's not possible to do to so.
func (e *SomeUnexportedFieldEvent) FromStackItem(item *stackitem.Array) error {
if item == nil {
return errors.New("nil item")
}
arr, ok := item.Value().([]stackitem.Item)
if !ok {
return errors.New("not an array")
}
if len(arr) != 1 {
return errors.New("wrong number of structure elements")
}
var (
index = -1
err error
)
index++
e.S, err = func(item stackitem.Item) ([]any, error) {
arr, ok := item.Value().([]stackitem.Item)
if !ok {
return nil, errors.New("not an array")
}
res := make([]any, len(arr))
for i := range res {
res[i], err = arr[i].Value(), error(nil)
if err != nil {
return nil, fmt.Errorf("item %d: %w", i, err)
}
}
return res, nil
}(arr[index])
if err != nil {
return fmt.Errorf("field S: %w", err)
}
return nil
}

View file

@ -0,0 +1,623 @@
// Code generated by neo-go contract generate-rpcwrapper --manifest <file.json> --out <file.go> [--hash <hash>] [--config <config>]; DO NOT EDIT.
// Package structs contains RPC wrappers for Notifications contract.
package structs
import (
"errors"
"fmt"
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
"github.com/nspcc-dev/neo-go/pkg/neorpc/result"
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
"math/big"
"unicode/utf8"
)
// Hash contains contract hash.
var Hash = util.Uint160{0x33, 0x22, 0x11, 0x0, 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x0}
// CrazyStruct is a contract-specific crazyStruct type used by its methods.
type CrazyStruct struct {
I *big.Int
B bool
}
// SimpleStruct is a contract-specific simpleStruct type used by its methods.
type SimpleStruct struct {
I *big.Int
}
// ComplicatedNameEvent represents "! complicated name %$#" event emitted by the contract.
type ComplicatedNameEvent struct {
ComplicatedParam string
}
// SomeMapEvent represents "SomeMap" event emitted by the contract.
type SomeMapEvent struct {
M map[*big.Int]map[string][]util.Uint160
}
// SomeStructEvent represents "SomeStruct" event emitted by the contract.
type SomeStructEvent struct {
S *CrazyStruct
}
// SomeArrayEvent represents "SomeArray" event emitted by the contract.
type SomeArrayEvent struct {
A [][]*big.Int
}
// SomeUnexportedFieldEvent represents "SomeUnexportedField" event emitted by the contract.
type SomeUnexportedFieldEvent struct {
S *SimpleStruct
}
// Actor is used by Contract to call state-changing methods.
type Actor interface {
MakeCall(contract util.Uint160, method string, params ...any) (*transaction.Transaction, error)
MakeRun(script []byte) (*transaction.Transaction, error)
MakeUnsignedCall(contract util.Uint160, method string, attrs []transaction.Attribute, params ...any) (*transaction.Transaction, error)
MakeUnsignedRun(script []byte, attrs []transaction.Attribute) (*transaction.Transaction, error)
SendCall(contract util.Uint160, method string, params ...any) (util.Uint256, uint32, error)
SendRun(script []byte) (util.Uint256, uint32, error)
}
// Contract implements all contract methods.
type Contract struct {
actor Actor
hash util.Uint160
}
// New creates an instance of Contract using Hash and the given Actor.
func New(actor Actor) *Contract {
var hash = Hash
return &Contract{actor, hash}
}
// Array creates a transaction invoking `array` method of the contract.
// This transaction is signed and immediately sent to the network.
// The values returned are its hash, ValidUntilBlock value and error if any.
func (c *Contract) Array() (util.Uint256, uint32, error) {
return c.actor.SendCall(c.hash, "array")
}
// ArrayTransaction creates a transaction invoking `array` method of the contract.
// This transaction is signed, but not sent to the network, instead it's
// returned to the caller.
func (c *Contract) ArrayTransaction() (*transaction.Transaction, error) {
return c.actor.MakeCall(c.hash, "array")
}
// ArrayUnsigned creates a transaction invoking `array` method of the contract.
// This transaction is not signed, it's simply returned to the caller.
// Any fields of it that do not affect fees can be changed (ValidUntilBlock,
// Nonce), fee values (NetworkFee, SystemFee) can be increased as well.
func (c *Contract) ArrayUnsigned() (*transaction.Transaction, error) {
return c.actor.MakeUnsignedCall(c.hash, "array", nil)
}
// CrazyMap creates a transaction invoking `crazyMap` method of the contract.
// This transaction is signed and immediately sent to the network.
// The values returned are its hash, ValidUntilBlock value and error if any.
func (c *Contract) CrazyMap() (util.Uint256, uint32, error) {
return c.actor.SendCall(c.hash, "crazyMap")
}
// CrazyMapTransaction creates a transaction invoking `crazyMap` method of the contract.
// This transaction is signed, but not sent to the network, instead it's
// returned to the caller.
func (c *Contract) CrazyMapTransaction() (*transaction.Transaction, error) {
return c.actor.MakeCall(c.hash, "crazyMap")
}
// CrazyMapUnsigned creates a transaction invoking `crazyMap` method of the contract.
// This transaction is not signed, it's simply returned to the caller.
// Any fields of it that do not affect fees can be changed (ValidUntilBlock,
// Nonce), fee values (NetworkFee, SystemFee) can be increased as well.
func (c *Contract) CrazyMapUnsigned() (*transaction.Transaction, error) {
return c.actor.MakeUnsignedCall(c.hash, "crazyMap", nil)
}
// Main creates a transaction invoking `main` method of the contract.
// This transaction is signed and immediately sent to the network.
// The values returned are its hash, ValidUntilBlock value and error if any.
func (c *Contract) Main() (util.Uint256, uint32, error) {
return c.actor.SendCall(c.hash, "main")
}
// MainTransaction creates a transaction invoking `main` method of the contract.
// This transaction is signed, but not sent to the network, instead it's
// returned to the caller.
func (c *Contract) MainTransaction() (*transaction.Transaction, error) {
return c.actor.MakeCall(c.hash, "main")
}
// MainUnsigned creates a transaction invoking `main` method of the contract.
// This transaction is not signed, it's simply returned to the caller.
// Any fields of it that do not affect fees can be changed (ValidUntilBlock,
// Nonce), fee values (NetworkFee, SystemFee) can be increased as well.
func (c *Contract) MainUnsigned() (*transaction.Transaction, error) {
return c.actor.MakeUnsignedCall(c.hash, "main", nil)
}
// Struct creates a transaction invoking `struct` method of the contract.
// This transaction is signed and immediately sent to the network.
// The values returned are its hash, ValidUntilBlock value and error if any.
func (c *Contract) Struct() (util.Uint256, uint32, error) {
return c.actor.SendCall(c.hash, "struct")
}
// StructTransaction creates a transaction invoking `struct` method of the contract.
// This transaction is signed, but not sent to the network, instead it's
// returned to the caller.
func (c *Contract) StructTransaction() (*transaction.Transaction, error) {
return c.actor.MakeCall(c.hash, "struct")
}
// StructUnsigned creates a transaction invoking `struct` method of the contract.
// This transaction is not signed, it's simply returned to the caller.
// Any fields of it that do not affect fees can be changed (ValidUntilBlock,
// Nonce), fee values (NetworkFee, SystemFee) can be increased as well.
func (c *Contract) StructUnsigned() (*transaction.Transaction, error) {
return c.actor.MakeUnsignedCall(c.hash, "struct", nil)
}
// UnexportedField creates a transaction invoking `unexportedField` method of the contract.
// This transaction is signed and immediately sent to the network.
// The values returned are its hash, ValidUntilBlock value and error if any.
func (c *Contract) UnexportedField() (util.Uint256, uint32, error) {
return c.actor.SendCall(c.hash, "unexportedField")
}
// UnexportedFieldTransaction creates a transaction invoking `unexportedField` method of the contract.
// This transaction is signed, but not sent to the network, instead it's
// returned to the caller.
func (c *Contract) UnexportedFieldTransaction() (*transaction.Transaction, error) {
return c.actor.MakeCall(c.hash, "unexportedField")
}
// UnexportedFieldUnsigned creates a transaction invoking `unexportedField` method of the contract.
// This transaction is not signed, it's simply returned to the caller.
// Any fields of it that do not affect fees can be changed (ValidUntilBlock,
// Nonce), fee values (NetworkFee, SystemFee) can be increased as well.
func (c *Contract) UnexportedFieldUnsigned() (*transaction.Transaction, error) {
return c.actor.MakeUnsignedCall(c.hash, "unexportedField", nil)
}
// itemToCrazyStruct converts stack item into *CrazyStruct.
func itemToCrazyStruct(item stackitem.Item, err error) (*CrazyStruct, error) {
if err != nil {
return nil, err
}
var res = new(CrazyStruct)
err = res.FromStackItem(item)
return res, err
}
// FromStackItem retrieves fields of CrazyStruct from the given
// [stackitem.Item] or returns an error if it's not possible to do to so.
func (res *CrazyStruct) FromStackItem(item stackitem.Item) error {
arr, ok := item.Value().([]stackitem.Item)
if !ok {
return errors.New("not an array")
}
if len(arr) != 2 {
return errors.New("wrong number of structure elements")
}
var (
index = -1
err error
)
index++
res.I, err = arr[index].TryInteger()
if err != nil {
return fmt.Errorf("field I: %w", err)
}
index++
res.B, err = arr[index].TryBool()
if err != nil {
return fmt.Errorf("field B: %w", err)
}
return nil
}
// itemToSimpleStruct converts stack item into *SimpleStruct.
func itemToSimpleStruct(item stackitem.Item, err error) (*SimpleStruct, error) {
if err != nil {
return nil, err
}
var res = new(SimpleStruct)
err = res.FromStackItem(item)
return res, err
}
// FromStackItem retrieves fields of SimpleStruct from the given
// [stackitem.Item] or returns an error if it's not possible to do to so.
func (res *SimpleStruct) FromStackItem(item stackitem.Item) error {
arr, ok := item.Value().([]stackitem.Item)
if !ok {
return errors.New("not an array")
}
if len(arr) != 1 {
return errors.New("wrong number of structure elements")
}
var (
index = -1
err error
)
index++
res.I, err = arr[index].TryInteger()
if err != nil {
return fmt.Errorf("field I: %w", err)
}
return nil
}
// ComplicatedNameEventsFromApplicationLog retrieves a set of all emitted events
// with "! complicated name %$#" name from the provided [result.ApplicationLog].
func ComplicatedNameEventsFromApplicationLog(log *result.ApplicationLog) ([]*ComplicatedNameEvent, error) {
if log == nil {
return nil, errors.New("nil application log")
}
var res []*ComplicatedNameEvent
for i, ex := range log.Executions {
for j, e := range ex.Events {
if e.Name != "! complicated name %$#" {
continue
}
event := new(ComplicatedNameEvent)
err := event.FromStackItem(e.Item)
if err != nil {
return nil, fmt.Errorf("failed to deserialize ComplicatedNameEvent from stackitem (execution #%d, event #%d): %w", i, j, err)
}
res = append(res, event)
}
}
return res, nil
}
// FromStackItem converts provided [stackitem.Array] to ComplicatedNameEvent or
// returns an error if it's not possible to do to so.
func (e *ComplicatedNameEvent) FromStackItem(item *stackitem.Array) error {
if item == nil {
return errors.New("nil item")
}
arr, ok := item.Value().([]stackitem.Item)
if !ok {
return errors.New("not an array")
}
if len(arr) != 1 {
return errors.New("wrong number of structure elements")
}
var (
index = -1
err error
)
index++
e.ComplicatedParam, err = func(item stackitem.Item) (string, error) {
b, err := item.TryBytes()
if err != nil {
return "", err
}
if !utf8.Valid(b) {
return "", errors.New("not a UTF-8 string")
}
return string(b), nil
}(arr[index])
if err != nil {
return fmt.Errorf("field ComplicatedParam: %w", err)
}
return nil
}
// SomeMapEventsFromApplicationLog retrieves a set of all emitted events
// with "SomeMap" name from the provided [result.ApplicationLog].
func SomeMapEventsFromApplicationLog(log *result.ApplicationLog) ([]*SomeMapEvent, error) {
if log == nil {
return nil, errors.New("nil application log")
}
var res []*SomeMapEvent
for i, ex := range log.Executions {
for j, e := range ex.Events {
if e.Name != "SomeMap" {
continue
}
event := new(SomeMapEvent)
err := event.FromStackItem(e.Item)
if err != nil {
return nil, fmt.Errorf("failed to deserialize SomeMapEvent from stackitem (execution #%d, event #%d): %w", i, j, err)
}
res = append(res, event)
}
}
return res, nil
}
// FromStackItem converts provided [stackitem.Array] to SomeMapEvent or
// returns an error if it's not possible to do to so.
func (e *SomeMapEvent) FromStackItem(item *stackitem.Array) error {
if item == nil {
return errors.New("nil item")
}
arr, ok := item.Value().([]stackitem.Item)
if !ok {
return errors.New("not an array")
}
if len(arr) != 1 {
return errors.New("wrong number of structure elements")
}
var (
index = -1
err error
)
index++
e.M, err = func(item stackitem.Item) (map[*big.Int]map[string][]util.Uint160, error) {
m, ok := item.Value().([]stackitem.MapElement)
if !ok {
return nil, fmt.Errorf("%s is not a map", item.Type().String())
}
res := make(map[*big.Int]map[string][]util.Uint160)
for i := range m {
k, err := m[i].Key.TryInteger()
if err != nil {
return nil, fmt.Errorf("key %d: %w", i, err)
}
v, err := func(item stackitem.Item) (map[string][]util.Uint160, error) {
m, ok := item.Value().([]stackitem.MapElement)
if !ok {
return nil, fmt.Errorf("%s is not a map", item.Type().String())
}
res := make(map[string][]util.Uint160)
for i := range m {
k, err := func(item stackitem.Item) (string, error) {
b, err := item.TryBytes()
if err != nil {
return "", err
}
if !utf8.Valid(b) {
return "", errors.New("not a UTF-8 string")
}
return string(b), nil
}(m[i].Key)
if err != nil {
return nil, fmt.Errorf("key %d: %w", i, err)
}
v, err := func(item stackitem.Item) ([]util.Uint160, error) {
arr, ok := item.Value().([]stackitem.Item)
if !ok {
return nil, errors.New("not an array")
}
res := make([]util.Uint160, len(arr))
for i := range res {
res[i], err = func(item stackitem.Item) (util.Uint160, error) {
b, err := item.TryBytes()
if err != nil {
return util.Uint160{}, err
}
u, err := util.Uint160DecodeBytesBE(b)
if err != nil {
return util.Uint160{}, err
}
return u, nil
}(arr[i])
if err != nil {
return nil, fmt.Errorf("item %d: %w", i, err)
}
}
return res, nil
}(m[i].Value)
if err != nil {
return nil, fmt.Errorf("value %d: %w", i, err)
}
res[k] = v
}
return res, nil
}(m[i].Value)
if err != nil {
return nil, fmt.Errorf("value %d: %w", i, err)
}
res[k] = v
}
return res, nil
}(arr[index])
if err != nil {
return fmt.Errorf("field M: %w", err)
}
return nil
}
// SomeStructEventsFromApplicationLog retrieves a set of all emitted events
// with "SomeStruct" name from the provided [result.ApplicationLog].
func SomeStructEventsFromApplicationLog(log *result.ApplicationLog) ([]*SomeStructEvent, error) {
if log == nil {
return nil, errors.New("nil application log")
}
var res []*SomeStructEvent
for i, ex := range log.Executions {
for j, e := range ex.Events {
if e.Name != "SomeStruct" {
continue
}
event := new(SomeStructEvent)
err := event.FromStackItem(e.Item)
if err != nil {
return nil, fmt.Errorf("failed to deserialize SomeStructEvent from stackitem (execution #%d, event #%d): %w", i, j, err)
}
res = append(res, event)
}
}
return res, nil
}
// FromStackItem converts provided [stackitem.Array] to SomeStructEvent or
// returns an error if it's not possible to do to so.
func (e *SomeStructEvent) FromStackItem(item *stackitem.Array) error {
if item == nil {
return errors.New("nil item")
}
arr, ok := item.Value().([]stackitem.Item)
if !ok {
return errors.New("not an array")
}
if len(arr) != 1 {
return errors.New("wrong number of structure elements")
}
var (
index = -1
err error
)
index++
e.S, err = itemToCrazyStruct(arr[index], nil)
if err != nil {
return fmt.Errorf("field S: %w", err)
}
return nil
}
// SomeArrayEventsFromApplicationLog retrieves a set of all emitted events
// with "SomeArray" name from the provided [result.ApplicationLog].
func SomeArrayEventsFromApplicationLog(log *result.ApplicationLog) ([]*SomeArrayEvent, error) {
if log == nil {
return nil, errors.New("nil application log")
}
var res []*SomeArrayEvent
for i, ex := range log.Executions {
for j, e := range ex.Events {
if e.Name != "SomeArray" {
continue
}
event := new(SomeArrayEvent)
err := event.FromStackItem(e.Item)
if err != nil {
return nil, fmt.Errorf("failed to deserialize SomeArrayEvent from stackitem (execution #%d, event #%d): %w", i, j, err)
}
res = append(res, event)
}
}
return res, nil
}
// FromStackItem converts provided [stackitem.Array] to SomeArrayEvent or
// returns an error if it's not possible to do to so.
func (e *SomeArrayEvent) FromStackItem(item *stackitem.Array) error {
if item == nil {
return errors.New("nil item")
}
arr, ok := item.Value().([]stackitem.Item)
if !ok {
return errors.New("not an array")
}
if len(arr) != 1 {
return errors.New("wrong number of structure elements")
}
var (
index = -1
err error
)
index++
e.A, err = func(item stackitem.Item) ([][]*big.Int, error) {
arr, ok := item.Value().([]stackitem.Item)
if !ok {
return nil, errors.New("not an array")
}
res := make([][]*big.Int, len(arr))
for i := range res {
res[i], err = func(item stackitem.Item) ([]*big.Int, error) {
arr, ok := item.Value().([]stackitem.Item)
if !ok {
return nil, errors.New("not an array")
}
res := make([]*big.Int, len(arr))
for i := range res {
res[i], err = arr[i].TryInteger()
if err != nil {
return nil, fmt.Errorf("item %d: %w", i, err)
}
}
return res, nil
}(arr[i])
if err != nil {
return nil, fmt.Errorf("item %d: %w", i, err)
}
}
return res, nil
}(arr[index])
if err != nil {
return fmt.Errorf("field A: %w", err)
}
return nil
}
// SomeUnexportedFieldEventsFromApplicationLog retrieves a set of all emitted events
// with "SomeUnexportedField" name from the provided [result.ApplicationLog].
func SomeUnexportedFieldEventsFromApplicationLog(log *result.ApplicationLog) ([]*SomeUnexportedFieldEvent, error) {
if log == nil {
return nil, errors.New("nil application log")
}
var res []*SomeUnexportedFieldEvent
for i, ex := range log.Executions {
for j, e := range ex.Events {
if e.Name != "SomeUnexportedField" {
continue
}
event := new(SomeUnexportedFieldEvent)
err := event.FromStackItem(e.Item)
if err != nil {
return nil, fmt.Errorf("failed to deserialize SomeUnexportedFieldEvent from stackitem (execution #%d, event #%d): %w", i, j, err)
}
res = append(res, event)
}
}
return res, nil
}
// FromStackItem converts provided [stackitem.Array] to SomeUnexportedFieldEvent or
// returns an error if it's not possible to do to so.
func (e *SomeUnexportedFieldEvent) FromStackItem(item *stackitem.Array) error {
if item == nil {
return errors.New("nil item")
}
arr, ok := item.Value().([]stackitem.Item)
if !ok {
return errors.New("not an array")
}
if len(arr) != 1 {
return errors.New("wrong number of structure elements")
}
var (
index = -1
err error
)
index++
e.S, err = itemToSimpleStruct(arr[index], nil)
if err != nil {
return fmt.Errorf("field S: %w", err)
}
return nil
}

View file

@ -0,0 +1,636 @@
// Code generated by neo-go contract generate-rpcwrapper --manifest <file.json> --out <file.go> [--hash <hash>] [--config <config>]; DO NOT EDIT.
// Package structs contains RPC wrappers for Notifications contract.
package structs
import (
"errors"
"fmt"
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
"github.com/nspcc-dev/neo-go/pkg/neorpc/result"
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
"math/big"
"unicode/utf8"
)
// Hash contains contract hash.
var Hash = util.Uint160{0x33, 0x22, 0x11, 0x0, 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x0}
// Unnamed is a contract-specific unnamed type used by its methods.
type Unnamed struct {
I *big.Int
B bool
}
// UnnamedX is a contract-specific unnamedX type used by its methods.
type UnnamedX struct {
I *big.Int
}
// ComplicatedNameEvent represents "! complicated name %$#" event emitted by the contract.
type ComplicatedNameEvent struct {
ComplicatedParam string
}
// SomeMapEvent represents "SomeMap" event emitted by the contract.
type SomeMapEvent struct {
M map[*big.Int][]map[string][]util.Uint160
}
// SomeStructEvent represents "SomeStruct" event emitted by the contract.
type SomeStructEvent struct {
S *Unnamed
}
// SomeArrayEvent represents "SomeArray" event emitted by the contract.
type SomeArrayEvent struct {
A [][]*big.Int
}
// SomeUnexportedFieldEvent represents "SomeUnexportedField" event emitted by the contract.
type SomeUnexportedFieldEvent struct {
S *UnnamedX
}
// Actor is used by Contract to call state-changing methods.
type Actor interface {
MakeCall(contract util.Uint160, method string, params ...any) (*transaction.Transaction, error)
MakeRun(script []byte) (*transaction.Transaction, error)
MakeUnsignedCall(contract util.Uint160, method string, attrs []transaction.Attribute, params ...any) (*transaction.Transaction, error)
MakeUnsignedRun(script []byte, attrs []transaction.Attribute) (*transaction.Transaction, error)
SendCall(contract util.Uint160, method string, params ...any) (util.Uint256, uint32, error)
SendRun(script []byte) (util.Uint256, uint32, error)
}
// Contract implements all contract methods.
type Contract struct {
actor Actor
hash util.Uint160
}
// New creates an instance of Contract using Hash and the given Actor.
func New(actor Actor) *Contract {
var hash = Hash
return &Contract{actor, hash}
}
// Array creates a transaction invoking `array` method of the contract.
// This transaction is signed and immediately sent to the network.
// The values returned are its hash, ValidUntilBlock value and error if any.
func (c *Contract) Array() (util.Uint256, uint32, error) {
return c.actor.SendCall(c.hash, "array")
}
// ArrayTransaction creates a transaction invoking `array` method of the contract.
// This transaction is signed, but not sent to the network, instead it's
// returned to the caller.
func (c *Contract) ArrayTransaction() (*transaction.Transaction, error) {
return c.actor.MakeCall(c.hash, "array")
}
// ArrayUnsigned creates a transaction invoking `array` method of the contract.
// This transaction is not signed, it's simply returned to the caller.
// Any fields of it that do not affect fees can be changed (ValidUntilBlock,
// Nonce), fee values (NetworkFee, SystemFee) can be increased as well.
func (c *Contract) ArrayUnsigned() (*transaction.Transaction, error) {
return c.actor.MakeUnsignedCall(c.hash, "array", nil)
}
// CrazyMap creates a transaction invoking `crazyMap` method of the contract.
// This transaction is signed and immediately sent to the network.
// The values returned are its hash, ValidUntilBlock value and error if any.
func (c *Contract) CrazyMap() (util.Uint256, uint32, error) {
return c.actor.SendCall(c.hash, "crazyMap")
}
// CrazyMapTransaction creates a transaction invoking `crazyMap` method of the contract.
// This transaction is signed, but not sent to the network, instead it's
// returned to the caller.
func (c *Contract) CrazyMapTransaction() (*transaction.Transaction, error) {
return c.actor.MakeCall(c.hash, "crazyMap")
}
// CrazyMapUnsigned creates a transaction invoking `crazyMap` method of the contract.
// This transaction is not signed, it's simply returned to the caller.
// Any fields of it that do not affect fees can be changed (ValidUntilBlock,
// Nonce), fee values (NetworkFee, SystemFee) can be increased as well.
func (c *Contract) CrazyMapUnsigned() (*transaction.Transaction, error) {
return c.actor.MakeUnsignedCall(c.hash, "crazyMap", nil)
}
// Main creates a transaction invoking `main` method of the contract.
// This transaction is signed and immediately sent to the network.
// The values returned are its hash, ValidUntilBlock value and error if any.
func (c *Contract) Main() (util.Uint256, uint32, error) {
return c.actor.SendCall(c.hash, "main")
}
// MainTransaction creates a transaction invoking `main` method of the contract.
// This transaction is signed, but not sent to the network, instead it's
// returned to the caller.
func (c *Contract) MainTransaction() (*transaction.Transaction, error) {
return c.actor.MakeCall(c.hash, "main")
}
// MainUnsigned creates a transaction invoking `main` method of the contract.
// This transaction is not signed, it's simply returned to the caller.
// Any fields of it that do not affect fees can be changed (ValidUntilBlock,
// Nonce), fee values (NetworkFee, SystemFee) can be increased as well.
func (c *Contract) MainUnsigned() (*transaction.Transaction, error) {
return c.actor.MakeUnsignedCall(c.hash, "main", nil)
}
// Struct creates a transaction invoking `struct` method of the contract.
// This transaction is signed and immediately sent to the network.
// The values returned are its hash, ValidUntilBlock value and error if any.
func (c *Contract) Struct() (util.Uint256, uint32, error) {
return c.actor.SendCall(c.hash, "struct")
}
// StructTransaction creates a transaction invoking `struct` method of the contract.
// This transaction is signed, but not sent to the network, instead it's
// returned to the caller.
func (c *Contract) StructTransaction() (*transaction.Transaction, error) {
return c.actor.MakeCall(c.hash, "struct")
}
// StructUnsigned creates a transaction invoking `struct` method of the contract.
// This transaction is not signed, it's simply returned to the caller.
// Any fields of it that do not affect fees can be changed (ValidUntilBlock,
// Nonce), fee values (NetworkFee, SystemFee) can be increased as well.
func (c *Contract) StructUnsigned() (*transaction.Transaction, error) {
return c.actor.MakeUnsignedCall(c.hash, "struct", nil)
}
// UnexportedField creates a transaction invoking `unexportedField` method of the contract.
// This transaction is signed and immediately sent to the network.
// The values returned are its hash, ValidUntilBlock value and error if any.
func (c *Contract) UnexportedField() (util.Uint256, uint32, error) {
return c.actor.SendCall(c.hash, "unexportedField")
}
// UnexportedFieldTransaction creates a transaction invoking `unexportedField` method of the contract.
// This transaction is signed, but not sent to the network, instead it's
// returned to the caller.
func (c *Contract) UnexportedFieldTransaction() (*transaction.Transaction, error) {
return c.actor.MakeCall(c.hash, "unexportedField")
}
// UnexportedFieldUnsigned creates a transaction invoking `unexportedField` method of the contract.
// This transaction is not signed, it's simply returned to the caller.
// Any fields of it that do not affect fees can be changed (ValidUntilBlock,
// Nonce), fee values (NetworkFee, SystemFee) can be increased as well.
func (c *Contract) UnexportedFieldUnsigned() (*transaction.Transaction, error) {
return c.actor.MakeUnsignedCall(c.hash, "unexportedField", nil)
}
// itemToUnnamed converts stack item into *Unnamed.
func itemToUnnamed(item stackitem.Item, err error) (*Unnamed, error) {
if err != nil {
return nil, err
}
var res = new(Unnamed)
err = res.FromStackItem(item)
return res, err
}
// FromStackItem retrieves fields of Unnamed from the given
// [stackitem.Item] or returns an error if it's not possible to do to so.
func (res *Unnamed) FromStackItem(item stackitem.Item) error {
arr, ok := item.Value().([]stackitem.Item)
if !ok {
return errors.New("not an array")
}
if len(arr) != 2 {
return errors.New("wrong number of structure elements")
}
var (
index = -1
err error
)
index++
res.I, err = arr[index].TryInteger()
if err != nil {
return fmt.Errorf("field I: %w", err)
}
index++
res.B, err = arr[index].TryBool()
if err != nil {
return fmt.Errorf("field B: %w", err)
}
return nil
}
// itemToUnnamedX converts stack item into *UnnamedX.
func itemToUnnamedX(item stackitem.Item, err error) (*UnnamedX, error) {
if err != nil {
return nil, err
}
var res = new(UnnamedX)
err = res.FromStackItem(item)
return res, err
}
// FromStackItem retrieves fields of UnnamedX from the given
// [stackitem.Item] or returns an error if it's not possible to do to so.
func (res *UnnamedX) FromStackItem(item stackitem.Item) error {
arr, ok := item.Value().([]stackitem.Item)
if !ok {
return errors.New("not an array")
}
if len(arr) != 1 {
return errors.New("wrong number of structure elements")
}
var (
index = -1
err error
)
index++
res.I, err = arr[index].TryInteger()
if err != nil {
return fmt.Errorf("field I: %w", err)
}
return nil
}
// ComplicatedNameEventsFromApplicationLog retrieves a set of all emitted events
// with "! complicated name %$#" name from the provided [result.ApplicationLog].
func ComplicatedNameEventsFromApplicationLog(log *result.ApplicationLog) ([]*ComplicatedNameEvent, error) {
if log == nil {
return nil, errors.New("nil application log")
}
var res []*ComplicatedNameEvent
for i, ex := range log.Executions {
for j, e := range ex.Events {
if e.Name != "! complicated name %$#" {
continue
}
event := new(ComplicatedNameEvent)
err := event.FromStackItem(e.Item)
if err != nil {
return nil, fmt.Errorf("failed to deserialize ComplicatedNameEvent from stackitem (execution #%d, event #%d): %w", i, j, err)
}
res = append(res, event)
}
}
return res, nil
}
// FromStackItem converts provided [stackitem.Array] to ComplicatedNameEvent or
// returns an error if it's not possible to do to so.
func (e *ComplicatedNameEvent) FromStackItem(item *stackitem.Array) error {
if item == nil {
return errors.New("nil item")
}
arr, ok := item.Value().([]stackitem.Item)
if !ok {
return errors.New("not an array")
}
if len(arr) != 1 {
return errors.New("wrong number of structure elements")
}
var (
index = -1
err error
)
index++
e.ComplicatedParam, err = func(item stackitem.Item) (string, error) {
b, err := item.TryBytes()
if err != nil {
return "", err
}
if !utf8.Valid(b) {
return "", errors.New("not a UTF-8 string")
}
return string(b), nil
}(arr[index])
if err != nil {
return fmt.Errorf("field ComplicatedParam: %w", err)
}
return nil
}
// SomeMapEventsFromApplicationLog retrieves a set of all emitted events
// with "SomeMap" name from the provided [result.ApplicationLog].
func SomeMapEventsFromApplicationLog(log *result.ApplicationLog) ([]*SomeMapEvent, error) {
if log == nil {
return nil, errors.New("nil application log")
}
var res []*SomeMapEvent
for i, ex := range log.Executions {
for j, e := range ex.Events {
if e.Name != "SomeMap" {
continue
}
event := new(SomeMapEvent)
err := event.FromStackItem(e.Item)
if err != nil {
return nil, fmt.Errorf("failed to deserialize SomeMapEvent from stackitem (execution #%d, event #%d): %w", i, j, err)
}
res = append(res, event)
}
}
return res, nil
}
// FromStackItem converts provided [stackitem.Array] to SomeMapEvent or
// returns an error if it's not possible to do to so.
func (e *SomeMapEvent) FromStackItem(item *stackitem.Array) error {
if item == nil {
return errors.New("nil item")
}
arr, ok := item.Value().([]stackitem.Item)
if !ok {
return errors.New("not an array")
}
if len(arr) != 1 {
return errors.New("wrong number of structure elements")
}
var (
index = -1
err error
)
index++
e.M, err = func(item stackitem.Item) (map[*big.Int][]map[string][]util.Uint160, error) {
m, ok := item.Value().([]stackitem.MapElement)
if !ok {
return nil, fmt.Errorf("%s is not a map", item.Type().String())
}
res := make(map[*big.Int][]map[string][]util.Uint160)
for i := range m {
k, err := m[i].Key.TryInteger()
if err != nil {
return nil, fmt.Errorf("key %d: %w", i, err)
}
v, err := func(item stackitem.Item) ([]map[string][]util.Uint160, error) {
arr, ok := item.Value().([]stackitem.Item)
if !ok {
return nil, errors.New("not an array")
}
res := make([]map[string][]util.Uint160, len(arr))
for i := range res {
res[i], err = func(item stackitem.Item) (map[string][]util.Uint160, error) {
m, ok := item.Value().([]stackitem.MapElement)
if !ok {
return nil, fmt.Errorf("%s is not a map", item.Type().String())
}
res := make(map[string][]util.Uint160)
for i := range m {
k, err := func(item stackitem.Item) (string, error) {
b, err := item.TryBytes()
if err != nil {
return "", err
}
if !utf8.Valid(b) {
return "", errors.New("not a UTF-8 string")
}
return string(b), nil
}(m[i].Key)
if err != nil {
return nil, fmt.Errorf("key %d: %w", i, err)
}
v, err := func(item stackitem.Item) ([]util.Uint160, error) {
arr, ok := item.Value().([]stackitem.Item)
if !ok {
return nil, errors.New("not an array")
}
res := make([]util.Uint160, len(arr))
for i := range res {
res[i], err = func(item stackitem.Item) (util.Uint160, error) {
b, err := item.TryBytes()
if err != nil {
return util.Uint160{}, err
}
u, err := util.Uint160DecodeBytesBE(b)
if err != nil {
return util.Uint160{}, err
}
return u, nil
}(arr[i])
if err != nil {
return nil, fmt.Errorf("item %d: %w", i, err)
}
}
return res, nil
}(m[i].Value)
if err != nil {
return nil, fmt.Errorf("value %d: %w", i, err)
}
res[k] = v
}
return res, nil
}(arr[i])
if err != nil {
return nil, fmt.Errorf("item %d: %w", i, err)
}
}
return res, nil
}(m[i].Value)
if err != nil {
return nil, fmt.Errorf("value %d: %w", i, err)
}
res[k] = v
}
return res, nil
}(arr[index])
if err != nil {
return fmt.Errorf("field M: %w", err)
}
return nil
}
// SomeStructEventsFromApplicationLog retrieves a set of all emitted events
// with "SomeStruct" name from the provided [result.ApplicationLog].
func SomeStructEventsFromApplicationLog(log *result.ApplicationLog) ([]*SomeStructEvent, error) {
if log == nil {
return nil, errors.New("nil application log")
}
var res []*SomeStructEvent
for i, ex := range log.Executions {
for j, e := range ex.Events {
if e.Name != "SomeStruct" {
continue
}
event := new(SomeStructEvent)
err := event.FromStackItem(e.Item)
if err != nil {
return nil, fmt.Errorf("failed to deserialize SomeStructEvent from stackitem (execution #%d, event #%d): %w", i, j, err)
}
res = append(res, event)
}
}
return res, nil
}
// FromStackItem converts provided [stackitem.Array] to SomeStructEvent or
// returns an error if it's not possible to do to so.
func (e *SomeStructEvent) FromStackItem(item *stackitem.Array) error {
if item == nil {
return errors.New("nil item")
}
arr, ok := item.Value().([]stackitem.Item)
if !ok {
return errors.New("not an array")
}
if len(arr) != 1 {
return errors.New("wrong number of structure elements")
}
var (
index = -1
err error
)
index++
e.S, err = itemToUnnamed(arr[index], nil)
if err != nil {
return fmt.Errorf("field S: %w", err)
}
return nil
}
// SomeArrayEventsFromApplicationLog retrieves a set of all emitted events
// with "SomeArray" name from the provided [result.ApplicationLog].
func SomeArrayEventsFromApplicationLog(log *result.ApplicationLog) ([]*SomeArrayEvent, error) {
if log == nil {
return nil, errors.New("nil application log")
}
var res []*SomeArrayEvent
for i, ex := range log.Executions {
for j, e := range ex.Events {
if e.Name != "SomeArray" {
continue
}
event := new(SomeArrayEvent)
err := event.FromStackItem(e.Item)
if err != nil {
return nil, fmt.Errorf("failed to deserialize SomeArrayEvent from stackitem (execution #%d, event #%d): %w", i, j, err)
}
res = append(res, event)
}
}
return res, nil
}
// FromStackItem converts provided [stackitem.Array] to SomeArrayEvent or
// returns an error if it's not possible to do to so.
func (e *SomeArrayEvent) FromStackItem(item *stackitem.Array) error {
if item == nil {
return errors.New("nil item")
}
arr, ok := item.Value().([]stackitem.Item)
if !ok {
return errors.New("not an array")
}
if len(arr) != 1 {
return errors.New("wrong number of structure elements")
}
var (
index = -1
err error
)
index++
e.A, err = func(item stackitem.Item) ([][]*big.Int, error) {
arr, ok := item.Value().([]stackitem.Item)
if !ok {
return nil, errors.New("not an array")
}
res := make([][]*big.Int, len(arr))
for i := range res {
res[i], err = func(item stackitem.Item) ([]*big.Int, error) {
arr, ok := item.Value().([]stackitem.Item)
if !ok {
return nil, errors.New("not an array")
}
res := make([]*big.Int, len(arr))
for i := range res {
res[i], err = arr[i].TryInteger()
if err != nil {
return nil, fmt.Errorf("item %d: %w", i, err)
}
}
return res, nil
}(arr[i])
if err != nil {
return nil, fmt.Errorf("item %d: %w", i, err)
}
}
return res, nil
}(arr[index])
if err != nil {
return fmt.Errorf("field A: %w", err)
}
return nil
}
// SomeUnexportedFieldEventsFromApplicationLog retrieves a set of all emitted events
// with "SomeUnexportedField" name from the provided [result.ApplicationLog].
func SomeUnexportedFieldEventsFromApplicationLog(log *result.ApplicationLog) ([]*SomeUnexportedFieldEvent, error) {
if log == nil {
return nil, errors.New("nil application log")
}
var res []*SomeUnexportedFieldEvent
for i, ex := range log.Executions {
for j, e := range ex.Events {
if e.Name != "SomeUnexportedField" {
continue
}
event := new(SomeUnexportedFieldEvent)
err := event.FromStackItem(e.Item)
if err != nil {
return nil, fmt.Errorf("failed to deserialize SomeUnexportedFieldEvent from stackitem (execution #%d, event #%d): %w", i, j, err)
}
res = append(res, event)
}
}
return res, nil
}
// FromStackItem converts provided [stackitem.Array] to SomeUnexportedFieldEvent or
// returns an error if it's not possible to do to so.
func (e *SomeUnexportedFieldEvent) FromStackItem(item *stackitem.Array) error {
if item == nil {
return errors.New("nil item")
}
arr, ok := item.Value().([]stackitem.Item)
if !ok {
return errors.New("not an array")
}
if len(arr) != 1 {
return errors.New("wrong number of structure elements")
}
var (
index = -1
err error
)
index++
e.S, err = itemToUnnamedX(arr[index], nil)
if err != nil {
return fmt.Errorf("field S: %w", err)
}
return nil
}

View file

@ -0,0 +1,3 @@
name: "Types"
sourceurl: https://github.com/nspcc-dev/neo-go/
safemethods: ["contract", "block", "transaction", "struct"]

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,40 @@
package structs
import (
"github.com/nspcc-dev/neo-go/pkg/interop"
"github.com/nspcc-dev/neo-go/pkg/interop/native/ledger"
"github.com/nspcc-dev/neo-go/pkg/interop/native/management"
)
type Internal struct {
Bool bool
Int int
Bytes []byte
String string
H160 interop.Hash160
H256 interop.Hash256
PK interop.PublicKey
PubKey interop.PublicKey
Sign interop.Signature
ArrOfBytes [][]byte
ArrOfH160 []interop.Hash160
Map map[int][]interop.PublicKey
Struct *Internal
unexportedField int // this one should be exported in the resulting RPC binding.
}
func Contract(mc management.Contract) management.Contract {
return mc
}
func Block(b *ledger.Block) *ledger.Block {
return b
}
func Transaction(t *ledger.Transaction) *ledger.Transaction {
return t
}
func Struct(s *Internal) *Internal {
return s
}

View file

@ -0,0 +1,3 @@
name: "Types"
sourceurl: https://github.com/nspcc-dev/neo-go/
safemethods: ["bool", "int", "bytes", "string", "any", "hash160", "hash256", "publicKey", "signature", "bools", "ints", "bytess", "strings", "hash160s", "hash256s", "publicKeys", "signatures", "aAAStrings", "maps", "crazyMaps", "anyMaps", "unnamedStructs", "unnamedStructsX"]

View file

@ -0,0 +1,444 @@
// Code generated by neo-go contract generate-rpcwrapper --manifest <file.json> --out <file.go> [--hash <hash>] [--config <config>]; DO NOT EDIT.
// Package types contains RPC wrappers for Types contract.
package types
import (
"errors"
"fmt"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
"github.com/nspcc-dev/neo-go/pkg/neorpc/result"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap"
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
"math/big"
"unicode/utf8"
)
// Hash contains contract hash.
var Hash = util.Uint160{0x33, 0x22, 0x11, 0x0, 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x0}
// Unnamed is a contract-specific unnamed type used by its methods.
type Unnamed struct {
I *big.Int
}
// UnnamedX is a contract-specific unnamedX type used by its methods.
type UnnamedX struct {
I *big.Int
B bool
}
// Invoker is used by ContractReader to call various safe methods.
type Invoker interface {
Call(contract util.Uint160, operation string, params ...any) (*result.Invoke, error)
}
// ContractReader implements safe contract methods.
type ContractReader struct {
invoker Invoker
hash util.Uint160
}
// NewReader creates an instance of ContractReader using Hash and the given Invoker.
func NewReader(invoker Invoker) *ContractReader {
var hash = Hash
return &ContractReader{invoker, hash}
}
// AAAStrings invokes `aAAStrings` method of contract.
func (c *ContractReader) AAAStrings(s [][][]string) ([][][]string, error) {
return func(item stackitem.Item, err error) ([][][]string, error) {
if err != nil {
return nil, err
}
return func(item stackitem.Item) ([][][]string, error) {
arr, ok := item.Value().([]stackitem.Item)
if !ok {
return nil, errors.New("not an array")
}
res := make([][][]string, len(arr))
for i := range res {
res[i], err = func(item stackitem.Item) ([][]string, error) {
arr, ok := item.Value().([]stackitem.Item)
if !ok {
return nil, errors.New("not an array")
}
res := make([][]string, len(arr))
for i := range res {
res[i], err = func(item stackitem.Item) ([]string, error) {
arr, ok := item.Value().([]stackitem.Item)
if !ok {
return nil, errors.New("not an array")
}
res := make([]string, len(arr))
for i := range res {
res[i], err = func(item stackitem.Item) (string, error) {
b, err := item.TryBytes()
if err != nil {
return "", err
}
if !utf8.Valid(b) {
return "", errors.New("not a UTF-8 string")
}
return string(b), nil
}(arr[i])
if err != nil {
return nil, fmt.Errorf("item %d: %w", i, err)
}
}
return res, nil
}(arr[i])
if err != nil {
return nil, fmt.Errorf("item %d: %w", i, err)
}
}
return res, nil
}(arr[i])
if err != nil {
return nil, fmt.Errorf("item %d: %w", i, err)
}
}
return res, nil
}(item)
}(unwrap.Item(c.invoker.Call(c.hash, "aAAStrings", s)))
}
// Any invokes `any` method of contract.
func (c *ContractReader) Any(a any) (any, error) {
return func(item stackitem.Item, err error) (any, error) {
if err != nil {
return nil, err
}
return item.Value(), error(nil)
}(unwrap.Item(c.invoker.Call(c.hash, "any", a)))
}
// AnyMaps invokes `anyMaps` method of contract.
func (c *ContractReader) AnyMaps(m map[*big.Int]any) (map[*big.Int]any, error) {
return func(item stackitem.Item, err error) (map[*big.Int]any, error) {
if err != nil {
return nil, err
}
return func(item stackitem.Item) (map[*big.Int]any, error) {
m, ok := item.Value().([]stackitem.MapElement)
if !ok {
return nil, fmt.Errorf("%s is not a map", item.Type().String())
}
res := make(map[*big.Int]any)
for i := range m {
k, err := m[i].Key.TryInteger()
if err != nil {
return nil, fmt.Errorf("key %d: %w", i, err)
}
v, err := m[i].Value.Value(), error(nil)
if err != nil {
return nil, fmt.Errorf("value %d: %w", i, err)
}
res[k] = v
}
return res, nil
}(item)
}(unwrap.Item(c.invoker.Call(c.hash, "anyMaps", m)))
}
// Bool invokes `bool` method of contract.
func (c *ContractReader) Bool(b bool) (bool, error) {
return unwrap.Bool(c.invoker.Call(c.hash, "bool", b))
}
// Bools invokes `bools` method of contract.
func (c *ContractReader) Bools(b []bool) ([]bool, error) {
return unwrap.ArrayOfBools(c.invoker.Call(c.hash, "bools", b))
}
// Bytes invokes `bytes` method of contract.
func (c *ContractReader) Bytes(b []byte) ([]byte, error) {
return unwrap.Bytes(c.invoker.Call(c.hash, "bytes", b))
}
// Bytess invokes `bytess` method of contract.
func (c *ContractReader) Bytess(b [][]byte) ([][]byte, error) {
return unwrap.ArrayOfBytes(c.invoker.Call(c.hash, "bytess", b))
}
// CrazyMaps invokes `crazyMaps` method of contract.
func (c *ContractReader) CrazyMaps(m map[*big.Int][]map[string][]util.Uint160) (map[*big.Int][]map[string][]util.Uint160, error) {
return func(item stackitem.Item, err error) (map[*big.Int][]map[string][]util.Uint160, error) {
if err != nil {
return nil, err
}
return func(item stackitem.Item) (map[*big.Int][]map[string][]util.Uint160, error) {
m, ok := item.Value().([]stackitem.MapElement)
if !ok {
return nil, fmt.Errorf("%s is not a map", item.Type().String())
}
res := make(map[*big.Int][]map[string][]util.Uint160)
for i := range m {
k, err := m[i].Key.TryInteger()
if err != nil {
return nil, fmt.Errorf("key %d: %w", i, err)
}
v, err := func(item stackitem.Item) ([]map[string][]util.Uint160, error) {
arr, ok := item.Value().([]stackitem.Item)
if !ok {
return nil, errors.New("not an array")
}
res := make([]map[string][]util.Uint160, len(arr))
for i := range res {
res[i], err = func(item stackitem.Item) (map[string][]util.Uint160, error) {
m, ok := item.Value().([]stackitem.MapElement)
if !ok {
return nil, fmt.Errorf("%s is not a map", item.Type().String())
}
res := make(map[string][]util.Uint160)
for i := range m {
k, err := func(item stackitem.Item) (string, error) {
b, err := item.TryBytes()
if err != nil {
return "", err
}
if !utf8.Valid(b) {
return "", errors.New("not a UTF-8 string")
}
return string(b), nil
}(m[i].Key)
if err != nil {
return nil, fmt.Errorf("key %d: %w", i, err)
}
v, err := func(item stackitem.Item) ([]util.Uint160, error) {
arr, ok := item.Value().([]stackitem.Item)
if !ok {
return nil, errors.New("not an array")
}
res := make([]util.Uint160, len(arr))
for i := range res {
res[i], err = func(item stackitem.Item) (util.Uint160, error) {
b, err := item.TryBytes()
if err != nil {
return util.Uint160{}, err
}
u, err := util.Uint160DecodeBytesBE(b)
if err != nil {
return util.Uint160{}, err
}
return u, nil
}(arr[i])
if err != nil {
return nil, fmt.Errorf("item %d: %w", i, err)
}
}
return res, nil
}(m[i].Value)
if err != nil {
return nil, fmt.Errorf("value %d: %w", i, err)
}
res[k] = v
}
return res, nil
}(arr[i])
if err != nil {
return nil, fmt.Errorf("item %d: %w", i, err)
}
}
return res, nil
}(m[i].Value)
if err != nil {
return nil, fmt.Errorf("value %d: %w", i, err)
}
res[k] = v
}
return res, nil
}(item)
}(unwrap.Item(c.invoker.Call(c.hash, "crazyMaps", m)))
}
// Hash160 invokes `hash160` method of contract.
func (c *ContractReader) Hash160(h util.Uint160) (util.Uint160, error) {
return unwrap.Uint160(c.invoker.Call(c.hash, "hash160", h))
}
// Hash160s invokes `hash160s` method of contract.
func (c *ContractReader) Hash160s(h []util.Uint160) ([]util.Uint160, error) {
return unwrap.ArrayOfUint160(c.invoker.Call(c.hash, "hash160s", h))
}
// Hash256 invokes `hash256` method of contract.
func (c *ContractReader) Hash256(h util.Uint256) (util.Uint256, error) {
return unwrap.Uint256(c.invoker.Call(c.hash, "hash256", h))
}
// Hash256s invokes `hash256s` method of contract.
func (c *ContractReader) Hash256s(h []util.Uint256) ([]util.Uint256, error) {
return unwrap.ArrayOfUint256(c.invoker.Call(c.hash, "hash256s", h))
}
// Int invokes `int` method of contract.
func (c *ContractReader) Int(i *big.Int) (*big.Int, error) {
return unwrap.BigInt(c.invoker.Call(c.hash, "int", i))
}
// Ints invokes `ints` method of contract.
func (c *ContractReader) Ints(i []*big.Int) ([]*big.Int, error) {
return unwrap.ArrayOfBigInts(c.invoker.Call(c.hash, "ints", i))
}
// Maps invokes `maps` method of contract.
func (c *ContractReader) Maps(m map[string]string) (map[string]string, error) {
return func(item stackitem.Item, err error) (map[string]string, error) {
if err != nil {
return nil, err
}
return func(item stackitem.Item) (map[string]string, error) {
m, ok := item.Value().([]stackitem.MapElement)
if !ok {
return nil, fmt.Errorf("%s is not a map", item.Type().String())
}
res := make(map[string]string)
for i := range m {
k, err := func(item stackitem.Item) (string, error) {
b, err := item.TryBytes()
if err != nil {
return "", err
}
if !utf8.Valid(b) {
return "", errors.New("not a UTF-8 string")
}
return string(b), nil
}(m[i].Key)
if err != nil {
return nil, fmt.Errorf("key %d: %w", i, err)
}
v, err := func(item stackitem.Item) (string, error) {
b, err := item.TryBytes()
if err != nil {
return "", err
}
if !utf8.Valid(b) {
return "", errors.New("not a UTF-8 string")
}
return string(b), nil
}(m[i].Value)
if err != nil {
return nil, fmt.Errorf("value %d: %w", i, err)
}
res[k] = v
}
return res, nil
}(item)
}(unwrap.Item(c.invoker.Call(c.hash, "maps", m)))
}
// PublicKey invokes `publicKey` method of contract.
func (c *ContractReader) PublicKey(k *keys.PublicKey) (*keys.PublicKey, error) {
return unwrap.PublicKey(c.invoker.Call(c.hash, "publicKey", k))
}
// PublicKeys invokes `publicKeys` method of contract.
func (c *ContractReader) PublicKeys(k keys.PublicKeys) (keys.PublicKeys, error) {
return unwrap.ArrayOfPublicKeys(c.invoker.Call(c.hash, "publicKeys", k))
}
// Signature invokes `signature` method of contract.
func (c *ContractReader) Signature(s []byte) ([]byte, error) {
return unwrap.Bytes(c.invoker.Call(c.hash, "signature", s))
}
// Signatures invokes `signatures` method of contract.
func (c *ContractReader) Signatures(s [][]byte) ([][]byte, error) {
return unwrap.ArrayOfBytes(c.invoker.Call(c.hash, "signatures", s))
}
// String invokes `string` method of contract.
func (c *ContractReader) String(s string) (string, error) {
return unwrap.UTF8String(c.invoker.Call(c.hash, "string", s))
}
// Strings invokes `strings` method of contract.
func (c *ContractReader) Strings(s []string) ([]string, error) {
return unwrap.ArrayOfUTF8Strings(c.invoker.Call(c.hash, "strings", s))
}
// UnnamedStructs invokes `unnamedStructs` method of contract.
func (c *ContractReader) UnnamedStructs() (*Unnamed, error) {
return itemToUnnamed(unwrap.Item(c.invoker.Call(c.hash, "unnamedStructs")))
}
// UnnamedStructsX invokes `unnamedStructsX` method of contract.
func (c *ContractReader) UnnamedStructsX() (*UnnamedX, error) {
return itemToUnnamedX(unwrap.Item(c.invoker.Call(c.hash, "unnamedStructsX")))
}
// itemToUnnamed converts stack item into *Unnamed.
func itemToUnnamed(item stackitem.Item, err error) (*Unnamed, error) {
if err != nil {
return nil, err
}
var res = new(Unnamed)
err = res.FromStackItem(item)
return res, err
}
// FromStackItem retrieves fields of Unnamed from the given
// [stackitem.Item] or returns an error if it's not possible to do to so.
func (res *Unnamed) FromStackItem(item stackitem.Item) error {
arr, ok := item.Value().([]stackitem.Item)
if !ok {
return errors.New("not an array")
}
if len(arr) != 1 {
return errors.New("wrong number of structure elements")
}
var (
index = -1
err error
)
index++
res.I, err = arr[index].TryInteger()
if err != nil {
return fmt.Errorf("field I: %w", err)
}
return nil
}
// itemToUnnamedX converts stack item into *UnnamedX.
func itemToUnnamedX(item stackitem.Item, err error) (*UnnamedX, error) {
if err != nil {
return nil, err
}
var res = new(UnnamedX)
err = res.FromStackItem(item)
return res, err
}
// FromStackItem retrieves fields of UnnamedX from the given
// [stackitem.Item] or returns an error if it's not possible to do to so.
func (res *UnnamedX) FromStackItem(item stackitem.Item) error {
arr, ok := item.Value().([]stackitem.Item)
if !ok {
return errors.New("not an array")
}
if len(arr) != 2 {
return errors.New("wrong number of structure elements")
}
var (
index = -1
err error
)
index++
res.I, err = arr[index].TryInteger()
if err != nil {
return fmt.Errorf("field I: %w", err)
}
index++
res.B, err = arr[index].TryBool()
if err != nil {
return fmt.Errorf("field B: %w", err)
}
return nil
}

View file

@ -0,0 +1,440 @@
// Code generated by neo-go contract generate-rpcwrapper --manifest <file.json> --out <file.go> [--hash <hash>] [--config <config>]; DO NOT EDIT.
// Package types contains RPC wrappers for Types contract.
package types
import (
"errors"
"fmt"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
"github.com/nspcc-dev/neo-go/pkg/neorpc/result"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap"
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
"math/big"
"unicode/utf8"
)
// Unnamed is a contract-specific unnamed type used by its methods.
type Unnamed struct {
I *big.Int
}
// UnnamedX is a contract-specific unnamedX type used by its methods.
type UnnamedX struct {
I *big.Int
B bool
}
// Invoker is used by ContractReader to call various safe methods.
type Invoker interface {
Call(contract util.Uint160, operation string, params ...any) (*result.Invoke, error)
}
// ContractReader implements safe contract methods.
type ContractReader struct {
invoker Invoker
hash util.Uint160
}
// NewReader creates an instance of ContractReader using provided contract hash and the given Invoker.
func NewReader(invoker Invoker, hash util.Uint160) *ContractReader {
return &ContractReader{invoker, hash}
}
// AAAStrings invokes `aAAStrings` method of contract.
func (c *ContractReader) AAAStrings(s [][][]string) ([][][]string, error) {
return func(item stackitem.Item, err error) ([][][]string, error) {
if err != nil {
return nil, err
}
return func(item stackitem.Item) ([][][]string, error) {
arr, ok := item.Value().([]stackitem.Item)
if !ok {
return nil, errors.New("not an array")
}
res := make([][][]string, len(arr))
for i := range res {
res[i], err = func(item stackitem.Item) ([][]string, error) {
arr, ok := item.Value().([]stackitem.Item)
if !ok {
return nil, errors.New("not an array")
}
res := make([][]string, len(arr))
for i := range res {
res[i], err = func(item stackitem.Item) ([]string, error) {
arr, ok := item.Value().([]stackitem.Item)
if !ok {
return nil, errors.New("not an array")
}
res := make([]string, len(arr))
for i := range res {
res[i], err = func(item stackitem.Item) (string, error) {
b, err := item.TryBytes()
if err != nil {
return "", err
}
if !utf8.Valid(b) {
return "", errors.New("not a UTF-8 string")
}
return string(b), nil
}(arr[i])
if err != nil {
return nil, fmt.Errorf("item %d: %w", i, err)
}
}
return res, nil
}(arr[i])
if err != nil {
return nil, fmt.Errorf("item %d: %w", i, err)
}
}
return res, nil
}(arr[i])
if err != nil {
return nil, fmt.Errorf("item %d: %w", i, err)
}
}
return res, nil
}(item)
}(unwrap.Item(c.invoker.Call(c.hash, "aAAStrings", s)))
}
// Any invokes `any` method of contract.
func (c *ContractReader) Any(a any) (any, error) {
return func(item stackitem.Item, err error) (any, error) {
if err != nil {
return nil, err
}
return item.Value(), error(nil)
}(unwrap.Item(c.invoker.Call(c.hash, "any", a)))
}
// AnyMaps invokes `anyMaps` method of contract.
func (c *ContractReader) AnyMaps(m map[*big.Int]any) (map[*big.Int]any, error) {
return func(item stackitem.Item, err error) (map[*big.Int]any, error) {
if err != nil {
return nil, err
}
return func(item stackitem.Item) (map[*big.Int]any, error) {
m, ok := item.Value().([]stackitem.MapElement)
if !ok {
return nil, fmt.Errorf("%s is not a map", item.Type().String())
}
res := make(map[*big.Int]any)
for i := range m {
k, err := m[i].Key.TryInteger()
if err != nil {
return nil, fmt.Errorf("key %d: %w", i, err)
}
v, err := m[i].Value.Value(), error(nil)
if err != nil {
return nil, fmt.Errorf("value %d: %w", i, err)
}
res[k] = v
}
return res, nil
}(item)
}(unwrap.Item(c.invoker.Call(c.hash, "anyMaps", m)))
}
// Bool invokes `bool` method of contract.
func (c *ContractReader) Bool(b bool) (bool, error) {
return unwrap.Bool(c.invoker.Call(c.hash, "bool", b))
}
// Bools invokes `bools` method of contract.
func (c *ContractReader) Bools(b []bool) ([]bool, error) {
return unwrap.ArrayOfBools(c.invoker.Call(c.hash, "bools", b))
}
// Bytes invokes `bytes` method of contract.
func (c *ContractReader) Bytes(b []byte) ([]byte, error) {
return unwrap.Bytes(c.invoker.Call(c.hash, "bytes", b))
}
// Bytess invokes `bytess` method of contract.
func (c *ContractReader) Bytess(b [][]byte) ([][]byte, error) {
return unwrap.ArrayOfBytes(c.invoker.Call(c.hash, "bytess", b))
}
// CrazyMaps invokes `crazyMaps` method of contract.
func (c *ContractReader) CrazyMaps(m map[*big.Int][]map[string][]util.Uint160) (map[*big.Int][]map[string][]util.Uint160, error) {
return func(item stackitem.Item, err error) (map[*big.Int][]map[string][]util.Uint160, error) {
if err != nil {
return nil, err
}
return func(item stackitem.Item) (map[*big.Int][]map[string][]util.Uint160, error) {
m, ok := item.Value().([]stackitem.MapElement)
if !ok {
return nil, fmt.Errorf("%s is not a map", item.Type().String())
}
res := make(map[*big.Int][]map[string][]util.Uint160)
for i := range m {
k, err := m[i].Key.TryInteger()
if err != nil {
return nil, fmt.Errorf("key %d: %w", i, err)
}
v, err := func(item stackitem.Item) ([]map[string][]util.Uint160, error) {
arr, ok := item.Value().([]stackitem.Item)
if !ok {
return nil, errors.New("not an array")
}
res := make([]map[string][]util.Uint160, len(arr))
for i := range res {
res[i], err = func(item stackitem.Item) (map[string][]util.Uint160, error) {
m, ok := item.Value().([]stackitem.MapElement)
if !ok {
return nil, fmt.Errorf("%s is not a map", item.Type().String())
}
res := make(map[string][]util.Uint160)
for i := range m {
k, err := func(item stackitem.Item) (string, error) {
b, err := item.TryBytes()
if err != nil {
return "", err
}
if !utf8.Valid(b) {
return "", errors.New("not a UTF-8 string")
}
return string(b), nil
}(m[i].Key)
if err != nil {
return nil, fmt.Errorf("key %d: %w", i, err)
}
v, err := func(item stackitem.Item) ([]util.Uint160, error) {
arr, ok := item.Value().([]stackitem.Item)
if !ok {
return nil, errors.New("not an array")
}
res := make([]util.Uint160, len(arr))
for i := range res {
res[i], err = func(item stackitem.Item) (util.Uint160, error) {
b, err := item.TryBytes()
if err != nil {
return util.Uint160{}, err
}
u, err := util.Uint160DecodeBytesBE(b)
if err != nil {
return util.Uint160{}, err
}
return u, nil
}(arr[i])
if err != nil {
return nil, fmt.Errorf("item %d: %w", i, err)
}
}
return res, nil
}(m[i].Value)
if err != nil {
return nil, fmt.Errorf("value %d: %w", i, err)
}
res[k] = v
}
return res, nil
}(arr[i])
if err != nil {
return nil, fmt.Errorf("item %d: %w", i, err)
}
}
return res, nil
}(m[i].Value)
if err != nil {
return nil, fmt.Errorf("value %d: %w", i, err)
}
res[k] = v
}
return res, nil
}(item)
}(unwrap.Item(c.invoker.Call(c.hash, "crazyMaps", m)))
}
// Hash160 invokes `hash160` method of contract.
func (c *ContractReader) Hash160(h util.Uint160) (util.Uint160, error) {
return unwrap.Uint160(c.invoker.Call(c.hash, "hash160", h))
}
// Hash160s invokes `hash160s` method of contract.
func (c *ContractReader) Hash160s(h []util.Uint160) ([]util.Uint160, error) {
return unwrap.ArrayOfUint160(c.invoker.Call(c.hash, "hash160s", h))
}
// Hash256 invokes `hash256` method of contract.
func (c *ContractReader) Hash256(h util.Uint256) (util.Uint256, error) {
return unwrap.Uint256(c.invoker.Call(c.hash, "hash256", h))
}
// Hash256s invokes `hash256s` method of contract.
func (c *ContractReader) Hash256s(h []util.Uint256) ([]util.Uint256, error) {
return unwrap.ArrayOfUint256(c.invoker.Call(c.hash, "hash256s", h))
}
// Int invokes `int` method of contract.
func (c *ContractReader) Int(i *big.Int) (*big.Int, error) {
return unwrap.BigInt(c.invoker.Call(c.hash, "int", i))
}
// Ints invokes `ints` method of contract.
func (c *ContractReader) Ints(i []*big.Int) ([]*big.Int, error) {
return unwrap.ArrayOfBigInts(c.invoker.Call(c.hash, "ints", i))
}
// Maps invokes `maps` method of contract.
func (c *ContractReader) Maps(m map[string]string) (map[string]string, error) {
return func(item stackitem.Item, err error) (map[string]string, error) {
if err != nil {
return nil, err
}
return func(item stackitem.Item) (map[string]string, error) {
m, ok := item.Value().([]stackitem.MapElement)
if !ok {
return nil, fmt.Errorf("%s is not a map", item.Type().String())
}
res := make(map[string]string)
for i := range m {
k, err := func(item stackitem.Item) (string, error) {
b, err := item.TryBytes()
if err != nil {
return "", err
}
if !utf8.Valid(b) {
return "", errors.New("not a UTF-8 string")
}
return string(b), nil
}(m[i].Key)
if err != nil {
return nil, fmt.Errorf("key %d: %w", i, err)
}
v, err := func(item stackitem.Item) (string, error) {
b, err := item.TryBytes()
if err != nil {
return "", err
}
if !utf8.Valid(b) {
return "", errors.New("not a UTF-8 string")
}
return string(b), nil
}(m[i].Value)
if err != nil {
return nil, fmt.Errorf("value %d: %w", i, err)
}
res[k] = v
}
return res, nil
}(item)
}(unwrap.Item(c.invoker.Call(c.hash, "maps", m)))
}
// PublicKey invokes `publicKey` method of contract.
func (c *ContractReader) PublicKey(k *keys.PublicKey) (*keys.PublicKey, error) {
return unwrap.PublicKey(c.invoker.Call(c.hash, "publicKey", k))
}
// PublicKeys invokes `publicKeys` method of contract.
func (c *ContractReader) PublicKeys(k keys.PublicKeys) (keys.PublicKeys, error) {
return unwrap.ArrayOfPublicKeys(c.invoker.Call(c.hash, "publicKeys", k))
}
// Signature invokes `signature` method of contract.
func (c *ContractReader) Signature(s []byte) ([]byte, error) {
return unwrap.Bytes(c.invoker.Call(c.hash, "signature", s))
}
// Signatures invokes `signatures` method of contract.
func (c *ContractReader) Signatures(s [][]byte) ([][]byte, error) {
return unwrap.ArrayOfBytes(c.invoker.Call(c.hash, "signatures", s))
}
// String invokes `string` method of contract.
func (c *ContractReader) String(s string) (string, error) {
return unwrap.UTF8String(c.invoker.Call(c.hash, "string", s))
}
// Strings invokes `strings` method of contract.
func (c *ContractReader) Strings(s []string) ([]string, error) {
return unwrap.ArrayOfUTF8Strings(c.invoker.Call(c.hash, "strings", s))
}
// UnnamedStructs invokes `unnamedStructs` method of contract.
func (c *ContractReader) UnnamedStructs() (*Unnamed, error) {
return itemToUnnamed(unwrap.Item(c.invoker.Call(c.hash, "unnamedStructs")))
}
// UnnamedStructsX invokes `unnamedStructsX` method of contract.
func (c *ContractReader) UnnamedStructsX() (*UnnamedX, error) {
return itemToUnnamedX(unwrap.Item(c.invoker.Call(c.hash, "unnamedStructsX")))
}
// itemToUnnamed converts stack item into *Unnamed.
func itemToUnnamed(item stackitem.Item, err error) (*Unnamed, error) {
if err != nil {
return nil, err
}
var res = new(Unnamed)
err = res.FromStackItem(item)
return res, err
}
// FromStackItem retrieves fields of Unnamed from the given
// [stackitem.Item] or returns an error if it's not possible to do to so.
func (res *Unnamed) FromStackItem(item stackitem.Item) error {
arr, ok := item.Value().([]stackitem.Item)
if !ok {
return errors.New("not an array")
}
if len(arr) != 1 {
return errors.New("wrong number of structure elements")
}
var (
index = -1
err error
)
index++
res.I, err = arr[index].TryInteger()
if err != nil {
return fmt.Errorf("field I: %w", err)
}
return nil
}
// itemToUnnamedX converts stack item into *UnnamedX.
func itemToUnnamedX(item stackitem.Item, err error) (*UnnamedX, error) {
if err != nil {
return nil, err
}
var res = new(UnnamedX)
err = res.FromStackItem(item)
return res, err
}
// FromStackItem retrieves fields of UnnamedX from the given
// [stackitem.Item] or returns an error if it's not possible to do to so.
func (res *UnnamedX) FromStackItem(item stackitem.Item) error {
arr, ok := item.Value().([]stackitem.Item)
if !ok {
return errors.New("not an array")
}
if len(arr) != 2 {
return errors.New("wrong number of structure elements")
}
var (
index = -1
err error
)
index++
res.I, err = arr[index].TryInteger()
if err != nil {
return fmt.Errorf("field I: %w", err)
}
index++
res.B, err = arr[index].TryBool()
if err != nil {
return fmt.Errorf("field B: %w", err)
}
return nil
}

View file

@ -0,0 +1,103 @@
package types
import (
"github.com/nspcc-dev/neo-go/pkg/interop"
)
func Bool(b bool) bool {
return false
}
func Int(i int) int {
return 0
}
func Bytes(b []byte) []byte {
return nil
}
func String(s string) string {
return ""
}
func Any(a any) any {
return nil
}
func Hash160(h interop.Hash160) interop.Hash160 {
return nil
}
func Hash256(h interop.Hash256) interop.Hash256 {
return nil
}
func PublicKey(k interop.PublicKey) interop.PublicKey {
return nil
}
func Signature(s interop.Signature) interop.Signature {
return nil
}
func Bools(b []bool) []bool {
return nil
}
func Ints(i []int) []int {
return nil
}
func Bytess(b [][]byte) [][]byte {
return nil
}
func Strings(s []string) []string {
return nil
}
func Hash160s(h []interop.Hash160) []interop.Hash160 {
return nil
}
func Hash256s(h []interop.Hash256) []interop.Hash256 {
return nil
}
func PublicKeys(k []interop.PublicKey) []interop.PublicKey {
return nil
}
func Signatures(s []interop.Signature) []interop.Signature {
return nil
}
func AAAStrings(s [][][]string) [][][]string {
return s
}
func Maps(m map[string]string) map[string]string {
return m
}
func CrazyMaps(m map[int][]map[string][]interop.Hash160) map[int][]map[string][]interop.Hash160 {
return m
}
func AnyMaps(m map[int]any) map[int]any {
return m
}
func UnnamedStructs() struct{ I int } {
return struct{ I int }{I: 123}
}
func UnnamedStructsX() struct {
I int
B bool
} {
return struct {
I int
B bool
}{I: 123, B: true}
}

Some files were not shown because too many files have changed in this diff Show more