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

[stateless_validation] Orphan state witnesses pool #10552

Closed
Tracked by #46
Longarithm opened this issue Feb 2, 2024 · 0 comments · Fixed by #10613
Closed
Tracked by #46

[stateless_validation] Orphan state witnesses pool #10552

Longarithm opened this issue Feb 2, 2024 · 0 comments · Fixed by #10613
Assignees
Labels
A-stateless-validation Area: stateless validation

Comments

@Longarithm
Copy link
Member

Be able to process state witness even if we don't have prev_block_hash on receiving it. Replace #10535 with proper solution.

Latest discussion https://near.zulipchat.com/#narrow/stream/407237-pagoda.2Fcore.2Fstateless-validation/topic/Handling.20orphan.20state.20witness/near/419062956

@Longarithm Longarithm added the A-stateless-validation Area: stateless validation label Feb 2, 2024
@shreyan-gupta shreyan-gupta changed the title Orphan state witnesses pool [stateless_validation] Orphan state witnesses pool Feb 5, 2024
@jancionear jancionear self-assigned this Feb 12, 2024
github-merge-queue bot pushed a commit 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
Labels
A-stateless-validation Area: stateless validation
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants