Commit graph

313 commits

Author SHA1 Message Date
Anna Shaleva
3b7807e897 network: request unknown MPT nodes
In this commit:

1. Request unknown MPT nodes from peers. Note, that StateSync module itself
shouldn't be responsible for nodes requests, that's a server duty.
2. Do not request the same node twice, check if it is in storage
already. If so, then the only thing remaining is to update refcounter.
2021-09-07 19:43:27 +03:00
Anna Shaleva
d67ff30704 core: implement statesync module
And support GetMPTData and MPTData P2P commands.
2021-09-07 19:43:27 +03:00
Roman Khimov
5aff82aef4
Merge pull request #2119 from nspcc-dev/states-exchange/insole
core, network: prepare basis for Insole module
2021-08-12 10:35:02 +03:00
Anna Shaleva
6ca7983be8 network: fix typo in error message 2021-08-10 11:00:39 +03:00
Roman Khimov
7bb82f1f99 network: merge two loops in iteratePeersWithSendMsg, send to 2/3
Refactor code and be fine with sending to just 2/3 of proper peers. Previously
it was an edge case, but it can be a normal thing to do also as broadcasting
to everyone is obviously too expensive and excessive (hi, #608).

Baseline (four node, 10 workers):

RPS    8180.760 8137.822 7858.358 7820.011 8051.076 ≈ 8010   ± 2.04%
TPS    7819.831 7521.172 7519.023 7242.965 7426.000 ≈ 7506   ± 2.78%
CPU %    41.983   38.775   40.606   39.375   35.537 ≈   39.3 ± 6.15%
Mem MB 2947.189 2743.658 2896.688 2813.276 2863.108 ≈ 2853   ± 2.74%

Patched:

RPS    9714.567 9676.102 9358.609 9371.408 9301.372 ≈ 9484   ±  2.05% ↑ 18.40%
TPS    8809.796 8796.854 8534.754 8661.158 8426.162 ≈ 8646   ±  1.92% ↑ 15.19%
CPU %    44.980   45.018   33.640   29.645   43.830 ≈   39.4 ± 18.41% ↑  0.25%
Mem MB 2989.078 2976.577 2306.185 2351.929 2910.479 ≈ 2707   ± 12.80% ↓  5.12%

There is a nuance with this patch however. While typically it works the way
outlined above, sometimes it works like this:

RPS ≈ 6734.368
TPS ≈ 6299.332
CPU ≈ 25.552%
Mem ≈ 2706.046MB

And that's because the log looks like this:

DeltaTime, TransactionsCount, TPS
5014, 44212, 8817.710
5163, 49690, 9624.249
5166, 49523, 9586.334
5189, 49693, 9576.604
5198, 49339, 9491.920
5147, 49559, 9628.716
5192, 49680, 9568.567
5163, 49750, 9635.871
5183, 49189, 9490.450
5159, 49653, 9624.540
5167, 47945, 9279.079
5179, 2051, 396.022
5015, 4, 0.798
5004, 0, 0.000
5003, 0, 0.000
5003, 0, 0.000
5003, 0, 0.000
5003, 0, 0.000
5004, 0, 0.000
5003, 2925, 584.649
5040, 49099, 9741.865
5161, 49718, 9633.404
5170, 49228, 9521.857
5179, 49773, 9610.543
5167, 47253, 9145.152
5202, 49788, 9570.934
5177, 47704, 9214.603
5209, 46610, 8947.975
5249, 49156, 9364.831
5163, 18284, 3541.352
5072, 174, 34.306

On a network with 4 CNs and 1 RPC node there is 1/256 probability that a block
won't be broadcasted to RPC node, so it won't see it until ping timeout kicks
in. While it doesn't see a block it can't accept new incoming transactions so
the bench gets stuck basically. To me that's an acceptable trade-off because
normal networks are much larger than that and the effect of this patch is way
more important there, but still that's what we have and we need to take into
account.
2021-08-06 21:10:34 +03:00
Roman Khimov
966a16e80e network: keep track of dead peers in iteratePeersWithSendMsg()
send() can return errStateMismatch, errGone and errBusy. errGone means the
peer is dead and it won't ever be active again, it doesn't make sense retrying
sends to it. errStateMismatch is technically "not yet ready", but we can't
wait for it either, no one knows how much will it take to complete
handshake. So only errBusy means we can retry.

So keep track of dead peers and adjust tries counting appropriately.
2021-08-06 21:10:34 +03:00
Roman Khimov
80f3ec2312 network: move peer filtering to getPeers()
It doesn't change much, we can't magically get more valid peers and if some
die while we're iterating we'd detect that by an error returned from send().
2021-08-06 21:10:34 +03:00
Roman Khimov
de6f4987f6 network: microoptimize iteratePeersWithSendMsg()
Now that s.getPeers() returns a slice we can use slice for `success` too, maps
are more expensive.
2021-08-06 21:10:34 +03:00
Roman Khimov
d51db20405 network: randomize peer iteration order
While iterating over map in getPeers() is non-deterministic it's not really
random enough for our purposes (usually maps have 2-3 paths through them), we
need to fill our peers queues more uniformly.

Believe it or not, but it does affect performance metrics, baseline (four
nodes, 10 workers):

RPS ≈  7791.675 7996.559 7834.504 7746.705 7891.614 ≈ 7852   ±  1.10%
TPS ≈  7241.497 7711.765 7520.211 7425.890 7334.443 ≈ 7447   ±  2.17%
CPU %    29.853   39.936   39.945   36.371   39.999 ≈   37.2 ± 10.57%
Mem MB 2749.635 2791.609 2828.610 2910.431 2863.344 ≈ 2829   ±  1.97%

Patched:

RPS    8180.760 8137.822 7858.358 7820.011 8051.076 ≈ 8010   ± 2.04% ↑ 2.01%
TPS    7819.831 7521.172 7519.023 7242.965 7426.000 ≈ 7506   ± 2.78% ↑ 0.79%
CPU %    41.983   38.775   40.606   39.375   35.537 ≈   39.3 ± 6.15% ↑ 5.65%
Mem MB 2947.189 2743.658 2896.688 2813.276 2863.108 ≈ 2853   ± 2.74% ↑ 0.85%
2021-08-06 21:10:34 +03:00
Roman Khimov
b55c75d59d network: hide Peers, make it return a slice
Slice is a bit more efficient, we don't need a map for Peers() users and it's
not really interesting to outside users, so better hide this method.
2021-08-06 21:10:34 +03:00
Roman Khimov
119b4200ac network: add fail-fast route for tx double processing
When transaction spreads through the network many nodes are likely to get it
in roughly the same time. They will rebroadcast it also in roughly the same
time. As we have a number of peers it's quite likely that we'd get an Inv with
the same transaction from multiple peers simultaneously. We will ask them for
this transaction (independently!) and again we're likely to get it in roughly
the same time. So we can easily end up with multiple threads processing the
same transaction. Only one will succeed, but we can actually easily avoid
doing it in the first place saving some CPU cycles for other things.

Notice that we can't do it _before_ receiving a transaction because nothing
guarantees that the peer will respond to our transaction request, so
communication overhead is unavoidable at the moment, but saving on processing
already gives quite interesting results.

Baseline, four nodes with 10 workers:

RPS    7176.784 7014.511 6139.663 7191.280 7080.852 ≈ 6921   ± 5.72%
TPS    6945.409 6562.756 5927.050 6681.187 6821.794 ≈ 6588   ± 5.38%
CPU %    44.400   43.842   40.418   49.211   49.370 ≈   45.4 ± 7.53%
Mem MB 2693.414 2640.602 2472.007 2731.482 2707.879 ≈ 2649   ± 3.53%

Patched:

RPS ≈  7791.675 7996.559 7834.504 7746.705 7891.614 ≈ 7852   ±  1.10% ↑ 13.45%
TPS ≈  7241.497 7711.765 7520.211 7425.890 7334.443 ≈ 7447   ±  2.17% ↑ 13.04%
CPU %    29.853   39.936   39.945   36.371   39.999 ≈   37.2 ± 10.57% ↓ 18.06%
Mem MB 2749.635 2791.609 2828.610 2910.431 2863.344 ≈ 2829   ±  1.97% ↑  6.80%
2021-08-06 21:10:25 +03:00
Roman Khimov
7fc153ed2a network: only ask mempool for intersections with received Inv
Most of the time on healthy network we see new transactions appearing that are
not present in the mempool. Once they get into mempool we don't ask for them
again when some other peer sends an Inv with them. Then these transactions are
usually added into block, removed from mempool and no one actually sends them
again to us. Some stale nodes can do that, but it's not very likely to
happen.

At the receiving end at the same time it's quite expensive to do full chain
HasTransaction() query, so if we can avoid doing that it's always good. Here
it technically allows resending old transaction that will be re-requested and
an attempt to add it to mempool will be made. But it'll inevitably fail
because the same HasTransaction() check is done there too. One can try to
maliciously flood the node with stale transactions but it doesn't differ from
flooding it with any other invalid transactions, so there is no new attack
vector added.

Baseline, 4 nodes with 10 workers:

RPS    6902.296 6465.662 6856.044 6785.515 6157.024 ≈ 6633   ± 4.26%
TPS    6468.431 6218.867 6610.565 6288.596 5790.556 ≈ 6275   ± 4.44%
CPU %    50.231   42.925   49.481   48.396   42.662 ≈   46.7 ± 7.01%
Mem MB 2856.841 2684.103 2756.195 2733.485 2422.787 ≈ 2691   ± 5.40%

Patched:

RPS    7176.784 7014.511 6139.663 7191.280 7080.852 ≈ 6921   ± 5.72% ↑ 4.34%
TPS    6945.409 6562.756 5927.050 6681.187 6821.794 ≈ 6588   ± 5.38% ↑ 4.99%
CPU %    44.400   43.842   40.418   49.211   49.370 ≈   45.4 ± 7.53% ↓ 2.78%
Mem MB 2693.414 2640.602 2472.007 2731.482 2707.879 ≈ 2649   ± 3.53% ↓ 1.56%
2021-08-06 20:53:02 +03:00
Roman Khimov
f9663a97a1 network: fix Ping messages
* NewPing() accepts block index first and nonce then.
 * Block height should be used, it'll be important for state exchanging nodes
2021-08-06 11:28:09 +03:00
Roman Khimov
1cea0dd894
Merge pull request #1997 from nspcc-dev/drop-syncreached-check
network: drop useless flag check
2021-06-04 23:39:34 +03:00
Roman Khimov
f6da88af0d network: drop useless flag check
It's the first thing done in tryStartServices(), so checking it here doesn't
make much sense.
2021-06-04 20:29:47 +03:00
Anna Shaleva
1dbf1d4310 rpc: allow to track notary requests via Notification subsystem 2021-06-01 16:29:04 +03:00
Roman Khimov
c4e084b0d8 *: fix whitespace errors
leading/trailing newlines
2021-05-12 22:51:41 +03:00
Roman Khimov
99108c620f network: fix errcheck warning 2021-05-12 20:14:35 +03:00
Roman Khimov
cfc067dd24 *: remove dead code
Found by deadcode via golangci-lint.
2021-05-12 18:13:14 +03:00
Evgeniy Stratonikov
275a5c9daa network: limit message number from the same sender 2021-05-12 10:52:11 +03:00
Anna Shaleva
09bb162de0 network: add ability to specify port for P2P version exchange 2021-04-30 11:27:55 +03:00
Roman Khimov
99b71bbbd1 network: move service starts to tryStartServices
All of them only make sense on a fully synchronized node, doing anything
during the initial sync is just a waste of time.
2021-04-02 13:12:06 +03:00
Roman Khimov
690a1db589 network: replace consensusStarted/canHandleExtens with syncReached flag
They're essentially the same.
2021-04-02 12:55:56 +03:00
Roman Khimov
a01636a1b0 stateroot: set networking callback in a more straightforward way 2021-04-02 12:12:36 +03:00
Roman Khimov
546faf5e70
Merge pull request #1859 from nspcc-dev/rework-signing-fix-stateroots
Rework signing, fix stateroots
2021-03-26 14:04:23 +03:00
Roman Khimov
d314f82db3 transaction: drop Network from Transaction
We only need it when signing/verifying.
2021-03-26 13:45:18 +03:00
Roman Khimov
fa4380c9da network: prevent putting duplicate addresses into pool from peer's data
It can't be trusted.
2021-03-26 12:31:07 +03:00
Anna Shaleva
23a3514cc0 consensus: store ProtocolConfiguration in consensus config 2021-03-15 16:58:27 +03:00
Evgeniy Stratonikov
2f3abf95a2 stateroot: broadcast state on new blocks 2021-03-09 13:51:11 +03:00
Evgeniy Stratonikov
3c65ed1507 stateroot: allow to sign new roots 2021-03-09 13:51:11 +03:00
Evgeniy Stratonikov
ac227a80fe stateroot: use RoleStateValidator for verification 2021-03-09 13:51:10 +03:00
Anna Shaleva
94430ef3ca network: refactor RelayTx error handling
We don't need to wrap different core errors in server. Also it would be
good to provede more error info to the user.
2021-02-18 12:40:40 +03:00
Anna Shaleva
9f6fba5926 network: specify error message
For better user experience.
2021-02-16 14:11:42 +03:00
Anna Shaleva
bcb82b457d config: move notary module config to ApplicationConfiguration 2021-02-16 13:58:25 +03:00
Anna Shaleva
8444f3d816 network: refactor notary service's PostBlock
There was a deadlock while trying to finalize transaction during
PostBlock:
	1) (*Notary).PostBlock is called under the blockchain lock
	2) (*Notary).onTransaction is called inside the PostBlock
	3) (*Notary).onTransaction needs to RLock the blockchain to add
