Commit graph

120 commits

Author SHA1 Message Date
Anna Shaleva
b66f666267 core: ensure memcached Seek operation is properly cancelled
PR #2495 is not enought, the problem is reproduced during dump restore
with the stacktrace attached down below.

The reason is that SeekAsync starts goroutine that performs Seek
operation over private MemCachedStore. The goroutine iterates over
MemCachedStore's map without holding the lock (it's OK, because it's
private), whereas the main thread continues invocation and
performs writes to the same map. To fix that ic.Exec() needs to
wait until all goroutines are properly exited.

```
2022-05-17T08:34:50.430+0300	INFO	persisted to disk	{"blocks": 632, "keys": 16546, "headerHeight": 54091, "blockHeight": 54091, "took": "57.904387ms"}
fatal error: concurrent map iteration and map write

goroutine 218853 [running]:
runtime.throw({0xf56a31, 0x614968})
	runtime/panic.go:1198 +0x71 fp=0xc0000ceae0 sp=0xc0000ceab0 pc=0x4357b1
runtime.mapiternext(0x0)
	runtime/map.go:858 +0x4eb fp=0xc0000ceb50 sp=0xc0000ceae0 pc=0x40f82b
runtime.mapiterinit(0xc0000cec18, 0xc00359ca40, 0x1a)
	runtime/map.go:848 +0x236 fp=0xc0000ceb70 sp=0xc0000ceb50 pc=0x40f2f6
github.com/nspcc-dev/neo-go/pkg/core/storage.(*MemCachedStore).prepareSeekMemSnapshot(0xc005315680, {{0xc00359ca40, 0x1a, 0x1a}, {0x0, 0x0, 0x0}, 0x0})
	github.com/nspcc-dev/neo-go/pkg/core/storage/memcached_store.go:209 +0x24a fp=0xc0000ced88 sp=0xc0000ceb70 pc=0x823fca
github.com/nspcc-dev/neo-go/pkg/core/storage.(*MemCachedStore).Seek(0xd94ac0, {{0xc00359ca40, 0x1a, 0x1a}, {0x0, 0x0, 0x0}, 0x0}, 0x20)
	github.com/nspcc-dev/neo-go/pkg/core/storage/memcached_store.go:156 +0x9b fp=0xc0000cee20 sp=0xc0000ced88 pc=0x82369b
github.com/nspcc-dev/neo-go/pkg/core/storage.performSeek({0x11c3330, 0xc002240dc0}, {0x11cb258, 0xc005315680}, {0x0, 0x0, 0x1}, {{0xc00359ca40, 0x1a, 0x1a}, ...}, ...)
	github.com/nspcc-dev/neo-go/pkg/core/storage/memcached_store.go:304 +0x4b7 fp=0xc0000cef00 sp=0xc0000cee20 pc=0x824a37
github.com/nspcc-dev/neo-go/pkg/core/storage.(*MemCachedStore).SeekAsync.func1()
	github.com/nspcc-dev/neo-go/pkg/core/storage/memcached_store.go:176 +0x16c fp=0xc0000cefe0 sp=0xc0000cef00 pc=0x823b8c
runtime.goexit()
	runtime/asm_amd64.s:1581 +0x1 fp=0xc0000cefe8 sp=0xc0000cefe0 pc=0x468a41
created by github.com/nspcc-dev/neo-go/pkg/core/storage.(*MemCachedStore).SeekAsync
	github.com/nspcc-dev/neo-go/pkg/core/storage/memcached_store.go:175 +0x1f6

goroutine 1 [runnable]:
github.com/nspcc-dev/neo-go/pkg/core/mpt.MapToMPTBatch.func1(0x4, 0x0)
	github.com/nspcc-dev/neo-go/pkg/core/mpt/batch.go:28 +0x95
sort.doPivot_func({0xc000457878, 0xc003305bc0}, 0x0, 0x1a)
	sort/zfuncversion.go:121 +0x46a
sort.quickSort_func({0xc000457878, 0xc003305bc0}, 0xc001014d20, 0x0, 0xc003304ff0)
	sort/zfuncversion.go:143 +0x85
sort.Slice({0xd94800, 0xc001014d20}, 0x1a)
	sort/slice.go:20 +0x9f
github.com/nspcc-dev/neo-go/pkg/core/mpt.MapToMPTBatch(0xc003304ff0)
	github.com/nspcc-dev/neo-go/pkg/core/mpt/batch.go:28 +0x2e7
github.com/nspcc-dev/neo-go/pkg/core.(*Blockchain).storeBlock(0xc000400280, 0xc000f178c0, 0xc005a04370)
	github.com/nspcc-dev/neo-go/pkg/core/blockchain.go:1136 +0xfef
github.com/nspcc-dev/neo-go/pkg/core.(*Blockchain).AddBlock(0xc000400280, 0xc000f178c0)
	github.com/nspcc-dev/neo-go/pkg/core/blockchain.go:893 +0x755
github.com/nspcc-dev/neo-go/pkg/core/chaindump.Restore({0x11c3528, 0xc000400280}, 0xc350, 0x0, 0x4c221, 0xc000458710)
	github.com/nspcc-dev/neo-go/pkg/core/chaindump/dump.go:73 +0x2ca
github.com/nspcc-dev/neo-go/cli/server.restoreDB(0xc000410000)
	github.com/nspcc-dev/neo-go/cli/server/server.go:381 +0xcfa
github.com/urfave/cli.HandleAction({0xdbbfa0, 0x10a1078}, 0x7)
	github.com/urfave/cli@v1.22.5/app.go:524 +0xa8
github.com/urfave/cli.Command.Run({{0xf32b10, 0x7}, {0x0, 0x0}, {0x0, 0x0, 0x0}, {0xf4a41d, 0x1c}, {0x0, ...}, ...}, ...)
	github.com/urfave/cli@v1.22.5/command.go:173 +0x652
github.com/urfave/cli.(*App).RunAsSubcommand(0xc0001f7880, 0xc0001adce0)
	github.com/urfave/cli@v1.22.5/app.go:405 +0x9ec
github.com/urfave/cli.Command.startApp({{0xf2e982, 0x2}, {0x0, 0x0}, {0x0, 0x0, 0x0}, {0xf41af9, 0x16}, {0x0, ...}, ...}, ...)
	github.com/urfave/cli@v1.22.5/command.go:372 +0x6e9
github.com/urfave/cli.Command.Run({{0xf2e982, 0x2}, {0x0, 0x0}, {0x0, 0x0, 0x0}, {0xf41af9, 0x16}, {0x0, ...}, ...}, ...)
	github.com/urfave/cli@v1.22.5/command.go:102 +0x808
github.com/urfave/cli.(*App).Run(0xc0001f76c0, {0xc00012e000, 0x8, 0x8})
	github.com/urfave/cli@v1.22.5/app.go:277 +0x705
main.main()
	./main.go:19 +0x33

goroutine 66 [select]:
github.com/syndtr/goleveldb/leveldb/util.(*BufferPool).drain(0xc00027e1c0)
	github.com/syndtr/goleveldb@v1.0.1-0.20210305035536-64b5b1c73954/leveldb/util/buffer_pool.go:209 +0xcd
created by github.com/syndtr/goleveldb/leveldb/util.NewBufferPool
	github.com/syndtr/goleveldb@v1.0.1-0.20210305035536-64b5b1c73954/leveldb/util/buffer_pool.go:240 +0x19b

goroutine 67 [select]:
github.com/syndtr/goleveldb/leveldb.(*session).refLoop(0xc0002441e0)
	github.com/syndtr/goleveldb@v1.0.1-0.20210305035536-64b5b1c73954/leveldb/session_util.go:189 +0x5bb
created by github.com/syndtr/goleveldb/leveldb.newSession
	github.com/syndtr/goleveldb@v1.0.1-0.20210305035536-64b5b1c73954/leveldb/session.go:93 +0x2de

goroutine 85 [select]:
github.com/syndtr/goleveldb/leveldb.(*DB).compactionError(0xc0001f7a40)
	github.com/syndtr/goleveldb@v1.0.1-0.20210305035536-64b5b1c73954/leveldb/db_compaction.go:91 +0x15e
created by github.com/syndtr/goleveldb/leveldb.openDB
	github.com/syndtr/goleveldb@v1.0.1-0.20210305035536-64b5b1c73954/leveldb/db.go:148 +0x4ef

goroutine 86 [select]:
github.com/syndtr/goleveldb/leveldb.(*DB).mpoolDrain(0xc0001f7a40)
	github.com/syndtr/goleveldb@v1.0.1-0.20210305035536-64b5b1c73954/leveldb/db_state.go:101 +0xae
created by github.com/syndtr/goleveldb/leveldb.openDB
	github.com/syndtr/goleveldb@v1.0.1-0.20210305035536-64b5b1c73954/leveldb/db.go:149 +0x531

goroutine 87 [runnable]:
github.com/syndtr/goleveldb/leveldb.(*compaction).shouldStopBefore(0xc001787440, {0xc001890720, 0x29, 0x30})
	github.com/syndtr/goleveldb@v1.0.1-0.20210305035536-64b5b1c73954/leveldb/session_compaction.go:272 +0x10a
github.com/syndtr/goleveldb/leveldb.(*tableCompactionBuilder).run(0xc0001ca140, 0xc002039638)
	github.com/syndtr/goleveldb@v1.0.1-0.20210305035536-64b5b1c73954/leveldb/db_compaction.go:461 +0x565
github.com/syndtr/goleveldb/leveldb.(*DB).compactionTransact(0xc0001f7a40, {0xf369f0, 0xb}, {0x11b9b60, 0xc0001ca140})
	github.com/syndtr/goleveldb@v1.0.1-0.20210305035536-64b5b1c73954/leveldb/db_compaction.go:186 +0x22f
github.com/syndtr/goleveldb/leveldb.(*DB).tableCompaction(0xc0001f7a40, 0xc001787440, 0x0)
	github.com/syndtr/goleveldb@v1.0.1-0.20210305035536-64b5b1c73954/leveldb/db_compaction.go:580 +0xa30
github.com/syndtr/goleveldb/leveldb.(*DB).tableAutoCompaction(0xc0001f7a40)
	github.com/syndtr/goleveldb@v1.0.1-0.20210305035536-64b5b1c73954/leveldb/db_compaction.go:644 +0x39
github.com/syndtr/goleveldb/leveldb.(*DB).tCompaction(0xc0001f7a40)
	github.com/syndtr/goleveldb@v1.0.1-0.20210305035536-64b5b1c73954/leveldb/db_compaction.go:863 +0x43b
created by github.com/syndtr/goleveldb/leveldb.openDB
	github.com/syndtr/goleveldb@v1.0.1-0.20210305035536-64b5b1c73954/leveldb/db.go:155 +0x5a7

goroutine 88 [select]:
github.com/syndtr/goleveldb/leveldb.(*DB).mCompaction(0xc0001f7a40)
	github.com/syndtr/goleveldb@v1.0.1-0.20210305035536-64b5b1c73954/leveldb/db_compaction.go:773 +0x119
created by github.com/syndtr/goleveldb/leveldb.openDB
	github.com/syndtr/goleveldb@v1.0.1-0.20210305035536-64b5b1c73954/leveldb/db.go:156 +0x5e9

goroutine 78 [select]:
github.com/nspcc-dev/neo-go/pkg/core.(*Blockchain).Run(0xc000400280)
	github.com/nspcc-dev/neo-go/pkg/core/blockchain.go:615 +0x185
created by github.com/nspcc-dev/neo-go/cli/server.initBCWithMetrics
	github.com/nspcc-dev/neo-go/cli/server/server.go:217 +0x23d

goroutine 79 [IO wait]:
internal/poll.runtime_pollWait(0x7ffb00b2aad8, 0x72)
	runtime/netpoll.go:229 +0x89
internal/poll.(*pollDesc).wait(0xc00012e180, 0x4, 0x0)
	internal/poll/fd_poll_runtime.go:84 +0x32
internal/poll.(*pollDesc).waitRead(...)
	internal/poll/fd_poll_runtime.go:89
internal/poll.(*FD).Accept(0xc00012e180)
	internal/poll/fd_unix.go:402 +0x22c
net.(*netFD).accept(0xc00012e180)
	net/fd_unix.go:173 +0x35
net.(*TCPListener).accept(0xc000280090)
	net/tcpsock_posix.go:140 +0x28
net.(*TCPListener).Accept(0xc000280090)
	net/tcpsock.go:262 +0x3d
net/http.(*Server).Serve(0xc00027e380, {0x11bd4a8, 0xc000280090})
	net/http/server.go:3001 +0x394
net/http.(*Server).ListenAndServe(0xc00027e380)
	net/http/server.go:2930 +0x7d
github.com/nspcc-dev/neo-go/pkg/network/metrics.(*Service).Start(0xc000097d10)
	github.com/nspcc-dev/neo-go/pkg/network/metrics/metrics.go:29 +0x115
created by github.com/nspcc-dev/neo-go/cli/server.initBCWithMetrics
	github.com/nspcc-dev/neo-go/cli/server/server.go:218 +0x285

goroutine 9 [syscall]:
os/signal.signal_recv()
	runtime/sigqueue.go:169 +0x98
os/signal.loop()
	os/signal/signal_unix.go:24 +0x19
created by os/signal.Notify.func1.1
	os/signal/signal.go:151 +0x2c

goroutine 8 [select]:
github.com/nspcc-dev/neo-go/pkg/core.(*Blockchain).notificationDispatcher(0xc000400280)
	github.com/nspcc-dev/neo-go/pkg/core/blockchain.go:739 +0x2e7
created by github.com/nspcc-dev/neo-go/pkg/core.(*Blockchain).Run
	github.com/nspcc-dev/neo-go/pkg/core/blockchain.go:612 +0xe5

goroutine 10 [chan receive]:
github.com/nspcc-dev/neo-go/cli/server.newGraceContext.func1()
	github.com/nspcc-dev/neo-go/cli/server/server.go:117 +0x28
created by github.com/nspcc-dev/neo-go/cli/server.newGraceContext
	github.com/nspcc-dev/neo-go/cli/server/server.go:116 +0xde
```
2022-05-18 07:35:48 +03:00
Anna Shaleva
5505acf10e core: change Create[Standard, Multisig]Account prices
And make a hard-fork from this change.
2022-05-11 14:21:43 +03:00
Anna Shaleva
544f2c2cb2 core: use proper storage price within the whole interop context
We shouldn't use StoragePrice from Blockchain because its dao doesn't
contain the whole set of changes from previouse transactions in the
current block. Instead, we should use an updated storage price for
each transaction and retrieve the price from cached DAO.
2022-04-08 12:50:56 +03:00
Roman Khimov
3ab2ab5cba core: drop outdated comment from storageFind 2022-03-31 16:39:11 +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
9c8ba5777e
Merge pull request #2323 from nspcc-dev/drop-blockchainer
Reduce blockchainer.Blockchainer use
2022-01-14 20:47:26 +03:00
AnnaShaleva
6bc92abe19 storage: allow to seek starting from some point 2022-01-13 12:44:29 +03:00
Roman Khimov
c942402957 blockchainer: drop Policer interface
We never use it as a proper interface, so it makes no sense keeping it this
way.
2022-01-12 00:58:03 +03:00
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
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
Roman Khimov
b07347e602 core: reuse PushItem for interops
Probably less critical here, but still let's push things faster.
2021-08-30 23:43:58 +03:00
Roman Khimov
5f13de3a76 *: simplify some integer checks with IsUint64()
If we need a positive number we can do `IsUint64()` instead of checking that
`Int64()` is `> 0`.
2021-07-19 15:42:42 +03:00
Evgeniy Stratonikov
eb7bd7b99b core: optimize storageFind
Because `Map` stores elements in arbitrary order, addition of new
element takes linear time (`Index` iterates over all keys). Thus our
`storageFind` is actually quadratic in time. Optimize this by creating
map from sorted slice.

