Commit graph

1507 commits

Author SHA1 Message Date
Roman Khimov
3b19b34122 storage: fix memcached test with boltdb store
Everything was wrong here, wrong file used, wrong cleanup procedure, the net
result is this (and some failing tests from time to time):

  $ ls -l /tmp/test_bolt_db* | wc -l
  30939
2021-07-20 12:35:24 +03:00
Roman Khimov
c88ebaede9
Merge pull request #2075 from nspcc-dev/small-refactoring
Array util refactoring and naming improvement
2021-07-20 11:29:59 +03:00
Roman Khimov
7477e2cd9f
Merge pull request #2074 from nspcc-dev/fix-oracle-service-behaviour
Fix oracle service behaviour
2021-07-20 11:29:39 +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
Roman Khimov
a54e3516d1 slice: add Reverse function, deduplicate code a bit 2021-07-19 22:57:55 +03:00
Roman Khimov
3a93977b7b oracle: only process new requests after initial sync
If an oracle node is resynchronized from the genesis the service receives all
requests from all blocks via AddRequests() invoked from the native
contract. Almost all of them are long obsolete and need to be removed, native
oracle contract will try to do that with RemoveRequests() calls, but they
won't change anything.

So queue up all "initial" requests in special map and manage it directly
before the module is Run() which happens after synchronization
completion. Then process any requests that are still active and work with new
blocks as usual.
2021-07-19 22:52:59 +03:00
Roman Khimov
588f3fbbd3 state: drop State from NEOBalance and NEP17Balance
We're in the `state` package already.
2021-07-19 22:01:07 +03:00
Roman Khimov
f4a9139a05
Merge pull request #2071 from nspcc-dev/fix-more-vm-bugs
Fix more VM bugs
2021-07-19 22:00:17 +03:00
Roman Khimov
79b1bf72aa native: check that oracle request GAS IsInt64()
We use int64 value down below, so check for IsInt64() while MinimumResponseGas
check still covers for values less than zero.
2021-07-19 15:42:42 +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
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
aab18c3083 stackitem: introduce Convertible interface
We have a lot of native contract types that are converted to stack items
before serialization, then deserialized as stack items and converted back to
regular structures. stackitem.Convertible allows to remove a lot of repetitive
io.Serializable code.

This also introduces to/from converter in testserdes which unfortunately
required to change util tests to avoid circular references.
2021-07-19 15:42:42 +03:00
Roman Khimov
2d993d0da5 state: store notary deposit as stackitem
Which is less effective, but makes it more similar to other native contracts
that are supposed to be contracts anyway.
2021-07-19 15:42:42 +03:00
Roman Khimov
70ddbf7180 native: reuse stackitem.(De)Serialize more for data structures
Less code bloat, no functional changes.
2021-07-19 15:42:42 +03:00
Roman Khimov
4775b513f9 native: do proper error handling when deserializing user data 2021-07-19 15:42:42 +03:00
Roman Khimov
3a991abb62 fee: adjust SQRT price
See neo-project/neo#2540.
2021-07-19 15:42:41 +03:00
Roman Khimov
21e05f5779
Merge pull request #2055 from nspcc-dev/fix-gas-limits
Tune fixed GAS limits
2021-07-16 16:53:06 +03:00
Evgeniy Stratonikov
8077f9232d interop: implement System.Runtime.GetRandom
Our murmur3 implementation is architecture independent and optimized in
assembly.

Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2021-07-15 16:00:01 +03:00
Evgeniy Stratonikov
fdb54f2dc3 core/test: get rid of empty tx scripts
Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2021-07-15 15:58:49 +03:00
Evgeniy Stratonikov
3a4e0caeb8 core/block: add Nonce field to header
Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2021-07-15 15:58:49 +03:00
Evgeniy Stratonikov
2cd5b63f0b policy: fix max exec fee
Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2021-07-14 10:27:09 +03:00
Evgeniy Stratonikov
451b02122a *: increase GAS for verification
Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2021-07-14 10:27:09 +03:00
Roman Khimov
2b7abd20e7
Merge pull request #2057 from nspcc-dev/optimize-storage-find
Optimize `storageFind`
2021-07-13 12:51:10 +03:00
Roman Khimov
83a557f0eb
Merge pull request #2042 from nspcc-dev/oracle-not-supported
Check oracle response Content-Type header
2021-07-13 11:31:37 +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
Evgeniy Stratonikov
b8b272c8c4 core/test: add benchmark for storageFind
Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2021-07-12 14:20:45 +03:00
Evgeniy Stratonikov
0d5ede0bff core/test: use testing.TB in constructors
This allows to use chain in benchmarks.

Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2021-07-12 14:20:45 +03:00
Evgeniy Stratonikov
9f377cde12 storage: convert key once in MemoryStore.seek
There is no need in additional allocations.

Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2021-07-12 14:14:32 +03:00
Evgeniy Stratonikov
8e9302f40b oracle: check response Content-Type
If not specified everything is allowed.

Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2021-07-12 13:13:48 +03:00
Roman Khimov
bc5a1b7bcd
Merge pull request #2043 from nspcc-dev/runtime-getnetwork
interop/runtime: add `System.Runtime.GetNetwork`, fix #2038
2021-07-12 10:46:41 +03:00
Roman Khimov
1853d0c713 core: don't copy config in ApplyPolicyToTxSet
Makes no sense, GetConfig() is for external users.
2021-07-09 13:01:42 +03:00
Evgeniy Stratonikov
96a42cd011 interop: add System.Runtime.GetNetwork, fix #2038
Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2021-07-08 17:02:37 +03:00
Roman Khimov
7bc7457fbe
Merge pull request #2050 from nspcc-dev/fix-network-test-race
Fix some test failures
2021-07-08 14:50:50 +03:00
Roman Khimov
bd400dfe20 native: copy contract on update
It can be a pointer to cached data:

