Skip to content

Commit

Permalink
Merge pull request optimism-java#149 from fearlessfe/proof-test
Browse files Browse the repository at this point in the history
feat: add history proof validation test
  • Loading branch information
fearlessfe authored Sep 12, 2024
2 parents ef9012a + d9a379d commit 8dc76c1
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 30 deletions.
29 changes: 18 additions & 11 deletions portalnetwork/beacon/beacon_network.go
Original file line number Diff line number Diff line change
Expand Up @@ -253,20 +253,10 @@ func (bn *BeaconNetwork) validateContent(contentKey []byte, content []byte) erro
return nil
// TODO: VERIFY
case HistoricalSummaries:
key := &HistoricalSummariesWithProofKey{}
err := key.Deserialize(codec.NewDecodingReader(bytes.NewReader(contentKey[1:]), uint64(len(contentKey[1:]))))
forkedHistoricalSummariesWithProof, err := bn.generalSummariesValidation(contentKey, content)
if err != nil {
return err
}
forkedHistoricalSummariesWithProof := &ForkedHistoricalSummariesWithProof{}
err = forkedHistoricalSummariesWithProof.Deserialize(bn.spec, codec.NewDecodingReader(bytes.NewReader(content), uint64(len(content))))
if err != nil {
return err
}
if forkedHistoricalSummariesWithProof.HistoricalSummariesWithProof.EPOCH != common.Epoch(key.Epoch) {
return fmt.Errorf("historical summaries with proof epoch does not match the content key epoch: %d != %d", forkedHistoricalSummariesWithProof.HistoricalSummariesWithProof.EPOCH, key.Epoch)
}

// TODO get root from light client
header := bn.lightClient.GetFinalityHeader()
latestFinalizedRoot := header.StateRoot
Expand Down Expand Up @@ -329,6 +319,23 @@ func (bn *BeaconNetwork) processContentLoop(ctx context.Context) {
}
}

func (bn *BeaconNetwork) generalSummariesValidation(contentKey, content []byte) (*ForkedHistoricalSummariesWithProof, error) {
key := &HistoricalSummariesWithProofKey{}
err := key.Deserialize(codec.NewDecodingReader(bytes.NewReader(contentKey[1:]), uint64(len(contentKey[1:]))))
if err != nil {
return nil, err
}
forkedHistoricalSummariesWithProof := &ForkedHistoricalSummariesWithProof{}
err = forkedHistoricalSummariesWithProof.Deserialize(bn.spec, codec.NewDecodingReader(bytes.NewReader(content), uint64(len(content))))
if err != nil {
return nil, err
}
if forkedHistoricalSummariesWithProof.HistoricalSummariesWithProof.EPOCH != common.Epoch(key.Epoch) {
return nil, fmt.Errorf("historical summaries with proof epoch does not match the content key epoch: %d != %d", forkedHistoricalSummariesWithProof.HistoricalSummariesWithProof.EPOCH, key.Epoch)
}
return forkedHistoricalSummariesWithProof, nil
}

