Commit Graph

472 Commits

Author SHA1 Message Date
KonradStaniec aa3fbbd95d
Add proof verification to public api (#390) 2021-08-12 16:15:02 +02:00
Jamie Lokier 83e5638212 Add option to `connectToNetwork` return without waiting for peers
The new sync code wants to start without waiting.  We can `discard` the async
result but there is no need for a background task polling and running a timer
for no clear benefit.

Signed-off-by: Jamie Lokier <jamie@shareable.org>
2021-08-10 14:09:57 +03:00
Jamie Lokier 9a28ed7ef5 RLPx: Protocol names have never been limited to 3 characters
Don't treat 3 characters as special in `cmp`.  `cmp` for `ProtocolInfo` was
wrong because it ignored all characters after the first 3.

In the wild we have seen protocol names longer than 3 characters.  `snap`,
`hive`, `istanbul`, `bzzeth`, `bzz-stream`, `bzz-retrieve`, `dbix`, `opera`,
`pchain`, `pchain_child_0`, `sero`, `smilobft`, `spock`.

There was never a 3 character limit in the [specification]
(https://github.com/ethereum/devp2p/blob/master/rlpx.md).

It always said "short ASCII name", until recently on 2021-02-25 it was changed
to an 8 characters limit.

Also `pi.nameStr` can be removed.  Nothing uses it, and it has the same actual
effect as just copying the string `pi.name`.

Signed-off-by: Jamie Lokier <jamie@shareable.org>
2021-08-10 14:08:35 +03:00
Jamie Lokier 5234e30f8b Remove `{.rlpInline.}` which was never really implemented
For a long time this caused invalid RLP parsing of `NewBlock` messages in the
`eth` protocol.

The `rlpInline` pragma was accepted but had no effect.  We could implemented
it, but it doesn't seem worth doing, with tests etc, as there's only one user
which has been fixed another way.

With `NewBlock`, whenever a peer sent us `NewBlock`, we'd get an RLP decoding
error, and disconnected the peer thinking it was the peer's error.

These messages are sent often by good peers, so whenever we connected to a
really good peer, we'd end up disconnecting within a minute due to this.  This
went unnoticed for years, as we stayed connected to old peers which have no new
blocks, and we weren't looking at peer quality, disconnect reasons or real-time
blockchain updates anyway.

Signed-off-by: Jamie Lokier <jamie@shareable.org>
2021-08-10 14:08:35 +03:00
KonradStaniec 50c0c5f123
Add helpers to generate merkle proofs (#381) 2021-08-09 12:17:21 +02:00
Kim De Mey 9bc4fa366a
Let talkreq directly return the seq[byte] for easier API (#384) 2021-07-30 16:04:14 +02:00
Kim De Mey dd02d1be23
Remove unused lastUpdated from buckets (#382) 2021-07-29 21:58:10 +02:00
Jamie Lokier 04ff8e460f Fix RLP serialisation of `seq[Transaction]` used in `eth` protocol
1. Generalises the special cases for serialising RLP `seq[Transaction]`.
   Previously it only used the special case inside `BlockBody` and `EthBlock`.
   Now it uses it for all `seq[Transaction]` regardless of what objects they
   are parts of, or no object at all.  `openArray[Transaction]` is also
   included, as this was found to be necessary to match in some places.

2. Bug fix parsing `Transaction`: Always read the first byte to get the
   transaction type instead of parsing an RLP `int`.  This way invalid or
   adversarial input gives a correct error (i.e. invalid type code).

   When it was read with `rlp.read(int)`, those inputs gave many crazy
   messages (e.g. "too large to fit in memory").  In the specification it's a
   byte.  (Technically the input is not RLP and we shouldn't be using the RLP
   parser anyway to parse standalone transaction objects).

3. Bug fix parsing `Transaction`: If a typed transaction is detected in
   `seq[Transaction]`, the previous code removed the RLP (blob) wrapper, then
   passed the contents to `read(Transaction)`.  That meant a blob-wrapped
   legacy transaction would be accepted.  This is incorrect.  The new code
   passes the contents to the typed transaction decoder, which correctly
   rejects a wrapped legacy transaction as having invalid type.

Change 1 has a large, practical effect on `eth/65` syncing with peers.

Serialisation of `eth` message types `Transactions` and `PooledTransactions`
have been broken since the introduction of typed transactions (EIP-2718), as
used in Berlin/London forks.  (The special case for `seq[Transaction]` inside
`BlockBody` only fixed message type `BlockBodies`.)

Due to this, whenever a peer sent us a `Transactions` message, we had an RLP
decoding error processing it, and disconnected the peer thinking it was the
peer's error.

These messages are sent often by good peers, so whenever we connected to a
really good peer, we'd end up disconnecting from it within a few tens of
seconds due to this.

This didn't get noticed before updating to `eth/65`, because with old protocols
we tend to only connect to old peers, which may be out of date themselves and
have no typed transactions.  Also, we didn't really investigate occasional
disconnects before, we assumed they're just part of P2P life.

The root cause is the RLP serialisation of individual `Transaction` is meant to
be subtly different from arrays/sequences of `Transaction` objects in network
messages.  RFC-2976 covers this but it's quite subtle:

- Individual transactions are encoded and stored as either `RLP([fields..])`
  for legacy transactions, or `Type || RLP([fields..])`.  Both of these
  encodings are byte sequences.  The part after `Type` doesn't have to be
  RLP in theory, but all types so far use RLP.  EIP-2718 covers this.

- In arrays (sequences), transactions are encoded as either `RLP([fields..])`
  for legacy transactions, or `RLP(Type || RLP([fields..]))` for all typed
  transactions to date.  Spot the extra `RLP(..)` blob encoding, to make it
  valid RLP inside a larger RLP.  EIP-2976 covers this, "Typed Transactions
  over Gossip", although it's not very clear about the blob encoding.

In practice the extra `RLP(..)` applies to all arrays/sequences of transactions
that are to be RLP-encoded as a list.  In principle, it should be all
aggregates (object fields etc.), but it's enough for us to enable it for all
arrays/sequences, as this is what's used in the protocol and EIP-2976.

Signed-off-by: Jamie Lokier <jamie@shareable.org>
2021-07-29 15:37:11 +03:00
KonradStaniec e3fba48f0f
add merkle proof verification (#379)
* add merkle proof verification

* remove redundant buffer

* simplify verification function
2021-07-23 13:40:47 +02:00
KonradStaniec 20ad6504b7
Add merkleization tests (#378)
* Add merkleization tests

* Fix typo in build file

* add test prefix
2021-07-21 09:24:07 +02:00
KonradStaniec 44fee391f4
Port merkleization off ssz (#376) 2021-07-19 15:58:09 +02:00
Kim De Mey a8d11dd30b
Add top level push raises Defect to p2p code (#374) 2021-07-16 21:44:30 +02:00
Kim De Mey 2557fd35c6
Use aesKeySize const for aes key instead if ivSize (same values) (#375) 2021-07-16 14:55:52 +02:00
Kim De Mey eb0908e33f
Push raises Defect to rlpx and accompanying changes (#373) 2021-07-14 10:35:35 +02:00
Kim De Mey 79911ed5d8
Log distance to uint16 and add public neighbours calls (#371)
* Use uint16 instead of uint32 for discv5 log distance

* Make neighboursAtDistances and neighbours calls available
2021-07-13 10:05:46 +02:00
Kim De Mey 41127eaee8
Remove portal wire code which was moved to nimbus-eth1 repo (#370) 2021-07-09 22:14:31 +02:00
Ștefan Talpalaru 2dfd352fd0 metrics: initialise lock for custom collector 2021-07-06 17:46:23 +03:00
jangko a10d301085
implement EIP-1559 Transaction and BlockHeader 2021-06-27 20:12:47 +07:00
kdeme 1c400e3f0e
Improve Portal message tracing 2021-06-09 14:57:35 +02:00
kdeme 880b753ad2
Add Portal wire readme doc 2021-06-09 14:57:35 +02:00
kdeme e2e30247bf
Add implementation of Portal wire protocol 2021-06-09 14:57:30 +02:00
Kim De Mey d18ebaa570
Slightly improved logging traces for error on message responses (#364) 2021-06-09 14:55:00 +02:00
Jacek Sieka 3514ee6484
sqlite: quick exec with result (#361) 2021-05-27 11:31:34 +02:00
Jacek Sieka 68e6aadc29 sqlite3: support option type
.. and any integer when writing but don't support int32 on reads -
internally sqlite will truncate on overflow which isn't nice.
2021-05-26 13:32:31 +03:00
Jacek Sieka 2a292cfb62
sqlite: fix readonly mode (#359)
* sqlite: fix readonly mode

* document kvstore versions
2021-05-25 20:57:28 +02:00
Kim De Mey 8abe6b7144
Add support for discv5 talk protocols (#357) 2021-05-20 09:49:46 +02:00
Jacek Sieka 1995afb87e
kvstore fixes (#350)
Storing large blobs in a "WITHOUT ROWID" table turns out to be extremely
slow when the tree must be rebalanced.

* Split out keystore capability into separate interface, making each
keystore a separate instance
* Disable "WITHOUT ROWID" optimization by default
* Implement prefix lookup that allows iterating over all values with a
certain prefix in their key
2021-05-17 15:55:57 +02:00
jangko ea8530f6a0
EIP-2718: fixes BlockBody rlp encoding 2021-05-17 10:07:05 +07:00
jangko d0eb2de328
eip2718: protect against malformed rlp in tx sequence decoder 2021-05-16 19:15:48 +07:00
jangko ef49a6f50a
fixes EIP2718/EIP2930 misinterpretation
the new Tx format (txType || txPayload) needs envelope
encoding at EthBlock level, not at the Tx level itself.
2021-05-16 12:10:09 +07:00
jangko 343d4f25e1
fix eip2718 bug
- fixes bug in rlp decoder of Receipt
- fixes bug in rlp decoder of Transaction
- refactor rlpEncode for AccessListTx in eth/common/transaction.nim
2021-05-15 14:34:43 +07:00
jangko b6b6f3dec7
implement txHashNoSignature for EIP2817's AccessListTx 2021-05-15 08:18:19 +07:00
jangko 61d5327f55
implement eip2718: transaction type envelope
also add more test cases for both tx and receipt
rlp encoding decoding
2021-05-15 08:18:08 +07:00
Jacek Sieka 8890175b6a remove WITHOUT ROWID
This is a minimal performance hotfix for storing large blobs in kvstore
2021-05-14 20:04:14 +03:00
Kim De Mey d05cb5d3bd
Fix raw Exceptions in hexary caused by forward declarations (#349)
* Fix raw Exceptions in hexary caused by forward declarations

* Fix raw Exceptions in trie/db caused by forward declarations

* And now we can remove those db Proc CatchableError raises
2021-05-11 17:32:47 +02:00
kdeme 00a45a7b91
Remove inline pragmas 2021-05-11 09:59:58 +02:00
kdeme 81f0a56ebd
Add/update bunch of license headers 2021-05-11 09:37:33 +02:00
kdeme 755729c6a1
Fix several compiler warnings
Mostly replacing deprecated calls
2021-05-11 09:24:23 +02:00
kdeme bcb58216d1
Add CatchableErrors where needed because of db backends used
In nim-eth this will not fail, as they are base, not implemented
methods. In for example Nimbus-eth1 it will.
2021-05-07 16:28:48 +02:00
kdeme 90b4724492
Adjust for chronosStrictException usage in rest of eth/p2p 2021-05-06 17:20:54 +02:00
kdeme e10ef19f81
Move push raises to top and add/update license info where needed 2021-04-28 16:20:05 +02:00
kdeme b0474c0d40
Add raises annotations to discovery.nim
And add push raises Defect, remove unneeded gcsafe and remove
all usage of inline.
2021-04-27 21:11:54 +02:00
kdeme a1da5d5e59
Use asyncSpawn instead of asyncCheck so chronos strict makes sense
And additional cleanup:
- Push raises Defect at top
- remove inlines
- remove unneeded gcsafe
- remove usage of deprecated calls
2021-04-27 11:30:08 +02:00
kdeme 9fed10de88
Allow for discv4 chronos strict usage
And group p2p tests that can be run with strict usage along the way.
2021-04-27 10:09:54 +02:00
Jamie Lokier 0f3bb61678
Fix import syntax error in `les_protocol.nim` added by PR #344
`les_protocol.nim` failed to build, due to very silly Nim bugs
nim-lang/Nim#8792 and nim-lang/Nim#17102.

    import
      ../../[rlp, keys], ../../common/eth_types,
      ../[rlpx, kademlia, blockchain_utils], ../private/p2p_types,

The silly part is `../` has to be quoted if it's before a group of files, but
not before a single file.  Most places in PR #344 / 7624153 use the workaround
`".."/` but it was missed in `les_protocol.nim`:

    nimbus-eth1/vendor/nim-eth/eth/p2p/rlpx_protocols/les_protocol.nim(14, 3)
        Error: cannot open file: ../../[rlp,keys]

Signed-off-by: Jamie Lokier <jamie@shareable.org>
2021-04-07 18:07:00 +01:00
Jamie Lokier 209171d97d
discv4: Refactor findNode so it can be called directly from a test
Signed-off-by: Jamie Lokier <jamie@shareable.org>
2021-04-06 18:41:47 +01:00
Kim De Mey 762415319c
Add build_dcli target and add it to CI (#344)
* Add build_dcli target and add it to CI

* Fix local imports for dcli

* And use local imports for all other files too

* Use local imports in tests and rlpx protocols
2021-04-06 13:33:24 +02:00
Jamie Lokier e4b4b7f4af
discv4: Fix Kademlia crash when trying to sync (#342)
Fixes status-im/nim-eth#341, status-im/nimbus-eth1#489.

When using discv4 (Kademlia) to find peers, there is a crash after a few
minutes.  It occurs for most of us on Eth1 mainnet, and everyone on Ropsten.

The cause is `findNodes` being called twice in succession to the same peer,
within about 5 seconds of each other.  ("About" 5 seconds, because Chronos does
not guarantee to run the timeout branch at a particular time, due to queuing
and clock reading delays.)

Then `findNodes` sends a duplicate message to the peer and calls
`waitNeighbours` to listen for the reply.  There's already a `waitNeighbours`
callback in a shared table, so that function hits an assert failure.

Ignoring the assert would be wrong as it would break timeout logic, and sending
`FindNodes` twice in rapid succession also makes us a bad peer.

As a simple workaround, just skip `findNodes` in this state and return a fake
empty `Neighbours` reply.  This is a bit of a hack as `findNodes` should not be
called like this; there's a logic error at a higher level.  But it works.

Tested for about 4 days constant operation on Ropsten.  The crash which occured
every few minutes no longer occurs, and discv4 keeps working.

Signed-off-by: Jamie Lokier <jamie@shareable.org>
2021-04-02 23:29:02 +02:00
Kim De Mey c5dace27ca
Use chronos http server for dcli metrics and remove insecure compile flag (#343)
And add cfg file to default have runtime log filtering on
2021-04-02 17:29:38 +02:00
Kim De Mey ae4177851f
Remove no longer needed try/except (#339) 2021-03-26 17:49:03 +01:00