Commit graph

315 commits

Author SHA1 Message Date
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
Roman Khimov
233307aca5 stackitem: completely drop MaxArraySize
Turns out C# VM doesn't have it since preview2, so our limiting of
MaxArraySize in incompatible with it. Removing this limit shouldn't be a
problem with the reference counter we have, both APPEND and SETITEM add things
to reference counter and we can't exceed MaxStackSize. PACK on the other hand
can't get more than MaxStackSize-1 of input elements.

Unify NEWSTRUCT with NEWARRAY* and use better integer checks at the same time.

Multisig limit is still 1024.
2021-07-19 15:42:42 +03:00
Roman Khimov
15be763bb3 vm: limit POW, fix #2060
Calculating pow(pow(2, 255), 0xffffffff) takes unknown amount of time. See
also neo-project/neo-vm#422.
2021-07-19 15:42:41 +03:00
Roman Khimov
fe3c68b92d vm: panic in cloneIfStruct
It's internal, so we can deduplicate code a bit.
2021-07-12 11:52:24 +03:00
Roman Khimov
4000dd692c vm: make cloning limits a bit more effective
Take actual reference counter value into account.
2021-07-11 19:37:06 +03:00
Roman Khimov
cfe41abd35 vm: fix OOM during nested structure cloning
Resulting item can't have more than MaxStackSize elements. Technically this
limits to MaxStackSize cloned elements but it's considered to be enough to
mitigate the issue (the next size check is going to happen during push to the
stack). See neo-project/neo#2534, thanks @vang1ong7ang.
2021-07-11 18:47:50 +03:00
Evgeniy Stratonikov
1863023e27 vm: copy argument in unary opcodes, fix #2051
We already do this in binary opcodes, let's be consistent.

This fixes state difference at height 275663
for tx 3c498317684d63849b03e4c58ad57ce4b19bb206b7b01bcc64233de3b3e207f4

Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2021-07-08 17:09:04 +03:00
Anna Shaleva
e3611bfa4c vm, cli: allow to specify flags while loading VM 2021-05-28 12:07:41 +03:00
Roman Khimov
9d2712573f *: enable godot linter and fix all its warnings
It's important for NeoGo to have clean documentation. No functional changes.
2021-05-12 23:17:03 +03:00
Evgeniy Stratonikov
8fa4a576f4 vm: allow Null arguments for LT,LE,GT,GE opcodes 2021-04-29 16:10:51 +03:00
Evgeniy Stratonikov
dc393642a2 opcode: fix GTE, LTE string representations 2021-04-29 16:08:48 +03:00
Anna Shaleva
f57187e611 vm: throw unhandled exception with message instead of panic
The result is the same HALT state, but the exception message is the real
one got from user. Changes ported from C#:

1. Throw exception: 59b8ac73d2/src/neo-vm/ExecutionEngine.cs (L1448)
2. Prettify message: https://github.com/neo-project/neo-vm/blob/master/src/neo-vm/VMUnhandledException.cs#L28

The result is that instead of
```
2021-03-31T17:02:54.508+0300	WARN	contract invocation failed	{"tx": "2aefeb705f3a609df8767d9b45e036b9dd1eb77407e5732375981915668889b8", "block": 30640, "error": "error encountered at instruction 970 (THROW): runtime error: invalid memory address or nil pointer dereference"}
```

we'll get
```
2021-03-31T17:33:56.299+0300	WARN	contract invocation failed	{"tx": "2aefeb705f3a609df8767d9b45e036b9dd1eb77407e5732375981915668889b8", "block": 30640, "error": "error encountered at instruction 970 (THROW): unhandled exception: No authorization."}
```
in the node logs.
2021-03-31 19:37:52 +03:00
Anna Shaleva
793f27084b vm: specify syscall ID when panicing on syscall invocation
It's convinient to know the failing syscall without dumping
smartcontract instructions.
2021-03-31 19:00:59 +03:00
Evgeniy Stratonikov
d255c4a517 vm: implement SQRT opcode 2021-03-01 16:58:53 +03:00
Evgeniy Stratonikov
6496782736 vm: implement POW opcode 2021-03-01 16:58:53 +03:00
Roman Khimov
158f0d9d9c native/vm: add script check for deployed contracts
Refs. #1699.
2021-02-09 22:31:26 +03:00
Anna Shaleva
6a4e312eac core: move GetPrice from core to interop
We have additional logic for getting BaseExecFee policy value. This
logic should be moved to interop context instead of being in Policer,
because Policer is just an interface over Policy contract.

After moving this logic to interop context, we need to use it to define
BaseExecFee instead of (Policer).BaseExecFee. Thus, moving
(*Blockchain).GetPrice to (*Context).GetPrice is necessary.
2021-02-05 11:36:32 +03:00
Evgeniy Stratonikov
49de8161ef core: implement LoadToken handler 2021-01-22 09:04:37 +03:00
Evgenii Stratonikov
bb706aa55b vm: implement CALLT opcode 2021-01-21 19:30:04 +03:00
Evgeniy Stratonikov
324107b31e vm: implement POPITEM opcode 2021-01-19 09:46:01 +03:00
Evgenii Stratonikov
1c0c331e25 core: update System.Contract.Call syscall
1. Remove `System.Contract.CallEx`.
2. Extend number of parameters.
3. Add return value count to `VM.Context`.
2021-01-14 18:23:36 +03:00
Evgenii Stratonikov
dbe81f9b80 smartcontract: move flags to a separate package 2021-01-14 17:52:09 +03:00
Evgenii Stratonikov
e63191d31f core: hangle CallingScriptHash correctly
When using native contracts, script hash of second-to-top context
on invocation stack does not always correspond to a real calling
contract.
2020-12-10 16:52:36 +03:00
Evgenii Stratonikov
e903e40085 core: call from native contracts synchronously
Follow neo-project/neo#2130.
2020-12-10 16:43:46 +03:00
Evgenii Stratonikov
d7ffa89811 vmcli: set breakpoint before the instruction
Breakpoint should occur before actual instruction execution.
2020-12-02 10:49:37 +03:00
Evgenii Stratonikov
2f39701d76 vm: provide writer in PrintOps()
Make it more flexible and testable. Fallback to using
stdout if no writer is provided.
2020-12-02 10:49:37 +03:00
Roman Khimov
d93aa745bb contract: avoid going to the DB for entry scripts
This optimizes out DB access for non-deployed contracts under the assumption
that deployed ones are always loaded via `LoadScriptWithHash` (and if they're
not --- it's a bug anyway with the new hashing model) which actually is a very
popular case (every entry script does that).
2020-11-27 21:47:08 +03:00
Anna Shaleva
0f68528095 core: add callback to VM context 2020-11-25 18:37:29 +03:00
Roman Khimov
bf9ecc2bd3 vm: improve REVERSEITEMS for 1M Buffer
Before:
BenchmarkOpcodes/REVERSEITEMS/buffer/1M-8                   1680            758747 ns/op

After:
BenchmarkOpcodes/REVERSEITEMS/buffer/1M-8                   2649            442720 ns/op
2020-11-06 23:31:26 +03:00
Roman Khimov
2522271161 vm: use Application trigger by default
Don't mess with System, it's too powerful to be the default.
2020-10-29 19:17:07 +03:00
Roman Khimov
27a01c7759 vm: optimize stack traversal on exception handling
Before:
BenchmarkOpcodes/THROW/0/1-8       10000               506 ns/op
BenchmarkOpcodes/THROW/0/16-8      10000               524 ns/op
BenchmarkOpcodes/THROW/255/0-8     10000             49363 ns/op
BenchmarkOpcodes/THROW/1023/0-8                    10000           1628480 ns/op

After:
BenchmarkOpcodes/THROW/0/1-8       10000               575 ns/op
BenchmarkOpcodes/THROW/0/16-8      10000               516 ns/op
BenchmarkOpcodes/THROW/255/0-8     10000              8290 ns/op
BenchmarkOpcodes/THROW/1023/0-8                    10000             34605 ns/op
2020-10-15 16:20:34 +03:00
Roman Khimov
3d8434a50c vm: fix invocation stack checks
It should be done on every new context push.
2020-10-15 16:20:34 +03:00
Anna Shaleva
fe1f0a7245 core: introduce CheckReturnState constants
At the moment we should have 3 possible options to check return state
during vm context unloading:
	* no check
	* ensure the stack is empty
	* ensure the stack is not empty

It is necessary to distinguish them because new _deploy method shouldn't
left anything on stack. Example: if we use _deploy method before some
ordinary contract method which returns one value. Without these changes
the contract invocation will fail due to 2 elements on stack left after
invocation (the first `null` element is from _deploy, the second element
is return-value from the ordinary contract method).
2020-10-13 19:14:44 +03:00
Anna Shaleva
cbf89fbb19 vm: add Call method which increments invocation counter 2020-10-08 16:25:45 +03:00
Anna Shaleva
6ce00fde82 vm, core: move invocation counter from InteropContext to VM 2020-10-08 11:33:26 +03:00
Anna Shaleva
66ca654b07 vm: refactor ISNULL opcode handling 2020-09-29 18:46:20 +03:00
Anna Shaleva
543fd58e93 vm: restrict map key size 2020-09-29 18:46:15 +03:00
Roman Khimov
26339c75dc vm/core: drop old key caching system
Obsoleted by f5f58a7e91.
2020-09-10 14:43:24 +03:00
Evgenii Stratonikov
04f5fdefa0 vm: properly unload context on exception
Do not copy exception context on CALL*.
2020-08-27 10:28:50 +03:00
Evgenii Stratonikov
ab4cd8a990 vm: fix typo in MEMCPY handling 2020-08-25 08:53:29 +03:00
Roman Khimov
681ae4d5d6 vm: fix TRY offsets check
TRY can have an offset != 0 and still it can't have both parameters set to
zero.
2020-08-24 16:20:57 +03:00
Roman Khimov
32112249d5 vm: limit maximum nesting of exception contexts
Follow neo-project/neo#365. neo-vm submodule is updated just to show the
relevant latest commit, nothing really changed there.
2020-08-24 15:37:39 +03:00
Roman Khimov
324f4c265b stackitem: don't copy existing slices for TryBytes
Most often we only need to read them and it doesn't require copying. Make an
explicit copy (and copy only things we need!) where needed.

After the recent neo-vm tests update our vm package testing time jumped to
~12s, with this change it's now more like ~8s.
2020-08-22 23:36:38 +03:00
Roman Khimov
74097ae8b0 stackitem: add NewPointerWithHash() to save on hash calculations
Inspired by neo-project/neo-vm#352. We can't directly compare slices, so we're
better optimize things we already have. At the same time this code would
behave a bit different if A is to call B and then B is call A and then some
pointer from the first A invocation is to be compared with a pointer from the
second A invocation. Not sure it really matters.
2020-08-22 22:19:44 +03:00
Evgenii Stratonikov
a080d24cf5 vm: fix debugger and add tests
1. `Run()` must be able to continue execution after a breakpoint.
2. VM must stop right before the breakpoint, not after.
3. Initial vm state is NONE, not HALT.
2020-08-18 11:26:27 +03:00
Evgenii Stratonikov
b2e53fedac vm: pretty-print SYSCALL opcode 2020-08-14 14:22:46 +03:00
Evgenii Stratonikov
9cc6e22365 vm: pretty-print ST*/LD* opcodes 2020-08-13 10:38:13 +03:00
Evgenii Stratonikov
7d08d38cd2 vm: pretty-print PUSHINT* opcodes 2020-08-13 10:38:13 +03:00
Evgenii Stratonikov
92ddc474d8 vm: pretty-print CONVERT and ISTYPE opcodes 2020-08-13 10:38:13 +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
c87e2262c3 core: remove ScriptHashGetter from interop context
We have VM inside the context, so don't need ScriptHashGetter anymore.
2020-08-07 20:31:20 +03:00
Roman Khimov
5ef08f60ae remove github.com/pkg/errors from dependencies
It's not needed any more with Go 1.13 as we have wrapping/unwrapping in base
packages. All errors.Wrap calls are replaced with fmt.Errorf, some strings are
improved along the way.
2020-08-07 12:21:52 +03:00
Evgenii Stratonikov
54590062e6 vm: use raw stack items when printing stack
Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
2020-07-31 16:07:16 +03:00
Evgenii Stratonikov
51ae12e4fd *: move syscall handling out of VM
Remove interop-related structures from the `vm` package.

Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
2020-07-29 13:41:08 +03:00
fyrchik
b187dfe3ce
Merge pull request #1236 from nspcc-dev/rpc/getrawmempool
rpc: update `getrawmempool` and `getrawtransaction` RPC-calls
2020-07-29 10:18:51 +03:00
Anna Shaleva
70ef733ce7 core, vm: store VMState as byte instead of string
Part of #1183
2020-07-29 10:14:08 +03:00
Evgenii Stratonikov
466af55dea vm: isolate stack in LoadScript
When calling contract it must be provided with a new stack containing
only it's arguments. The result is then copied back on RET.

Fix #1220.
2020-07-27 13:00:35 +03:00
Evgenii Stratonikov
13b9eda08d vm: allow to call VM methods from outside
Abstract out (*VM).Call method and use in in CALL* opcodes.
2020-07-27 13:00:35 +03:00
Evgenii Stratonikov
6ecd1ae437 vm: allow to initialize static slot in method 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
Evgenii Stratonikov
797324cb04 vm: support exceptions
Implement 3 new instructions: TRY,ENDTRY,ENDFINALLY.
1. TRY marks the start of the block where exceptions are catched.
    It has 2 arguments which are relative offsets of exception handler
    and the end of the whole try/catch construction.
2. ENDTRY denotes either end of try or catch block.
3. ENDFINALLY denotes end of finally block which is executed
    irregardless of whether an exception has occured.
2020-07-24 10:41:41 +03:00
Evgenii Stratonikov
c0d7b9d234 vm: clear references on context unload
Remove argument and local references from the reference counter when
returning from function.
2020-07-24 10:41:40 +03:00
Evgenii Stratonikov
aec9111961 vm: replace jumpIf with jump
`jumpIf` is used only once with non-constant condition.
2020-07-24 10:36:51 +03:00
Roman Khimov
2800179ce0
Merge pull request #1226 from nspcc-dev/fix/pusha
vm: make offset in PUSHA relative
2020-07-23 23:40:21 +03:00
Anna Shaleva
8fde41001e core, vm: remove allowed triggers from syscalls
Closes #1205.
2020-07-23 20:44:39 +03:00
Evgenii Stratonikov
b8843a2dfa vm: make offset in PUSHA relative
Follow neo-project/neo-vm#317 .
2020-07-23 13:07:30 +03:00
Evgenii Stratonikov
58a594e3d4 vm: remove rvcount
It isn't used anymore.
2020-07-23 10:29:05 +03:00
Evgenii Stratonikov
261ff3c655 vm: remove alt.stack
It is no longer present in NEO3.
2020-07-22 13:20:31 +03:00
Anna Shaleva
a3e306ff78 core: implement Secp256k1 Verify and CheckMultisig interops
Closes #918.
2020-07-14 16:21:34 +03:00
Roman Khimov
db027ad9c5 vm: zero GAS means no GAS, use fee data to properly limit execution
We were accepting transactions with zero system fee, but we shouldn't do
that. Also, transaction's verification execution has to be limited by network
fee.
2020-07-14 08:37:29 +03:00
Roman Khimov
15c6cc932d vm: drop checkedhash, it's an unused NeoVM 2 remnant 2020-07-09 15:05:14 +03:00
Roman Khimov
1bb26dcdc1 vm: fix INITSSLOT, it's context-wide, not VM-wide
It's tied to the current contract, not to VM.
2020-07-09 15:00:49 +03:00
Roman Khimov
08c516014f
Merge pull request #1132 from nspcc-dev/neo3/rpc/fixed8_marshalling
*: switch from Fixed8 to int64
2020-06-29 21:44:40 +03:00
Anna Shaleva
73b630db9b *: switch from fixed8 to int64
Follow C# implementation, we have to marshall JSON Fixed8 fields without
taking into account decimals.
2020-06-29 21:39:27 +03:00
Roman Khimov
372dd71708
Merge pull request #1108 from nspcc-dev/neo3/compiler/nef
compiler: support *.nef and *.manifest.json generation
2020-06-29 20:55:47 +03:00
Anna Shaleva
b387deaa05 vm: switch from .avm to .nef 2020-06-29 09:15:29 +03:00
Evgenii Stratonikov
bdaffe75cb vm: extend PrintOps() with INITSSLOT & INITSLOT 2020-06-26 19:35:03 +03:00
Evgenii Stratonikov
82417499d7 vm: beautify PrintOps() output for JMP* instructions 2020-06-26 19:34:58 +03:00
Evgenii Stratonikov
709f656bcf vm: remove unused parameter from getJumpOffset 2020-06-26 19:17:17 +03:00
Roman Khimov
a77357227a vm: fix caller's script hash returned from VM
Regular CALLs don't update it, only Contract.Call does. Fixes the following
mismatch on preview2 testnet:

file BlockStorage_100000/dump-block-49000.json: block 48644, changes number mismatch: 6 vs 4
2020-06-24 10:22:21 +03:00
Evgenii Stratonikov
a7d4fff897 vm: make (*VM).GasLimit public
VM is inherently single-threaded and replacing setter/getter methods
with public field simplifies code a bit.
2020-06-16 15:13:20 +03:00
Evgenii Stratonikov
f2f01a08c9 vm: move MaxArraySize and MaxItemSize to stackitem package 2020-06-16 11:32:16 +03:00
Evgenii Stratonikov
4dfce07d11 vm: provide trigger upon VM creation 2020-06-11 13:16:07 +03:00
Evgenii Stratonikov
bda94c74c3 vm: check calling flags on syscall invocation 2020-06-11 13:16:07 +03:00
Evgenii Stratonikov
55ab7535be core: optimize contractCallEx
Provide script hash upon script load.
2020-06-11 13:06:10 +03:00
Evgenii Stratonikov
5514b3f52f smartcontract,vm: remove DynamicInvoke feature
It doesn't exist in NEO3.
2020-06-11 10:45:25 +03:00
Evgenii Stratonikov
7256efd1ed vm: implement (*VM).AddGas
Calculating interop prices can be tricky. It is more convenitent to burn
gas inside interops where necessary parameters are popped.
2020-06-11 10:45:25 +03:00
Anna Shaleva
7ca2807875 vm/encoding: move bigint from vm to encoding package 2020-06-08 13:27:13 +03:00
Anna Shaleva
783f5ecb01 vm: move StackItem to a separate package
closes #912
2020-06-08 13:27:08 +03:00
Evgenii Stratonikov
9dca2288ba vm: make LEFT fail if count is too big 2020-05-22 14:16:32 +03:00
Evgenii Stratonikov
86c4f1abc5 vm: do not use State as a mask
In NEO2 state could be used as a mask, but now it contains only a single
value.
2020-05-22 14:16:32 +03:00
Evgenii Stratonikov
063c29636b vm: fail if NEWSTRUCT/NEWARRAY argument is not an integer
NEO3 VM does not support creating new Array from a Struct.
For this purpose CONVERT opcode is used.
2020-05-22 14:16:32 +03:00
Evgenii Stratonikov
781def735d vm: use Null item as a default value for Array/Struct elements 2020-05-22 14:16:32 +03:00
Evgenii Stratonikov
f4fa712440 vm: make PUSH0 emit Integer 2020-05-22 14:16:32 +03:00
Evgenii Stratonikov
3917b4b4e4 vm: update stack size in SETITEM properly 2020-05-21 18:00:51 +03:00
Evgenii Stratonikov
98c508d361 vm: implement MEMCPY opcode
MEMCPY copies byte-slice to a destination buffer.
2020-05-20 17:45:56 +03:00
Evgenii Stratonikov
a5f6e0e53d vm: implement NEWBUFFER opcode 2020-05-20 17:45:56 +03:00
Evgenii Stratonikov
a3a3a77431 vm: make slice opcodes emit Buffer 2020-05-20 17:45:56 +03:00
Evgenii Stratonikov
c3f7832f3b vm: implement Buffer stack item
Buffer is a stack item type introduced in NEO3
which represents mutable byte-array.
2020-05-20 17:45:56 +03:00