completed transaction to the memory pool (and the blockchain is Lock'ed
by this moment)

The problem is fixed by using notifications subsistem, because it's not
required to call (*Notary).PostBlock under the blockchain lock.
2021-02-11 17:11:36 +03:00
Anna Shaleva
5d6fdda664 network: fix P2PNotaryRequest payload broadcaster 2021-02-11 17:11:36 +03:00
Anna Shaleva
c14e34cdb5 network: add RelayP2PNotaryRequest method 2021-02-11 16:56:24 +03:00
Roman Khimov
a87b8578b2 network: stub "StateService" payloads out for now
And stop dropping connections if we're to receive them. Proper handling is
subject of #1701, but we need at least some connection-level stability for
now.
2021-02-05 14:59:41 +03:00
Roman Khimov
686f983ccf network: prevent disconnects during initial sync
Node receiving extensible payload from the future is confused and drops
connection. Note that this can still happen if the node is to loose its
synchrony.

Calling `IsInSync()` is quite expensive, so we stop doing that once synchrony
is reached (hence bool flag).
2021-02-05 14:54:43 +03:00
Anna Shaleva
bfbd096fed core: introduce mempool notifications 2021-02-02 22:01:32 +03:00
Anna Shaleva
19fa0daaa6 core, network: add Notary module 2021-02-02 22:01:20 +03:00
Evgeniy Stratonikov
9592f3e052 network: implement pool for Extensible payloads 2021-01-28 17:09:06 +03:00
Evgenii Stratonikov
43e4d3af88 oracle: integrate module in core and RPC
1. Initialization is performed via `Blockchain` methods.
2. Native Oracle contract updates list of oracle nodes
  and in-fly requests in `PostPersist`.
3. RPC uses Oracle module directly.
2021-01-28 13:00:58 +03:00
Evgeniy Stratonikov
5d83c28bc9 network: replace ConsensusType with ExtensibleType 2021-01-22 10:38:33 +03:00
Evgenii Stratonikov
5bd6c1e5cc network: fix a bug in discovery with a peer connected twice
It could be the case that checks are performed simultaneosly and
peers connections goes down from 2 to 0. We must take such case into
account and register address as good in discovery.
2020-12-25 14:36:53 +03:00
Evgenii Stratonikov
2cb536a6a1 network: provide NullPayload where necessary 2020-12-25 14:36:53 +03:00
Evgenii Stratonikov
0a5049658f network: support non-blocking broadcast
Right now a single slow peer can slow down whole network.
Do broadcast in 2 parts:
1. Perform non-blocking send to all peers if possible.
2. Perform blocking sends until message is sent to 2/3 of good peers.
2020-12-25 14:36:52 +03:00
Anna Shaleva
0b5cf78468 network: add notary request payload 2020-12-10 18:17:31 +03:00
Evgenii Stratonikov
27624946d9 network/test: add tests for server commands 2020-12-09 15:23:49 +03:00
Evgenii Stratonikov
bd81b19a7a network: fix requestTx()
2 bugs were here:
1. If amount of tx is small, no messages were sent.
2. Correctly cut byte slice if last message is small.
2020-12-09 12:04:10 +03:00
Evgenii Stratonikov
074ba5f394 network: fix GetBlocks command
Return exactly requested amount of hashes.
2020-12-09 12:04:10 +03:00
Evgenii Stratonikov
4aa1a37f3f network: fetch blocks in parallel
Blockcache size is 2000, while max request size is 500.
Try to fetch blocks in chunks starting from current height.
Lower height has priority.
2020-12-02 10:50:35 +03:00
Roman Khimov
2ce3c8b75f network: treat unsolicited addr commands as errors
See neo-project/neo#2097.
2020-11-25 13:34:38 +03:00
Evgenii Stratonikov
1869d6d460 core: allow to use state root in header 2020-11-20 17:16:32 +03:00
Evgenii Stratonikov
3e5b84348d network: retransmit stale transactions 2020-11-12 13:51:44 +03:00
Roman Khimov
38a22b44b2 network: try connecting to seeds indefinitely, use them with 0 pool
If the node is to start with seeds unavailable it will try connecting to each
of them three times, blacklist them and then sit forever waiting for
something. It's not a good behavior, it should always try connecting to seeds
if nothing else works.
2020-10-13 19:02:10 +03:00
Roman Khimov
5abec520c7 payload: limit the number of possible addresses 2020-10-07 23:29:20 +03:00
Evgenii Stratonikov
282b55494b consensus: allow to shutdown service 2020-09-18 12:07:01 +03:00
Roman Khimov
b78bc7f097 network: fix tx requests, we can't ask more than 500 txes at once 2020-09-09 20:46:31 +03:00
Roman Khimov
097b2b8e78 network: fail fast in iteratePeersWithSendMsg
This easily saves us some allocations for single node.
2020-09-09 20:46:31 +03:00
Roman Khimov
8d19f0e6f5 network: don't request block we already have
GetBlockByIndex handler starts sending blocks right from the start index and
if that index is s.chain.BlockHeight() then we're requesting and receiving a
block we already have.
2020-08-14 16:25:13 +03:00
Roman Khimov
c8cc91eeee network: request blocks when there is a ping with bigger than ours height
Turns out, C# node no longer broadcasts an Inv when it's creating a block,
instead it sends a ping and if we're not paying attention to the height
specified there we're technically missing a new block. Of course we'll get it
later after ping timer expiration and regular ping/pong sequence, but that's
delaying it for no good reason.
2020-08-14 16:22:15 +03:00
Roman Khimov
205f52c563 core: use error wrapping to provide more details 2020-08-07 12:21:52 +03:00
Anna Shaleva
6c8accf18c core, network: request blocks instead of headers
Closes #1192