```
name           old time/op    new time/op    delta
StorageFind-8     157µs ± 2%     112µs ± 1%  -28.60%  (p=0.000 n=10+10)

name           old alloc/op   new alloc/op   delta
StorageFind-8    69.4kB ± 0%    60.5kB ± 0%  -12.90%  (p=0.000 n=9+10)

name           old allocs/op  new allocs/op  delta
StorageFind-8     2.21k ± 0%     2.00k ± 0%   -9.37%  (p=0.000 n=10+7)
```

Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2021-07-12 14:22:17 +03:00
Anna Shaleva
f824789116 core: remove neointerops-related files
And move their content to systeminterops-related files.
2021-05-12 13:30:04 +03:00
Anna Shaleva
f0c222b385 core: move StorageItem-related constants to storage pkg
Need this to avoid import cycle problem.
2021-04-01 10:17:08 +03:00
Anna Shaleva
ec19a087bb core: remove StorageFlag remnant 2021-04-01 10:17:08 +03:00
Anna Shaleva
7118eae467 core: remove useless code from putWithContext 2021-03-19 18:57:29 +03:00
Anna Shaleva
5b18f5974f core: fix storage.Delete price 2021-03-19 18:57:00 +03:00
Anna Shaleva
0d9266d407 core: remove System.Contract.IsStandard 2021-03-16 16:59:23 +03:00
Evgeniy Stratonikov
55698d0426 dao: use raw state.StorageItem instead of pointer
It is now a slice, there is no need for additional indirection.
2021-03-09 12:11:25 +03:00
Evgeniy Stratonikov
fd4174ad31 core/state: remove IsConst from StorageItem 2021-03-09 11:59:08 +03:00
Anna Shaleva
5a37201319 core: add System.Contract.CreateMultisigAccount interop 2021-02-19 17:31:50 +03:00
Roman Khimov
ac527650eb native: add Ledger contract, fix #1696
But don't change the way we process/store transactions and blocks. Effectively
it's just an interface for smart contracts that replaces old syscalls.

