Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Known issue: orphan state witness #15

Closed
pugachAG opened this issue Feb 14, 2024 · 0 comments · Fixed by near/nearcore#10613
Closed

Known issue: orphan state witness #15

pugachAG opened this issue Feb 14, 2024 · 0 comments · Fixed by near/nearcore#10613

Comments

@pugachAG
Copy link

Bug Report

Overview

Currently we don't properly handle the case when state witness arrives before the parent block.
For more information see near/nearcore#10552

Impact

This results in chunk validator not sending endorsement to block producer which could cause chunk not to be included in the block.

github-merge-queue bot pushed a commit to near/nearcore that referenced this issue Feb 23, 2024
### Description
This PR adds a pool for orphaned `ChunkStateWitnesses`.
To process a `ChunkStateWitness` we need the previous block, but
sometimes it isn't available immediately. The node might receive a
`ChunkStateWitness` before the block that's required to process it. In
such cases the witness becomes an "orphaned chunk state witness" and
it's put in `OrphanChunkStateWitnessPool`, where it waits for the
desired block to appear. Once a new block is accepted, we fetch all
orphaned witnesses that were waiting for this block from the pool and
process them.

### Design of `OrphanStateWitnessPool`

`OrphanStateWitnessPool` keeps a cache which maps `shard_id` and
`height` to an orphan `ChunkStateWitness` with these parameters:
```rust
witness_cache: LruCache<(ShardId, BlockHeight), ChunkStateWitness>,
```

All `ChunkStateWitnesses` go through basic validation before being put
in the orphan cache.
* The signature is checked to make sure that this witness really comes
from the right chunk producer that should produce a witness at this
height and shard_id.
* Client keeps only witnesses which are within 5 blocks of the current
chain head to prevent spam attacks. Without this limitation a single
malicious chunk producer could fill the whole cache with their fake
witnesses.
* There's also a limitation on witness size to limit the amount of
memory consumed by the pool. During StatelessNet loadtests performed by
`@staffik` and `@Longarithm` the observed `ChunkStateWitness` sIze was
16-32MB, so a 40MB limit should be alright. This PR only limits the size
of orphaned witnesses, limiting the size of non-orphan witnesses is much
more tricky, see the discussion in
#10615.

It's impossible to fully validate an orphaned witness, but this partial
validation should be enough to protect against attacks on the orphan
pool.

Under normal circumstances there should be only a few orphaned witnesses
per shard. If the node has fallen behind by more than a few blocks, it
has to catch up and its chunk endorsements don't matter.
The default cache capacity is set to 25 witnesses. With 5 shards it
provides capacity for 5 orphaned witnesses on each shard, which should
be enough.
Assuming that a single witness can take up 40 MB, the pool will consume
at most 1GB at full capacity.

The changes are divided into individual commits, they can be reviewed
commit-by-commit.

### Fixes
Fixes: #10552
Fixes: near/stakewars-iv#15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant