Commit graph

133 commits

Author SHA1 Message Date
Anna Shaleva
9cf6cc61f4 network: allow multiple bind addresses for server
And replace Transporter.Address() with Transporter.HostPort() along the way.
2022-12-07 13:06:03 +03:00
Roman Khimov
23f118a1a9 network: rework discoverer/server interaction
* treat connected/handshaked peers separately in the discoverer, save
   "original" address for connected ones, it can be a name instead of IP and
   it's important to keep it to avoid reconnections
 * store name->IP mapping for seeds if and when they're connected to avoid
   reconnections
 * block seed if it's detected to be our own node (which is often the case for
   small private networks)
 * add an event for handshaked peers in the server, connected but
   non-handshaked ones are not really helpful for MinPeers or GetAddr logic

Fixes #2796.
2022-11-17 17:07:19 +03:00
Roman Khimov
cfb5058018 network: batch getdata replies
This is not exactly the protocol-level batching as was tried in #1770 and
proposed by neo-project/neo#2365, but it's a TCP-level change in that we now
Write() a set of messages and given that Go sets up TCP sockets with
TCP_NODELAY by default this is a substantial change, we have less packets
generated with the same amount of data. It doesn't change anything on properly
connected networks, but the ones with delays benefit from it a lot.

This also improves queueing because we no longer generate 32 messages to
deliver on transaction's GetData, it's just one stream of bytes with 32
messages inside.

Do the same with GetBlocksByIndex, we can have a lot of messages there too.

But don't forget about potential peer DoS attacks, if a peer is to request a
lot of big blocks we need to flush them before we process the whole set.
2022-10-21 17:16:32 +03:00
Roman Khimov
dce9f80585
Merge pull request #2743 from nspcc-dev/log-fan-out
Logarithmic gossip fan out
2022-10-14 23:18:34 +07:00
Roman Khimov
851cbc7dab network: implement adaptive peer requests
When the network is big enough, MinPeers may be suboptimal for good network
connectivity, but if we know the network size we can do some estimation on the
number of sufficient peers.
2022-10-14 15:53:32 +03:00
Roman Khimov
215e8704f1 network: simplify discoverer, make it almost a lib
We already have two basic lists: connected and unconnected nodes, we don't
need an additional channel and we don't need a goroutine to handle it.
2022-10-14 15:53:32 +03:00
Roman Khimov
631f166709 network: broadcast to log-dependent number of nodes
Fixes #608.
2022-10-14 14:12:33 +03:00
Roman Khimov
bcf77c3c42 network: filter out not-yet-ready nodes when broadcasting
They can fail right in the getPeers or they can fail later when packet send
is attempted. Of course they can complete handshake in-between these events,
but most likely they won't and we'll waste more resources on this attempt. So
rule out bad peers immediately.
2022-10-12 16:51:01 +03:00
Roman Khimov
104da8caff network: broadcast messages, enqueue packets
Drop EnqueueP2PPacket, replace EnqueueHPPacket with EnqueueHPMessage. We use
Enqueue* when we have a specific per-peer message, it makes zero sense
duplicating serialization code for it (unlike Broadcast*).
2022-10-12 15:39:20 +03:00
Roman Khimov
b345581c72 network: pings are broadcasted, don't send them to everyone
Follow the general rules of broadcasts, even though it's somewhat different
from Inv, we just want to get some reply from our neighbors to see if we're
behind. We don't strictly need all neighbors for it.
2022-10-12 15:25:03 +03:00
Roman Khimov
e80c60a3b9 network: rework broadcast logic
We have a number of queues for different purposes:
 * regular broadcast queue
 * direct p2p queue
 * high-priority queue

