Skip to content

Commit

Permalink
Merge branch 'ethereum:master' into portal
Browse files Browse the repository at this point in the history
  • Loading branch information
GrapeBaBa authored Mar 27, 2024
2 parents 923ec25 + 304879d commit 66de3b2
Show file tree
Hide file tree
Showing 72 changed files with 580 additions and 234 deletions.
2 changes: 1 addition & 1 deletion accounts/abi/argument.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ func (arguments Arguments) Copy(v interface{}, values []interface{}) error {
return arguments.copyAtomic(v, values[0])
}

// unpackAtomic unpacks ( hexdata -> go ) a single value
// copyAtomic copies ( hexdata -> go ) a single value
func (arguments Arguments) copyAtomic(v interface{}, marshalledValues interface{}) error {
dst := reflect.ValueOf(v).Elem()
src := reflect.ValueOf(marshalledValues)
Expand Down
2 changes: 1 addition & 1 deletion accounts/keystore/account_cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ var (
}
)

// waitWatcherStarts waits up to 1s for the keystore watcher to start.
// waitWatcherStart waits up to 1s for the keystore watcher to start.
func waitWatcherStart(ks *KeyStore) bool {
// On systems where file watch is not supported, just return "ok".
if !ks.cache.watcher.enabled() {
Expand Down
35 changes: 24 additions & 11 deletions beacon/blsync/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,9 @@ var (
)

func makeChainConfig(ctx *cli.Context) lightClientConfig {
utils.CheckExclusive(ctx, utils.MainnetFlag, utils.GoerliFlag, utils.SepoliaFlag)
customConfig := ctx.IsSet(utils.BeaconConfigFlag.Name) || ctx.IsSet(utils.BeaconGenesisRootFlag.Name) || ctx.IsSet(utils.BeaconGenesisTimeFlag.Name)
var config lightClientConfig
customConfig := ctx.IsSet(utils.BeaconConfigFlag.Name)
utils.CheckExclusive(ctx, utils.MainnetFlag, utils.GoerliFlag, utils.SepoliaFlag, utils.BeaconConfigFlag)
switch {
case ctx.Bool(utils.MainnetFlag.Name):
config = MainnetConfig
Expand All @@ -87,24 +87,37 @@ func makeChainConfig(ctx *cli.Context) lightClientConfig {
config = MainnetConfig
}
}
if customConfig && config.Forks != nil {
utils.Fatalf("Cannot use custom beacon chain config flags in combination with pre-defined network config")
}
if ctx.IsSet(utils.BeaconGenesisRootFlag.Name) {
// Genesis root and time should always be specified together with custom chain config
if customConfig {
if !ctx.IsSet(utils.BeaconGenesisRootFlag.Name) {
utils.Fatalf("Custom beacon chain config is specified but genesis root is missing")
}
if !ctx.IsSet(utils.BeaconGenesisTimeFlag.Name) {
utils.Fatalf("Custom beacon chain config is specified but genesis time is missing")
}
if !ctx.IsSet(utils.BeaconCheckpointFlag.Name) {
utils.Fatalf("Custom beacon chain config is specified but checkpoint is missing")
}
config.ChainConfig = &types.ChainConfig{
GenesisTime: ctx.Uint64(utils.BeaconGenesisTimeFlag.Name),
}
if c, err := hexutil.Decode(ctx.String(utils.BeaconGenesisRootFlag.Name)); err == nil && len(c) <= 32 {
copy(config.GenesisValidatorsRoot[:len(c)], c)
} else {
utils.Fatalf("Invalid hex string", "beacon.genesis.gvroot", ctx.String(utils.BeaconGenesisRootFlag.Name), "error", err)
}
}
if ctx.IsSet(utils.BeaconGenesisTimeFlag.Name) {
config.GenesisTime = ctx.Uint64(utils.BeaconGenesisTimeFlag.Name)
}
if ctx.IsSet(utils.BeaconConfigFlag.Name) {
if err := config.ChainConfig.LoadForks(ctx.String(utils.BeaconConfigFlag.Name)); err != nil {
utils.Fatalf("Could not load beacon chain config file", "file name", ctx.String(utils.BeaconConfigFlag.Name), "error", err)
}
} else {
if ctx.IsSet(utils.BeaconGenesisRootFlag.Name) {
utils.Fatalf("Genesis root is specified but custom beacon chain config is missing")
}
if ctx.IsSet(utils.BeaconGenesisTimeFlag.Name) {
utils.Fatalf("Genesis time is specified but custom beacon chain config is missing")
}
}
// Checkpoint is required with custom chain config and is optional with pre-defined config
if ctx.IsSet(utils.BeaconCheckpointFlag.Name) {
if c, err := hexutil.Decode(ctx.String(utils.BeaconCheckpointFlag.Name)); err == nil && len(c) <= 32 {
copy(config.Checkpoint[:len(c)], c)
Expand Down
108 changes: 75 additions & 33 deletions beacon/light/api/light_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@
package api

import (
"context"
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
"sync"
"time"

"github.com/donovanhide/eventsource"
Expand Down Expand Up @@ -287,7 +289,7 @@ func decodeFinalityUpdate(enc []byte) (types.FinalityUpdate, error) {
}, nil
}

// GetHead fetches and validates the beacon header with the given blockRoot.
// GetHeader fetches and validates the beacon header with the given blockRoot.
// If blockRoot is null hash then the latest head header is fetched.
func (api *BeaconLightApi) GetHeader(blockRoot common.Hash) (types.Header, error) {
var blockId string
Expand Down Expand Up @@ -416,39 +418,34 @@ type HeadEventListener struct {
// The callbacks are also called for the current head and optimistic head at startup.
// They are never called concurrently.
func (api *BeaconLightApi) StartHeadListener(listener HeadEventListener) func() {
closeCh := make(chan struct{}) // initiate closing the stream
closedCh := make(chan struct{}) // stream closed (or failed to create)
stoppedCh := make(chan struct{}) // sync loop stopped
streamCh := make(chan *eventsource.Stream, 1)
var (
ctx, closeCtx = context.WithCancel(context.Background())
streamCh = make(chan *eventsource.Stream, 1)
wg sync.WaitGroup
)

// When connected to a Lodestar node the subscription blocks until the first actual
// event arrives; therefore we create the subscription in a separate goroutine while
// letting the main goroutine sync up to the current head.
wg.Add(1)
go func() {
defer close(closedCh)
// when connected to a Lodestar node the subscription blocks until the
// first actual event arrives; therefore we create the subscription in
// a separate goroutine while letting the main goroutine sync up to the
// current head
req, err := http.NewRequest("GET", api.url+
"/eth/v1/events?topics=head&topics=light_client_optimistic_update&topics=light_client_finality_update", nil)
if err != nil {
listener.OnError(fmt.Errorf("error creating event subscription request: %v", err))
return
}
for k, v := range api.customHeaders {
req.Header.Set(k, v)
}
stream, err := eventsource.SubscribeWithRequest("", req)
if err != nil {
listener.OnError(fmt.Errorf("error creating event subscription: %v", err))
close(streamCh)
defer wg.Done()
stream := api.startEventStream(ctx, &listener)
if stream == nil {
// This case happens when the context was closed.
return
}
// Stream was opened, wait for close signal.
streamCh <- stream
<-closeCh
<-ctx.Done()
stream.Close()
}()

wg.Add(1)
go func() {
defer close(stoppedCh)
defer wg.Done()

// Request initial data.
if head, err := api.GetHeader(common.Hash{}); err == nil {
listener.OnNewHead(head.Slot, head.Hash())
}
Expand All @@ -458,39 +455,50 @@ func (api *BeaconLightApi) StartHeadListener(listener HeadEventListener) func()
if finalityUpdate, err := api.GetFinalityUpdate(); err == nil {
listener.OnFinality(finalityUpdate)
}
stream := <-streamCh
if stream == nil {

// Receive the stream.
var stream *eventsource.Stream
select {
case stream = <-streamCh:
case <-ctx.Done():
return
}

for {
select {
case <-ctx.Done():
stream.Close()

case event, ok := <-stream.Events:
if !ok {
return
}
switch event.Event() {
case "head":
if slot, blockRoot, err := decodeHeadEvent([]byte(event.Data())); err == nil {
slot, blockRoot, err := decodeHeadEvent([]byte(event.Data()))
if err == nil {
listener.OnNewHead(slot, blockRoot)
} else {
listener.OnError(fmt.Errorf("error decoding head event: %v", err))
}
case "light_client_optimistic_update":
if signedHead, err := decodeOptimisticHeadUpdate([]byte(event.Data())); err == nil {
signedHead, err := decodeOptimisticHeadUpdate([]byte(event.Data()))
if err == nil {
listener.OnSignedHead(signedHead)
} else {
listener.OnError(fmt.Errorf("error decoding optimistic update event: %v", err))
}
case "light_client_finality_update":
if finalityUpdate, err := decodeFinalityUpdate([]byte(event.Data())); err == nil {
finalityUpdate, err := decodeFinalityUpdate([]byte(event.Data()))
if err == nil {
listener.OnFinality(finalityUpdate)
} else {
listener.OnError(fmt.Errorf("error decoding finality update event: %v", err))
}
default:
listener.OnError(fmt.Errorf("unexpected event: %s", event.Event()))
}

case err, ok := <-stream.Errors:
if !ok {
return
Expand All @@ -499,9 +507,43 @@ func (api *BeaconLightApi) StartHeadListener(listener HeadEventListener) func()
}
}
}()

return func() {
close(closeCh)
<-closedCh
<-stoppedCh
closeCtx()
wg.Wait()
}
}

// startEventStream establishes an event stream. This will keep retrying until the stream has been
// established. It can only return nil when the context is canceled.
func (api *BeaconLightApi) startEventStream(ctx context.Context, listener *HeadEventListener) *eventsource.Stream {
for retry := true; retry; retry = ctxSleep(ctx, 5*time.Second) {
path := "/eth/v1/events?topics=head&topics=light_client_optimistic_update&topics=light_client_finality_update"
req, err := http.NewRequestWithContext(ctx, "GET", api.url+path, nil)
if err != nil {
listener.OnError(fmt.Errorf("error creating event subscription request: %v", err))
continue
}
for k, v := range api.customHeaders {
req.Header.Set(k, v)
}
stream, err := eventsource.SubscribeWithRequest("", req)
if err != nil {
listener.OnError(fmt.Errorf("error creating event subscription: %v", err))
continue
}
return stream
}
return nil
}

func ctxSleep(ctx context.Context, timeout time.Duration) (ok bool) {
timer := time.NewTimer(timeout)
defer timer.Stop()
select {
case <-timer.C:
return true
case <-ctx.Done():
return false
}
}
4 changes: 2 additions & 2 deletions beacon/light/head_tracker.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,15 @@ func (h *HeadTracker) ValidatedHead() (types.SignedHeader, bool) {
return h.signedHead, h.hasSignedHead
}

// ValidatedHead returns the latest validated head.
// ValidatedFinality returns the latest validated finality.
func (h *HeadTracker) ValidatedFinality() (types.FinalityUpdate, bool) {
h.lock.RLock()
defer h.lock.RUnlock()

return h.finalityUpdate, h.hasFinalityUpdate
}

// Validate validates the given signed head. If the head is successfully validated
// ValidateHead validates the given signed head. If the head is successfully validated
// and it is better than the old validated head (higher slot or same slot and more
// signers) then ValidatedHead is updated. The boolean return flag signals if
// ValidatedHead has been changed.
Expand Down
4 changes: 2 additions & 2 deletions beacon/light/request/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ func (s *serverWithTimeout) startTimeout(reqData RequestResponse) {
})
}

// stop stops all goroutines associated with the server.
// unsubscribe stops all goroutines associated with the server.
func (s *serverWithTimeout) unsubscribe() {
s.lock.Lock()
defer s.lock.Unlock()
Expand Down Expand Up @@ -337,7 +337,7 @@ func (s *serverWithLimits) sendRequest(request Request) (reqId ID) {
return s.serverWithTimeout.sendRequest(request)
}

// stop stops all goroutines associated with the server.
// unsubscribe stops all goroutines associated with the server.
func (s *serverWithLimits) unsubscribe() {
s.lock.Lock()
defer s.lock.Unlock()
Expand Down
4 changes: 2 additions & 2 deletions beacon/light/sync/head_sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ func (s *HeadSync) newSignedHead(server request.Server, signedHead types.SignedH
s.headTracker.ValidateHead(signedHead)
}

// newSignedHead handles received signed head; either validates it if the chain
// newFinalityUpdate handles received finality update; either validates it if the chain
// is properly synced or stores it for further validation.
func (s *HeadSync) newFinalityUpdate(server request.Server, finalityUpdate types.FinalityUpdate) {
if !s.chainInit || types.SyncPeriod(finalityUpdate.SignatureSlot) > s.nextSyncPeriod {
Expand All @@ -111,7 +111,7 @@ func (s *HeadSync) newFinalityUpdate(server request.Server, finalityUpdate types
s.headTracker.ValidateFinality(finalityUpdate)
}

// processUnvalidatedHeads iterates the list of unvalidated heads and validates
// processUnvalidated iterates the list of unvalidated heads and validates
// those which can be validated.
func (s *HeadSync) processUnvalidated() {
if !s.chainInit {
Expand Down
2 changes: 1 addition & 1 deletion beacon/types/exec_header.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ type ExecutionHeader struct {
obj headerObject
}

// HeaderFromJSON decodes an execution header from JSON data provided by
// ExecutionHeaderFromJSON decodes an execution header from JSON data provided by
// the beacon chain API.
func ExecutionHeaderFromJSON(forkName string, data []byte) (*ExecutionHeader, error) {
var obj headerObject
Expand Down
2 changes: 1 addition & 1 deletion cmd/geth/attach_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func TestAttachWithHeaders(t *testing.T) {
// This is fixed in a follow-up PR.
}

// TestAttachWithHeaders tests that 'geth db --remotedb' with custom headers works, i.e
// TestRemoteDbWithHeaders tests that 'geth db --remotedb' with custom headers works, i.e
// that custom headers are forwarded to the target.
func TestRemoteDbWithHeaders(t *testing.T) {
t.Parallel()
Expand Down
2 changes: 1 addition & 1 deletion cmd/utils/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ func testExport(t *testing.T, f string) {
}
}

// testDeletion tests if the deletion markers can be exported/imported correctly
// TestDeletionExport tests if the deletion markers can be exported/imported correctly
func TestDeletionExport(t *testing.T) {
f := fmt.Sprintf("%v/tempdump", os.TempDir())
defer func() {
Expand Down
2 changes: 1 addition & 1 deletion common/lru/basiclru.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ func (l *list[T]) init() {
l.root.prev = &l.root
}

// push adds an element to the front of the list.
// pushElem adds an element to the front of the list.
func (l *list[T]) pushElem(e *listElem[T]) {
e.prev = &l.root
e.next = l.root.next
Expand Down
2 changes: 1 addition & 1 deletion consensus/ethash/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -568,7 +568,7 @@ var (
u256_32 = uint256.NewInt(32)
)

// AccumulateRewards credits the coinbase of the given block with the mining
// accumulateRewards credits the coinbase of the given block with the mining
// reward. The total reward consists of the static block reward and rewards for
// included uncles. The coinbase of each uncle block is also rewarded.
func accumulateRewards(config *params.ChainConfig, stateDB *state.StateDB, header *types.Header, uncles []*types.Header) {
Expand Down
2 changes: 1 addition & 1 deletion core/asm/lexer.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ func (l *lexer) ignore() {
l.start = l.pos
}

// Accepts checks whether the given input matches the next rune
// accept checks whether the given input matches the next rune
func (l *lexer) accept(valid string) bool {
if strings.ContainsRune(valid, l.next()) {
return true
Expand Down
Loading

0 comments on commit 66de3b2

Please sign in to comment.