2021-07-07T20:05:24.8508647Z ==================
2021-07-07T20:05:24.8509294Z WARNING: DATA RACE
2021-07-07T20:05:24.8510243Z Write at 0x00c000142cc8 by goroutine 51:
2021-07-07T20:05:24.8511350Z   github.com/nspcc-dev/neo-go/pkg/core/native.(*Management).Update()
2021-07-07T20:05:24.8529622Z       /home/runner/work/neo-go/neo-go/pkg/core/native/management.go:335 +0x70a
2021-07-07T20:05:24.8531266Z   github.com/nspcc-dev/neo-go/pkg/core/native.(*Management).updateWithData()
2021-07-07T20:05:24.8532544Z       /home/runner/work/neo-go/neo-go/pkg/core/native/management.go:316 +0x1e9
2021-07-07T20:05:24.8533726Z   github.com/nspcc-dev/neo-go/pkg/core/native.(*Management).update()
2021-07-07T20:05:24.8534928Z       /home/runner/work/neo-go/neo-go/pkg/core/native/management.go:303 +0x111
2021-07-07T20:05:24.8536123Z   github.com/nspcc-dev/neo-go/pkg/core/native.(*Management).update-fm()
2021-07-07T20:05:24.8537389Z       /home/runner/work/neo-go/neo-go/pkg/core/native/management.go:302 +0x34
2021-07-07T20:05:24.8538462Z   github.com/nspcc-dev/neo-go/pkg/core/native.Call()
2021-07-07T20:05:24.8539565Z       /home/runner/work/neo-go/neo-go/pkg/core/native/interop.go:54 +0x90c
2021-07-07T20:05:24.8540751Z   github.com/nspcc-dev/neo-go/pkg/core/interop.(*Context).SyscallHandler()
2021-07-07T20:05:24.8542177Z       /home/runner/work/neo-go/neo-go/pkg/core/interop/context.go:262 +0x216
2021-07-07T20:05:24.8543328Z   github.com/nspcc-dev/neo-go/pkg/core/interop.(*Context).SyscallHandler-fm()
2021-07-07T20:05:24.8544586Z       /home/runner/work/neo-go/neo-go/pkg/core/interop/context.go:250 +0x53
2021-07-07T20:05:24.8545648Z   github.com/nspcc-dev/neo-go/pkg/vm.(*VM).execute()
2021-07-07T20:05:24.8546635Z       /home/runner/work/neo-go/neo-go/pkg/vm/vm.go:1312 +0xb2d5
2021-07-07T20:05:24.8547632Z   github.com/nspcc-dev/neo-go/pkg/vm.(*VM).Step()
2021-07-07T20:05:24.8548640Z       /home/runner/work/neo-go/neo-go/pkg/vm/vm.go:416 +0x1f2
2021-07-07T20:05:24.8549836Z   github.com/nspcc-dev/neo-go/pkg/vm.(*VM).Run()
2021-07-07T20:05:24.8550852Z       /home/runner/work/neo-go/neo-go/pkg/vm/vm.go:393 +0x195
2021-07-07T20:05:24.8551989Z   github.com/nspcc-dev/neo-go/pkg/rpc/server.(*Server).runScriptInVM()
2021-07-07T20:05:24.8553174Z       /home/runner/work/neo-go/neo-go/pkg/rpc/server/server.go:1326 +0x7eb
2021-07-07T20:05:24.8554345Z   github.com/nspcc-dev/neo-go/pkg/rpc/server.(*Server).invokeFunction()
2021-07-07T20:05:24.8555560Z       /home/runner/work/neo-go/neo-go/pkg/rpc/server/server.go:1219 +0x50c
2021-07-07T20:05:24.8556616Z   github.com/nspcc-dev/neo-go/pkg/rpc/server.(*Server).handleIn()
2021-07-07T20:05:24.8557823Z       /home/runner/work/neo-go/neo-go/pkg/rpc/server/server.go:345 +0xecb
2021-07-07T20:05:24.8558987Z   github.com/nspcc-dev/neo-go/pkg/rpc/server.(*Server).handleRequest()
2021-07-07T20:05:24.8560356Z       /home/runner/work/neo-go/neo-go/pkg/rpc/server/server.go:315 +0x364
2021-07-07T20:05:24.8561599Z   github.com/nspcc-dev/neo-go/pkg/rpc/server.(*Server).handleHTTPRequest()
2021-07-07T20:05:24.8562976Z       /home/runner/work/neo-go/neo-go/pkg/rpc/server/server.go:309 +0xf9b
2021-07-07T20:05:24.8564208Z   github.com/nspcc-dev/neo-go/pkg/rpc/server.(*Server).handleHTTPRequest-fm()
2021-07-07T20:05:24.8565523Z       /home/runner/work/neo-go/neo-go/pkg/rpc/server/server.go:257 +0x64
2021-07-07T20:05:24.8566348Z   net/http.HandlerFunc.ServeHTTP()
2021-07-07T20:05:24.8567290Z       /opt/hostedtoolcache/go/1.15.13/x64/src/net/http/server.go:2042 +0x51
2021-07-07T20:05:24.8568185Z   net/http.serverHandler.ServeHTTP()
2021-07-07T20:05:24.8569130Z       /opt/hostedtoolcache/go/1.15.13/x64/src/net/http/server.go:2843 +0xca
2021-07-07T20:05:24.8569861Z   net/http.(*conn).serve()
2021-07-07T20:05:24.8570634Z       /opt/hostedtoolcache/go/1.15.13/x64/src/net/http/server.go:1925 +0x84c
2021-07-07T20:05:24.8571139Z
2021-07-07T20:05:24.8571639Z Previous read at 0x00c000142cc8 by goroutine 41:
2021-07-07T20:05:24.8572892Z   github.com/nspcc-dev/neo-go/pkg/core/interop/contract.callExFromNative()
2021-07-07T20:05:24.8574265Z       /home/runner/work/neo-go/neo-go/pkg/core/interop/contract/call.go:101 +0x2d4
2021-07-07T20:05:24.8575581Z   github.com/nspcc-dev/neo-go/pkg/core/interop/contract.callInternal()
2021-07-07T20:05:24.8576951Z       /home/runner/work/neo-go/neo-go/pkg/core/interop/contract/call.go:85 +0x1f5
2021-07-07T20:05:24.8578094Z   github.com/nspcc-dev/neo-go/pkg/core/interop/contract.Call()
2021-07-07T20:05:24.8579306Z       /home/runner/work/neo-go/neo-go/pkg/core/interop/contract/call.go:69 +0x804
2021-07-07T20:05:24.8580514Z   github.com/nspcc-dev/neo-go/pkg/core/interop.(*Context).SyscallHandler()
2021-07-07T20:05:24.8581755Z       /home/runner/work/neo-go/neo-go/pkg/core/interop/context.go:262 +0x216
2021-07-07T20:05:24.8582907Z   github.com/nspcc-dev/neo-go/pkg/core/interop.(*Context).SyscallHandler-fm()
2021-07-07T20:05:24.8584300Z       /home/runner/work/neo-go/neo-go/pkg/core/interop/context.go:250 +0x53
2021-07-07T20:05:24.8585422Z   github.com/nspcc-dev/neo-go/pkg/vm.(*VM).execute()
2021-07-07T20:05:24.8586403Z       /home/runner/work/neo-go/neo-go/pkg/vm/vm.go:1312 +0xb2d5
2021-07-07T20:05:24.8590451Z   github.com/nspcc-dev/neo-go/pkg/vm.(*VM).Step()
2021-07-07T20:05:24.8591549Z       /home/runner/work/neo-go/neo-go/pkg/vm/vm.go:416 +0x1f2
2021-07-07T20:05:24.8592466Z   github.com/nspcc-dev/neo-go/pkg/vm.(*VM).Run()
2021-07-07T20:05:24.8593550Z       /home/runner/work/neo-go/neo-go/pkg/vm/vm.go:393 +0x195
2021-07-07T20:05:24.8594531Z   github.com/nspcc-dev/neo-go/pkg/core.(*Blockchain).storeBlock()
2021-07-07T20:05:24.8595708Z       /home/runner/work/neo-go/neo-go/pkg/core/blockchain.go:717 +0x1694
2021-07-07T20:05:24.8596793Z   github.com/nspcc-dev/neo-go/pkg/core.(*Blockchain).AddBlock()
2021-07-07T20:05:24.8598142Z       /home/runner/work/neo-go/neo-go/pkg/core/blockchain.go:579 +0x544
2021-07-07T20:05:24.8599419Z   github.com/nspcc-dev/neo-go/pkg/consensus.(*service).processBlock()
2021-07-07T20:05:24.8601093Z       /home/runner/work/neo-go/neo-go/pkg/consensus/consensus.go:521 +0x141
2021-07-07T20:05:24.8602485Z   github.com/nspcc-dev/neo-go/pkg/consensus.(*service).processBlock-fm()
2021-07-07T20:05:24.8603809Z       /home/runner/work/neo-go/neo-go/pkg/consensus/consensus.go:517 +0x55
2021-07-07T20:05:24.8604910Z   github.com/nspcc-dev/dbft.(*DBFT).checkCommit()
2021-07-07T20:05:24.8606098Z       /home/runner/go/pkg/mod/github.com/nspcc-dev/dbft@v0.0.0-20210302103605-cc75991b7cfb/check.go:73 +0xd8a
2021-07-07T20:05:24.8607235Z   github.com/nspcc-dev/dbft.(*DBFT).checkPrepare()
2021-07-07T20:05:24.8608551Z       /home/runner/go/pkg/mod/github.com/nspcc-dev/dbft@v0.0.0-20210302103605-cc75991b7cfb/check.go:36 +0x677
2021-07-07T20:05:24.8609681Z   github.com/nspcc-dev/dbft.(*DBFT).sendPrepareRequest()
2021-07-07T20:05:24.8611016Z       /home/runner/go/pkg/mod/github.com/nspcc-dev/dbft@v0.0.0-20210302103605-cc75991b7cfb/send.go:42 +0x47c
2021-07-07T20:05:24.8612107Z   github.com/nspcc-dev/dbft.(*DBFT).OnTimeout()
2021-07-07T20:05:24.8613257Z       /home/runner/go/pkg/mod/github.com/nspcc-dev/dbft@v0.0.0-20210302103605-cc75991b7cfb/dbft.go:188 +0x68c
2021-07-07T20:05:24.8614499Z   github.com/nspcc-dev/neo-go/pkg/consensus.(*service).eventLoop()
2021-07-07T20:05:24.8615712Z       /home/runner/work/neo-go/neo-go/pkg/consensus/consensus.go:274 +0x17ed
2021-07-07T20:05:24.8616284Z
2021-07-07T20:05:24.8616757Z Goroutine 51 (running) created at:
2021-07-07T20:05:24.8617367Z   net/http.(*Server).Serve()
2021-07-07T20:05:24.8618159Z       /opt/hostedtoolcache/go/1.15.13/x64/src/net/http/server.go:2969 +0x5d3
2021-07-07T20:05:24.8619253Z   github.com/nspcc-dev/neo-go/pkg/rpc/server.(*Server).Start.func2()
2021-07-07T20:05:24.8620437Z       /home/runner/work/neo-go/neo-go/pkg/rpc/server/server.go:224 +0x85
2021-07-07T20:05:24.8620936Z
2021-07-07T20:05:24.8621405Z Goroutine 41 (running) created at:
2021-07-07T20:05:24.8622393Z   github.com/nspcc-dev/neo-go/pkg/consensus.(*service).Start()
2021-07-07T20:05:24.8623562Z       /home/runner/work/neo-go/neo-go/pkg/consensus/consensus.go:250 +0x17c
2021-07-07T20:05:24.8624682Z   github.com/nspcc-dev/neo-go/pkg/network.(*Server).tryStartServices()
2021-07-07T20:05:24.8626078Z       /home/runner/work/neo-go/neo-go/pkg/network/server.go:445 +0x2e1
2021-07-07T20:05:24.8627226Z   github.com/nspcc-dev/neo-go/pkg/network.(*Server).Start()
2021-07-07T20:05:24.8628333Z       /home/runner/work/neo-go/neo-go/pkg/network/server.go:268 +0x2af
2021-07-07T20:05:24.8628973Z ==================
2021-07-08 10:40:54 +03:00
Roman Khimov
ea9dde257c
Merge pull request #2047 from nspcc-dev/fix-state
Don't create an extension node for the last branch child
2021-07-08 10:20:59 +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
Roman Khimov
0cd9cd0c80 state/result: save/return real JSONization errors
Don't hide/obfuscate real problems.
2021-07-07 00:42:36 +03:00
Roman Khimov
e62a766058 state: move nil check down to stackitem JSON processing
We want to return real errors, not some generic thing for any kind of thing
happening.
2021-07-07 00:38:19 +03:00
Roman Khimov
0de949b575 stackitem: remove Item/StackItem from function names
They're useless in a package named 'stackitem', make this package a bit more
user-friendly.
2021-07-06 19:56:23 +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
d2e8254848 native: fix typo in comments
Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2021-07-05 11:04:19 +03:00
Evgeniy Stratonikov
a7722f0fa5 native: save balance value in storage for failed transfers
Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2021-07-05 11:03:42 +03:00
Roman Khimov
e3323faf69
Merge pull request #2032 from nspcc-dev/optimize-restore
native: cache GAS per vote values
2021-07-01 15:17:37 +03:00
Evgeniy Stratonikov
0591366f85 native: cache GAS per vote values
`storage.Seek()` is rather expensive and we need only last updated value
of gas per block in `PostPersist()`.

Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2021-07-01 10:34:04 +03:00
Anna Shaleva
9673a04009 core: allow to add several headers with StateRootInHeader on
Problem: with StateRootInHeader setting on only one header of height N+1
can be added to the chain of height N, because we need local stateroot
to verify headers (which is calculated for the last stored block N).
Thus, adding chunk of headers starting from the current chain's heigh
is impossible and (*Blockchain).AddHeaders doesn't have much sense.

