Commit graph

950 commits

Author SHA1 Message Date
Roman Khimov
b567ce86ac mempool: implement insertion to sorted slice
Which is way faster than sort.Sort'ing things all the time.
2020-02-06 15:44:18 +03:00
Roman Khimov
35183b6dba mempool: reverse the order of sorted slice
Chopping off the last element of the slice if way easier than doing it with
the first one.
2020-02-06 15:44:16 +03:00
Roman Khimov
794027a90b mempool: use one slice for both priorities
It doesn't harm as we have transactions naturally ordered by fee anyway and it
makes managing them a little easier. This also makes slices store item itself
instead of pointers to it which reduces the pressure on the memory subsystem.
2020-02-06 15:43:45 +03:00
Roman Khimov
325bea3fa9 mempool: cache Feer invocation results in the item
They shouldn't depend on the chain state and for the same transaction they
should always produce the same result. Thus, it makes no sense recalculating
them over and over again.
2020-02-06 15:41:56 +03:00
Roman Khimov
e01bfeeb4d mempool: remove lock indirection from the Pool
After the f0bb886be3 with all methods of Pool
being pointer-based it makes no sense having this lock as a pointer.
2020-02-06 15:41:56 +03:00
Roman Khimov
a928ad9cfa mempool: make item an internal thing of mempool package
Nobody outside should care about these details, mempool operates on
transactions and that's it.
2020-02-06 15:41:56 +03:00
Roman Khimov
f0e3a31bc8 mempool: fix appending to sorted pools
Appending and not changing the real Items is utterly wrong.
2020-02-06 15:41:56 +03:00
Roman Khimov
b9b77ac1be network: fix block relaying, don't spit out useless errors
We can only add one block of the given height and we have two competing
goroutines to do that --- consensus and block queue. Whomever adds the block
first shouldn't trigger an error in another one.

