Commit graph

76 commits

Author SHA1 Message Date
Pavel Karpy
f8549a4fb8 mpt: refactor lcp to be possible to use range
It took some time to understand why changing a regular `for` to a `range`
one leads to behavior changes; let it be more clear and explicit. Also, a
correct code is always better than a correct code with `nolint`.

Signed-off-by: Pavel Karpy <carpawell@nspcc.ru>
2024-09-04 14:15:44 +03:00
Pavel Karpy
32f91dd726 .golangci.yml: add intrange linter
It checks that go 1.22's range-over-numbers feature is not skipped. Also,
fix some warnings it found.

Signed-off-by: Pavel Karpy <carpawell@nspcc.ru>
2024-09-04 14:15:32 +03:00
Roman Khimov
1b83dc2476 *: improve for loop syntax
Mostly it's about Go 1.22+ syntax with ranging over integers, but it also
prefers ranging over slices where possible (it makes code a little better to
read).

Notice that we have a number of dangerous loops where slices are mutated
during loop execution, many of these can't be converted since we need proper
length evalutation at every iteration.

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2024-08-30 21:45:18 +03:00
Roman Khimov
357bc76882 *: use slices.Concat where appropriate
Signed-off-by: Roman Khimov <roman@nspcc.ru>
2024-08-30 17:00:11 +03:00
Roman Khimov
6d4ebdcef3 *: return errors.ErrUnsupported where appropriate
Signed-off-by: Roman Khimov <roman@nspcc.ru>
2024-08-27 12:51:12 +03:00
Roman Khimov
a1a7e3d708 *: use slices package for sorting and searching
Signed-off-by: Roman Khimov <roman@nspcc.ru>
2024-08-27 12:29:44 +03:00
Roman Khimov
d9ee31fb52 *: use clear() to clear maps
Supposedly more efficient since we can avoid some memory management dances.

Memory pool agrees:

goos: linux
goarch: amd64
pkg: github.com/nspcc-dev/neo-go/pkg/core/mempool
cpu: AMD Ryzen 7 PRO 7840U w/ Radeon 780M Graphics
                       │  pool.old   │              pool.new               │
                       │   sec/op    │   sec/op     vs base                │
Pool/one,_incr_fee-16    12.44m ± 1%   12.51m ± 1%   +0.55% (p=0.029 n=10)
Pool/many,_same_fee-16   4.960m ± 2%   3.100m ± 1%  -37.50% (p=0.000 n=10)
Pool/many,_incr_fee-16   16.03m ± 2%   14.11m ± 1%  -12.00% (p=0.000 n=10)
Pool/one,_same_fee-16                  1.742m ± 1%
geomean                  9.964m        5.556m       -17.92%

                       │    pool.old     │                pool.new                │
                       │      B/op       │      B/op       vs base                │
Pool/one,_incr_fee-16     8.117Ki ± 120%   7.101Ki ± 128%  -12.52% (p=0.022 n=10)
Pool/many,_same_fee-16   3941.2Ki ±   0%   805.4Ki ±   0%  -79.56% (p=0.000 n=10)
Pool/many,_incr_fee-16   3936.2Ki ±   0%   829.8Ki ±   0%  -78.92% (p=0.000 n=10)
Pool/one,_same_fee-16                      12.98Ki ±  10%
geomean                   501.2Ki          88.59Ki         -66.47%

                       │   pool.old   │               pool.new               │
                       │  allocs/op   │  allocs/op    vs base                │
Pool/one,_incr_fee-16     28.00 ± 21%    24.00 ± 21%  -14.29% (p=0.002 n=10)
Pool/many,_same_fee-16   40.38k ±  0%   40.03k ±  0%   -0.86% (p=0.000 n=10)
Pool/many,_incr_fee-16   40.38k ±  0%   40.04k ±  0%   -0.85% (p=0.000 n=10)
Pool/one,_same_fee-16                    23.00 ±  4%
geomean                  3.574k          969.8         -5.55%

