mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-29 16:13:47 +00:00
198 lines
5.6 KiB
Go
198 lines
5.6 KiB
Go
package beacon
|
|
|
|
import (
|
|
"encoding/json"
|
|
"os"
|
|
"testing"
|
|
|
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
|
"github.com/ethereum/go-ethereum/internal/testlog"
|
|
"github.com/ethereum/go-ethereum/log"
|
|
"github.com/protolambda/zrnt/eth2/beacon/capella"
|
|
"github.com/protolambda/zrnt/eth2/beacon/common"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
var _ ConsensusAPI = (*MockConsensusAPI)(nil)
|
|
|
|
type MockConsensusAPI struct {
|
|
testdataDir string
|
|
}
|
|
|
|
func NewMockConsensusAPI(path string) (ConsensusAPI, error) {
|
|
return &MockConsensusAPI{testdataDir: path}, nil
|
|
}
|
|
|
|
func (m MockConsensusAPI) GetUpdates(_, _ uint64) ([]common.SpecObj, error) {
|
|
jsonStr, _ := os.ReadFile(m.testdataDir + "/updates.json")
|
|
|
|
updates := make([]*capella.LightClientUpdate, 0)
|
|
_ = json.Unmarshal(jsonStr, &updates)
|
|
|
|
res := make([]common.SpecObj, 0)
|
|
|
|
for _, item := range updates {
|
|
res = append(res, item)
|
|
}
|
|
return res, nil
|
|
}
|
|
|
|
func (m MockConsensusAPI) GetBootstrap(_ common.Root) (common.SpecObj, error) {
|
|
jsonStr, _ := os.ReadFile(m.testdataDir + "/bootstrap.json")
|
|
|
|
bootstrap := &capella.LightClientBootstrap{}
|
|
_ = json.Unmarshal(jsonStr, &bootstrap)
|
|
|
|
return bootstrap, nil
|
|
}
|
|
|
|
func (m MockConsensusAPI) GetFinalityUpdate() (common.SpecObj, error) {
|
|
jsonStr, _ := os.ReadFile(m.testdataDir + "/finality.json")
|
|
|
|
finality := &capella.LightClientFinalityUpdate{}
|
|
_ = json.Unmarshal(jsonStr, &finality)
|
|
|
|
return finality, nil
|
|
}
|
|
|
|
func (m MockConsensusAPI) GetOptimisticUpdate() (common.SpecObj, error) {
|
|
jsonStr, _ := os.ReadFile(m.testdataDir + "/optimistic.json")
|
|
|
|
optimistic := &capella.LightClientOptimisticUpdate{}
|
|
_ = json.Unmarshal(jsonStr, &optimistic)
|
|
|
|
return optimistic, nil
|
|
}
|
|
|
|
func (m MockConsensusAPI) ChainID() uint64 {
|
|
panic("implement me")
|
|
}
|
|
|
|
func (m MockConsensusAPI) Name() string {
|
|
return "mock"
|
|
}
|
|
|
|
func getClient(strictCheckpointAge bool, t *testing.T) (*ConsensusLightClient, error) {
|
|
baseConfig := Mainnet()
|
|
api, err := NewMockConsensusAPI("testdata/mockdata")
|
|
assert.NoError(t, err)
|
|
|
|
config := &Config{
|
|
ConsensusAPI: api.Name(),
|
|
Chain: baseConfig.Chain,
|
|
Spec: baseConfig.Spec,
|
|
StrictCheckpointAge: strictCheckpointAge,
|
|
}
|
|
|
|
checkpoint := common.Root(hexutil.MustDecode("0xc62aa0de55e6f21230fa63713715e1a6c13e73005e89f6389da271955d819bde"))
|
|
|
|
client, err := NewConsensusLightClient(api, config, checkpoint, testlog.Logger(t, log.LvlTrace))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return client, nil
|
|
}
|
|
|
|
func TestVerifyCheckpointAgeInvalid(t *testing.T) {
|
|
_, err := getClient(true, t)
|
|
assert.ErrorContains(t, err, "checkpoint is too old")
|
|
}
|
|
|
|
func TestVerifyUpdate(t *testing.T) {
|
|
client, err := getClient(false, t)
|
|
require.NoError(t, err)
|
|
client.Config.MaxCheckpointAge = 123123123
|
|
|
|
period := CalcSyncPeriod(uint64(client.Store.FinalizedHeader.Slot))
|
|
updates, err := client.API.GetUpdates(period, MaxRequestLightClientUpdates)
|
|
require.NoError(t, err)
|
|
// normal
|
|
err = client.VerifyUpdate(updates[0])
|
|
require.NoError(t, err)
|
|
// ErrInvalidNextSyncCommitteeProof
|
|
genericUpdate, err := FromLightClientUpdate(updates[0])
|
|
require.NoError(t, err)
|
|
genericUpdate.NextSyncCommittee.Pubkeys[0] = common.BLSPubkey{}
|
|
err = client.VerifyGenericUpdate(genericUpdate)
|
|
require.Equal(t, ErrInvalidNextSyncCommitteeProof, err)
|
|
// ErrInvalidFinalityProof
|
|
updates, err = client.API.GetUpdates(period, MaxRequestLightClientUpdates)
|
|
require.NoError(t, err)
|
|
genericUpdate, err = FromLightClientUpdate(updates[0])
|
|
require.NoError(t, err)
|
|
genericUpdate.FinalizedHeader = &common.BeaconBlockHeader{}
|
|
err = client.VerifyGenericUpdate(genericUpdate)
|
|
require.Equal(t, ErrInvalidFinalityProof, err)
|
|
|
|
// ErrInvalidSignature
|
|
updates, err = client.API.GetUpdates(period, MaxRequestLightClientUpdates)
|
|
require.NoError(t, err)
|
|
genericUpdate, err = FromLightClientUpdate(updates[0])
|
|
require.NoError(t, err)
|
|
genericUpdate.SyncAggregate.SyncCommitteeSignature[1] = 0xFE
|
|
err = client.VerifyGenericUpdate(genericUpdate)
|
|
require.Error(t, err)
|
|
}
|
|
|
|
func TestVerifyFinalityUpdate(t *testing.T) {
|
|
client, err := getClient(false, t)
|
|
require.NoError(t, err)
|
|
|
|
update, err := client.API.GetFinalityUpdate()
|
|
require.NoError(t, err)
|
|
|
|
// normal
|
|
err = client.VerifyFinalityUpdate(update)
|
|
require.NoError(t, err)
|
|
|
|
genericUpdate, err := FromLightClientFinalityUpdate(update)
|
|
require.NoError(t, err)
|
|
|
|
genericUpdate.FinalizedHeader = &common.BeaconBlockHeader{}
|
|
err = client.VerifyGenericUpdate(genericUpdate)
|
|
require.Equal(t, ErrInvalidFinalityProof, err)
|
|
// ErrInvalidSignature
|
|
update, err = client.API.GetFinalityUpdate()
|
|
require.NoError(t, err)
|
|
|
|
genericUpdate, err = FromLightClientFinalityUpdate(update)
|
|
require.NoError(t, err)
|
|
genericUpdate.SyncAggregate.SyncCommitteeSignature[1] = 0xFE
|
|
err = client.VerifyGenericUpdate(genericUpdate)
|
|
require.Error(t, err)
|
|
}
|
|
|
|
func TestVerifyOptimisticUpdate(t *testing.T) {
|
|
client, err := getClient(false, t)
|
|
require.NoError(t, err)
|
|
|
|
update, err := client.API.GetOptimisticUpdate()
|
|
require.NoError(t, err)
|
|
|
|
// normal
|
|
err = client.VerifyOptimisticUpdate(update)
|
|
require.NoError(t, err)
|
|
|
|
genericUpdate, err := FromLightClientOptimisticUpdate(update)
|
|
require.NoError(t, err)
|
|
|
|
genericUpdate.SyncAggregate.SyncCommitteeSignature = common.BLSSignature{}
|
|
err = client.VerifyGenericUpdate(genericUpdate)
|
|
require.Error(t, err)
|
|
}
|
|
|
|
func TestSync(t *testing.T) {
|
|
client, err := getClient(false, t)
|
|
require.NoError(t, err)
|
|
|
|
err = client.Sync()
|
|
require.NoError(t, err)
|
|
|
|
header := client.GetHeader()
|
|
require.Equal(t, header.Slot, common.Slot(7358726))
|
|
|
|
finalizedHead := client.GetFinalityHeader()
|
|
require.Equal(t, finalizedHead.Slot, common.Slot(7358656))
|
|
}
|