Fix block relaying for blocks added via the block queue also, previously one
consensus-generated blocks were broadcasted.
2020-02-06 15:41:56 +03:00
Roman Khimov
f9963cca37 core: short-circuit verifyInputs when there are no inputs 2020-02-06 15:41:56 +03:00
Roman Khimov
70b3839fd0 core/mempool: fix AddBlock and tx pooling concurrency issues
Eliminate races between tx checks and adding them to the mempool, ensure the
chain doesn't change while we're working with the new tx. Ensure only one
block addition attempt could be in progress.
2020-02-06 15:41:52 +03:00
Evgenii Stratonikov
24bb66e606 util: fix a bug with not copying slice of len=1 in ArrayReverse
ArrayReverse copies it's argument only if it's len is > 1.
It needs to be consistent in all cases.
2020-02-06 12:15:35 +03:00
Evgenii Stratonikov
d07d6f3371 util: refactor tests for ArrayReverse 2020-02-06 12:15:35 +03:00
Evgenii Stratonikov
2a86149c82 vm: leave single CHECKMULTISIG implementation
Remove sequential implementation and benchmarks.
They will be still present in commit history.
2020-02-05 17:17:22 +03:00
Roman Khimov
02a5e036fc vm: deduplicate checkMultisigPar
Make its logic more clear.
2020-02-05 17:12:23 +03:00
Evgenii Stratonikov
d93d060010 vm: parallelize CHECKMULTISIG 2020-02-05 17:12:18 +03:00
Roman Khimov
f0bb886be3 mempool: make all methods pointer methods
Makes no sense copying the Pool around.
2020-02-04 17:36:11 +03:00
Roman Khimov
70c22ebc7b
Merge pull request #641 from nspcc-dev/consensus-update
Consensus update
2020-02-04 15:39:53 +03:00
Roman Khimov
9ceefe17e2 consensus: check current chain height before processing timer
The chain may already be more current than our dBFT state (like when the node
has commited something at view 0, but all the other nodes changed view and
accepted something at view 1), so in this case we should reinit dBFT on new
height.
2020-02-04 13:16:09 +03:00
Evgenii Stratonikov
e65b5c9914 consensus: fill preparation hash in recovery message 2020-02-04 13:16:05 +03:00
Evgenii Stratonikov
e441cb1414 consensus: add preparation hash to logger 2020-02-04 13:16:00 +03:00
Evgenii Stratonikov
42dfb52e98 consensus: add more logging in consensus service 2020-02-04 13:15:54 +03:00
Roman Khimov
553b2391a3 consensus: handle encoding errors in Hash() 2020-02-03 16:33:03 +03:00
Roman Khimov
388fed06e5 transaction: forbid serializing invalid transactions
Transaction that has no data is invalid and can't be serialized, so throw an
error if someone tries to.
2020-02-03 16:33:03 +03:00
Roman Khimov
9374c5e7c2
Merge pull request #639 from nspcc-dev/networking-improvements
Networking improvements
2020-02-03 16:26:04 +03:00
Evgenii Stratonikov
c3094123a1 compiler: do not store constants as variables
Because the constants are loaded directly via `emitLoadConst`, there is no need to store
them in an array of locals. It can have a big overhead, because it
is done at the beginning of every function.
2020-02-03 13:29:28 +03:00
Roman Khimov
e5d0125a3f network: do async broadcast when processing P2P TX
It can lead to some goroutine explosion, but supposedly it's better than
stalling other processing and eventually all of these goroutines should finish
their sends. Note that this doesn't change the behavior for RPC-relayed
transactions that are still waiting for the broadcast to finish ensuring
proper transaction distribution before returning the result to the client.
2020-01-30 14:03:52 +03:00
Roman Khimov
0fcbc697ca network: only tell consensus service about new valid transactions
Transactions can be bad and can duplicate each other, consensus service
shouldn't be bothered with that.
2020-01-30 14:03:52 +03:00
Roman Khimov
fdbaac7a30 network: prevent broadcast queue starving, share time with p2p
Blocked broadcast queue of one peer may affect broadcasting capabilities of
the server, so prevent total blocking of it by p2p queue.
2020-01-30 14:03:52 +03:00
Roman Khimov
b2c4587dad network: fix PeerAddr() for not-yet-handshaked case
If we have already got Version message, we don't need the rest of handshake to
complete before being able to properly answer the PeerAddr() requests. Fixes
some duplicate connections between machines.
2020-01-30 14:03:52 +03:00
Roman Khimov
49bd7aada5 network: log peerCount on connection registration
Symmetrical to disconnects, make it easier to look through the logs.
2020-01-30 14:03:52 +03:00
Roman Khimov
32695b4f40 network: don't unregister connected peers
If we drop connection because we're already connected don't unregister this
connected address because it's connected anyway!
2020-01-30 14:03:52 +03:00
Roman Khimov
eb4ec61b8b network: register connected addr in handleVersionCmd()
Prevent useless attempts to connect to this peer if the peer has already made
a connection to us.
2020-01-30 14:03:52 +03:00
Roman Khimov
9eafec0d1d network: introduce peer-to-peer message queue
This one is designed to give more priority to direct nodes communication, that
is that their messaging would have more priority than generic broadcasts. It
should improve consensus process under TX pressure and allow to handle
pings in time (preventing disconnects).
2020-01-30 14:03:52 +03:00
Roman Khimov
72e4eb7172 network: fix wrong NewPing() parameters
They have the opposite order, height first and nonce second. It was done wrong
in 4e6ed902 and never fixed since. Fixes sending wrong peer state leading to
useless getheaders messages (and disconnects when the other side is lagging
behind).
2020-01-30 14:03:52 +03:00
Roman Khimov
da09fda575 network: add debug on message receival 2020-01-30 14:03:52 +03:00
Roman Khimov
1c28dd2567 network: add message type to disconnect error message
If it was caused by message processing, but only after the handshake to
preserve errIdenticalID and other handshaking errors.
2020-01-30 14:03:52 +03:00
Roman Khimov
b79abd1e27 network: detect duplicate connections before handshake completes
We can have more than one connection attempt in progress and not yet completed
the handshake, so if there is a Version already received we should look it.
2020-01-30 14:03:52 +03:00
Roman Khimov
b1b660c779 rpc: fix getaccountstate/getunspents for unknown addresses
Returning error string as a result (not an error) is utterly wrong, but C#
implementation just returns a zero balance for unknown addresses, so we should
follow that.
2020-01-29 19:01:00 +03:00
Roman Khimov
0ccc59628c
Merge pull request #631 from nspcc-dev/fix/return3
compiler: fix a bug with assignment to underscore
2020-01-29 18:32:43 +03:00
Evgenii Stratonikov
390bf58f97 consensus: use our implementations of Recovery* messages
While decoding payload, local implementations of Recovery*
messages were used, but when creating RecoveryMessage inside dBFT
library default NewRecoveryMessage was invoked. This lead to parsing
errors.
2020-01-29 17:56:26 +03:00
Evgenii Stratonikov
8b922c057c compiler: fix a bug with assignment to underscore
When using underscore it does not appear in the list
of local variables, so it can't be assigned.
In this commit the value is dropped.
2020-01-29 17:07:55 +03:00
Evgenii Stratonikov
7053b3b2c0 compiler: optimize append argument processing
Append should leave it's result on top of the stack.
Thus we need to transform top of the stack:
(top) a . b --> (top) a . b . b
It can be done with just OVER + SWAP.
2020-01-29 12:28:38 +03:00
Evgenii Stratonikov
b6629fb6bd compiler: refactor argument handling for builtins
It is more convenient to have all unusual logic in one place.
2020-01-29 12:28:38 +03:00
Evgenii Stratonikov
d2326a8b96 compiler: support panic in source
In situations where VM's FAULT state needs to be reached,
panic function can be used. It compiles to THROW instruction.
2020-01-29 12:28:38 +03:00
Evgenii Stratonikov
e0f47decc7 compiler: replace ROLL(2) with equivalent ROT 2020-01-29 09:56:16 +03:00
Evgenii Stratonikov
28571bd3dc compiler: implement switch statement support 2020-01-29 09:56:16 +03:00
Roman Khimov
0ce0ecb95e
Merge pull request #624 from nspcc-dev/feature/bigint
compiler: emit integers correctly
2020-01-28 18:04:32 +03:00
Roman Khimov
ab03aee2cf
Merge pull request #627 from nspcc-dev/fix-getdata-and-pings
Fix getdata and pings
2020-01-28 17:43:13 +03:00
Roman Khimov
06c3fbe455 network: rework ping sends, fix overpinging
Our node was too pingy because of wrong timer setups (that divided timeout
Duration by time.Second), it also was wrong in its time calculations (using
UTC time to calculate intervals). At the same time missing block is a
server-wide problem, so it's better solved with server-wide protocol loop.
2020-01-28 17:39:52 +03:00
Roman Khimov
39800aecb3 network: fix getdata handling
It was broken by 0ba6b2a7, the peer only responded with one message instead of
full requested set.
2020-01-28 17:39:52 +03:00
Evgenii Stratonikov
d190b3a2e0 compiler: emit integers correctly
A while ago VM serialization format for Integer items was changed
but compiler continued to emit Integers in old format.
This commit changes compiler behaviour to be compatible with VM.
2020-01-28 16:39:19 +03:00
Evgenii Stratonikov
f15ceff592 vm: make IntToBytes, BytesToInt public
VM serialization format should be able to be reused.
2020-01-28 16:39:19 +03:00
Evgenii Stratonikov
77f9a2ee26 compiler: convert AppCall parameter from string properly 2020-01-27 15:34:03 +03:00
Evgenii Stratonikov
d65d6ab08d compiler: allow to convert string constants to []byte
Also load constant directly into stack, not by name.
2020-01-27 15:29:52 +03:00
Evgenii Stratonikov
097d35b9d5 compiler: fix a bug with FromAddress handling
Conversion of string to address with FromAddress is performed
at compile time so there is no need to push parameters on stack.
2020-01-27 13:14:40 +03:00
Evgenii Stratonikov
330db36168 compiler: implement engine.AppCall interop 2020-01-27 13:14:36 +03:00
Evgenii Stratonikov
4fd766fe09 compiler: allow usage of string literals in index expressions 2020-01-23 17:28:35 +03:00
Evgenii Stratonikov
058958729d compiler: support map literals 2020-01-23 17:06:15 +03:00
Evgenii Stratonikov
def73db8e9 compiler: support variables in slice literals 2020-01-23 15:51:16 +03:00
Evgeniy Kulikov
eb59460032
Merge pull request #614 from nspcc-dev/configurable-mempool-size
config: add MemPoolSize configuration parameter
2020-01-23 13:25:27 +03:00
Roman Khimov
67fe99b0ba
Merge pull request #618 from nspcc-dev/feature/for
compiler: support for loops with no init/post condition
2020-01-23 13:19:55 +03:00
Roman Khimov
04db87c770
Merge pull request #617 from nspcc-dev/feature/checksig
compiler: implement ECDSA signature verification
2020-01-23 13:18:21 +03:00
Roman Khimov
9aa5d0cf1e
Merge pull request #615 from nspcc-dev/network-peer-updates
Network peer updates
2020-01-23 13:15:43 +03:00
Roman Khimov
d6784e8f45 config: add MemPoolSize configuration parameter
Allow tuning/experimenting with mempool.
2020-01-23 13:10:44 +03:00
Evgenii Stratonikov
328267ca6f compiler: support for loops with no init/post condition
Make it possible to use `for` loop with a single condition.
2020-01-23 11:48:43 +03:00
Evgenii Stratonikov
bd37359393 compiler: implement ECDSA signature verification
Add VerifySignature interop for signature verification.
It is converted to VERIFY opcode.
2020-01-23 10:56:15 +03:00
Evgenii Stratonikov
303b82cc44 core: set free GAS limit via config 2020-01-22 14:32:21 +03:00
Evgenii Stratonikov
54e0b5a4a7 rpc: set MaxGasInvoke in config
Implement ability to restrict maximum amount of GAS
available for free RPC calls.
2020-01-22 14:31:57 +03:00
Evgenii Stratonikov
4718375db1 rpc: return amount of consumed GAS in invoke* 2020-01-22 14:31:57 +03:00
Evgenii Stratonikov
2f865480d3 util: add YAML marshaler to Fixed8 2020-01-22 14:31:57 +03:00
Evgenii Stratonikov
7a6d6f43ce vm: get rid of recursive (*VM).execute calls
Recursive execute() calls can affect gas calculation.
This commit makes execute() be called only for real opcodes
and moves duplicate logic for CALL/JMP into a separate function.
2020-01-22 14:31:57 +03:00
Evgenii Stratonikov
4eae55143f core: restrict GAS available for invocation transactions
There are 10 GAS available for free plus any amount of GAS
attached to a transaction.
2020-01-22 14:31:54 +03:00
Evgenii Stratonikov
d72d978a19 vm: abstract out GetInterop() function 2020-01-22 14:04:40 +03:00
Evgenii Stratonikov
c22d09adad vm: set GAS limit
Make it possible to set maximum amount of GAS which can be spent
during execution.
2020-01-22 14:04:40 +03:00
Evgenii Stratonikov
0662a7e3c2 vm: calculate GAS spent during execution
If getPrice callback is provided, accumulate spent GAS.
2020-01-22 14:04:40 +03:00
Roman Khimov
99dfdc19e7 network: drop now useless addrReq queue from the server
Just broadcast a high-priority message to everyone.
2020-01-22 11:28:59 +03:00
Roman Khimov
ea3b76ded1 network: make NewServer return an error, fix #612
It can return nil in two cases, so we're better return an error and handle
it.
2020-01-22 11:17:51 +03:00
Roman Khimov
f2ffffddb7 network: rework broadcasting functions, tune priorities
This gives more priority to anything related to consensus.
2020-01-22 11:01:13 +03:00
Roman Khimov
34b863d645 network: introduce Server's MkMsg()
That wraps NewMessage() for a configured network.
2020-01-21 17:31:51 +03:00
Roman Khimov
1f672e0da7 network: move SendVersion() to the Peer
Only leave server-specific `getVersionMsg()` in the Server, all the other
logic is peer-related.
2020-01-21 17:26:08 +03:00
Roman Khimov
9befd8de99
Merge pull request #610 from nspcc-dev/ping-improvements
Ping improvements
2020-01-21 13:34:15 +03:00
Roman Khimov
760b39e324 consensus: close chain in tests
Avoid test failures like this one:

=== RUN   TestService_OnPayload
==================
WARNING: DATA RACE
Read at 0x00c00015a843 by goroutine 112:
  testing.(*common).logDepth()
      /usr/local/go/src/testing/testing.go:665 +0xa1
  testing.(*common).Logf()
      /usr/local/go/src/testing/testing.go:658 +0x8f
  testing.(*T).Logf()
      <autogenerated>:1 +0x75
  go.uber.org/zap/zaptest.testingWriter.Write()
      /go/pkg/mod/go.uber.org/zap@v1.10.0/zaptest/logger.go:130 +0x11f
  go.uber.org/zap/zaptest.(*testingWriter).Write()
      <autogenerated>:1 +0xa9
  go.uber.org/zap/zapcore.(*ioCore).Write()
      /go/pkg/mod/go.uber.org/zap@v1.10.0/zapcore/core.go:90 +0x1c3
  go.uber.org/zap/zapcore.(*CheckedEntry).Write()
      /go/pkg/mod/go.uber.org/zap@v1.10.0/zapcore/entry.go:215 +0x1e7
  go.uber.org/zap.(*Logger).Info()
      /go/pkg/mod/go.uber.org/zap@v1.10.0/logger.go:187 +0x95
  github.com/CityOfZion/neo-go/pkg/core.(*Blockchain).persist()
      /go/src/github.com/CityOfZion/neo-go/pkg/core/blockchain.go:720 +0x6bb
  github.com/CityOfZion/neo-go/pkg/core.(*Blockchain).Run.func2()
      /go/src/github.com/CityOfZion/neo-go/pkg/core/blockchain.go:228 +0x53

