github.1485827954.workers.dev/ethereum/go-ethereum@v1.14.3/beacon/light/test_helpers.go (about)

     1  // Copyright 2023 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package light
    18  
    19  import (
    20  	"crypto/rand"
    21  	"crypto/sha256"
    22  	mrand "math/rand"
    23  
    24  	"github.com/ethereum/go-ethereum/beacon/merkle"
    25  	"github.com/ethereum/go-ethereum/beacon/params"
    26  	"github.com/ethereum/go-ethereum/beacon/types"
    27  	"github.com/ethereum/go-ethereum/common"
    28  )
    29  
    30  func GenerateTestCommittee() *types.SerializedSyncCommittee {
    31  	s := new(types.SerializedSyncCommittee)
    32  	rand.Read(s[:32])
    33  	return s
    34  }
    35  
    36  func GenerateTestUpdate(config *types.ChainConfig, period uint64, committee, nextCommittee *types.SerializedSyncCommittee, signerCount int, finalizedHeader bool) *types.LightClientUpdate {
    37  	update := new(types.LightClientUpdate)
    38  	update.NextSyncCommitteeRoot = nextCommittee.Root()
    39  	var attestedHeader types.Header
    40  	if finalizedHeader {
    41  		update.FinalizedHeader = new(types.Header)
    42  		*update.FinalizedHeader, update.NextSyncCommitteeBranch = makeTestHeaderWithMerkleProof(types.SyncPeriodStart(period)+100, params.StateIndexNextSyncCommittee, merkle.Value(update.NextSyncCommitteeRoot))
    43  		attestedHeader, update.FinalityBranch = makeTestHeaderWithMerkleProof(types.SyncPeriodStart(period)+200, params.StateIndexFinalBlock, merkle.Value(update.FinalizedHeader.Hash()))
    44  	} else {
    45  		attestedHeader, update.NextSyncCommitteeBranch = makeTestHeaderWithMerkleProof(types.SyncPeriodStart(period)+2000, params.StateIndexNextSyncCommittee, merkle.Value(update.NextSyncCommitteeRoot))
    46  	}
    47  	update.AttestedHeader = GenerateTestSignedHeader(attestedHeader, config, committee, attestedHeader.Slot+1, signerCount)
    48  	return update
    49  }
    50  
    51  func GenerateTestSignedHeader(header types.Header, config *types.ChainConfig, committee *types.SerializedSyncCommittee, signatureSlot uint64, signerCount int) types.SignedHeader {
    52  	bitmask := makeBitmask(signerCount)
    53  	signingRoot, _ := config.Forks.SigningRoot(header)
    54  	c, _ := dummyVerifier{}.deserializeSyncCommittee(committee)
    55  	return types.SignedHeader{
    56  		Header: header,
    57  		Signature: types.SyncAggregate{
    58  			Signers:   bitmask,
    59  			Signature: makeDummySignature(c.(dummySyncCommittee), signingRoot, bitmask),
    60  		},
    61  		SignatureSlot: signatureSlot,
    62  	}
    63  }
    64  
    65  func GenerateTestCheckpoint(period uint64, committee *types.SerializedSyncCommittee) *types.BootstrapData {
    66  	header, branch := makeTestHeaderWithMerkleProof(types.SyncPeriodStart(period)+200, params.StateIndexSyncCommittee, merkle.Value(committee.Root()))
    67  	return &types.BootstrapData{
    68  		Header:          header,
    69  		Committee:       committee,
    70  		CommitteeRoot:   committee.Root(),
    71  		CommitteeBranch: branch,
    72  	}
    73  }
    74  
    75  func makeBitmask(signerCount int) (bitmask [params.SyncCommitteeBitmaskSize]byte) {
    76  	for i := 0; i < params.SyncCommitteeSize; i++ {
    77  		if mrand.Intn(params.SyncCommitteeSize-i) < signerCount {
    78  			bitmask[i/8] += byte(1) << (i & 7)
    79  			signerCount--
    80  		}
    81  	}
    82  	return
    83  }
    84  
    85  func makeTestHeaderWithMerkleProof(slot, index uint64, value merkle.Value) (types.Header, merkle.Values) {
    86  	var branch merkle.Values
    87  	hasher := sha256.New()
    88  	for index > 1 {
    89  		var proofHash merkle.Value
    90  		rand.Read(proofHash[:])
    91  		hasher.Reset()
    92  		if index&1 == 0 {
    93  			hasher.Write(value[:])
    94  			hasher.Write(proofHash[:])
    95  		} else {
    96  			hasher.Write(proofHash[:])
    97  			hasher.Write(value[:])
    98  		}
    99  		hasher.Sum(value[:0])
   100  		index >>= 1
   101  		branch = append(branch, proofHash)
   102  	}
   103  	return types.Header{Slot: slot, StateRoot: common.Hash(value)}, branch
   104  }
   105  
   106  // syncCommittee holds either a blsSyncCommittee or a fake dummySyncCommittee used for testing
   107  type syncCommittee interface{}
   108  
   109  // committeeSigVerifier verifies sync committee signatures (either proper BLS
   110  // signatures or fake signatures used for testing)
   111  type committeeSigVerifier interface {
   112  	deserializeSyncCommittee(s *types.SerializedSyncCommittee) (syncCommittee, error)
   113  	verifySignature(committee syncCommittee, signedRoot common.Hash, aggregate *types.SyncAggregate) bool
   114  }
   115  
   116  // blsVerifier implements committeeSigVerifier
   117  type blsVerifier struct{}
   118  
   119  // deserializeSyncCommittee implements committeeSigVerifier
   120  func (blsVerifier) deserializeSyncCommittee(s *types.SerializedSyncCommittee) (syncCommittee, error) {
   121  	return s.Deserialize()
   122  }
   123  
   124  // verifySignature implements committeeSigVerifier
   125  func (blsVerifier) verifySignature(committee syncCommittee, signingRoot common.Hash, aggregate *types.SyncAggregate) bool {
   126  	return committee.(*types.SyncCommittee).VerifySignature(signingRoot, aggregate)
   127  }
   128  
   129  type dummySyncCommittee [32]byte
   130  
   131  // dummyVerifier implements committeeSigVerifier
   132  type dummyVerifier struct{}
   133  
   134  // deserializeSyncCommittee implements committeeSigVerifier
   135  func (dummyVerifier) deserializeSyncCommittee(s *types.SerializedSyncCommittee) (syncCommittee, error) {
   136  	var sc dummySyncCommittee
   137  	copy(sc[:], s[:32])
   138  	return sc, nil
   139  }
   140  
   141  // verifySignature implements committeeSigVerifier
   142  func (dummyVerifier) verifySignature(committee syncCommittee, signingRoot common.Hash, aggregate *types.SyncAggregate) bool {
   143  	return aggregate.Signature == makeDummySignature(committee.(dummySyncCommittee), signingRoot, aggregate.Signers)
   144  }
   145  
   146  func makeDummySignature(committee dummySyncCommittee, signingRoot common.Hash, bitmask [params.SyncCommitteeBitmaskSize]byte) (sig [params.BLSSignatureSize]byte) {
   147  	for i, b := range committee[:] {
   148  		sig[i] = b ^ signingRoot[i]
   149  	}
   150  	copy(sig[32:], bitmask[:])
   151  	return
   152  }