Commit graph

807 commits

Author SHA1 Message Date
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
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
Anna Shaleva
0ceae612c6 vm: improve failed SYSCALL logging
For better user experience.
2022-11-28 17:16:27 +03:00
Roman Khimov
4e26f4b26e runtime: implement System.Runtime.LoadScript, fix #2701 2022-11-25 15:11:49 +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
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
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
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
Anna Shaleva
7db9258104 vm: make LoadFileWithFlags actually load with flags provided 2022-10-13 16:07:34 +03: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
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
0b717b0c22 vm: move vm CLI to cli/vm package 2022-10-07 15:56:34 +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
f78a065230 vm/cli: generate Go 1.17 go.mods 2022-09-08 21:18:51 +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
4f3ffe7290 golangci: enable errorlint and fix everything it found 2022-09-02 18:36:23 +03:00
Evgeniy Stratonikov
9712be78fd vm: optimize refcounter
```
name                    old time/op    new time/op    delta
RefCounter_Add-8          9.47ns ± 4%    2.75ns ± 1%   -70.92%  (p=0.000 n=10+9)
RefCounter_AddRemove-8    88.9ns ±20%     5.5ns ± 4%   -93.78%  (p=0.000 n=10+10)

name                    old alloc/op   new alloc/op   delta
RefCounter_Add-8           0.00B          0.00B           ~     (all equal)
RefCounter_AddRemove-8     48.0B ± 0%      0.0B       -100.00%  (p=0.000 n=10+10)

name                    old allocs/op  new allocs/op  delta
RefCounter_Add-8            0.00           0.00           ~     (all equal)
RefCounter_AddRemove-8      2.00 ± 0%      0.00       -100.00%  (p=0.000 n=10+10)
```

Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2022-08-23 13:18:06 +03:00
Evgeniy Stratonikov
59fbc689e4 vm/bench: extend refcounter benchmarks
Adding an array multiple times leads to the fast update via `IncRC`.
This hides the allocation that is there on the first addition. In this
commit add another benchmark which measures Add/Remove together, to
ensure that `switch` in `refCounter.Add` is entered. Benchmark results
are meaningful, because `Add`/`Remove` have almost identical implementation.

Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2022-08-23 13:08:42 +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
Anna Shaleva
bb751535d3 *: bump minimum supported go version
Close #2497.
2022-08-08 13:59:32 +03:00
Roman Khimov
e8d2277fe5 contract/vm: only push NULL after call in dynamic contexts
And determine the need for Null dynamically. For some reason the only dynamic
context is Contract.Call. CALLT is not dynamic and neither is a call from
native contract, go figure...
2022-08-05 14:35:00 +03:00
Roman Khimov
99e2681d3a interop/vm: use more robust CalledByEntry check
Directly check contexts.
2022-08-05 14:35:00 +03:00
Roman Khimov
13f5fdbe8a vm: extract shared parts of the Context
Local calls reuse them, cross-contract calls create new ones. This allows to
avoid some allocations and use a little less memory.
2022-08-05 14:26:25 +03:00
Roman Khimov
1e62474514 vm: move InvocationTree into a package of its own
result.Invoke shouldn't depend on vm.
2022-07-08 23:30:30 +03:00
Roman Khimov
fab8dfb9f8 vm: move State type into a package of its own
It's used a lot in other places that need it, but don't need whole VM at the
same time.
2022-07-08 18:34:52 +03:00
Roman Khimov
926b082d39
Merge pull request #2538 from nspcc-dev/restrict-out-of-bounds
core: check methods offsets while contract deploying
2022-07-04 12:54:32 +03:00
Roman Khimov
19ad31dc52 vm: optimize IsSignatureContract
We use it a lot in (*Blockchain).IsTxStillRelevant().

name                   old time/op    new time/op    delta
IsSignatureContract-8    19.1ns ± 5%     1.2ns ± 4%  -93.81%  (p=0.000 n=10+10)

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