Previous write at 0x00c00015a843 by goroutine 98:
  testing.tRunner.func1()
      /usr/local/go/src/testing/testing.go:900 +0x353
  testing.tRunner()
      /usr/local/go/src/testing/testing.go:913 +0x1bb

Goroutine 112 (running) created at:
  github.com/CityOfZion/neo-go/pkg/core.(*Blockchain).Run()
      /go/src/github.com/CityOfZion/neo-go/pkg/core/blockchain.go:227 +0x264

Goroutine 98 (finished) created at:
  testing.(*T).Run()
      /usr/local/go/src/testing/testing.go:960 +0x651
  testing.runTests.func1()
      /usr/local/go/src/testing/testing.go:1202 +0xa6
  testing.tRunner()
      /usr/local/go/src/testing/testing.go:909 +0x199
  testing.runTests()
      /usr/local/go/src/testing/testing.go:1200 +0x521
  testing.(*M).Run()
      /usr/local/go/src/testing/testing.go:1117 +0x2ff
  main.main()
      _testmain.go:162 +0x337
==================
--- FAIL: TestService_OnPayload (4.11s)
2020-01-20 19:40:52 +03:00
Roman Khimov
f56383e9c8 network: use p.LastBlockIndex() in requestBlocks()
Always compare to the best known block index, comparing to the StartHeight is
just plain wrong now.
2020-01-20 19:37:17 +03:00
Roman Khimov
2c4ace022e network/config: redesign ping timeout handling a bit
1) Make timeout a timeout, don't do magic ping counts.
2) Drop additional timer from the main peer's protocol loop, create it
   dynamically and make it disconnect the peer.