Signed-off-by: Roman Khimov <roman@nspcc.ru>
2024-08-24 22:41:48 +03:00
Anna Shaleva
c06543cf50 *: fix linter issues
Linter is updated up to v1.60.1, the following issue is fixed:
```
predeclared  variable max has same name as predeclared identifier
```

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
2024-08-14 12:36:15 +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
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
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
Roman Khimov
63f212f4b3 golangci: enable/fix misspell 2022-09-02 18:36:26 +03:00
Anna Shaleva
916f2293b8 *: apply go 1.19 formatter heuristics
And make manual corrections where needed. See the "Common mistakes
and pitfalls" section of https://tip.golang.org/doc/comment.
2022-08-09 15:37:52 +03:00
Roman Khimov
8cd7b93208 limits: new package with storage limits
Packages like core/state or core/mpt shouldn't import whole core/storage just
to get some constant value, it's not a good dependency.
2022-07-08 23:30:30 +03:00
Elizaveta Chichindaeva
28908aa3cf [#2442] English Check
Signed-off-by: Elizaveta Chichindaeva <elizaveta@nspcc.ru>
2022-05-04 19:48:27 +03:00
Anna Shaleva
f8b5972f61 core: support Store interface over MPT 2022-04-29 16:10:04 +03:00
Anna Shaleva
0cf525d62e core: add ability to traverse backwards for Billet 2022-04-29 16:10:04 +03:00
Roman Khimov
f80680187e storage: expose private storage map for more efficient MPT batch
It couldn't be done previously with two maps and mixed storage, but now all of
the storage changes are located in a single map, so it's trivial to do exact
slice allocations and avoid string->[]byte conversions.
2022-02-17 23:41:10 +03:00
Roman Khimov
9d2ef775cf storage: simplify (*MemCachedStore).Put/Delete interface
They never return errors, so their interface should reflect that. This allows
to remove quite a lot of useless and never tested code.

Notice that Get still does return an error. It can be made not to do that, but
usually we need to differentiate between successful/unsuccessful accesses
anyway, so this doesn't help much.
2022-02-16 18:24:20 +03:00
Roman Khimov
c5f1e2fbcd mpt: don't allocate for every key
Microoptimization.
2022-02-11 14:19:54 +03:00
Roman Khimov
c4ee310e85 mpt: modify refcounted storage scheme to make GC possible
Add "active" flag into the node data and make the remainder modal, for active
nodes it's a reference counter, for inactive ones the deactivation height is
stored.

Technically, refcounted chains storing just one trie don't need a flag, but
it's a bit simpler this way.
2022-02-10 21:56:20 +03:00
Roman Khimov
86cb4ed80f mpt: add the notion of MPT mode
It directly affects the storage format, so it's important. ModeGC is not used
at the moment, but defined for future extensibility.
2022-02-10 19:15:18 +03:00
Roman Khimov
2bc493a839 mpt: simplify makeStorageKey() interface 2022-02-08 12:38:03 +03:00
Evgeniy Stratonikov
856e9cf67b statesync: copy state by swapping prefix
Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2021-11-24 16:22:27 +03:00
Evgeniy Stratonikov
856385b106 dao: use custom storage prefix
We use 2 prefixes for storing items because of state synchronization.
This commit allows to parametrize dao with the default prefix.

Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2021-11-24 16:22:07 +03:00
AnnaShaleva
3fed7b8eec core: handle empty MPT batch properly
It's OK to have it.
2021-10-27 18:44:39 +03:00
Anna Shaleva
002b5a2c3c core: add Trie.Find compatibility test 2021-10-15 10:28:08 +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
c8120a139d core: add MaxKeyLength restrictions to MPT's operations 2021-10-06 16:37:23 +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
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
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
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
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
Evgeniy Stratonikov
73e4040628 mpt: use BinWriter.Grow() instead of custom buffer
Also add benchmarks.

Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2021-08-10 09:34:05 +03:00
Evgeniy Stratonikov
bd2b1a0521 mpt: add Size method to trie nodes
Knowing serialized size of the node is useful for
preallocating byte-slice in advance.

Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2021-08-06 12:01:16 +03:00
Evgeniy Stratonikov
db80ef28df mpt: move empty hash node in a separate type
We use them quite frequently (consider children for a new branch
node) and it is better to get rid of unneeded allocations.

Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2021-08-06 12:01:16 +03:00
Evgeniy Stratonikov
43ee671f36 mpt: do not allocate NodeObject for serialization
Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2021-08-06 10:28:19 +03:00
Roman Khimov
19717dd9a8 slice: introduce common Copy helper
It's a bit more convenient to use.
2021-07-19 22:57:55 +03:00
Evgeniy Stratonikov
a33e422b79 mpt: do not create an Extension for the last child of a Branch
Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2021-07-07 15:49:53 +03:00
Evgeniy Stratonikov
25428d53f1 mpt: strip branch node in a simple implementation
Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2021-07-07 15:47:07 +03:00
Evgeniy Stratonikov
9691eee10c mpt: strip branch if 1 child is left
If the child left is a hash node, we should retrieve it from store.

Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2021-07-05 11:04:20 +03:00
Evgeniy Stratonikov
f3d02b9fef mpt/tests: add compatibility tests 2021-06-04 11:09:17 +03:00
Evgeniy Stratonikov
e833d333fe mpt: disallow empty keys
This is not a problem in practice, as all keys are prefixed
by a contract ID. However in theory it can lead to a different
state root after new portion of changes thus this fix.
2021-06-04 11:09:17 +03:00