2023-04-08 01:01:10 +00:00
package forkchoice_test
import (
2023-09-27 09:15:51 +00:00
"context"
2023-04-08 01:01:10 +00:00
_ "embed"
2024-01-01 21:18:11 +00:00
"fmt"
2023-05-14 22:12:24 +00:00
"testing"
2023-12-30 19:51:28 +00:00
"github.com/ledgerwatch/erigon/cl/antiquary/tests"
2023-05-14 22:12:24 +00:00
"github.com/ledgerwatch/erigon/cl/cltypes/solid"
2023-05-13 21:44:07 +00:00
"github.com/ledgerwatch/erigon/cl/phase1/core/state"
"github.com/ledgerwatch/erigon/cl/phase1/forkchoice"
2023-10-21 21:10:58 +00:00
"github.com/ledgerwatch/erigon/cl/phase1/forkchoice/fork_graph"
2023-09-29 21:42:07 +00:00
"github.com/ledgerwatch/erigon/cl/pool"
2024-01-01 21:18:11 +00:00
"github.com/ledgerwatch/erigon/cl/transition"
2023-10-21 21:10:58 +00:00
"github.com/spf13/afero"
2023-04-08 01:01:10 +00:00
libcommon "github.com/ledgerwatch/erigon-lib/common"
"github.com/ledgerwatch/erigon/cl/clparams"
"github.com/ledgerwatch/erigon/cl/cltypes"
"github.com/ledgerwatch/erigon/cl/utils"
"github.com/stretchr/testify/require"
)
//go:embed test_data/anchor_state.ssz_snappy
var anchorStateEncoded [ ] byte
//go:embed test_data/block_0x3af8b5b42ca135c75b32abb32b3d71badb73695d3dc638bacfb6c8b7bcbee1a9.ssz_snappy
var block3aEncoded [ ] byte
//go:embed test_data/block_0xc2788d6005ee2b92c3df2eff0aeab0374d155fa8ca1f874df305fa376ce334cf.ssz_snappy
var blockc2Encoded [ ] byte
//go:embed test_data/block_0xd4503d46e43df56de4e19acb0f93b3b52087e422aace49a7c3816cf59bafb0ad.ssz_snappy
var blockd4Encoded [ ] byte
//go:embed test_data/attestation_0xfb924d35b2888d9cd70e6879c1609e6cad7ea3b028a501967747d96e49068cb6.ssz_snappy
var attestationEncoded [ ] byte
// this is consensus spec test altair/forkchoice/ex_ante/ex_ante_attestations_is_greater_than_proposer_boost_with_boost
func TestForkChoiceBasic ( t * testing . T ) {
2023-05-14 22:12:24 +00:00
expectedCheckpoint := solid . NewCheckpointFromParameters ( libcommon . HexToHash ( "0x564d76d91f66c1fb2977484a6184efda2e1c26dd01992e048353230e10f83201" ) , 0 )
2023-04-08 01:01:10 +00:00
// Decode test blocks
2023-08-10 20:34:58 +00:00
block0x3a , block0xc2 , block0xd4 := cltypes . NewSignedBeaconBlock ( & clparams . MainnetBeaconConfig ) , cltypes . NewSignedBeaconBlock ( & clparams . MainnetBeaconConfig ) , cltypes . NewSignedBeaconBlock ( & clparams . MainnetBeaconConfig )
2023-05-05 09:19:24 +00:00
require . NoError ( t , utils . DecodeSSZSnappy ( block0x3a , block3aEncoded , int ( clparams . AltairVersion ) ) )
require . NoError ( t , utils . DecodeSSZSnappy ( block0xc2 , blockc2Encoded , int ( clparams . AltairVersion ) ) )
require . NoError ( t , utils . DecodeSSZSnappy ( block0xd4 , blockd4Encoded , int ( clparams . AltairVersion ) ) )
2023-04-08 01:01:10 +00:00
// decode test attestation
2023-05-14 22:12:24 +00:00
testAttestation := & solid . Attestation { }
2023-05-05 09:19:24 +00:00
require . NoError ( t , utils . DecodeSSZSnappy ( testAttestation , attestationEncoded , int ( clparams . AltairVersion ) ) )
2023-04-08 01:01:10 +00:00
// Initialize forkchoice store
anchorState := state . New ( & clparams . MainnetBeaconConfig )
2023-05-05 09:19:24 +00:00
require . NoError ( t , utils . DecodeSSZSnappy ( anchorState , anchorStateEncoded , int ( clparams . AltairVersion ) ) )
2023-09-29 21:42:07 +00:00
pool := pool . NewOperationsPool ( & clparams . MainnetBeaconConfig )
2023-10-21 21:10:58 +00:00
store , err := forkchoice . NewForkChoiceStore ( context . Background ( ) , anchorState , nil , nil , pool , fork_graph . NewForkGraphDisk ( anchorState , afero . NewMemMapFs ( ) ) )
2023-04-08 01:01:10 +00:00
require . NoError ( t , err )
// first steps
store . OnTick ( 0 )
store . OnTick ( 12 )
2023-04-26 13:33:21 +00:00
require . NoError ( t , store . OnBlock ( block0x3a , false , true ) )
2023-04-08 01:01:10 +00:00
// Check if we get correct status (1)
require . Equal ( t , store . Time ( ) , uint64 ( 12 ) )
require . Equal ( t , store . ProposerBoostRoot ( ) , libcommon . HexToHash ( "0xc9bd7bcb6dfa49dc4e5a67ca75e89062c36b5c300bc25a1b31db4e1a89306071" ) )
require . Equal ( t , store . JustifiedCheckpoint ( ) , expectedCheckpoint )
require . Equal ( t , store . FinalizedCheckpoint ( ) , expectedCheckpoint )
headRoot , headSlot , err := store . GetHead ( )
require . NoError ( t , err )
require . Equal ( t , headRoot , libcommon . HexToHash ( "0xc9bd7bcb6dfa49dc4e5a67ca75e89062c36b5c300bc25a1b31db4e1a89306071" ) )
2023-04-20 20:47:58 +00:00
require . Equal ( t , headSlot , uint64 ( 1 ) )
2023-04-08 01:01:10 +00:00
// process another tick and another block
store . OnTick ( 36 )
2023-04-26 13:33:21 +00:00
require . NoError ( t , store . OnBlock ( block0xc2 , false , true ) )
2023-04-08 01:01:10 +00:00
// Check if we get correct status (2)
require . Equal ( t , store . Time ( ) , uint64 ( 36 ) )
require . Equal ( t , store . ProposerBoostRoot ( ) , libcommon . HexToHash ( "0x744cc484f6503462f0f3a5981d956bf4fcb3e57ab8687ed006467e05049ee033" ) )
require . Equal ( t , store . JustifiedCheckpoint ( ) , expectedCheckpoint )
require . Equal ( t , store . FinalizedCheckpoint ( ) , expectedCheckpoint )
headRoot , headSlot , err = store . GetHead ( )
require . NoError ( t , err )
require . Equal ( t , headSlot , uint64 ( 3 ) )
require . Equal ( t , headRoot , libcommon . HexToHash ( "0x744cc484f6503462f0f3a5981d956bf4fcb3e57ab8687ed006467e05049ee033" ) )
// last block
2023-04-26 13:33:21 +00:00
require . NoError ( t , store . OnBlock ( block0xd4 , false , true ) )
2023-04-08 01:01:10 +00:00
require . Equal ( t , store . Time ( ) , uint64 ( 36 ) )
require . Equal ( t , store . ProposerBoostRoot ( ) , libcommon . HexToHash ( "0x744cc484f6503462f0f3a5981d956bf4fcb3e57ab8687ed006467e05049ee033" ) )
require . Equal ( t , store . JustifiedCheckpoint ( ) , expectedCheckpoint )
require . Equal ( t , store . FinalizedCheckpoint ( ) , expectedCheckpoint )
headRoot , headSlot , err = store . GetHead ( )
require . NoError ( t , err )
require . Equal ( t , headSlot , uint64 ( 3 ) )
require . Equal ( t , headRoot , libcommon . HexToHash ( "0x744cc484f6503462f0f3a5981d956bf4fcb3e57ab8687ed006467e05049ee033" ) )
// lastly do attestation
2024-01-08 16:13:25 +00:00
require . NoError ( t , store . OnAttestation ( testAttestation , false , false ) )
2023-09-29 21:42:07 +00:00
// Try processing a voluntary exit
err = store . OnVoluntaryExit ( & cltypes . SignedVoluntaryExit {
VoluntaryExit : & cltypes . VoluntaryExit {
Epoch : 0 ,
ValidatorIndex : 0 ,
} ,
} , true )
require . NoError ( t , err )
2023-10-01 15:16:55 +00:00
// Try processing a bls execution change exit
err = store . OnBlsToExecutionChange ( & cltypes . SignedBLSToExecutionChange {
Message : & cltypes . BLSToExecutionChange {
ValidatorIndex : 0 ,
} ,
} , true )
require . NoError ( t , err )
2023-09-29 21:42:07 +00:00
require . Equal ( t , len ( pool . VoluntaryExistsPool . Raw ( ) ) , 1 )
2023-04-08 01:01:10 +00:00
}
2023-12-30 19:51:28 +00:00
func TestForkChoiceChainBellatrix ( t * testing . T ) {
blocks , anchorState , _ := tests . GetBellatrixRandom ( )
2024-01-01 21:18:11 +00:00
intermediaryState , err := anchorState . Copy ( )
require . NoError ( t , err )
intermediaryBlockRoot := blocks [ 0 ] . Block . ParentRoot
for i := 0 ; i < 35 ; i ++ {
require . NoError ( t , transition . TransitionState ( intermediaryState , blocks [ i ] , nil , false ) )
intermediaryBlockRoot , err = blocks [ i ] . Block . HashSSZ ( )
require . NoError ( t , err )
}
2023-12-30 19:51:28 +00:00
// Initialize forkchoice store
pool := pool . NewOperationsPool ( & clparams . MainnetBeaconConfig )
store , err := forkchoice . NewForkChoiceStore ( context . Background ( ) , anchorState , nil , nil , pool , fork_graph . NewForkGraphDisk ( anchorState , afero . NewMemMapFs ( ) ) )
store . OnTick ( 2000 )
require . NoError ( t , err )
for _ , block := range blocks {
require . NoError ( t , store . OnBlock ( block , false , true ) )
}
root1 , err := blocks [ 20 ] . Block . HashSSZ ( )
require . NoError ( t , err )
rewards , ok := store . BlockRewards ( libcommon . Hash ( root1 ) )
require . True ( t , ok )
require . Equal ( t , rewards . Attestations , uint64 ( 0x511ad ) )
2024-01-01 21:18:11 +00:00
// test randao mix
mixes := solid . NewHashVector ( int ( clparams . MainnetBeaconConfig . EpochsPerHistoricalVector ) )
require . True ( t , store . RandaoMixes ( intermediaryBlockRoot , mixes ) )
for i := 0 ; i < mixes . Length ( ) ; i ++ {
require . Equal ( t , mixes . Get ( i ) , intermediaryState . RandaoMixes ( ) . Get ( i ) , fmt . Sprintf ( "mixes mismatch at index %d, have: %x, expected: %x" , i , mixes . Get ( i ) , intermediaryState . RandaoMixes ( ) . Get ( i ) ) )
}
currentIntermediarySyncCommittee , nextIntermediarySyncCommittee , ok := store . GetSyncCommittees ( intermediaryBlockRoot )
require . True ( t , ok )
require . Equal ( t , intermediaryState . CurrentSyncCommittee ( ) , currentIntermediarySyncCommittee )
require . Equal ( t , intermediaryState . NextSyncCommittee ( ) , nextIntermediarySyncCommittee )
2023-12-30 19:51:28 +00:00
}