1. We now have CMDGetBlockByIndex, so there's no need to request headers
   first when we can just ask for blocks.
2. We don't ask for headers (i.e. we don't send CMDGetHeaders),
   consequently, we shouldn't react on CMDHeaders.
3. But we still keep on reacting on CMDGetHeaders command as
   there could be a node which needs headers.
2020-08-04 17:52:34 +03:00
Anna Shaleva
f6f3863e0e network: allow to GetHeaders by index
Use GetBlockByIndex payload for GetHeaders command instead of GetBlocks
payload.
2020-08-04 17:52:34 +03:00
Anna Shaleva
7b1c305000 network: fix handleGetBlockByIndexCmd method
It returned an error in case if block wasn't found (it might be when our
chain is lower). Fixed. It also should return all requested blocks, not
the first one.
2020-08-04 17:52:34 +03:00
Anna Shaleva
0b0591fc34 network: allow to use -1 to specify GetBlockByIndex.Count 2020-08-04 17:52:34 +03:00
Anna Shaleva
737ba700e9 network: rename GetBlockData command
GetBlockData -> GetBlockByIndex
2020-08-04 17:52:34 +03:00
Roman Khimov
432cef59f4 network: copy peers for Shutdown iteration
We can't lock them (or there will be a deadlock), but we need to fix this:

fatal error: concurrent map iteration and map write

goroutine 1 [running]:
runtime.throw(0xdec086, 0x26)
        /usr/lib64/go/1.12/src/runtime/panic.go:617 +0x72 fp=0xc02fec2bf8 sp=0xc02fec2bc8 pc=0x42d932
runtime.mapiternext(0xc02fec2d40)
        /usr/lib64/go/1.12/src/runtime/map.go:860 +0x597 fp=0xc02fec2c80 sp=0xc02fec2bf8 pc=0x40efe7
github.com/nspcc-dev/neo-go/pkg/network.(*Server).Shutdown(0xc0000fc160)
        /home/rik/dev/neo-go2/pkg/network/server.go:194 +0x238 fp=0xc02fec2db0 sp=0xc02fec2c80 pc=0xa89da8
github.com/nspcc-dev/neo-go/cli/server.startServer(0xc0000fcc60, 0x0, 0x0)
        /home/rik/dev/neo-go2/cli/server/server.go:399 +0x7a9 fp=0xc02fec3820 sp=0xc02fec2db0 pc=0xae2079
...
2020-07-17 19:03:12 +03:00
Anna Shaleva
db5b42b601 network: update CMDUncknown
Closes #1135
2020-07-16 06:58:55 +03:00
Evgenii Stratonikov
57bb2f73de network: implement CMDMempool command
CMDMempool returns hashes of transactions in mempool in chunks.
2020-06-24 10:46:26 +03:00
Roman Khimov
bbe174ee4a network: fix inverted logic of address addition to the pool
Fix #1066.
2020-06-18 21:34:45 +03:00
Roman Khimov
b483c38593 block/transaction: add network magic into the hash
We make it explicit in the appropriate Block/Transaction structures, not via a
singleton as C# node does. I think this approach has a bit more potential and
allows better packages reuse for different purposes.
2020-06-18 12:39:50 +03:00
Anna Shaleva
3418e4f7f4 rpc: update getversion RPC-call
closes #1035
2020-06-10 10:47:11 +03:00
Roman Khimov
a446821753
Merge pull request #980 from nspcc-dev/neo3/protocol/version_payload_optimisation
protocol: add node capabilities
2020-05-27 19:13:00 +03:00
Anna Shaleva
7547a3efe1 network: minor code refactoring
We need to handle IPv6 addresses correctly and net.JoinHostPort takes it
into account.
2020-05-27 19:04:09 +03:00
Anna Shaleva
8c5c248e79 protocol: add capabilities to address payload
Part of #871
2020-05-27 19:02:25 +03:00
Anna Shaleva
c590cc02f4 protocol: add capabilities to version payload
closes #871
2020-05-27 19:01:14 +03:00
Roman Khimov
b7d2b659b4 network: get blocks directly from the chain for rebroadcasting
Simplify network<->consensus relations, also broadcast blocks received by
other means like RPC.
2020-05-25 00:27:39 +03:00
Roman Khimov
462022bbdd consensus: remove OnNewBlock(), use Blockchain subscription
Get new blocks directly from the Blockchain. It may lead to some duplications
(as we'll also receive our own blocks), but at the same time it's more
correct, because technically we can also get blocks via other means besides
network server like RPC (submitblock call). And it simplifies network server
at the same time.
2020-05-25 00:27:39 +03:00
Roman Khimov
bd98940a54
Merge pull request #982 from nspcc-dev/neo3/protocol/getblockdata
protocol: implement getblockdata p2p command
2020-05-22 19:28:42 +03:00
Anna Shaleva
8142caaf8b protocol: implement getblockdata p2p command
closes #891
2020-05-22 19:16:49 +03:00
Anna Shaleva
2f6a3e9af5 protocol: refactor getblocks payload
closes #890
2020-05-22 17:33:59 +03:00
Anna Shaleva
64a2fb63e1 protocol: move magic exchange to version payload
closes #889
2020-05-21 14:23:41 +03:00
Anna Shaleva
3bcc56bdcf protocol: switch to binary MessageCommand
closes #888
2020-05-21 13:57:49 +03:00
Anna Shaleva
29d321b5e1 *: drop miner transaction
1. Completely remove miner transaction

2. Change validation rule for block: block without transactions is
valid.
2020-04-27 17:57:37 +03:00
Evgenii Stratonikov
a7c19d445b core: move Blockchainer interface to a separate package 2020-04-11 10:56:36 +03:00
Roman Khimov
e41d434a49 *: move all packages from CityOfZion to nspcc-dev 2020-03-03 17:21:42 +03:00
Evgenii Stratonikov
0ef7a76e84 network: batch transactions on broadcast 2020-03-02 10:37:27 +03:00
Roman Khimov
36197056b1
Merge pull request #691 from nspcc-dev/network-conn-overflow-and-shutdown
Network conn overflow and shutdown
2020-02-28 18:16:29 +03:00
Roman Khimov
e213e69a33 network: rework shutdown sequence of Server
Close transport and disconnect peers right in the Shutdown(), so that no new
connections would be accepted and so that all the peers would be disconnected
correctly (avoiding the same deadlock as in e2116e4c3f).
2020-02-28 16:22:04 +03:00
Roman Khimov
77624a8847 network: add Close() to discoverer, shut it down on exit 2020-02-28 16:22:04 +03:00
Roman Khimov
e2116e4c3f network: don't deadlock on connection overflow
(*Peer).Disconnect send an unregister signal to this goroutine, so invoking it
from here is not a good idea, run it asynchronously.
2020-02-24 15:56:49 +03:00
Roman Khimov
723b33e108 network: implement unconnected/bad peers getters
Which allows node to respond to `getpeers` RPC request correctly.
2020-02-21 15:12:03 +03:00
Roman Khimov
d92e193e63 rpc/network: refactor getpeers logic
Deduplicate and simplify code.
2020-02-21 15:12:03 +03:00
Roman Khimov
eb11e5fb11 core: implement basic policying support, fix #370
Implement mempool and consensus block creation policies, almost the same as
SimplePolicy plugin for C# node provides with two caveats:
 * HighPriorityTxType is not configured and hardcoded to ClaimType
 * BlockedAccounts are not supported

Other than that it allows us to run successfuly as testnet CN, previously our
proposals were rejected because we were proposing blocks with oversized
transactions (that are rejected by PoolTx() now).

Mainnet and testnet configuration files are updated accordingly, but privnet
is left as is with no limits.

Configuration is currently attached to the Blockchain and so is the code that
does policying, it may be moved somewhere in the future, but it works for
now.
2020-02-19 12:19:02 +03:00
Roman Khimov
37c48b00b4 consensus/network: reinit dbft after block addition
Don't stall on some height if everyone else have moved up already. Fix #673.
2020-02-19 12:19:02 +03:00
Roman Khimov
c5d54e9992 network: introduce (*Server).IsInSync, start consensus in synced state
We define synchronized state as a combination of minimum number of peers and
chain height being not behind of more than 2/3 of these peers.
2020-02-19 12:13:27 +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
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
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
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
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
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
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
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
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
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
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
bb80ba9b9e
Merge pull request #456 from nspcc-dev/pingpong_430
add ping pong processing
2020-01-20 16:10:29 +03:00
Vsevolod Brekelov
4e6ed9021c network: add ping pong processing
add pingInterval same as used in ref C# implementation with the same logic
add pingTimeout which is used to check whether pong received. If not -- drop the peer.
add pingLimit which is hardcoded to 4 in TCPPeer. It's limit for unsuccessful ping/pong calls (where pong wasn't received in pingTimeout interval)
2020-01-17 13:24:14 +03:00
Evgenii Stratonikov
fed6fba9b6 core: refactor out MemPool 2020-01-16 10:16:24 +03:00
Evgenii Stratonikov
63c56cca5c core: refactor out Block, BlockBase and Header structs
See #597.
2020-01-16 10:16:24 +03:00
Roman Khimov
7d4d57351e network: fix requestTx() behaviour for consensus service
It wasn't actually requesting transactions but rather sending an inventory
message telling everyone that we have them which is completely wrong and
easily leads to ChangeView that could be avoided.
2020-01-15 14:31:56 +03:00
Roman Khimov
0420d48e56 network: micro-optimize relayInventory
Do less allocations, we're sending the same message with the same payload.
2020-01-15 13:16:09 +03:00
Evgenii Stratonikov
70b23076f8 network: allow single-node privnet setup 2020-01-13 18:01:20 +03:00
Evgenii Stratonikov
5f5d0097e2 network: use TimePerBlock from config 2020-01-13 17:58:12 +03:00
Evgenii Stratonikov
aecdf470e7 cli,pkg: use zap.Logger 2020-01-10 11:14:27 +03:00
Roman Khimov
234d94d27e network: implement getblocks command
Fixes #577, tested with C# nodes connecting to neo-go privnet.
2019-12-25 19:46:57 +03:00
Roman Khimov
abc0ec33bd
Merge pull request #532 from nspcc-dev/fix/peer_count
Consensus fixes.
2019-12-02 18:08:36 +03:00
Evgenii Stratonikov
7c900edd2d network: count only handshaked peers as connected 2019-12-02 15:09:09 +03:00
Roman Khimov
1da76a8eb4 network: rework inventory handling, check for item presence
Don't ask peers about the items we already have.
2019-12-02 11:02:52 +03:00
Roman Khimov
b4d9935bda network: deduplicate a part of RelayTxn()
We already have relayInventory() for this.
2019-11-29 16:26:44 +03:00
Roman Khimov
293615ea5f network/consensus: add new block relaying
Tell everyone about our new shiny blocks.
2019-11-29 12:27:15 +03:00
Roman Khimov
4d286dcfeb network: check height before requesting headers
Only request headers from the other peer if his height is bigger than
ours. Otherwise we routinely ask 0-height newcomers for some random headers
that they know nothing about.
2019-11-29 11:48:17 +03:00
Roman Khimov
a730529b0c network: process incoming p2p transactions
It's the same relaying as for RPC, but we don't need to return any result for
it.
2019-11-29 11:09:54 +03:00
Roman Khimov
9f9cf4ae3f network: add getheaders message processing
This one is essential for the consensus nodes as otherwise they won't give out
the blocks they generate making their generation almost useless. It also makes
our networking part more complete.
2019-11-29 11:08:22 +03:00
Roman Khimov
734338ad70 network: move Version sending to the tcp transport
We have a race between reader and writer goroutines for the same connection
that leads to handshake failures when reader is faster to read the incoming
version (and try to reply to it) than writer is to write our own Version:

