Commit graph

1630 commits

Author SHA1 Message Date
Anna Shaleva
07cbe4d253 core: add finalizer functions to interop context
These functions are aimed to free the resources occupied by storage
iterator by the end of script execution or whenever Finilize is called.
2021-10-21 10:05:12 +03:00
Anna Shaleva
0a4f45c9b0 core: add ability to free storage.Iterator resources 2021-10-21 10:05:12 +03:00
Anna Shaleva
89ee2e7720 core: refactor storage.Find and storage.Iterator to work with channel
Add SeekAsync methods in order to fetch matching storage items
on demand. Refactor storage.Find and storage.Iterator wrt these changes.
2021-10-21 10:05:12 +03:00
Anna Shaleva
f2ac07a3c0 core: do not copy key/value results got from MemCachedStore.Seek
They are already copied inside the MemCachedStore.Seek, so that
persistent storage  can't change them anymore.
2021-10-21 10:05:12 +03:00
Anna Shaleva
72726d46d3 core: refactor callers of MemCachedStore.Seek
MemCachedStore.Seek now sorts results, so its callers may omit sorting.
2021-10-21 10:05:12 +03:00
Anna Shaleva
7ba88e98e2 core: optimize (*MemCachedStore).Seek operation
Real persistent storage guarantees that result of Seek is sorted
by keys. The idea of optimisation is to merge two sorted seek
results into one (memStore+persistentStore), so that
(*MemCachedStore).Seek will return sorted list. The only thing
that remains is to sort items got from (*MemoryStore).Seek.
2021-10-21 10:05:12 +03:00
Anna Shaleva
191cc45032 core: sort items in MemoryStore.Seek
MemoryStore is used in a MemCachedStore as a persistent layer in tests.
Further commits suppose that persistent storage returns sorted values
from Seek, so sort the result of MemoryStore.Seek.

Benchmark results for 10000 matching items in MemoryStore compared to
master:
name          old time/op    new time/op    delta
MemorySeek-8     712µs ± 0%    3850µs ± 0%   +440.52%  (p=0.000 n=8+8)

name          old alloc/op   new alloc/op   delta
MemorySeek-8     160kB ± 0%    2724kB ± 0%  +1602.61%  (p=0.000 n=10+8)

name          old allocs/op  new allocs/op  delta
MemorySeek-8     10.0k ± 0%     10.0k ± 0%     +0.24%  (p=0.000 n=10+10)

For details on implementation efficiency see the
https://github.com/nspcc-dev/neo-go/pull/2193#discussion_r722993358.
2021-10-21 10:05:12 +03:00
Anna Shaleva
d8210c0137 core: add benchmarks for iterator.Next, MemCached.Seek, Mem.Seek 2021-10-21 10:05:12 +03:00
Anna Shaleva
8d8071f97e core: distinguish storage.KeyValue and storage.KeyValueExists
We need Exists field for storage batch related code; other cases may go
without Exists, so add new KeyValue structure and refactor related code.
2021-10-21 10:05:12 +03:00
Anna Shaleva
495aba4174 core: try to collapse traversed Billet part on errStop 2021-10-13 14:47:59 +03:00
Anna Shaleva
892eadf86d core: mandate passing from as a subprefix for (*Trie).Find
However, we need to distinguish empty subprefix and nil subprefix (no
start specified) to match the C# behaviour.
2021-10-13 14:47:41 +03:00
Anna Shaleva
8e7c76827b core: optimise (*Billet).Traverse and (*Trie).Find
(*Billet).Traverse changes:
1. Get rid of the `offset` argument. We can cut `from` and pass just the
part that remains. This implies that node with path matching `from` will
also be included in the result, so additional check needs to be added to
the callback function.
2. Pass `path` and `from` without search prefix. Append prefix to the
result inside the callback.
3. Remove duplicating code.

(*Trie).Find changes:
1. Properly prepare `from` argument for traversing function. It closly
depends on the `path` argument.
2021-10-13 13:52:33 +03:00
Anna Shaleva
43ac4e1517 rpc: implement findstates RPC handler 2021-10-13 11:41:05 +03:00
Anna Shaleva
7da394fd3f core: check MPT node is not requested twice by StateSync module
This check prevents infinite loop if something goes wrong with MPT nodes
restore process.
2021-10-12 14:08:56 +03:00
Anna Shaleva
01143da621 rpc: add getstate RPC handler 2021-10-11 16:43:44 +03:00
Anna Shaleva
c8120a139d core: add MaxKeyLength restrictions to MPT's operations 2021-10-06 16:37:23 +03:00
Evgeniy Stratonikov
e6aa9b76ee mempool: reword ErrConflict message, fix #2197
Make it more user-friendly.

Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2021-09-28 09:57:42 +03:00
Anna Shaleva
b3ea7504cb subscriptions: add container hash to notification event
External users make use of it. Close #2190.
2021-09-24 17:42:02 +03:00
Roman Khimov
c009356b73 core: simplify component flushing in storeBlock
Instead of flushing everything to `cache` and then to `bc.dao`, wrap `bc.dao`
directly for block/tx data and AERs and then flush to it. Block/transactions
are usually processed more quickly than other components, so they easily end
up in `cache` where they directly affect Seek performance for any executing
transaction.

Simple as it is this change improves voter NEO transfer benchmark with 1000
accounts by more than 25%, from ~18500 TPS to ~23500 TPS. It doesn't affect
much other cases.
2021-09-22 17:15:12 +03:00
Roman Khimov
b66bc33cf9 native: short-circuit successive GAS distributions
GAS can only be distributed once in a block for particular address, so it
makes little sense trying to calculate it again and again. This fixes
neo-bench for NEO voter, because without it we get ~2500 TPS for
single-address test and with it it jumps 13-fold to normal values like
~33500.
2021-09-22 17:13:55 +03:00
Anna Shaleva
06d3c21e3f core: remove unused interopnames 2021-09-21 16:43:09 +03:00
Roman Khimov
4743d5aacf
Merge pull request #2181 from nspcc-dev/states-diff_testnet_289026
core: fix NEO balance state handler
2021-09-21 15:39:37 +03:00
Anna Shaleva
c113d682bd core: fix NEO balance state handler
We need to store NEO balance's LastUpdateHeight before GAS mint,
because mint can call onNEP17Payment and onNEP17Payment can call NEO
transfer which also calls GAS mint. Storing balance height allows to
avoid recursion.
2021-09-20 19:23:35 +03:00
Roman Khimov
56dd7b7364
Merge pull request #2177 from nspcc-dev/fix-lint
Replace golint with revive
2021-09-15 17:59:04 +03:00
Roman Khimov
1480e29548
Merge pull request #2178 from nspcc-dev/fix-oracle-unsupported-code
transaction: fix ContentTypeNotSupported oracle code processing
2021-09-14 18:01:40 +03:00
Roman Khimov
24a3cce1ca
Merge pull request #2169 from nspcc-dev/states-diff_mainnet_131795
core: allow transfer 0 GAS/NEO with zero balance
2021-09-14 17:30:41 +03:00
Roman Khimov
8a440a4016 transaction: fix ContentTypeNotSupported oracle code processing
Fix testnet block 311487 block processing and synchronization errors:
  2021-09-14T15:18:53.611+0300    WARN    peer disconnected       {"addr": "20.198.226.132:20333", "reason": "invalid oracle response code", "peerCount": 10}

Fix 8e9302f40b.
2021-09-14 15:18:38 +03:00
Evgeniy Stratonikov
176b61e317 *: fix linter issues
Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2021-09-14 14:39:39 +03:00
Roman Khimov
63e00ac128
Merge pull request #2166 from nspcc-dev/fix-nns-compat
Fix NNS compatibility
2021-09-10 18:10:17 +03:00
Anna Shaleva
7fc57c9d58 core: allow transfer 0 GAS/NEO with zero balance
This commit fixes states diff at 131795 block of mainnet.

Transaction:
```
NEO-GO-VM > loadbase64 DAAQDBSPsxdYh6cITC3gUKI4oWmYxJs49gwUj7MXWIenCEwt4FCiOKFpmMSbOPYUwB8MCHRyYW5zZmVyDBT1Y+pAvCg9TQ4FxI6jBbPyoHNA70FifVtSOQwAEQwUj7MXWIenCEwt4FCiOKFpmMSbOPYMFL1Mb4Fqp6gHiEwzM6xSc8fLS+RpFMAfDAh0cmFuc2ZlcgwU9WPqQLwoPU0OBcSOowWz8qBzQO9BYn1bUjk=
READY: loaded 176 instructions
NEO-GO-VM 0 > ops
INDEX    OPCODE       PARAMETER
0        PUSHDATA1     ("")                                       <<
2        PUSH0
3        PUSHDATA1    8fb3175887a7084c2de050a238a16998c49b38f6
25       PUSHDATA1    8fb3175887a7084c2de050a238a16998c49b38f6
47       PUSH4
48       PACK
49       PUSH15
50       PUSHDATA1    7472616e73666572 ("transfer")
60       PUSHDATA1    f563ea40bc283d4d0e05c48ea305b3f2a07340ef    // NEO token
82       SYSCALL      System.Contract.Call (627d5b52)
87       ASSERT
88       PUSHDATA1     ("")
90       PUSH1
91       PUSHDATA1    8fb3175887a7084c2de050a238a16998c49b38f6
113      PUSHDATA1    bd4c6f816aa7a807884c3333ac5273c7cb4be469
135      PUSH4
136      PACK
137      PUSH15
138      PUSHDATA1    7472616e73666572 ("transfer")
148      PUSHDATA1    f563ea40bc283d4d0e05c48ea305b3f2a07340ef    // NEO token
170      SYSCALL      System.Contract.Call (627d5b52)
175      ASSERT

```

Go's applog:
```
{
   "id" : 1,
   "result" : {
      "txid" : "0x97d2ccb01467b22c73a2cb95f7af298f3a5bd8c849d7044371898b8efecdaabd",
      "executions" : [
         {
            "exception" : "at instruction 87 (ASSERT): ASSERT failed",
            "stack" : [],
            "gasconsumed" : "4988995",
            "notifications" : [],
            "trigger" : "Application",
            "vmstate" : "FAULT"
         }
      ]
   },
   "jsonrpc" : "2.0"
}
```

C#'s applog:
```
{
   "jsonrpc" : "2.0",
   "result" : {
      "executions" : [
         {
            "stack" : [],
            "notifications" : [
               {
                  "contract" : "0xef4073a0f2b305a38ec4050e4d3d28bc40ea63f5",
                  "state" : {
                     "type" : "Array",
                     "value" : [
                        {
                           "type" : "ByteString",
                           "value" : "j7MXWIenCEwt4FCiOKFpmMSbOPY="
                        },
                        {
                           "type" : "ByteString",
                           "value" : "j7MXWIenCEwt4FCiOKFpmMSbOPY="
                        },
                        {
                           "value" : "0",
                           "type" : "Integer"
                        }
                     ]
                  },
                  "eventname" : "Transfer"
               },
               {
                  "contract" : "0xd2a4cff31913016155e38e474a2c06d08be276cf",
                  "state" : {
                     "value" : [
                        {
                           "type" : "Any"
                        },
                        {
                           "type" : "ByteString",
                           "value" : "vUxvgWqnqAeITDMzrFJzx8tL5Gk="
                        },
                        {
                           "value" : "2490",
                           "type" : "Integer"
                        }
                     ],
                     "type" : "Array"
                  },
                  "eventname" : "Transfer"
               },
               {
                  "contract" : "0xef4073a0f2b305a38ec4050e4d3d28bc40ea63f5",
                  "state" : {
                     "value" : [
                        {
                           "value" : "vUxvgWqnqAeITDMzrFJzx8tL5Gk=",
                           "type" : "ByteString"
                        },
                        {
                           "value" : "j7MXWIenCEwt4FCiOKFpmMSbOPY=",
                           "type" : "ByteString"
                        },
                        {
                           "value" : "1",
                           "type" : "Integer"
                        }
                     ],
                     "type" : "Array"
                  },
                  "eventname" : "Transfer"
               }
            ],
            "vmstate" : "HALT",
            "gasconsumed" : "9977990",
            "trigger" : "Application",
            "exception" : null
         }
      ],
      "txid" : "0x97d2ccb01467b22c73a2cb95f7af298f3a5bd8c849d7044371898b8efecdaabd"
   },
   "id" : 1
}

```
2021-09-10 17:18:09 +03:00
Roman Khimov
aaccf748ac nft-nd-nns: add getAllRecords method
See neo-project/non-native-contracts#5.
2021-09-10 16:30:45 +03:00
Anna Shaleva
61fd7bd6ba core: avoid nil values during natives manifest marshalling 2021-09-10 11:38:59 +03:00
Anna Shaleva
db13362e86 core: marshal Block.Nonce in upper-case hex 2021-09-09 15:52:51 +03:00
Anna Shaleva
51c8c0d82b core: add tests for StateSync module 2021-09-07 19:43:27 +03:00
Anna Shaleva
0aedfd0038 core: fix bug in MPT pool during Update
We need to copy the result of `TryGet` method, otherwice the slice can
be modified inside `Add` or `Update` methods, which leads to
inconsistent MPT pool state.
2021-09-07 19:43:27 +03:00
Anna Shaleva
36808b8904 core: clone MPT node while restoring it multiple times
We need this to avoid collapse collisions. Example of such collapse
described in
https://github.com/nspcc-dev/neo-go/pull/2019#discussion_r689629704.
2021-09-07 19:43:27 +03:00
Anna Shaleva
5cd78c31af core: allow to recover after state jump interruption
We need several stages to manage state jump process in order not to mess
up old and new contract storage items and to be sure about genesis state data
are properly removed from the storage. Other operations do not require
separate stage and can be performed each time `jumpToStateInternal` is
called.
2021-09-07 19:43:27 +03:00
Anna Shaleva
5cda24b3af core: initialize headers before current block 2021-09-07 19:43:27 +03:00
Anna Shaleva
0e0b55350a core: convert (*Blockchain).JumpToState to a callback
We don't need this method to be exposed, the only its user is the
StateSync module. At the same time StateSync module manages its state by
itself which guarantees that (*Blockchain).jumpToState will be called
with proper StateSync stage.
2021-09-07 19:43:27 +03:00
Anna Shaleva
6381173293 core: store statesync-related storage items under temp prefix
State jump should be an atomic operation, we can't modify contract
storage items state on-the-fly. Thus, store fresh items under temp
prefix and replase the outdated ones after state sync is completed.
Related
https://github.com/nspcc-dev/neo-go/pull/2019#discussion_r693350460.
2021-09-07 19:43:27 +03:00
Anna Shaleva
51f405471e core: remove outdated blocks/txs/AERs/MPT nodes during state sync
Before state sync process can be started, outdated MPT nodes
should be removed from storage. After state sync is completed,
outdated blocks/transactions/AERs should also be removed.
2021-09-07 19:43:27 +03:00
Anna Shaleva
a276a85b72 core: unify code of state sync module initialization 2021-09-07 19:43:27 +03:00
Anna Shaleva
3b7807e897 network: request unknown MPT nodes
In this commit:

1. Request unknown MPT nodes from peers. Note, that StateSync module itself
shouldn't be responsible for nodes requests, that's a server duty.
2. Do not request the same node twice, check if it is in storage
already. If so, then the only thing remaining is to update refcounter.
2021-09-07 19:43:27 +03:00
Anna Shaleva
6a04880b49 core: collapse completed parts of Billet
Some kind of marker is needed to check whether node has been collapsed
or not. So introduce (HashNode).Collapsed
2021-09-07 19:43:27 +03:00
Anna Shaleva
74f1848d19 core: adjust LastUpdatedBlock calculation for NEP17 balances
...wrt P2PStateExchange setting.
2021-09-07 19:43:27 +03:00
Anna Shaleva
d67ff30704 core: implement statesync module
And support GetMPTData and MPTData P2P commands.
2021-09-07 19:43:27 +03:00
Anna Shaleva
a22b1caa3e core: implement MPT Billet structure for MPT restore
MPT restore process is much simpler then regular MPT maintaining: trie
has a fixed structure, we don't need to remove or rebuild MPT nodes. The
only thing we should do is to replace Hash nodes to their unhashed
counterparts and increment refcount. It's better not to touch the
regular MPT code and create a separate structure for this.
2021-09-07 19:43:27 +03:00
Roman Khimov
c9e62769a6
Merge pull request #2143 from nspcc-dev/mpt/add_empty_values
core: allow empty MPT Leaf values
2021-09-07 09:18:48 +03:00
Anna Shaleva
c95f2079d5 core: adjust comments on behaviour defferences for MPT TestCompatibility
C# node does not return empty proof enymore in case if path is bad. C#
node also throws an exception on bad Put.

Our node does not return an error on delete if the key is empty.
2021-09-03 13:46:52 +03:00
Anna Shaleva
f721384ead core: allow empty MPT Leaf values
Allow it for (*Trie).Put. And distinguish empty value and nil value for
(*Trie).PutBatch, because batch is already capable of handling both nil
and empty value. For (*Trie).PutBatch putting nil value means deletion,
while putting empty value means just putting LeafNode with an empty
value.
2021-09-03 13:46:48 +03:00