And two basic egress scenarios:
 * direct p2p messages (replies to requests in Server's handle* methods)
 * broadcasted messages

Low priority broadcasted messages:
 * transaction inventories
 * block inventories
 * notary inventories
 * non-consensus extensibles

High-priority broadcasted messages:
 * consensus extensibles
 * getdata transaction requests from consensus process
 * getaddr requests

P2P messages are a bit more complicated, most of the time they use p2p queue,
but extensible message requests/replies use HP queue.

Server's handle* code is run from Peer's handleIncoming, every peer has this
thread that handles incoming messages. When working with the peer it's
important to reply to requests and blocking this thread until we send (queue)
a reply is fine, if the peer is slow we just won't get anything new from
it. The queue used is irrelevant wrt this issue.

Broadcasted messages are radically different, we want them to be delivered to
many peers, but we don't care about specific ones. If it's delivered to 2/3 of
the peers we're fine, if it's delivered to more of them --- it's not an
issue. But doing this fairly is not an easy thing, current code tries performing
unblocked sends and if this doesn't yield enough results it then blocks (but
has a timeout, we can't wait indefinitely). But it does so in sequential
manner, once the peer is chosen the code will wait for it (and only it) until
timeout happens.

What can be done instead is an attempt to push the message to all of the peers
simultaneously (or close to that). If they all deliver --- OK, if some block
and wait then we can wait until _any_ of them pushes the message through (or
global timeout happens, we still can't wait forever). If we have enough
deliveries then we can cancel pending ones and it's again not an error if
these canceled threads still do their job.

This makes the system more dynamic and adds some substantial processing
overhead, but it's a networking code, any of this overhead is much lower than
the actual packet delivery time. It also allows to spread the load more
fairly, if there is any spare queue it'll get the packet and release the
broadcaster. On the next broadcast iteration another peer is more likely to be
chosen just because it didn't get a message previously (and had some time to
deliver already queued messages).

It works perfectly in tests, with optimal networking conditions we have much
better block times and TPS increases by 5-25%% depending on the scenario.

I'd go as far as to say that it fixes the original problem of #2678, because
in this particular scenario we have empty queues in ~100% of the cases and
this new logic will likely lead to 100% fan out in this case (cancelation just
won't happen fast enough). But when the load grows and there is some waiting
in the queue it will optimize out the slowest links.
2022-10-11 18:42:40 +03:00
Roman Khimov
9b0ea2c21b network/consensus: always process dBFT messages as high priority
Move category definition from consensus to payload, consensus service is the
one of its kind (HP), so network.Server can be adjusted accordingly.
2022-08-02 13:07:18 +03:00
Roman Khimov
5a7fa2d3df cli: restart consensus service on USR2
Fix #1949. Also drop wallet from the ServerConfig since it's not used in any
meaningful way after this change.
2022-08-02 13:05:07 +03:00
Roman Khimov
bf1604454c blockchainer/network: move StateSync interface to the user
Only network package cares about it.
2022-01-14 19:57:14 +03:00
Roman Khimov
508d36f698 network: drop consensus dependency 2022-01-14 19:55:53 +03:00
Anna Shaleva
6357af0bb0 network: fix race in TestHandleGetMPTData
Init server config before server start. Fixes the following data race:

```
WARNING: DATA RACE
Write at 0x00c00032ef20 by goroutine 26:
  github.com/nspcc-dev/neo-go/pkg/network.TestHandleGetMPTData.func2()
      /go/src/github.com/nspcc-dev/neo-go/pkg/network/server_test.go:755 +0x10a
  testing.tRunner()
      /usr/local/go/src/testing/testing.go:1193 +0x202

Previous read at 0x00c00032ef20 by goroutine 24:
  github.com/nspcc-dev/neo-go/internal/fakechain.(*FakeChain).GetConfig()
      /go/src/github.com/nspcc-dev/neo-go/internal/fakechain/fakechain.go:167 +0x6f
  github.com/nspcc-dev/neo-go/pkg/network.(*Server).initStaleMemPools()
      /go/src/github.com/nspcc-dev/neo-go/pkg/network/server.go:1433 +0x89
  github.com/nspcc-dev/neo-go/pkg/network.(*Server).Start()
      /go/src/github.com/nspcc-dev/neo-go/pkg/network/server.go:284 +0x288
  github.com/nspcc-dev/neo-go/pkg/network.startWithChannel.func1()
      /go/src/github.com/nspcc-dev/neo-go/pkg/network/server_test.go:91 +0x44

Goroutine 26 (running) created at:
  testing.(*T).Run()
      /usr/local/go/src/testing/testing.go:1238 +0x5d7
  github.com/nspcc-dev/neo-go/pkg/network.TestHandleGetMPTData()
      /go/src/github.com/nspcc-dev/neo-go/pkg/network/server_test.go:752 +0x8c
  testing.tRunner()
      /usr/local/go/src/testing/testing.go:1193 +0x202

Goroutine 24 (running) created at:
  github.com/nspcc-dev/neo-go/pkg/network.startWithChannel()
      /go/src/github.com/nspcc-dev/neo-go/pkg/network/server_test.go:90 +0x78
  github.com/nspcc-dev/neo-go/pkg/network.startTestServer()
      /go/src/github.com/nspcc-dev/neo-go/pkg/network/server_test.go:384 +0xbd
  github.com/nspcc-dev/neo-go/pkg/network.TestHandleGetMPTData.func2()
      /go/src/github.com/nspcc-dev/neo-go/pkg/network/server_test.go:753 +0x55
  testing.tRunner()
      /usr/local/go/src/testing/testing.go:1193 +0x202
```
2021-09-13 11:45:48 +03:00
Roman Khimov
601841ef35 *: drop unused structure fields
Found by structcheck:
 `good` is unused (structcheck)
and alike.
2021-05-12 19:41:23 +03:00
Roman Khimov
0888cf9ed2 network: drop Network from Message
It's not used any more.
2021-03-26 13:45:18 +03:00
Anna Shaleva
2c81fc8b8e *: upgrade tests to use T.Cleanup() 2021-03-01 17:08:00 +03:00
Anna Shaleva
4ad9c7929b internals: move testchain from network to internals
It'll be useful for tests outside of the network pkg.
2021-02-02 22:01:32 +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
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
Roman Khimov
dee97d8542
Merge pull request #1524 from nspcc-dev/rpc/invoke_verify
rpc: add `invokecontractverify` RPC-method
2020-12-21 10:36:54 +03:00
Evgenii Stratonikov
62da365302 native: allow to modify StoragePrice in the policy contract 2020-12-16 13:55:40 +03:00
Evgenii Stratonikov
1840c1c80d core: redefine opcode prices
Prices are defined in as a coefficients to `BaseExecFee` which
is defined by Policy contract (TBD later).
Native method prices are defined without need to multiply.
2020-12-16 13:55:39 +03:00
Anna Shaleva
da5eb67e85 rpc: implement invokecontractverify RPC method 2020-12-15 15:53:36 +03:00
Roman Khimov
ab12eee346 native: move contract deployment to management contract
See neo-project/neo#2119.
2020-12-14 15:23:46 +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
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
31eca342eb *: replace all NEP5 occurences to NEP17 2020-11-24 13:08:24 +03:00
Evgenii Stratonikov
a5914f89fa core: allow to provide block in GetTestVM()
Sometimes amount of GAS consumed depends on block height.
2020-11-24 12:17:29 +03:00
Evgenii Stratonikov
e38e8aa48a rpc: implement getproof RPC 2020-11-20 18:06:22 +03:00
Anna Shaleva
7ca93e76ac core, rpc: allow to store several AppExecResult for a single hash
It is required for we have several executions per block.
2020-11-12 16:24:39 +03:00
Evgenii Stratonikov
54992ad4f3 core: provide account in calculate claimable
`getunclaimedgas` RPC should return all GAS available to claim.
2020-11-10 16:08:21 +03:00
Anna Shaleva
15a939b1da rpc: allow to getcontractstate by address, id or name
close #1423
2020-11-03 17:23:49 +03:00
Anna Shaleva
ec63d5c456 core: add conflicts attribute
Close #1491
2020-10-29 10:57:31 +03:00
Roman Khimov
e4b52d3947 core/rpc: add continue flag to iterating functions
Most of the time we don't need to get all transfers from the DB and
deserialize them.
2020-09-21 22:23:34 +03:00
Anna Shaleva
770c8d774c core, rpc: add GetCommittee method
Closes #1414
2020-09-21 15:56:25 +03:00
Evgenii Stratonikov
7e34072519 core: implement (*Blockchain).VerifyWitness
`ScriptFromWitness` is no longer useful, because we support
contract verification.
2020-08-22 12:45:20 +03:00
Roman Khimov
55b2cbb74d core: refactor and improve verification and pooling
Now we have VerifyTx() and PoolTx() APIs that either verify transaction in
isolation or verify it against the mempool (either the primary one or the one
given) and then add it there. There is no possibility to check against the
mempool, but not add a transaction to it, but I doubt we really need it.

It allows to remove some duplication between old PoolTx and verifyTx where
they both tried to check transaction against mempool (verifying first and then
adding it). It also saves us utility token balance check because it's done by
the mempool anyway and we no longer need to do that explicitly in verifyTx.

It makes AddBlock() and verifyBlock() transaction's checks more correct,
because previously they could miss that even though sender S has enough
balance to pay for A, B or C, he can't pay for all of them.

Caveats:
 * consensus is running concurrently to other processes, so things could
   change while verifyBlock() is iterating over transactions, this will be
   mitigated in subsequent commits

Improves TPS value for single node by at least 11%.

Fixes #667, fixes #668.
2020-08-20 18:50:18 +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
b1034d8ed6 state: drop Neo 2 Account and everything related
It's substituted with NEP5Balances now.
2020-08-11 20:42:02 +03:00
Evgenii Stratonikov
807338f97e core: do not store NEP5 transfer log in memory
Traversing transfer log instead of accumulating and returning it
is faster and takes less memory.
2020-08-07 18:21:06 +03:00
Roman Khimov
c3c88a57cd
Merge pull request #1281 from nspcc-dev/drop-go-1.12-and-fix-some-things
Drop go 1.12 and fix some things
2020-08-07 13:34:54 +03:00
Roman Khimov
791c983304 core: drop GetScriptHashesForVerifying
It no longer depends on blockchain state and there can't ever be an error, in
fact we can always iterate over signers, so copying these hashes doesn't make
much sense at all as well as sorting arrays in verifyTxWitnesses (witnesses
order must match signers order).
2020-08-07 12:21:52 +03:00
Evgenii Stratonikov
27169d140f core: implement (*Blockchain).GetStandByCommitee() 2020-08-06 20:39:13 +03:00