name                   old allocs/op  new allocs/op  delta
IsSignatureContract-8      0.00           0.00          ~     (all equal)
2022-06-07 10:29:13 +03:00
Roman Khimov
92c94f265c interop/vm: make VM reusable and use on VM for all in-block execs
Avoid allocating again and again. Increases TPS by about 3%.
2022-06-07 10:05:47 +03:00
Anna Shaleva
1005c1f7db vm: forbid jumping out of the script bounds 2022-06-06 12:18:19 +03:00
Roman Khimov
edb6ca8926
Merge pull request #2531 from nspcc-dev/perf
Minor performance improvements
2022-06-03 10:40:56 +03:00
Roman Khimov
c3d989ebda stackitem: reusable serialization context
We serialize items a lot and this allows to avoid a number of allocations.
2022-06-02 15:38:39 +03:00
Roman Khimov
3d4076ca36 vm: microoptimize new estack creation
Subslice won't reach element -1, but it can reuse the same buffer space more
effectively.
2022-05-31 18:53:05 +03:00
Roman Khimov
e1607e23c2
Merge pull request #2525 from nspcc-dev/immutable-items
vm: implement immutable stackitems
2022-05-31 10:36:56 +03:00
Anna Shaleva
42a051e55a core: DeepCopy notifiction event args inside System.Runtime.Notify 2022-05-31 08:07:53 +03:00
Anna Shaleva
7296f0c913 vm: support immutable compound types 2022-05-31 08:07:50 +03:00
Anna Shaleva
107f5e0793 vm: adjust refcount operations order
Perform add/set/remove operations with VM type firstly, and with
refcounter after that. It is needed to be able to extend add/set/remove
operations with extra checks.
2022-05-31 08:02:13 +03:00
Roman Khimov
502cdd68ab
Merge pull request #2508 from nspcc-dev/snapshot-isolation
core, vm: implement snapshot isolation
2022-05-27 12:44:06 +03:00
Anna Shaleva
a79c80cb8d vm: wrap cross-contract exceptions 2022-05-26 11:44:26 +03:00
Anna Shaleva
a39b7cc3fd core, vm: move all isolation-related logic out of VM
Keep it inside the interop context.
2022-05-26 09:26:31 +03:00
Anna Shaleva
f79f62dab4 vm: use single function instead of committer/discarder 2022-05-26 09:26:31 +03:00
Anna Shaleva
08b68e9b82 vm, core: push Null return value only if no exception occurs
Close https://github.com/nspcc-dev/neo-go/issues/2509.
2022-05-26 09:26:31 +03:00
Anna Shaleva
ce226f6b76 vm: optimize context wrapping code
We can omit DAO wrapping for safe methods and for those methods that are not
wrapped into try-catch block. However, we still need to persist
notificationsCount changes for these methods to the parent context.
2022-05-26 09:26:31 +03:00
Anna Shaleva
0cd19f550e core, vm: implement snapshot isolation
Initial implementation without optimisations, but it should work.
2022-05-26 09:26:25 +03:00
Anna Shaleva
a3285eae04 vm: stringify InteropInterface stackitem type as InteropInterface 2022-05-25 13:20:21 +03:00
Roman Khimov
ae2395f55f vm: simplify (slot).Set code
Refcounter handles nil items just fine.
2022-05-17 16:26:22 +03:00
Roman Khimov
f2f66ad36e vm: clear static slot refs on exit, fix #2501 2022-05-17 16:26:22 +03:00
Roman Khimov
0d93b353e6 vm: count initial Null slot variables as well
Match C# behavior. Thanks to @ixje for finding this.
2022-05-16 17:42:57 +03:00
Roman Khimov
18d627e7f7 vm: count map key in the refcounter as well
Thanks @ixje for spotting this.
2022-05-16 16:07:25 +03:00
Anna Shaleva
e66e82278c vm: upgrade submodule 2022-05-12 14:25:14 +03:00
Anna Shaleva
a94ccf9236 vm: add MODMUL and MODPOW opcodes
Close #2470.
2022-05-12 14:25:14 +03:00
Roman Khimov
c6f8c33e66
Merge pull request #2478 from nspcc-dev/mainnet-fixes
Mainnet fixes
2022-05-12 10:04:53 +03:00
Roman Khimov
621db8c832 stackitem: allow to unJSONize big numbers (>int64), fix #2477
100000000000000000000 overflows int64 and NeoGo returns some garbage to
contracts instead of a proper number.
2022-05-11 21:03:10 +03:00
Anna Shaleva
3be37e8c5b vm: check instruction offset is valid before subsequent IP move
Reference implementation:
e167f03e25/src/neo-vm/ExecutionContext.cs (L77).

