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

SIMD-0074: Scrambled Transaction #74

Closed
wants to merge 12 commits into from
231 changes: 231 additions & 0 deletions proposals/0074-scrambled-transaction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,231 @@
---
simd: '0074'
title: Scrambled Transaction
authors:
- Ryo Onodera (Solana Labs)
category: Standard
type: Core
status: Draft
created: 2023-10-17
feature: (fill in with feature tracking issues once accepted)
---

## Summary

### general idea

- use asic-resistant time-lock encryption
- use proof-of-work client puzzle for spam mitigation even to hide the fee
payer
- make transaction expire very soon for minimal additional latency of the
time-lock decryption
- (future) spoof ip source address to avoid fingerprinting with one-shot
one-sided udp packet

### terminology

scrambling = time-lock encrypting
descrambling = time-lock decrypting

### pros

- stricter censorship resistance than bps.
- latency minimization incentive is formed and ledger is timestamped for
later inspection
- should reduce spamming in the first place
- (future) can generate unbiased random generator

### cons

- artificial latency
- complicated
- somewhat easier dos (hopefully not too easy) with garbage (mitigated by
client puzzles)
- tps scalability now depends on validator count
- maybe tps will be floated around 50k max for some time. i.e. 1 million
tps might not be a thing for awhile...
- however, there's strong incentive for high-staked nodes to add more nodes
for increased cluster-wide descrambling throughput if blocks are full.
- reliance on ntp via wall-clock time-stamp both on tx and ledger entries.
- burns electricity to some extent due to use of pow

### processing flow of a scrambled transaction

1. user pre-calculates a valid tuple for (de)scrambling: `(scramble_seed,
descramble_key = recursive-randomx(scramble_seed))`.
2. user measures network latency to the leader
3. user creates and signs a transaction with version=1 (new assigned version)
also sets tx's block inclusion `max_age` as `end-to-end latency + 20ms`.
4. user encrypts the transaction (aes-128-gcm with `descramble_key`)
5. user attaches the `scramble_seed` and the pow client puzzle to the
scrambled transaction
6. user submits the scrambled tx to leader
7. the tx is propagated via turbine
8. the tx is descrambled by a certain validator assigned by consistent
hashing as part of new distributed descrambling stage.
9. validator submits a vote tx with the descrambled key is attached
10. as soon as all descrambled keys are included in child blocks, the original
(parent) block is scheduled (ie. reordered by priority fee) and executed
at the replaying stage.

### protocol changes

- banking
- becomes bankless
- no practical buffering
- turbine
- timestamp is added to entries
- new ledger entry verification: shreds' timestamp comparison against
received time on socket (must be within sum(deterministic turbine path
network delay))
- and shred timestamp to be monotonically-increasing.
- needs to shred buffered entries more often
- vote transaction
- additional flag whether the voter thinks the slot was censorship resistant
or not.
- additional payload for solved decryption keys (`(Slot,
Vec<Result<Aes128Key,()>>)`).
- replay stage
- deterministically reorders transactions by priority fee batched at 50ms
intervals of entries' timestamp before executing.
- transactions in the block aren't guaranteed to be executed anymore;
- could be revealed the tx has expired according to the timestamp of its
ledger entry position.
- could be overflow from the fixed-size scheduling queue
- clients
- new transaction format
- additional steps: time-lock encrypting, pow client puzzle solving,
precise network latency measuring

### scrambling

