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 }