Try   HackMD

Contract Enforcement and Decentralized Consensus: The Case of Slashing

This document references this paper: https://papers.ssrn.com/sol3/papers.cfm?abstract_id=4036000

The paper claims that there are a large number of slashings going undetected on the beacon chain. However, myself and others have not been able to verify these claims.

To assist the authors, I will attempt to debunk one slashable offense in this document.

Debunking validator 5942

The paper claims on page 31 that validator 5942 included an attestation in block 1267818 and then another conflicting attestation in 1267822.

To investigate, I will obtain the beacon block and beacon state for both blocks from a synced Lighthouse node I am running locally:

# Download the block at slot 1267818
curl localhost:5052/eth/v2/beacon/blocks/0x6658521398f8004e6a3a837c305bfeb469307d81ce46b14e3cfe7ea6ff987de8 > block_0x6658.json
# Download the beacon state for the block at slot 1267818
curl localhost:5052/eth/v1/debug/beacon/states/0x2bdfec72208542010f7dedc8ace2797f521aed3b22a333214f5afc3c7b25914c > state_0x6658.json

# Download the block at slot 1267822
curl localhost:5052/eth/v2/beacon/blocks/0x541fefdb01c2c7f716b29afe8d9403f2e135b8d18ce814891580fe074ce6d23f > block_0x541f.json
# Download the beacon state for the block at slot 1267822
curl localhost:5052/eth/v1/debug/beacon/states/0x807345f9fb02aed2140e1bb13402ad7773ae1d43eef1e51d8d0092a282b041a9 > state_0x541f.json

Now, I will build a branch of Lighthouse with a custom tool for this specific job:

git clone https://github.com/paulhauner/lighthouse.git
git checkout attestation-indexer
cd lighthouse
make install-lcli

This will install the lcli tool into my path. It contains the attestation-indexer tool that turns an Attestation object into an IndexedAttestation. The difference between these two types is that IndexedAttestation has the aggregation_bits resolved to a list of attesting_indices (e.g., the validator indexes of the validators in the attestation).

Indexed attestations in block 1267818

I will get all the indexed attestations for block at slot 1267818:

lcli attestation-indexer --block block_0x6658.json --state state_0x6658.json > indexed_0x6658.json

This has produced the file indexed_0x6658.json containing all indexed attestations from the block at slot 1267818.

Indexed attestations in block 1267822

I will get all the indexed attestations for block at slot 1267822:

lcli attestation-indexer --block block_0x541f.json --state state_0x541f.json > indexed_0x541f.json

This has produced the file indexed_0x541f.json containing all indexed attestations from the block at slot 1267822.

Finding validator 5942 in the indexed attestations

Searching the block at 1267818 shows that there is an attestation from validator 5942:

cat indexed_0x6658.json | grep "\"5942\""
{"attesting_indices":["1156","1161","2249","5942","6252","9780","10707","10861","12640","13346","13878","14057","14320","17586","17861","18912","19523","19707","21223","22322","23516","23584","25929","26376","27192","27636","27676","27701","28389","35004","35738","37384","38634","39751","40445","41441","43012","44240","44384","46011","49639","50207","50234","52805","55140","55608","56156","57584","59903","61517","61557","61783","62281","64680","65776","67002","67366","67538","67653","68214","72575","73926","75392","75672","77758","78068","79101","80792","82720","84850","84969","87915","88712","89603","90259","91019","91317","91647","92021","93857","97825","98376","99698","99752","100393","101446","104472","105700","106344","106623","106924","107668","107863","109527","109545","112544","117176","119672","120720","121651","121757","122741","123902","125237","130528","130766","131275","131407","132423","133212","134134","134258","134638","135571","137927","138510","138805","140415","140691","140873","141344","141437","141764","146288","146847","147487"],"data":{"slot":"1267817","index":"0","beacon_block_root":"0x91ba16a5ece48495e45e30e1baab86fc47fc8f81ed8a063e2f279e9c442f19a1","source":{"epoch":"39618","root":"0x34b77ed76186f884aeff3af111d26cec656706f857e137a1d8b9192cd8e2aaff"},"target":{"epoch":"39619","root":"0xbfac3b8e502cf4c00ce3ce67f7cee4e03da9c5776d70a38721714255334ad789"}},"signature":"0xa930344b53110d357c8ed60fee25d22883cde1a1cffe47e2b17bd76f7ff6fa31e66b3b11ec640d5abf2a35f9b916786c089c18088e8d6749d74f2d353a35aad271ea5d98fc92d3d5bc3fe120462632378a59eb8bf29752679781edf48fc39903"}

However, searching the block at 1267822 shows no attestations for that validator:

cat indexed_0x541f.json | grep "\"5942\""
# no matching lines

Conflicts with beaconcha.in

My findings conflict with beaconcha.in, which shows an attestation for 5942 in block 1267822 in attestation #85.

However, we should note that our indexed_0x541f.json only shows 48 attestations. Also, beaconcha.in claims "Showing 48 Attestations" but then goes on to display 128.

So, the following is clear:

  • The data I have generated conflicts with beaconcha.in.
  • Beaconcha.in is also conflicting with itself (it's unsure if there are 128 or 48 attestations in block 1267822).

Summary

From my findings, I believe that there is a bug in beaconcha.in and that validator 5942 did not create the claimed slashable attestation.

Anecodatally, we have pulled some attestations from the beaconcha.in API and found them to have invalid signatures. This leads me to believe that these slashable attestations are invalid "phantom" attestations.

I have great respect for the beaconcha.in team. They have done a lot of work to further the Beacon Chain. I use their site frequently and I will continue to do so. However, it's important to be aware that indexing the beacon chain is hard and it's still fairly early days of the beacon chain. It is not enough to rely on just beaconcha.in (or any lone source) when analysing the beacon chain in an academic manner.