- scrambling is optional. ie. older transaction is supported as before.
- so validators as a whole can conduct a variant of downgrade attack by not
accepting scrambled txes. so some social consensus must be reached on as to
censorship resistance is good for solana in the long term
- (future work) additionally, vote txes can be forced to be scrambled so that
this blanket censoring for scrambled transaction isn't practical.
- uses recursive [randomx](https://github.com/tevador/RandomX) to derive
private key from plaintext seed attached to the tx. Recursion depth is
hard-coded.
- randomx is a hash function and asic & fpga resistant.
- also use [equix](https://github.com/tevador/equix) with difficulty is
attached to the tx for spam prevention
- verification is around 50us per tx.
- should be able to do line-rate filtering.
- will expire in 2 min or so to against at-once spamming after accumulating solved
puzzles over very long time locally
- difficulty will be dynamic
- padded to `1_232 bytes` (= `PACKET_DATA_SIZE`) to avoid finger printing.

### latency and safety parameters

- scrambled tx expires in **20ms**
- chosen to be enough for minimal buffering + jitter of one-way network
latency.
- so precise time-stamp with subsecond gratuity is attached to the tx
- the timestamp is scrambled to encourage FIFO at banking and avoid
fingerprinting via deduced network latency.
- oracle is needed for bad validator with intentionally large latency.
- descrambling is adjusted to take 100ms with modern machine
- this is **5 times** of tx expiration (20ms).
- given 2.5 ghz cpu as baseline, 12.5 ghz cpu should be impossible for
some time?

#### Latency of Average Scrambled Transaction

artificial latency increase is **300ms** due to the distributed descrambling.
note that this is a latency of single transaction processiong. repla stage can
be pipelined to some extent as was before, because shred propagation and
distributed descramblng can both be processed in streaming fashion. also note
that pipelining is still applied across slots.

```mermaid
gantt
dateFormat SSS
axisFormat +%S.%Ls
section tx liveness
can be sequenced before expiration :200, 20ms
section (A) normal
tx travels the globe to tpu :a1, 000, 200ms
tx is sequenced :milestone, after a1, 5ms
shred propagation via turbine :a2, after a1, 200ms
distributed descrambling :a33, after a2, 100ms
descramble key prop. (as tx) via turbine :a3, after a33, 200ms
replay :a4, after a3, 400ms
vote prop. :a5, after a4, 200ms
replay is optimistically confirmed :milestone, after a5, 5ms
section User's view
tx execution confirmation :milestone, after a5, 5ms
section (B) MEV
(tx expires) :milestone, 220, 0ms
ideally-accelerated descrambling: ai, after a1, 20ms
tx is reordered/censored and sequenced :milestone, mev, after ai, 5ms
shred propagation :mev2, after mev, 200ms
tx is ignored due to expiration for inclusion: milestone, after mev2, 5ms
```

### cooperative distributed descrambling

- this is needed because individual node can't descramble all txes: 100ms *
20000 tx/block = 5000s/block >> 400ms
- all of non-delinquent validators are shuffled and split into 3 groups of
the same size according to recent parent block
- each group independently solves all scrambled txes assigned with consistent
hashing
- note that this work balancing should be fully deterministic.
- so, 2000 (current mb node count) / 3 = 666 => 20000 / 666 = 30 descrambling
/ block / node.
- 128/8 * 30 => 480 bytes are increased for each vote transaction.
- liveness isn't strictly stake-weighted here but i'd argue turbine is similar in
that regard, right?

### edge cases

- user submits complete garbage as tx
- => simply discarded before including into block
- user submits garbage data with correct pow client puzzle
- => marked as garbage after distributed descrambling, the garbage will
remain in ledger though
- cluster fails to descramble all scrambled transactions within slot=4
- => mark the fork as dead as a whole
- valid scrambled transaction is marked as garbage at distributed descrambling stage
- => will be slashed
- descrambled transaction is identical to one of already executed transaction
- => simply ignored
- shred is arrived late via turbine or repaired.
- => vote normally but with `censorship_resistant={No,Unknown}` hint respectively.
- assigned validator misses to submit `descrambe_keys` on time.
- => staking reward is reduced (not slashing)
- less than 2/3 node votes on `censorship_resistant=Yes`
- => mark the fork as dead as a whole
- transaction's timestamp is revealed to be too old compared to ledger entry
timestamp
- => won't be executed. fee is paid.

### future work

- scramble vote transaction as well
- relay service to avoid ip source address fingerprinting
- unbiased random
- address tragedy of commons among staked validators.

## Motivation


## Alternatives Considered


## New Terminology


## Detailed Design


## Impact


## Security Considerations


## Drawbacks *(Optional)*