Transaction definition is moved temporarily to runtime package and Block
definition is removed (till we solve #1691 properly).
2021-02-04 13:12:11 +03:00
Evgeniy Stratonikov
0b26b46234 state: store NEF instead of script for contract
NEFs for native contracts are set statically, thus
field values are taken from the reference implementation.
2021-01-13 15:34:10 +03:00
Evgenii Stratonikov
62da365302 native: allow to modify StoragePrice in the policy contract 2020-12-16 13:55:40 +03:00
Evgenii Stratonikov
1840c1c80d core: redefine opcode prices
Prices are defined in as a coefficients to `BaseExecFee` which
is defined by Policy contract (TBD later).
Native method prices are defined without need to multiply.
2020-12-16 13:55:39 +03:00
Roman Khimov
ab12eee346 native: move contract deployment to management contract
See neo-project/neo#2119.
2020-12-14 15:23:46 +03:00
Evgenii Stratonikov
2eb256014e core: move System.Runtime.* interops to runtime/ package
Also extend test suite.
2020-12-02 15:54:03 +03:00
Roman Khimov
1cf1fe5d74 *: introduce stable contract hashes
Follow neo-project/neo#2044.
2020-11-27 21:47:08 +03:00
Evgenii Stratonikov
b97dfae8d8 native: replace NEP-5 with NEP-17 2020-11-24 13:08:23 +03:00
Anna Shaleva
ec8ebc292c core: restrict notification size for System.Runtime.Notify 2020-11-17 16:27:51 +03:00
Roman Khimov
3cb945f022 manifest: simplify marshaling 2020-11-13 21:46:26 +03:00
Roman Khimov
286d9185f4 smartcontract: remove contract features
We're featureless now, all contracts have access to storage and payable status
is to be determined via new NEP. Follow neo-project/neo#2060.
2020-11-13 21:26:23 +03:00
Roman Khimov
b327308df8 core/config: move MaxTraceableBlocks to configuration file
Follow neo-project/neo#2042, use 2102400 setting for mainnet/testnet and
200000 for private networks.
2020-11-06 13:41:46 +03:00
Roman Khimov
d7502debba core: adjust storage update fees
Follow neo-project/neo#2033.
2020-11-03 22:50:40 +03:00
Evgenii Stratonikov
833bbb1d35 core: calculate gas for System.Storage.Put correctly
If `Put` creates new key, its length should contribute
to a GAS cost of the syscall.
2020-10-05 13:03:44 +03:00
Evgenii Stratonikov
877b8ece63 core: move contractCall* to a separate package 2020-09-25 16:32:10 +03:00
Evgenii Stratonikov
bf01599430 vm: check return value on context unload
When calling external contracts we expect exactly 1 value to be on
stack. For methods returning nothing, `Null` value is pushed, otherwise
it is an error.`
2020-08-10 11:52:33 +03:00
Roman Khimov
f5131491b7
Merge pull request #1271 from nspcc-dev/core/call_from_native
core: contractCall from native contracts
2020-08-07 21:24:50 +03:00
Anna Shaleva
995053f2eb core: add VM into interop context 2020-08-07 16:15:24 +03:00
Evgenii Stratonikov
194da64975 core: deepcopy notification in System.Runtime.Notify
Make it impossible to change already emitted notifications via
`System.Runtime.GetNotifications`.
2020-08-05 11:19:41 +03:00
Anna Shaleva
90825efa16 core: move transaction's sender to cosigners
Closes #1184

Ported changes from https://github.com/neo-project/neo/pull/1752
2020-08-04 17:33:50 +03:00
Evgenii Stratonikov
3c99393bef core: simplify System.Contract.Call* parameter handling 2020-07-30 12:37:32 +03:00
Evgenii Stratonikov
f40aba4cd0 vm: convert items to UTF-8 strings
Add `stackitem.ToString` for seamless string conversion.
2020-07-30 12:37:31 +03:00
Evgenii Stratonikov
685d44dbc1 *: support _initialize method in contracts
Invoke `_initialize` method on every call if present.
In NEO3 there is no entrypoint and methods are invoked by offset,
thus `Main` function is no longer required.
We still have special `Main` method in tests to simplify them.
2020-07-27 13:00:35 +03:00
Evgenii Stratonikov
d2ddf7b7cb *: support invoking methods by offset
Allow to invoke methods by offset:
1. Every invoked contract must have manifest.
2. Check arguments count on invocation.
3. Change AppCall to a regular syscall.
4. Add test suite for `System.Contract.Call`.
2020-07-27 13:00:35 +03:00
Roman Khimov
d8a1c3de46
Merge pull request #1221 from nspcc-dev/neo3/interop/post-preview2_adjustment3
interop: post-preview2 adjustment, part 3
2020-07-23 20:35:53 +03:00
Anna Shaleva
120eff92f7 core: adjust System.Runtime.Notify interop
Part of #1198.

Notification name should be UTF8-encoded.
2020-07-23 07:55:12 +03:00