Skip to content

Research project on RANDAO manipulations in Ethereum using new forking techniques and realistic attestations

License

Notifications You must be signed in to change notification settings

nagyabi/RANDAO_Daemon

Repository files navigation

RANDAO Daemon

RANDAO Daemon

Warning: The project is intended for educational purposes only, we do not condone harmful usage on any live systems without explicit authorization.

RANDAO Daemon is a research system, which improves the effectiveness of RANDAO manipulations on Ethereum PoS. Compared to previous works, we used a realistic attestation model. One can verify our results through our REST API. Feel free to implement your own simulator for independent verification or use ours.

Results

We compare our results with the papers Forking the RANDAO and Slot à la carte. We considered the KPI effective stake, which is the probability (%) the adversary can propose and finalize a block / slot. One of the goals of the consensus protocol is to ensure fairness: everyone proposes blocks in proportion to their stake share. It means that if an adversary has an effective stake larger than their stake share, they violated fairness and proposed more blocks than their fair share.

WARNING: The previous 2 works assumed that the adversary has the same amount of voting power in every slot, while RANDAO Daemon uses a more accurate distribution of adversarial proposers/committee.

Stake of the adversary Forking the RANDAO Slot à la carte RANDAO Daemon Selfish Mining
5% 5.05% 5.07% 5.20% 5.24%
10% 10.19% 10.23% 10.57% 10.92%
15% 15.42% 15.51% 15.78% 17.01%
20% 20.95% 21.00% 21.56% 23.51%
25% 26.60% 26.80% 27.97% 30.48%
30% 32.83% 33.43% 36.09% 38.06%
35% 40.28% 44.36% 50.01% 46.55%
40% 47.49% 53.08% 58.30% 56.74%
45% 53.77% 60.00% 63.20% 70.94%

RANDAO Daemon

Setup

Create your configuration in a yaml similarly to default.yaml:

number_of_validators: 1000000 # ensure that it is divisible by 32
number_of_adv_validators: 280000 # Size of your pool you control
size_postfix: 15 # Number of slots considered at the end of the epoch
epoch_sample_size: 4000 # Number of epoch strings generated randomly with size_postfix. These will be used to create utilities, then train the neural network on 
votes_sample: 5000 # Permutations on validators generated. Later, we draw uniformly from this set, because its expensive.
dist_compression_size: 8 # Precision of distributions
diff_cluster_size: 3 # Number of clusters (>=2)
tree_batching: 200 # We rotate this many large trees
iteration: 10 # Number of value iterations
dataset_name: randao
train_weight: 0.8 # Size of epoch_sample_size to be included in the training dataset
val_weight: 0.15 # Size of epoch_sample_size to be included in the val dataset
model_name: daemon
train_rounds: 3 # Number of trains started each task
batch_size: 32
lr: 0.0001 # learning rate
weight_up_zero_class_options: # hyperparameters of one task
  - 1.5
  - 2.0
  - 2.5
epochs: 400 # length of training
save_every: 5 # intervals of saving the models
infer_rounds: 50000 # number of rounds during simulation
slot_capture: false # must be set to false, currently not supported for server setup
warmup_rounds: 10 # number of epochs before the slot we wish to `capture`

Ensure you have installed NVIDIA Toolchain

Build docker

docker build -t randaodaemon:latest .

Precomputate your models

Precomputation produces a run yaml file under .runs folder. The key inference_result holds the number of proposed blocks on average during the simulation. Additionally it produces every model necessary to run the server.

WARNING: The repo folder is mounted even for server setup. For the offline precomputation the model can be saved in the .models folder.

docker run --rm \
    --gpus all \
    -v $(pwd):/srv \
    randaodaemon:latest \
    bash -c "git config --global --add safe.directory /srv && python3 -m create_model default.yaml"

Running server

This phase is only necessary if you wish to verify independently the performance of the produced model and do not trust the simulation.

If you wish not to mount the repo, you must rebuild the docker with the extra row COPY . . and start it without the -v $(pwd):/srv flag.

In config.yaml provide the path of the run yaml file produced in the previous step.

docker run --rm --gpus all -v $(pwd):/srv -p 8001:8001 --network host randaodaemon:latest bash -c "git config --global --add safe.directory /srv && uvicorn main:app --host 0.0.0.0 --port 8001"

API Specification

The server in itself is not standalone. While we implemented the blockchain simulation server, you are welcome to independently verify our results and implement a different simulator. RANDAO Daemon requires an endpoint serving data about the (simulated) blockchain. After which it can return which action to execute (e.g. where to vote or how to build a block).

GET /start

The server will request information necessary for the attack. The server is ready.

Response:

{
  "status": "ok"
}

GET /stop

Stops the attack. Response:

{
  "status": "ok"
}

GET /advance

Advances the slot to the next slot number and to the next phase. propose -> vote vote -> propose - slot := slot + 1

Response:

{
  "status": "ok"
}

POST /actions

Queries actions for the given slot

Request:

{
  "slot": 12,
  "phase": "vote",
  "subscribe_url": "url"
}

where subscribe_url is optional. If provided and the server is busy, the results will be posted there eventually.

Expected response:

{
  "status": "ok",
  "slot": 12,
  "phase": "vote",
  "actions": [
    {
      "action": "vote",
      "to_slot": 11,
      "from_slot": 11,
      "amount": 178000
    },
    {
      "action": "propose",
      "slot": 10,
      "parent": 9
    }
  ]
}

Response in case the server is still computing for the slot:

{
  "status": "pending",
  "message": "Data does not exists for this slot"
}

Simulation server specification

The implementation of the simulation must follow the given specification

GET /time

Responds with the current slot and epoch:

{
  "status": "ok",
  "epoch": 1,
  "slot": 35
}

GET /epoch/{epoch}

Returns who proposes which slot and the adequate number of attestators for each slot.

An epoch string is a 32 long string with "A" and "H" characters. "A" denotes the slots controlled by the adversary, while "H" everone else's slot (honest). Response:

{
  "status": "ok",
  "epoch": 12,
  "success": 1,
  "epoch_string": "AHHHAHHHAA...A",
  "attestations": [
    123,
    543,
    ...,
    831
  ]
}

POST randao/

Returns the epoch string and votes corresponding to the input's 32 long canonical strings contains characters "N" and "C" corresponding to the slots of epoch. "N" denotes a noncanonical (i.e. missed or reorged) slot, while "C" a canonical (proposed). Request:

{
  "epoch": 12,
  "input": [
    "CCCNCCNC...N",
    "NCNNCCCC...C"
  ]
}

In the response, success denotes whether the RANDAO and the validators are precomputable at the moment:

{
  "status": "ok",
  "epoch": 12,
  "epochs": [
    {
      "outcome": "CCCNCCNC...N",
      "success": 1,
      "epoch_string": "AHHHAHHHAA...A",
      "attestations": [
        123,
        543,
        ...,
        831
      ]
    },
    {
      "outcome": "NCNNCCCC...C",
      "success": 0,
    }
  ]
}

About

Research project on RANDAO manipulations in Ethereum using new forking techniques and realistic attestations

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published