Solution: verify header.PrevStateRoot only for header N+1. Rest of the
headers should be added without PrevStateRoot verification.
2021-06-30 11:56:05 +03:00
Anna Shaleva
d49294b046 core: fix the way candidates are sorted
(*NEO).GetCandidates along with getCandidatesCall use candidates sorted
by serialized ECPoint bytes.

(*NEO).computeCommitteeMembers use candidates sorted by votes, and then
by deserialized ECPoint, i.e. using default ECPoint comparator.
2021-06-16 17:35:04 +03:00
Anna Shaleva
50296975e2 crypto: allow to provide non-default scrypt parameters 2021-06-11 15:22:28 +03:00
Anna Shaleva
6ff64153db core: check stored native states against autogenerated ones on start 2021-06-10 22:16:05 +03:00
Anna Shaleva
be902afe9e core: do not allow NEP17 roundtrip in case of insufficient funds
NEP17 roundtrip is prohibited if from account doesn't have enough funds.

This commit fixes states diff in block 92057 where account
NfuwpaQ1A2xaeVbxWe8FRtaRgaMa8yF3YM initiates two NEO roundtrips with
amount exceeding the account's balance:

block 92057: value mismatch for key +////xTbYWBH3r5qhRKZAPFPHabKfb2vhQ==: QQMhAkwBIQOZZwEA vs QQMhAkwBIQN/ZwEA
block 92057: value mismatch for key +v///ws=: kqlddcitCg== vs tphddcitCg==
block 92057: value mismatch for key +v///xTbYWBH3r5qhRKZAPFPHabKfb2vhQ==: QQEhBUWyDu0W vs QQEhBWmhDu0W

C#'s applog (contains False and False on stack for both transfers):
```
{
   "id" : 1,
   "jsonrpc" : "2.0",
   "result" : {
      "executions" : [
         {
            "gasconsumed" : "11955500",
            "exception" : null,
            "stack" : [
               {
                  "value" : false,
                  "type" : "Boolean"
               },
               {
                  "value" : false,
                  "type" : "Boolean"
               }
            ],
            "vmstate" : "HALT",
            "trigger" : "Application",
            "notifications" : []
         }
      ],
      "txid" : "0x8e73a7e9a566a514813907272ad65fc965002c3b098eacc5bdda529af19d7688"
   }
}
```

Go's applog (both transfers succeeded and GAS minted):
```
{
   "result" : {
      "executions" : [
         {
            "gasconsumed" : "11955500",
            "trigger" : "Application",
            "stack" : [
               {
                  "type" : "Boolean",
                  "value" : true
               },
               {
                  "type" : "Boolean",
                  "value" : true
               }
            ],
            "vmstate" : "HALT",
            "notifications" : [
               {
                  "eventname" : "Transfer",
                  "contract" : "0xd2a4cff31913016155e38e474a2c06d08be276cf",
                  "state" : {
                     "value" : [
                        {
                           "type" : "Any"
                        },
                        {
                           "value" : "22FgR96+aoUSmQDxTx2myn29r4U=",
                           "type" : "ByteString"
                        },
                        {
                           "value" : "4316",
                           "type" : "Integer"
                        }
                     ],
                     "type" : "Array"
                  }
               },
               {
                  "state" : {
                     "type" : "Array",
                     "value" : [
                        {
                           "value" : "22FgR96+aoUSmQDxTx2myn29r4U=",
                           "type" : "ByteString"
                        },
                        {
                           "type" : "ByteString",
                           "value" : "22FgR96+aoUSmQDxTx2myn29r4U="
                        },
                        {
                           "type" : "Integer",
                           "value" : "1111111111"
                        }
                     ]
                  },
                  "contract" : "0xef4073a0f2b305a38ec4050e4d3d28bc40ea63f5",
                  "eventname" : "Transfer"
               },
               {
                  "contract" : "0xef4073a0f2b305a38ec4050e4d3d28bc40ea63f5",
                  "state" : {
                     "type" : "Array",
                     "value" : [
                        {
                           "value" : "22FgR96+aoUSmQDxTx2myn29r4U=",
                           "type" : "ByteString"
                        },
                        {
                           "type" : "ByteString",
                           "value" : "22FgR96+aoUSmQDxTx2myn29r4U="
                        },
                        {
                           "type" : "Integer",
                           "value" : "1111111"
                        }
                     ]
                  },
                  "eventname" : "Transfer"
               }
            ]
         }
      ],
      "txid" : "0x8e73a7e9a566a514813907272ad65fc965002c3b098eacc5bdda529af19d7688"
   },
   "id" : 1,
   "jsonrpc" : "2.0"
}
```
2021-06-09 13:36:50 +03:00