func (bn *BeaconNetwork) stateSummariesValidation(f ForkedHistoricalSummariesWithProof, latestFinalizedRoot common.Root) bool {
proof := f.HistoricalSummariesWithProof.Proof
summariesRoot := f.HistoricalSummariesWithProof.HistoricalSummaries.HashTreeRoot(bn.spec, tree.GetHashFn())
Expand Down
25 changes: 24 additions & 1 deletion portalnetwork/beacon/beacon_network_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,29 @@ func TestLightClientOptimisticUpdateValidation(t *testing.T) {
}

func TestHistorySummariesWithProofValidation(t *testing.T) {
_, err := GetHistorySummariesWithProof()
historySummariesWithProof, root, err := GetHistorySummariesWithProof()
require.NoError(t, err)

key := &HistoricalSummariesWithProofKey{
Epoch: 450508969718611630,
}
var keyBuf bytes.Buffer
err = key.Serialize(codec.NewEncodingWriter(&keyBuf))
require.NoError(t, err)
contentKey := make([]byte, 0)
contentKey = append(contentKey, byte(HistoricalSummaries))
contentKey = append(contentKey, keyBuf.Bytes()...)

bn := NewBeaconNetwork(nil)
var buf bytes.Buffer
err = historySummariesWithProof.Serialize(bn.spec, codec.NewEncodingWriter(&buf))
require.NoError(t, err)
content := make([]byte, 0)
content = append(content, Deneb[:]...)
content = append(content, buf.Bytes()...)

forkedHistorySummaries, err := bn.generalSummariesValidation(contentKey, content)
require.NoError(t, err)
valid := bn.stateSummariesValidation(*forkedHistorySummaries, root)
require.True(t, valid)
}
37 changes: 19 additions & 18 deletions portalnetwork/beacon/test_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,24 +158,25 @@ func GetLightClientOptimisticUpdate(number uint8) (ForkedLightClientOptimisticUp
return *bootstrap, nil
}

func GetHistorySummariesWithProof() (HistoricalSummariesWithProof, error) {
func GetHistorySummariesWithProof() (HistoricalSummariesWithProof, common.Root, error) {
file, err := os.ReadFile("testdata/beacon/BeaconState/ssz_random/case_0/serialized.ssz_snappy")
if err != nil {
return HistoricalSummariesWithProof{}, err
return HistoricalSummariesWithProof{}, common.Root{}, err
}
data, err := snappy.Decode(nil, file)
if err != nil {
return HistoricalSummariesWithProof{}, err
return HistoricalSummariesWithProof{}, common.Root{}, err
}

beaconState := &deneb.BeaconState{}
err = beaconState.Deserialize(configs.Mainnet, codec.NewDecodingReader(bytes.NewReader(data), uint64(len(data))))
if err != nil {
return HistoricalSummariesWithProof{}, err
return HistoricalSummariesWithProof{}, common.Root{}, err
}
root := beaconState.HashTreeRoot(configs.Mainnet, tree.GetHashFn())
proof, err := BuildHistoricalSummariesProof(*beaconState)
if err != nil {
return HistoricalSummariesWithProof{}, err
return HistoricalSummariesWithProof{}, common.Root{}, err
}
summariesProof := [5]common.Bytes32{tree.Root(proof[0]), tree.Root(proof[1]), tree.Root(proof[2]), tree.Root(proof[3]), tree.Root(proof[4])}
return HistoricalSummariesWithProof{
Expand All @@ -184,7 +185,7 @@ func GetHistorySummariesWithProof() (HistoricalSummariesWithProof, error) {
Proof: HistoricalSummariesProof{
Proof: summariesProof,
},
}, nil
}, root, nil
}

func BuildHistoricalSummariesProof(beaconState deneb.BeaconState) ([][]byte, error) {
Expand All @@ -205,18 +206,18 @@ func BuildHistoricalSummariesProof(beaconState deneb.BeaconState) ([][]byte, err
leaves[13] = beaconState.RandaoMixes.HashTreeRoot(configs.Mainnet, tree.GetHashFn())
leaves[14] = beaconState.Slashings.HashTreeRoot(configs.Mainnet, tree.GetHashFn())
leaves[15] = beaconState.PreviousEpochParticipation.HashTreeRoot(configs.Mainnet, tree.GetHashFn())
leaves[16] = beaconState.JustificationBits.HashTreeRoot(tree.GetHashFn())
leaves[17] = beaconState.PreviousEpochParticipation.HashTreeRoot(configs.Mainnet, tree.GetHashFn())
leaves[18] = beaconState.CurrentJustifiedCheckpoint.HashTreeRoot(tree.GetHashFn())
leaves[19] = beaconState.FinalizedCheckpoint.HashTreeRoot(tree.GetHashFn())
leaves[20] = beaconState.InactivityScores.HashTreeRoot(configs.Mainnet, tree.GetHashFn())
leaves[21] = beaconState.CurrentSyncCommittee.HashTreeRoot(configs.Mainnet, tree.GetHashFn())
leaves[22] = beaconState.NextSyncCommittee.HashTreeRoot(configs.Mainnet, tree.GetHashFn())
leaves[23] = beaconState.LatestExecutionPayloadHeader.HashTreeRoot(tree.GetHashFn())
leaves[24] = beaconState.NextWithdrawalIndex.HashTreeRoot(tree.GetHashFn())
leaves[25] = beaconState.NextWithdrawalValidatorIndex.HashTreeRoot(tree.GetHashFn())
leaves[26] = beaconState.HistoricalSummaries.HashTreeRoot(configs.Mainnet, tree.GetHashFn())
leaves[27] = tree.Root{}
leaves[16] = beaconState.CurrentEpochParticipation.HashTreeRoot(configs.Mainnet, tree.GetHashFn())
leaves[17] = beaconState.JustificationBits.HashTreeRoot(tree.GetHashFn())
leaves[18] = beaconState.PreviousJustifiedCheckpoint.HashTreeRoot(tree.GetHashFn())
leaves[19] = beaconState.CurrentJustifiedCheckpoint.HashTreeRoot(tree.GetHashFn())
leaves[20] = beaconState.FinalizedCheckpoint.HashTreeRoot(tree.GetHashFn())
leaves[21] = beaconState.InactivityScores.HashTreeRoot(configs.Mainnet, tree.GetHashFn())
leaves[22] = beaconState.CurrentSyncCommittee.HashTreeRoot(configs.Mainnet, tree.GetHashFn())
leaves[23] = beaconState.NextSyncCommittee.HashTreeRoot(configs.Mainnet, tree.GetHashFn())
leaves[24] = beaconState.LatestExecutionPayloadHeader.HashTreeRoot(tree.GetHashFn())
leaves[25] = beaconState.NextWithdrawalIndex.HashTreeRoot(tree.GetHashFn())
leaves[26] = beaconState.NextWithdrawalValidatorIndex.HashTreeRoot(tree.GetHashFn())
leaves[27] = beaconState.HistoricalSummaries.HashTreeRoot(configs.Mainnet, tree.GetHashFn())
leaves[28] = tree.Root{}
leaves[29] = tree.Root{}
leaves[30] = tree.Root{}
Expand Down

0 comments on commit 8dc76c1

Please sign in to comment.