3) Don't expose the ping counter to the outside, handle more logic inside the
   Peer.

Relates to #430.
2020-01-20 19:37:17 +03:00
Roman Khimov
62092c703d network: use local timestamp to decide when to ping
We don't and we won't have synchronized clocks in the network so the only
timestamp that we can compare our local time with is the one made
ourselves. What this ping mechanism is used for is to recover from missing the
block broadcast, thus it's appropriate for it to trigger after X seconds of
the local time since the last block received.

Relates to #430.
2020-01-20 19:37:17 +03:00
Roman Khimov
a8252ecc05 network: remove wrong ping condition
In reality it will never be true exactly in the case where we want this ping
mechanism to work --- when the node failed to get a block from the net. It
won't get the header either and thus its block height will be equal to header
height. The only moment when this condition is met is when the node does
initial synchronization and this synchronization works just fine without any
pings.

Relates to #430.
2020-01-20 19:37:17 +03:00
Roman Khimov
247cfa4165 network: either request blocks or ping a peer, but not both
It makes to sense to do both actions, pings are made for a different purpose.

Relates to #430.
2020-01-20 19:37:17 +03:00
Roman Khimov
0ba6b2a754 network: introduce peer sending queues
Two queues for high-priority and ordinary messages. Fixes #590. These queues
are deliberately made small to avoid buffer bloat problem, there is gonna be
another queueing layer above them to compensate for that. The queues are
designed to be synchronous in enqueueing, async capabilities are to be added
layer above later.
2020-01-20 17:23:26 +03:00
Roman Khimov
7f0882767c network: remove useless Done() method from the peer
It's internal state of the peer that no one should care about.
2020-01-20 17:23:26 +03:00
Roman Khimov
f39d5d5a10 network: fix unregistration on peer Disconnect
It should always signal to the server, not duplicating this send and not
missing it like it happened in the Server.run().
2020-01-20 17:23:26 +03:00
Roman Khimov
907a236285 network: move per-peer goroutines into the TCPPeer
As they're directly tied to it.
2020-01-20 17:23:26 +03:00
Roman Khimov
32213b1454
Merge pull request #601 from nspcc-dev/refactoring/core
core: refactor out Block, BlockBase and Header, closes #597.
2020-01-20 16:19:20 +03:00
Roman Khimov
f4aa088d04
Merge pull request #603 from nspcc-dev/feature/wallet
consensus: use wallets instead of WIF, closes #588.
2020-01-20 16:16:10 +03:00
Roman Khimov
bb80ba9b9e
Merge pull request #456 from nspcc-dev/pingpong_430
add ping pong processing
2020-01-20 16:10:29 +03:00
Evgenii Stratonikov
f0083b94c5 vm: use new big.Int (de-)serialization routines
Also fix a test with CAT.
2020-01-17 17:37:50 +03:00
Evgenii Stratonikov
f26bdae2c5 vm: implement proper big.Int to []byte conversions
Big.Int Bytes()/SetBytes() methods are not symmetric.
Moreover we need to mimic C# node behavior:
- if a positive number has MSB set, 0x00 byte should be appended
  to distinguish positive number from negatives
- negative numbers should serialize as two's-complement
2020-01-17 17:37:50 +03:00
Evgenii Stratonikov
55d98ab19a consensus: update keys from wallet after every block 2020-01-17 17:30:45 +03:00
Evgenii Stratonikov
aaefcdecae consensus: use wallet in service 2020-01-17 17:25:51 +03:00
Evgenii Stratonikov
36cfa5b1f4 wallet: add GetAccount() method to Wallet
It is useful to be able to get account specified by script hash.
2020-01-17 17:25:51 +03:00
Evgenii Stratonikov
a798e4e0fa wallet: add ScriptHash() method to Contract 2020-01-17 17:25:51 +03:00