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

merge master to atomic base branch #744

Merged
merged 7 commits into from
Jan 14, 2025
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,36 @@ Please make sure your contributions adhere to our coding guidelines:
Before you submit a feature request, please check and make sure that it isn't
possible through some other means.

## Mocks

Mocks are auto-generated using [mockgen](https://pkg.go.dev/go.uber.org/mock/mockgen) and `//go:generate` commands in the code.

* To **re-generate all mocks**, use the command below from the root of the project:

```sh
go generate -run "go.uber.org/mock/mockgen" ./...
```

* To **add** an interface that needs a corresponding mock generated:
* if the file `mocks_generate_test.go` exists in the package where the interface is located, either:
* modify its `//go:generate go run go.uber.org/mock/mockgen` to generate a mock for your interface (preferred); or
* add another `//go:generate go run go.uber.org/mock/mockgen` to generate a mock for your interface according to specific mock generation settings
* if the file `mocks_generate_test.go` does not exist in the package where the interface is located, create it with content (adapt as needed):

```go
// Copyright (C) 2025-2025, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package mypackage

//go:generate go run go.uber.org/mock/mockgen -package=${GOPACKAGE} -destination=mocks_test.go . YourInterface
```

Notes:
1. Ideally generate all mocks to `mocks_test.go` for the package you need to use the mocks for and do not export mocks to other packages. This reduces package dependencies, reduces production code pollution and forces to have locally defined narrow interfaces.
1. Prefer using reflect mode to generate mocks than source mode, unless you need a mock for an unexported interface, which should be rare.
* To **remove** an interface from having a corresponding mock generated:
1. Edit the `mocks_generate_test.go` file in the directory where the interface is defined
1. If the `//go:generate` mockgen command line:
* generates a mock file for multiple interfaces, remove your interface from the line
* generates a mock file only for the interface, remove the entire line. If the file is empty, remove `mocks_generate_test.go` as well.
11 changes: 11 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,17 @@ jobs:
run: echo "TIMEOUT=1200s" >> "$GITHUB_ENV"
- run: go mod download
shell: bash
- name: go mod tidy
run: |
go mod tidy
git diff --exit-code
- name: Mocks are up to date
shell: bash
run: |
grep -lr -E '^// Code generated by MockGen\. DO NOT EDIT\.$' . | xargs -r rm
go generate -run "go.uber.org/mock/mockgen" ./...
git add --intent-to-add --all
git diff --exit-code
- run: ./scripts/build.sh evm
shell: bash
- run: ./scripts/build_test.sh
Expand Down
2 changes: 1 addition & 1 deletion consensus/dummy/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ The dynamic fee algorithm aims to adjust the base fee to handle network congesti

- EIP-1559 is intended for Ethereum where a block is produced roughly every 10s
- C-Chain typically produces blocks every 2 seconds, but the dynamic fee algorithm needs to handle the case that the network quiesces and there are no blocks for a long period of time
- Since C-Chain produces blocks at a different cadence, it adapts EIP-1559 to sum the amount of gas consumed within a 10 second interval instead of using only the amount of gas consumed in the parent block
- Since C-Chain produces blocks at a different cadence, it adapts EIP-1559 to sum the amount of gas consumed within a 10-second interval instead of using only the amount of gas consumed in the parent block

## Consensus Engine Callbacks

Expand Down
2 changes: 1 addition & 1 deletion core/state/pruner/pruner.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ const (
// stateBloomFilePrefix is the filename prefix of state bloom filter.
stateBloomFilePrefix = "statebloom"

// stateBloomFilePrefix is the filename suffix of state bloom filter.
// stateBloomFileSuffix is the filename suffix of state bloom filter.
stateBloomFileSuffix = "bf.gz"

// stateBloomFileTempSuffix is the filename suffix of state bloom filter
Expand Down
14 changes: 0 additions & 14 deletions core/txpool/legacypool/legacypool.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,9 +227,6 @@ type LegacyPool struct {
signer types.Signer
mu sync.RWMutex

// [currentStateLock] is required to allow concurrent access to address nonces
// and balances during reorgs and gossip handling.
currentStateLock sync.Mutex
// closed when the transaction pool is stopped. Any goroutine can listen
// to this to be notified if it should shut down.
generalShutdownChan chan struct{}
Expand Down Expand Up @@ -685,9 +682,6 @@ func (pool *LegacyPool) validateTxBasics(tx *types.Transaction, local bool) erro
// validateTx checks whether a transaction is valid according to the consensus
// rules and adheres to some heuristic limits of the local node (price and size).
func (pool *LegacyPool) validateTx(tx *types.Transaction, local bool) error {
pool.currentStateLock.Lock()
defer pool.currentStateLock.Unlock()

opts := &txpool.ValidationOptionsWithState{
State: pool.currentState,
Rules: pool.chainconfig.Rules(
Expand Down Expand Up @@ -1500,9 +1494,7 @@ func (pool *LegacyPool) reset(oldHead, newHead *types.Header) {
return
}
pool.currentHead.Store(newHead)
pool.currentStateLock.Lock()
pool.currentState = statedb
pool.currentStateLock.Unlock()
pool.pendingNonces = newNoncer(statedb)

// Inject any transactions discarded due to reorgs
Expand All @@ -1515,9 +1507,6 @@ func (pool *LegacyPool) reset(oldHead, newHead *types.Header) {
// future queue to the set of pending transactions. During this process, all
// invalidated transactions (low nonce, low balance) are deleted.
func (pool *LegacyPool) promoteExecutables(accounts []common.Address) []*types.Transaction {
pool.currentStateLock.Lock()
defer pool.currentStateLock.Unlock()

// Track the promoted transactions to broadcast them at once
var promoted []*types.Transaction

Expand Down Expand Up @@ -1724,9 +1713,6 @@ func (pool *LegacyPool) truncateQueue() {
// is always explicitly triggered by SetBaseFee and it would be unnecessary and wasteful
// to trigger a re-heap is this function
func (pool *LegacyPool) demoteUnexecutables() {
pool.currentStateLock.Lock()
defer pool.currentStateLock.Unlock()

// Iterate over all accounts and demote any non-executable transactions
gasLimit := pool.currentHead.Load().GasLimit
for addr, list := range pool.pending {
Expand Down
2 changes: 1 addition & 1 deletion eth/tracers/js/tracer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ func TestHaltBetweenSteps(t *testing.T) {
}
}

// testNoStepExec tests a regular value transfer (no exec), and accessing the statedb
// TestNoStepExec tests a regular value transfer (no exec), and accessing the statedb
// in 'result'
func TestNoStepExec(t *testing.T) {
execTracer := func(code string) []byte {
Expand Down
2 changes: 1 addition & 1 deletion eth/tracers/logger/access_list_tracer.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ func (al accessList) equal(other accessList) bool {
return true
}

// accesslist converts the accesslist to a types.AccessList.
// accessList converts the accesslist to a types.AccessList.
func (al accessList) accessList() types.AccessList {
acl := make(types.AccessList, 0, len(al))
for addr, slots := range al {
Expand Down
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ require (
golang.org/x/sys v0.28.0
golang.org/x/text v0.21.0
golang.org/x/time v0.3.0
golang.org/x/tools v0.22.0
google.golang.org/protobuf v1.34.2
gopkg.in/natefinch/lumberjack.v2 v2.0.0
)
Expand Down Expand Up @@ -120,6 +121,7 @@ require (
go.opentelemetry.io/proto/otlp v1.0.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.26.0 // indirect
golang.org/x/mod v0.18.0 // indirect
golang.org/x/net v0.33.0 // indirect
golang.org/x/term v0.27.0 // indirect
gonum.org/v1/gonum v0.11.0 // indirect
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,8 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0=
golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
Expand Down Expand Up @@ -855,6 +857,8 @@ golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4f
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA=
golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package atomic
package atomictest

import (
"testing"
Expand All @@ -9,21 +9,21 @@ import (
)

type SharedMemories struct {
thisChain atomic.SharedMemory
peerChain atomic.SharedMemory
ThisChain atomic.SharedMemory
PeerChain atomic.SharedMemory
thisChainID ids.ID
peerChainID ids.ID
}

func (s *SharedMemories) addItemsToBeRemovedToPeerChain(ops map[ids.ID]*atomic.Requests) error {
func (s *SharedMemories) AddItemsToBeRemovedToPeerChain(ops map[ids.ID]*atomic.Requests) error {
for _, reqs := range ops {
puts := make(map[ids.ID]*atomic.Requests)
puts[s.thisChainID] = &atomic.Requests{}
for _, key := range reqs.RemoveRequests {
val := []byte{0x1}
puts[s.thisChainID].PutRequests = append(puts[s.thisChainID].PutRequests, &atomic.Element{Key: key, Value: val})
}
if err := s.peerChain.Apply(puts); err != nil {
if err := s.PeerChain.Apply(puts); err != nil {
return err
}
}
Expand All @@ -35,7 +35,7 @@ func (s *SharedMemories) AssertOpsApplied(t *testing.T, ops map[ids.ID]*atomic.R
for _, reqs := range ops {
// should be able to get put requests
for _, elem := range reqs.PutRequests {
val, err := s.peerChain.Get(s.thisChainID, [][]byte{elem.Key})
val, err := s.PeerChain.Get(s.thisChainID, [][]byte{elem.Key})
if err != nil {
t.Fatalf("error finding puts in peerChainMemory: %s", err)
}
Expand All @@ -44,24 +44,24 @@ func (s *SharedMemories) AssertOpsApplied(t *testing.T, ops map[ids.ID]*atomic.R

// should not be able to get remove requests
for _, key := range reqs.RemoveRequests {
_, err := s.thisChain.Get(s.peerChainID, [][]byte{key})
_, err := s.ThisChain.Get(s.peerChainID, [][]byte{key})
assert.EqualError(t, err, "not found")
}
}
}

func (s *SharedMemories) assertOpsNotApplied(t *testing.T, ops map[ids.ID]*atomic.Requests) {
func (s *SharedMemories) AssertOpsNotApplied(t *testing.T, ops map[ids.ID]*atomic.Requests) {
t.Helper()
for _, reqs := range ops {
// should not be able to get put requests
for _, elem := range reqs.PutRequests {
_, err := s.peerChain.Get(s.thisChainID, [][]byte{elem.Key})
_, err := s.PeerChain.Get(s.thisChainID, [][]byte{elem.Key})
assert.EqualError(t, err, "not found")
}

// should be able to get remove requests (these were previously added as puts on peerChain)
for _, key := range reqs.RemoveRequests {
val, err := s.thisChain.Get(s.peerChainID, [][]byte{key})
val, err := s.ThisChain.Get(s.peerChainID, [][]byte{key})
assert.NoError(t, err)
assert.Equal(t, []byte{0x1}, val[0])
}
Expand All @@ -71,8 +71,8 @@ func (s *SharedMemories) assertOpsNotApplied(t *testing.T, ops map[ids.ID]*atomi
// TODO: once tests are moved to atomic package, unexport this function
func NewSharedMemories(atomicMemory *atomic.Memory, thisChainID, peerChainID ids.ID) *SharedMemories {
return &SharedMemories{
thisChain: atomicMemory.NewSharedMemory(thisChainID),
peerChain: atomicMemory.NewSharedMemory(peerChainID),
ThisChain: atomicMemory.NewSharedMemory(thisChainID),
PeerChain: atomicMemory.NewSharedMemory(peerChainID),
thisChainID: thisChainID,
peerChainID: peerChainID,
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// (c) 2020-2021, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package atomic
package atomictest

import (
"math/big"
Expand All @@ -17,20 +17,21 @@ import (
"github.com/ava-labs/avalanchego/utils/set"
"github.com/ava-labs/avalanchego/utils/wrappers"
"github.com/ava-labs/coreth/params"
"github.com/ava-labs/coreth/plugin/evm/atomic"
)

const testCodecVersion = 0

var testTxCodec codec.Manager
var TestTxCodec codec.Manager

func init() {
testTxCodec = codec.NewDefaultManager()
TestTxCodec = codec.NewDefaultManager()
c := linearcodec.NewDefault()

errs := wrappers.Errs{}
errs.Add(
c.RegisterType(&TestUnsignedTx{}),
testTxCodec.RegisterCodec(testCodecVersion, c),
TestTxCodec.RegisterCodec(testCodecVersion, c),
)

if errs.Errored() {
Expand All @@ -52,7 +53,7 @@ type TestUnsignedTx struct {
EVMStateTransferV error
}

var _ UnsignedAtomicTx = &TestUnsignedTx{}
var _ atomic.UnsignedAtomicTx = &TestUnsignedTx{}

// GasUsed implements the UnsignedAtomicTx interface
func (t *TestUnsignedTx) GasUsed(fixedFee bool) (uint64, error) { return t.GasUsedV, nil }
Expand Down Expand Up @@ -84,19 +85,19 @@ func (t *TestUnsignedTx) SignedBytes() []byte { return t.SignedBytesV }
func (t *TestUnsignedTx) InputUTXOs() set.Set[ids.ID] { return t.InputUTXOsV }

// SemanticVerify implements the UnsignedAtomicTx interface
func (t *TestUnsignedTx) SemanticVerify(backend *VerifierBackend, stx *Tx, parent AtomicBlockContext, baseFee *big.Int) error {
func (t *TestUnsignedTx) SemanticVerify(backend *atomic.VerifierBackend, stx *atomic.Tx, parent atomic.AtomicBlockContext, baseFee *big.Int) error {
return t.SemanticVerifyV
}

// EVMStateTransfer implements the UnsignedAtomicTx interface
func (t *TestUnsignedTx) EVMStateTransfer(ctx *snow.Context, state StateDB) error {
func (t *TestUnsignedTx) EVMStateTransfer(ctx *snow.Context, state atomic.StateDB) error {
return t.EVMStateTransferV
}

var TestBlockchainID = ids.GenerateTestID()

func GenerateTestImportTxWithGas(gasUsed uint64, burned uint64) *Tx {
return &Tx{
func GenerateTestImportTxWithGas(gasUsed uint64, burned uint64) *atomic.Tx {
return &atomic.Tx{
UnsignedAtomicTx: &TestUnsignedTx{
IDV: ids.GenerateTestID(),
GasUsedV: gasUsed,
Expand All @@ -112,8 +113,8 @@ func GenerateTestImportTxWithGas(gasUsed uint64, burned uint64) *Tx {
}
}

func GenerateTestImportTx() *Tx {
return &Tx{
func GenerateTestImportTx() *atomic.Tx {
return &atomic.Tx{
UnsignedAtomicTx: &TestUnsignedTx{
IDV: ids.GenerateTestID(),
AcceptRequestsBlockchainIDV: TestBlockchainID,
Expand All @@ -127,8 +128,8 @@ func GenerateTestImportTx() *Tx {
}
}

func GenerateTestExportTx() *Tx {
return &Tx{
func GenerateTestExportTx() *atomic.Tx {
return &atomic.Tx{
UnsignedAtomicTx: &TestUnsignedTx{
IDV: ids.GenerateTestID(),
AcceptRequestsBlockchainIDV: TestBlockchainID,
Expand All @@ -148,7 +149,7 @@ func GenerateTestExportTx() *Tx {
}
}

func NewTestTx() *Tx {
func NewTestTx() *atomic.Tx {
txType := rand.Intn(2)
switch txType {
case 0:
Expand All @@ -160,8 +161,8 @@ func NewTestTx() *Tx {
}
}

func NewTestTxs(numTxs int) []*Tx {
txs := make([]*Tx, 0, numTxs)
func NewTestTxs(numTxs int) []*atomic.Tx {
txs := make([]*atomic.Tx, 0, numTxs)
for i := 0; i < numTxs; i++ {
txs = append(txs, NewTestTx())
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
// (c) 2019-2024, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package atomic
package atomictest

import (
avalancheatomic "github.com/ava-labs/avalanchego/chains/atomic"
"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/coreth/plugin/evm/atomic"
)

func ConvertToAtomicOps(tx *Tx) (map[ids.ID]*avalancheatomic.Requests, error) {
func ConvertToAtomicOps(tx *atomic.Tx) (map[ids.ID]*avalancheatomic.Requests, error) {
id, reqs, err := tx.AtomicOps()
if err != nil {
return nil, err
Expand Down
Loading
Loading