Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use atomic pointer in go 1.19 #446

Merged
merged 26 commits into from Aug 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Expand Up @@ -29,7 +29,7 @@ jobs:

- uses: actions/setup-go@v3
with:
go-version: 1.18.x
go-version: 1.19.x

- name: Install dependencies on Linux
if: runner.os == 'Linux'
Expand Down
1 change: 1 addition & 0 deletions .golangci.yml
Expand Up @@ -50,6 +50,7 @@ linters:
- unconvert
- unparam
- wsl
- asasalint
#- errorlint causes stack overflow. TODO: recheck after each golangci update

linters-settings:
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Expand Up @@ -75,7 +75,7 @@ lint:

lintci-deps:
rm -f ./build/bin/golangci-lint
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b ./build/bin v1.46.0
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b ./build/bin v1.48.0

goimports:
goimports -local "$(PACKAGE)" -w .
Expand Down
8 changes: 5 additions & 3 deletions accounts/abi/bind/auth.go
Expand Up @@ -21,7 +21,6 @@ import (
"crypto/ecdsa"
"errors"
"io"
"io/ioutil"
"math/big"

"github.com/ethereum/go-ethereum/accounts"
Expand All @@ -45,14 +44,17 @@ var ErrNotAuthorized = errors.New("not authorized to sign this account")
// Deprecated: Use NewTransactorWithChainID instead.
func NewTransactor(keyin io.Reader, passphrase string) (*TransactOpts, error) {
log.Warn("WARNING: NewTransactor has been deprecated in favour of NewTransactorWithChainID")
json, err := ioutil.ReadAll(keyin)

json, err := io.ReadAll(keyin)
if err != nil {
return nil, err
}

key, err := keystore.DecryptKey(json, passphrase)
if err != nil {
return nil, err
}

return NewKeyedTransactor(key.PrivateKey), nil
}

Expand Down Expand Up @@ -106,7 +108,7 @@ func NewKeyedTransactor(key *ecdsa.PrivateKey) *TransactOpts {
// NewTransactorWithChainID is a utility method to easily create a transaction signer from
// an encrypted json key stream and the associated passphrase.
func NewTransactorWithChainID(keyin io.Reader, passphrase string, chainID *big.Int) (*TransactOpts, error) {
json, err := ioutil.ReadAll(keyin)
json, err := io.ReadAll(keyin)
if err != nil {
return nil, err
}
Expand Down
7 changes: 3 additions & 4 deletions accounts/abi/bind/bind_test.go
Expand Up @@ -18,7 +18,6 @@ package bind

import (
"fmt"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
Expand Down Expand Up @@ -1966,7 +1965,7 @@ func TestGolangBindings(t *testing.T) {
t.Skip("go sdk not found for testing")
}
// Create a temporary workspace for the test suite
ws, err := ioutil.TempDir("", "binding-test")
ws, err := os.MkdirTemp("", "binding-test")
if err != nil {
t.Fatalf("failed to create temporary workspace: %v", err)
}
Expand All @@ -1990,7 +1989,7 @@ func TestGolangBindings(t *testing.T) {
if err != nil {
t.Fatalf("test %d: failed to generate binding: %v", i, err)
}
if err = ioutil.WriteFile(filepath.Join(pkg, strings.ToLower(tt.name)+".go"), []byte(bind), 0600); err != nil {
if err = os.WriteFile(filepath.Join(pkg, strings.ToLower(tt.name)+".go"), []byte(bind), 0600); err != nil {
t.Fatalf("test %d: failed to write binding: %v", i, err)
}
// Generate the test file with the injected test code
Expand All @@ -2006,7 +2005,7 @@ func TestGolangBindings(t *testing.T) {
%s
}
`, tt.imports, tt.name, tt.tester)
if err := ioutil.WriteFile(filepath.Join(pkg, strings.ToLower(tt.name)+"_test.go"), []byte(code), 0600); err != nil {
if err := os.WriteFile(filepath.Join(pkg, strings.ToLower(tt.name)+"_test.go"), []byte(code), 0600); err != nil {
t.Fatalf("test %d: failed to write tests: %v", i, err)
}
})
Expand Down
6 changes: 2 additions & 4 deletions cmd/geth/config.go
Expand Up @@ -18,14 +18,12 @@ package main

import (
"fmt"
"io/ioutil"
"math/big"
"os"
"time"

"gopkg.in/urfave/cli.v1"

"github.com/BurntSushi/toml"
"gopkg.in/urfave/cli.v1"

"github.com/ethereum/go-ethereum/accounts/external"
"github.com/ethereum/go-ethereum/accounts/keystore"
Expand Down Expand Up @@ -71,7 +69,7 @@ type gethConfig struct {
}

func loadConfig(file string, cfg *gethConfig) error {
data, err := ioutil.ReadFile(file)
data, err := os.ReadFile(file)
if err != nil {
return err
}
Expand Down
61 changes: 38 additions & 23 deletions consensus/bor/bor.go
Expand Up @@ -12,6 +12,7 @@ import (
"sort"
"strconv"
"sync"
"sync/atomic"
"time"

lru "github.com/hashicorp/golang-lru"
Expand Down Expand Up @@ -97,6 +98,9 @@ var (
// errOutOfRangeChain is returned if an authorization list is attempted to
// be modified via out-of-range or non-contiguous headers.
errOutOfRangeChain = errors.New("out of range or non-contiguous chain")

errUncleDetected = errors.New("uncles not allowed")
errUnknownValidators = errors.New("unknown validators")
)

// SignerFn is a signer callback function to request a header to be signed by a
Expand Down Expand Up @@ -210,9 +214,7 @@ type Bor struct {
recents *lru.ARCCache // Snapshots for recent block to speed up reorgs
signatures *lru.ARCCache // Signatures of recent blocks to speed up mining

signer common.Address // Ethereum address of the signing key
signFn SignerFn // Signer function to authorize hashes with
lock sync.RWMutex // Protects the signer fields
authorizedSigner atomic.Pointer[signer] // Ethereum address and sign function of the signing key

ethAPI api.Caller
spanner Spanner
Expand All @@ -225,6 +227,11 @@ type Bor struct {
closeOnce sync.Once
}

type signer struct {
signer common.Address // Ethereum address of the signing key
signFn SignerFn // Signer function to authorize hashes with
}

// New creates a Matic Bor consensus engine.
func New(
chainConfig *params.ChainConfig,
Expand Down Expand Up @@ -257,6 +264,14 @@ func New(
HeimdallClient: heimdallClient,
}

c.authorizedSigner.Store(&signer{
common.Address{},
func(_ accounts.Account, _ string, i []byte) ([]byte, error) {
// return an error to prevent panics
return nil, &UnauthorizedSignerError{0, common.Address{}.Bytes()}
},
})

// make sure we can decode all the GenesisAlloc in the BorConfig.
for key, genesisAlloc := range c.config.BlockAlloc {
if _, err := decodeGenesisAlloc(genesisAlloc); err != nil {
Expand Down Expand Up @@ -572,7 +587,7 @@ func (c *Bor) snapshot(chain consensus.ChainHeaderReader, number uint64, hash co
// uncles as this consensus mechanism doesn't permit uncles.
func (c *Bor) VerifyUncles(_ consensus.ChainReader, block *types.Block) error {
if len(block.Uncles()) > 0 {
return errors.New("uncles not allowed")
return errUncleDetected
}

return nil
Expand Down Expand Up @@ -656,8 +671,10 @@ func (c *Bor) Prepare(chain consensus.ChainHeaderReader, header *types.Header) e
return err
}

currentSigner := *c.authorizedSigner.Load()

// Set the correct difficulty
header.Difficulty = new(big.Int).SetUint64(Difficulty(snap.ValidatorSet, c.signer))
header.Difficulty = new(big.Int).SetUint64(Difficulty(snap.ValidatorSet, currentSigner.signer))

// Ensure the extra data has all it's components
if len(header.Extra) < extraVanity {
Expand All @@ -670,7 +687,7 @@ func (c *Bor) Prepare(chain consensus.ChainHeaderReader, header *types.Header) e
if IsSprintStart(number+1, c.config.Sprint) {
newValidators, err := c.spanner.GetCurrentValidators(context.Background(), header.ParentHash, number+1)
if err != nil {
return errors.New("unknown validators")
return errUnknownValidators
}

// sort validator by address
Expand All @@ -695,8 +712,8 @@ func (c *Bor) Prepare(chain consensus.ChainHeaderReader, header *types.Header) e

var succession int
// if signer is not empty
if c.signer != (common.Address{}) {
succession, err = snap.GetSignerSuccessionNumber(c.signer)
if currentSigner.signer != (common.Address{}) {
succession, err = snap.GetSignerSuccessionNumber(currentSigner.signer)
if err != nil {
return err
}
Expand Down Expand Up @@ -774,7 +791,7 @@ func (c *Bor) changeContractCodeIfNeeded(headerNumber uint64, state *state.State
if blockNumber == strconv.FormatUint(headerNumber, 10) {
allocs, err := decodeGenesisAlloc(genesisAlloc)
if err != nil {
return fmt.Errorf("failed to decode genesis alloc: %v", err)
return fmt.Errorf("failed to decode genesis alloc: %w", err)
}

for addr, account := range allocs {
Expand Down Expand Up @@ -838,12 +855,11 @@ func (c *Bor) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header *typ

// Authorize injects a private key into the consensus engine to mint new blocks
// with.
func (c *Bor) Authorize(signer common.Address, signFn SignerFn) {
c.lock.Lock()
defer c.lock.Unlock()

c.signer = signer
c.signFn = signFn
func (c *Bor) Authorize(currentSigner common.Address, signFn SignerFn) {
c.authorizedSigner.Store(&signer{
signer: currentSigner,
signFn: signFn,
})
}

// Seal implements consensus.Engine, attempting to create a sealed block using
Expand All @@ -860,23 +876,22 @@ func (c *Bor) Seal(chain consensus.ChainHeaderReader, block *types.Block, result
log.Info("Sealing paused, waiting for transactions")
return nil
}

// Don't hold the signer fields for the entire sealing procedure
c.lock.RLock()
signer, signFn := c.signer, c.signFn
c.lock.RUnlock()
currentSigner := *c.authorizedSigner.Load()

snap, err := c.snapshot(chain, number-1, header.ParentHash, nil)
if err != nil {
return err
}

// Bail out if we're unauthorized to sign a block
if !snap.ValidatorSet.HasAddress(signer) {
if !snap.ValidatorSet.HasAddress(currentSigner.signer) {
// Check the UnauthorizedSignerError.Error() msg to see why we pass number-1
return &UnauthorizedSignerError{number - 1, signer.Bytes()}
return &UnauthorizedSignerError{number - 1, currentSigner.signer.Bytes()}
}

successionNumber, err := snap.GetSignerSuccessionNumber(signer)
successionNumber, err := snap.GetSignerSuccessionNumber(currentSigner.signer)
if err != nil {
return err
}
Expand All @@ -887,7 +902,7 @@ func (c *Bor) Seal(chain consensus.ChainHeaderReader, block *types.Block, result
wiggle := time.Duration(successionNumber) * time.Duration(c.config.CalculateBackupMultiplier(number)) * time.Second

// Sign all the things!
err = Sign(signFn, signer, header, c.config)
err = Sign(currentSigner.signFn, currentSigner.signer, header, c.config)
if err != nil {
return err
}
Expand Down Expand Up @@ -949,7 +964,7 @@ func (c *Bor) CalcDifficulty(chain consensus.ChainHeaderReader, _ uint64, parent
return nil
}

return new(big.Int).SetUint64(Difficulty(snap.ValidatorSet, c.signer))
return new(big.Int).SetUint64(Difficulty(snap.ValidatorSet, c.authorizedSigner.Load().signer))
}

// SealHash returns the hash of a block prior to it being sealed.
Expand Down
16 changes: 11 additions & 5 deletions consensus/bor/heimdallgrpc/state_sync.go
Expand Up @@ -3,10 +3,10 @@ package heimdallgrpc
import (
"context"

proto "github.com/maticnetwork/polyproto/heimdall"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus/bor/clerk"

proto "github.com/maticnetwork/polyproto/heimdall"
)

func (h *HeimdallGRPCClient) StateSyncEvents(ctx context.Context, fromID uint64, to int64) ([]*clerk.EventRecordWithTime, error) {
Expand All @@ -18,13 +18,19 @@ func (h *HeimdallGRPCClient) StateSyncEvents(ctx context.Context, fromID uint64,
Limit: uint64(stateFetchLimit),
}

res, err := h.client.StateSyncEvents(ctx, req)
var (
res proto.Heimdall_StateSyncEventsClient
events *proto.StateSyncEventsResponse
err error
)

res, err = h.client.StateSyncEvents(ctx, req)
if err != nil {
return nil, err
}

for {
events, err := res.Recv()
events, err = res.Recv()
if err != nil {
break
}
Expand All @@ -45,5 +51,5 @@ func (h *HeimdallGRPCClient) StateSyncEvents(ctx context.Context, fromID uint64,
}
}

return eventRecords, nil
return eventRecords, err
}
10 changes: 6 additions & 4 deletions eth/downloader/downloader.go
Expand Up @@ -207,7 +207,7 @@ type BlockChain interface {
}

// New creates a new downloader to fetch hashes and blocks from remote peers.
//nolint: staticcheck
// nolint: staticcheck
func New(checkpoint uint64, stateDb ethdb.Database, mux *event.TypeMux, chain BlockChain, lightchain LightChain, dropPeer peerDropFn, success func(), whitelistService ethereum.ChainValidator) *Downloader {
if lightchain == nil {
lightchain = chain
Expand Down Expand Up @@ -729,9 +729,11 @@ func (d *Downloader) fetchHead(p *peerConnection) (head *types.Header, pivot *ty
// calculateRequestSpan calculates what headers to request from a peer when trying to determine the
// common ancestor.
// It returns parameters to be used for peer.RequestHeadersByNumber:
// from - starting block number
// count - number of headers to request
// skip - number of headers to skip
//
// from - starting block number
// count - number of headers to request
// skip - number of headers to skip
//
// and also returns 'max', the last block which is expected to be returned by the remote peers,
// given the (from,count,skip)
func calculateRequestSpan(remoteHeight, localHeight uint64) (int64, int, int, uint64) {
Expand Down
6 changes: 5 additions & 1 deletion eth/filters/test_backend.go
Expand Up @@ -48,7 +48,11 @@ func (b *TestBackend) GetBorBlockReceipt(ctx context.Context, hash common.Hash)

func (b *TestBackend) GetBorBlockLogs(ctx context.Context, hash common.Hash) ([]*types.Log, error) {
receipt, err := b.GetBorBlockReceipt(ctx, hash)
if receipt == nil || err != nil {
if err != nil {
return []*types.Log{}, err
}

if receipt == nil {
return []*types.Log{}, nil
}

Expand Down
2 changes: 1 addition & 1 deletion go.mod
@@ -1,6 +1,6 @@
module github.com/ethereum/go-ethereum

go 1.18
go 1.19

require (
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.3.0
Expand Down
4 changes: 2 additions & 2 deletions internal/cli/server/config_legacy.go
Expand Up @@ -2,13 +2,13 @@ package server

import (
"fmt"
"io/ioutil"
"os"

"github.com/BurntSushi/toml"
)

func readLegacyConfig(path string) (*Config, error) {
data, err := ioutil.ReadFile(path)
data, err := os.ReadFile(path)
tomlData := string(data)

if err != nil {
Expand Down