WARN[0000] peer disconnected                             addr="172.200.0.4:20334" peerCount=5 reason="invalid handshake: tried to send VersionAck, but didn't send Version yet

Fix it by moving Version sending before the reader loop starts.
2019-11-29 11:05:42 +03:00
Evgenii Stratonikov
b5fb43bac9 network: don't reconnect to peers with identical ID 2019-11-27 11:58:17 +03:00
Evgenii Stratonikov
fdd5276d3e network: plug in dBFT library 2019-11-27 10:57:22 +03:00
Evgeniy Kulikov
0a56d3ddbc
network: generate randomized server id
math/rand might generate same id's on one environment, so.. use crypto/rand for generation id's
2019-11-18 17:17:21 +03:00
Evgenii Stratonikov
085ca7b770 network: implement Consensus payloads 2019-11-13 17:27:25 +03:00
Vsevolod Brekelov
11ce73af28 server: add log-path and address configuration
- LogPath can be configured through config
- node,rpc and monitoring address can be configured thought command line
or config
2019-11-06 15:58:54 +03:00
Roman Khimov
7cf9a40468 network: fix MaxPeers, introduce AttemptConnPeers
Our node didn't respect the MaxPeers setting, fix it with a drop of random
connection when this limit is reached (to give a chance for newcomers to
communicate), but also introduce AttemptConnPeers setting to tune the number
of attempted connections.

This also raises the default MaxPeers for testnet/mainnet to 100, because
neo-go nodes love making friends.
2019-11-06 15:29:58 +03:00
Roman Khimov
31954bb20c network: disallow double connections to the same peer
Makes no sense and C# node does it too.
2019-11-06 15:29:58 +03:00
Roman Khimov
d5a7ad2c47 network: fix data race in server peers map access 2019-11-06 15:29:58 +03:00