Turns out that exception-related code (try\finally handling) is the only
place where next instruction pointer bounds are not pre-checked before
assignment. This statement is true for both go and C# implementations.
However, C# code has duplicate check located inside the
InstructionPointer setter for all instructions except the
exception-related ones. Neo-go code doesn't perform this duplicate check.
Thus, C# VM FAULTs execution in case of invalid TRY/FINALLY offsets, and
neo-go VM does not.

This commit reverts a part of
https://github.com/nspcc-dev/neo-go/pull/2396. This bug is discovered
thanks to test added in https://github.com/neo-project/neo-vm/pull/453.
2022-05-11 14:04:02 +03:00
Anna Shaleva
8af043520d vm: adjust MaxByteArrayComparableSize value
https://github.com/neo-project/neo-vm/pull/454#discussion_r857533800.
2022-05-07 12:56:09 +03:00
Anna Shaleva
23b78b0be2 vm: limit ByteArray comparable length
Close #2460.
2022-05-07 12:56:04 +03:00
Elizaveta Chichindaeva
28908aa3cf [#2442] English Check
Signed-off-by: Elizaveta Chichindaeva <elizaveta@nspcc.ru>
2022-05-04 19:48:27 +03:00
Roman Khimov
bf3415e2bc emit: introduce CheckSig function
Which allows to create verification scripts without keys.PublicKey which is
convenient in some cases where we already have serialized key and don't want
to waste time decompressing it.
2022-04-27 22:57:10 +03:00
Anna Shaleva
2972569a0a vm: make byte representation of VMState compatible with C# 2022-04-04 13:52:29 +03:00
Roman Khimov
ad1dd3ebb7
Merge pull request #2399 from nspcc-dev/fuzz-tests
vm: add some Fuzz tests
2022-03-21 12:00:55 +03:00
Evgeniy Stratonikov
3f65473f64 vm: add some Fuzz tests
Both `IsScriptCorrect` and `VM.Run` should never panic.

Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2022-03-18 16:13:39 +03:00
Roman Khimov
906d99571b
Merge pull request #2369 from nspcc-dev/goshechka
*: go 1.18 support 🎉😍🎊🍰🥂
2022-03-18 15:07:20 +03:00
Roman Khimov
c2845852ae
Merge pull request #2397 from nspcc-dev/is-script-correct-panic
vm: avoid panic in `IsScriptCorrect`
2022-03-18 10:08:39 +03:00
Evgeniy Stratonikov
ef28308dbf vm: avoid panic in IsScriptCorrect
Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2022-03-17 20:12:50 +03:00
Anna Shaleva
2096ad6e81 *: remove io/ioutil uses
Close #1764.
2022-03-17 19:39:18 +03:00
Evgeniy Stratonikov
492c91b4c5 vm: disallow negative offset in (*Context).Next()
Currently the only known reason this can happen is processing
ENDFINALLY opcode before the corresponding ENDTRY.

Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2022-03-17 18:52:48 +03:00
Roman Khimov
5379ef75bb
Merge pull request #2391 from nspcc-dev/fix-reverse
vm: fix integer conversions
2022-03-10 12:27:10 +03:00
Evgeniy Stratonikov
32f4404954 vm: allow HASKEY on byte-arrays
Current neo-vm master has them https://github.com/neo-project/neo-vm/blob/master/src/neo-vm/ExecutionEngine.cs#L1157
Were silently added in
029466fa9d .

Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2022-03-10 10:34:13 +03:00
Evgeniy Stratonikov
39866b8512 vm: fix integer conversions
As can be seen in https://dotnetfiddle.net/s7eg21 (int) conversions
result in an exception in C# code.

Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2022-03-10 10:21:34 +03:00
Evgeniy Stratonikov
a8d2df874f stackitem: limit JSON size in ToJSONWithTypes
Also do not limit depth. It was introduced in e34fa2e915 as a simple
solution to OOM problem. In this commit we do exactly the refactoring
described there. Maximum size is the same as stack item size and
can be changed if needed withouth significat refactoring.
`1 MiB` seems sufficient, though.

Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2022-03-09 10:29:23 +03:00
AnnaShaleva
c35950206a vm: add test to check CLI UTF-8 compatibility 2022-02-18 19:20:50 +03:00
Anna Shaleva
c182141624 vm: fix linter issue
printf: `fmt.Fprintln` arg list ends with redundant newline (govet)
2022-02-18 19:20:43 +03:00
Anna Shaleva
2501ce3cb1 vm: adjust run description for VM CLI
With urfave/cli method name can be `help`.
2022-02-18 16:34:58 +03:00
Anna Shaleva
d04d55708c vm: setup autocompleter 2022-02-18 16:34:58 +03:00
Anna Shaleva
e8ec820d2e vm: add unload command
When execution fails it's the only way to change the prompt showing the
last executed instruction. Example:

```
NEO-GO-VM > loadgo examples/engine/engine.go
READY: loaded 117 instructions
NEO-GO-VM 0 > run
Error: at instruction 3 (SYSCALL): failed to invoke syscall 805851437: syscall not found
NEO-GO-VM 8 > parse
Error: missing argument
NEO-GO-VM 8 > parse 123
Integer to Hex			7b
Integer to Base64		ew==
String to Hex			313233
String to Base64		MTIz

NEO-GO-VM 8 > unload
NEO-GO-VM > exit

```
2022-02-18 16:34:58 +03:00
Anna Shaleva
563c3a4baa vm: replace ishell with urfave/cli
Use github.com/chzyer/readline for readline capabilities (including
history and ANSI escape sequences handling).
2022-02-18 16:34:50 +03:00
Roman Khimov
075fd05bfc
Merge pull request #2356 from nspcc-dev/rpc-big-numbers
Allow to use big integers in RPC
2022-02-11 13:24:35 +03:00
Evgeniy Stratonikov
c72b3f2176 vm/emit: check big integer size
Fix a bug where big integer could be emitted as 0 without reporting an
error. Also, add tests.

Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2022-02-11 12:48:55 +03:00
Evgeniy Stratonikov
0394a79ef8 rpc: support big integers as request parameters
Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2022-02-11 12:48:54 +03:00
Anna Shaleva
a9872063fe vm: refactor VM CLI tests as they take too long to pass
These tests are slow on Windows, so refactor them a bit and avoid the following
error:
```
--- FAIL: TestRunWithDifferentArguments (4.01s)
        cli_test.go:96:
                Error Trace:    cli_test.go:96
                                                                                cli_test.go:321
                Error:          command took too long time
                Test:           TestRunWithDifferentArguments
```
2022-02-10 18:04:16 +03:00
Evgeniy Stratonikov
10d006195a vm: properly clear try stack in CALL
Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2022-02-04 11:04:03 +03:00
Evgeniy Stratonikov
ad65d1fa1f compiler: implement custom logic for go1.15
For some reason `foo.go` is interpreted as an http URL, and even if we
replace it with `./foo.go` there is an errors with file missing on disk.
Because `CompileWithOptions` should be able to compile file under any
circumstances, we allocate temporary directory base on version used to
compile a binary.

Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2022-01-21 17:43:28 +03:00
Evgeniy Stratonikov
25583f9aeb compiler: make pkg/interop a separate module
Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2022-01-20 13:21:26 +03:00
Evgeniy Stratonikov
9871dc8f5a compiler: update x/tools package
Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2022-01-20 13:21:26 +03:00
Evgeniy Stratonikov
e7a0ecb349 compiler: provide .go filename to Compile
First argument contains filename, thus we use '.go' suffix to
distinguish between directories and files.
Contract name should be provided in options.

Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2022-01-20 13:21:24 +03:00
Evgeniy Stratonikov
8af9c870b1 compiler: remove CompileWithDebugInfo
It is a simple wrapper over `CompileWithOptions` which we don't really
need. Custom options can be specified explicitly instead of using some
random default. This default was introduced in 1578904da, however tests
written there use `CompileWithOptions` and all other tests
pass on that commit even without this default.

Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2022-01-20 13:15:48 +03:00
Anna Shaleva
0e1f85b2bf vm: optimise emit.Array() to use NEWARRAY0 for zero-lenght arrays 2022-01-14 17:56:10 +03:00
AnnaShaleva
48355ba9bf vm: allow to emit int[32, 16, 8] and some of uints 2022-01-13 19:12:20 +03:00
Evgeniy Stratonikov
ffb6504f67 vm: cut trailing spaces in PrintOps
When there is a single big instruction (like PUSHDATA4) in script,
all other instructions are padded to the right with spaces.
This makes it hard to view script in terminal, because long lines
are usually wrapped at the screen boundary and printed as multiple lines.

The culprit is our `cursor` field which is printed in the last column
and causes all previous fields to have the same length for every
instruction. One way to fix this is to omit cursor field if it is empty.

Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2021-12-28 11:27:31 +03:00
Roman Khimov
299a7ea614 compiler: use CALLT for native contract calls, fix #2257 2021-12-10 11:58:50 +03:00
Roman Khimov
96339e9f64
Merge pull request #2290 from nspcc-dev/microopt
Trivial microoptimizations
2021-12-02 19:21:45 +03:00
Roman Khimov
eb27699dad vm: put child invocation tree nodes into call element
As neo-project/neo-modules#657 currently does.
2021-12-02 17:46:48 +03:00
Roman Khimov
53cfde62de vm: don't allocate another stack for entry scripts
vm.New() creates a new stack, then we load an entry script with
LoadScriptWithFlags and it creates another one which doesn't make much
sense. rvcount is -1 for it, so all elements are to be copied down anyway and
it's clear so a new loaded script can't dig down to anything it shouldn't be
able to.
2021-12-02 15:59:51 +03:00
Roman Khimov
aa1da9de5a vm: preallocate for istack
Avoid growing it in runtime.
2021-12-01 21:36:35 +03:00
Roman Khimov
decff2bfb9 stackitem: simplify extracting value from map
Going through interfaces doesn't make it faster.
2021-12-01 21:36:35 +03:00
Roman Khimov
af8a4da6d9 stackitem: use type switch more effectively
Reduce the number of allocations, save some time.

name               old time/op    new time/op    delta
EncodeBinary-8       51.2µs ± 8%    44.6µs ± 7%  -12.79%  (p=0.008 n=5+5)
SerializeSimple-8     523ns ± 5%     449ns ± 4%  -14.27%  (p=0.008 n=5+5)

name               old alloc/op   new alloc/op   delta
EncodeBinary-8        329kB ± 0%     329kB ± 0%   -0.12%  (p=0.008 n=5+5)
SerializeSimple-8      432B ± 0%      408B ± 0%   -5.56%  (p=0.008 n=5+5)

name               old allocs/op  new allocs/op  delta
EncodeBinary-8         36.0 ± 0%      20.0 ± 0%  -44.44%  (p=0.008 n=5+5)
SerializeSimple-8      7.00 ± 0%      6.00 ± 0%  -14.29%  (p=0.008 n=5+5)
2021-12-01 21:36:35 +03:00
Roman Khimov
418ba1dbc3 *: use internal variables for simple big.NewInt() values
Avoid additional allocations.
2021-12-01 21:36:25 +03:00