Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
d24bd6a
lint enable gosec
JonathanOppenheimer Sep 10, 2025
b465187
make tests deterministic
JonathanOppenheimer Sep 10, 2025
969b51e
Merge branch 'master' into lint-enable-gosec
JonathanOppenheimer Sep 11, 2025
01395ef
Merge branch 'master' into lint-enable-gosec
JonathanOppenheimer Sep 12, 2025
3b51256
Update plugin/evm/message/helpers_test.go
JonathanOppenheimer Sep 12, 2025
fb0a1c6
first round stephen reviews
JonathanOppenheimer Sep 12, 2025
6021c88
redo rand implementation
JonathanOppenheimer Sep 12, 2025
e2dd1c0
Merge branch 'master' into lint-enable-gosec
JonathanOppenheimer Sep 12, 2025
eab8c81
Merge branch 'master' into lint-enable-gosec
JonathanOppenheimer Sep 17, 2025
e9e136d
austin suggestion
JonathanOppenheimer Sep 17, 2025
66e1c6f
lol what
JonathanOppenheimer Sep 17, 2025
7cbf4c8
lint
JonathanOppenheimer Sep 17, 2025
f92fa5a
Merge branch 'master' into lint-enable-gosec
JonathanOppenheimer Sep 17, 2025
37f65a0
revert balance
JonathanOppenheimer Sep 18, 2025
57ec43b
Merge branch 'master' into lint-enable-gosec
JonathanOppenheimer Sep 18, 2025
5fd167c
Merge branch 'master' into lint-enable-gosec
JonathanOppenheimer Sep 22, 2025
b050e4f
Austin suggestions
JonathanOppenheimer Sep 22, 2025
d960769
Merge branch 'master' into lint-enable-gosec
JonathanOppenheimer Sep 23, 2025
c121ab6
Merge branch 'master' into lint-enable-gosec
JonathanOppenheimer Sep 24, 2025
eaf433d
Austin suggestions
JonathanOppenheimer Sep 24, 2025
341e908
clean-up
JonathanOppenheimer Sep 24, 2025
7172e4f
update request strings
JonathanOppenheimer Sep 24, 2025
40ebd2b
this too
JonathanOppenheimer Sep 24, 2025
80c06b8
use correct rand
JonathanOppenheimer Sep 24, 2025
603dd3b
crypto rand
JonathanOppenheimer Sep 24, 2025
57989a3
more aggressive corruption
JonathanOppenheimer Sep 24, 2025
b244df3
fix seeding here too
JonathanOppenheimer Sep 24, 2025
62ec0ca
Merge branch 'master' into lint-enable-gosec
JonathanOppenheimer Sep 24, 2025
8e657bf
Merge branch 'master' into lint-enable-gosec
JonathanOppenheimer Sep 25, 2025
e02b224
Merge branch 'master' into lint-enable-gosec
JonathanOppenheimer Sep 29, 2025
8d0388a
fix imports
JonathanOppenheimer Sep 29, 2025
62612f3
lint
JonathanOppenheimer Sep 29, 2025
1f1bb2a
Merge branch 'master' into lint-enable-gosec
JonathanOppenheimer Sep 30, 2025
6786d70
Merge branch 'master' into lint-enable-gosec
JonathanOppenheimer Oct 2, 2025
791ba8d
austin review
JonathanOppenheimer Oct 8, 2025
7da3ca1
Merge branch 'master' into lint-enable-gosec
JonathanOppenheimer Oct 8, 2025
28e116d
lint
JonathanOppenheimer Oct 8, 2025
ba427bb
Merge branch 'master' into lint-enable-gosec
JonathanOppenheimer Oct 10, 2025
bc84850
Merge branch 'master' into lint-enable-gosec
JonathanOppenheimer Oct 14, 2025
ff54299
Merge branch 'master' into lint-enable-gosec
JonathanOppenheimer Oct 28, 2025
965443c
Merge branch 'master' into lint-enable-gosec
JonathanOppenheimer Oct 29, 2025
f01b4bf
revert to 50 requests
JonathanOppenheimer Oct 29, 2025
5040a65
error on rand fail
JonathanOppenheimer Oct 29, 2025
011e246
no gosec in test files
JonathanOppenheimer Oct 29, 2025
1dfa888
bubble up error
JonathanOppenheimer Oct 29, 2025
504821c
reduce diff
JonathanOppenheimer Oct 29, 2025
57af90d
reduce diff actually
JonathanOppenheimer Oct 29, 2025
c7dfb3e
reduce diffff
JonathanOppenheimer Oct 29, 2025
4ff26dd
return error even if okay
JonathanOppenheimer Oct 30, 2025
d0c59fd
Merge branch 'master' into lint-enable-gosec
JonathanOppenheimer Oct 30, 2025
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
11 changes: 10 additions & 1 deletion .avalanche-golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ linters:
- goconst
- gocritic
- goprintffuncname
# - gosec
- gosec
- govet
- importas
- ineffassign
Expand Down Expand Up @@ -244,3 +244,12 @@ linters:
- common-false-positives
- legacy
- std-error-handling
rules:
# Exclude some linters from running on test files.
# 1. Exclude the top level tests/ directory.
# 2. Exclude any file prefixed with test_ in any directory.
# 3. Exclude any directory suffixed with test.
# 4. Exclude any file suffixed with _test.go.
- path: "(^tests/)|(^(.*/)*test_[^/]*\\.go$)|(.*test/.*)|(.*_test\\.go$)"
linters:
- gosec
5 changes: 4 additions & 1 deletion cmd/simulator/metrics/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import (
"github.com/ava-labs/libevm/log"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"

"github.com/ava-labs/coreth/rpc"
)

type Metrics struct {
Expand Down Expand Up @@ -66,7 +68,8 @@ func (m *Metrics) Serve(ctx context.Context, metricsPort string, metricsEndpoint
ctx, cancel := context.WithCancel(ctx)
// Create a prometheus server to expose individual tx metrics
server := &http.Server{
Addr: ":" + metricsPort,
Addr: ":" + metricsPort,
ReadHeaderTimeout: rpc.DefaultHTTPTimeouts.ReadHeaderTimeout,
}

// Start up go routine to listen for SIGINT notifications to gracefully shut down server
Expand Down
2 changes: 1 addition & 1 deletion core/blockchain_ext_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1678,7 +1678,7 @@ func ReexecCorruptedStateTest(t *testing.T, create ReexecTestFunc) {
require.NoError(t, blockchain.Accept(chain[0]))

// Simulate a crash by updating the acceptor tip
blockchain.writeBlockAcceptedIndices(chain[1])
require.NoError(t, blockchain.writeBlockAcceptedIndices(chain[1]))
blockchain.Stop()

// Restart blockchain with existing state
Expand Down
2 changes: 1 addition & 1 deletion core/extstate/database_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ func (fs *fuzzState) deleteStorage(accountIndex int, storageIndexInput uint64) {
func FuzzTree(f *testing.F) {
f.Fuzz(func(t *testing.T, randSeed int64, byteSteps []byte) {
fuzzState := newFuzzState(t)
rand := rand.New(rand.NewSource(randSeed))
rand := rand.New(rand.NewSource(randSeed)) // this isn't a good fuzz test, but it is reproducible.

for range 10 {
fuzzState.createAccount()
Expand Down
6 changes: 5 additions & 1 deletion network/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,11 @@ func (n *network) SendAppRequestAny(ctx context.Context, minVersion *version.App

n.lock.Lock()
defer n.lock.Unlock()
if nodeID, ok := n.peers.GetAnyPeer(minVersion); ok {
nodeID, ok, err := n.peers.GetAnyPeer(minVersion)
if err != nil {
return ids.EmptyNodeID, err
}
if ok {
return nodeID, n.sendAppRequest(ctx, nodeID, request, handler)
}

Expand Down
38 changes: 26 additions & 12 deletions network/peer_tracker.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ package network

import (
"math"
"math/rand"
"time"

"github.com/ava-labs/avalanchego/ids"
Expand All @@ -14,6 +13,8 @@ import (
"github.com/ava-labs/libevm/log"
"github.com/ava-labs/libevm/metrics"

"github.com/ava-labs/coreth/utils/rand"

safemath "github.com/ava-labs/avalanchego/utils/math"
)

Expand Down Expand Up @@ -66,17 +67,21 @@ func NewPeerTracker() *peerTracker {

// shouldTrackNewPeer returns true if we are not connected to enough peers.
// otherwise returns true probabilistically based on the number of tracked peers.
func (p *peerTracker) shouldTrackNewPeer() bool {
func (p *peerTracker) shouldTrackNewPeer() (bool, error) {
numResponsivePeers := p.responsivePeers.Len()
if numResponsivePeers < desiredMinResponsivePeers {
return true
return true, nil
}
if len(p.trackedPeers) >= len(p.peers) {
// already tracking all the peers
return false
return false, nil
}
newPeerProbability := math.Exp(-float64(numResponsivePeers) * newPeerConnectFactor)
return rand.Float64() < newPeerProbability
randomValue, err := rand.SecureFloat64()
if err != nil {
return false, err
}
return randomValue < newPeerProbability, nil
}

// getResponsivePeer returns a random [ids.NodeID] of a peer that has responded
Expand All @@ -94,8 +99,12 @@ func (p *peerTracker) getResponsivePeer() (ids.NodeID, safemath.Averager, bool)
return nodeID, peer.bandwidth, true
}

func (p *peerTracker) GetAnyPeer(minVersion *version.Application) (ids.NodeID, bool) {
if p.shouldTrackNewPeer() {
func (p *peerTracker) GetAnyPeer(minVersion *version.Application) (ids.NodeID, bool, error) {
shouldTrackNewPeer, err := p.shouldTrackNewPeer()
if err != nil {
return ids.NodeID{}, false, err
}
if shouldTrackNewPeer {
for nodeID := range p.peers {
// if minVersion is specified and peer's version is less, skip
if minVersion != nil && p.peers[nodeID].version.Compare(minVersion) < 0 {
Expand All @@ -106,7 +115,7 @@ func (p *peerTracker) GetAnyPeer(minVersion *version.Application) (ids.NodeID, b
continue
}
log.Debug("peer tracking: connecting to new peer", "trackedPeers", len(p.trackedPeers), "nodeID", nodeID)
return nodeID, true
return nodeID, true, nil
}
}
var (
Expand All @@ -115,18 +124,23 @@ func (p *peerTracker) GetAnyPeer(minVersion *version.Application) (ids.NodeID, b
random bool
averager safemath.Averager
)
if rand.Float64() < randomPeerProbability {
randomValue, err := rand.SecureFloat64()
switch {
case err != nil:
return ids.NodeID{}, false, err
case randomValue < randomPeerProbability:
random = true
nodeID, averager, ok = p.getResponsivePeer()
} else {
default:
nodeID, averager, ok = p.bandwidthHeap.Pop()
}
if ok {
log.Debug("peer tracking: popping peer", "nodeID", nodeID, "bandwidth", averager.Read(), "random", random)
return nodeID, true
return nodeID, true, err
}
// if no nodes found in the bandwidth heap, return a tracked node at random
return p.trackedPeers.Peek()
nodeID, ok = p.trackedPeers.Peek()
return nodeID, ok, nil
}

func (p *peerTracker) TrackPeer(nodeID ids.NodeID) {
Expand Down
9 changes: 6 additions & 3 deletions network/peer_tracker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ func TestPeerTracker(t *testing.T) {

// Expect requests to go to new peers until we have desiredMinResponsivePeers responsive peers.
for i := 0; i < desiredMinResponsivePeers+numExtraPeers/2; i++ {
peer, ok := p.GetAnyPeer(nil)
peer, ok, err := p.GetAnyPeer(nil)
require.NoError(err)
require.True(ok)
require.NotNil(peer)

Expand All @@ -54,7 +55,8 @@ func TestPeerTracker(t *testing.T) {
// Expect requests to go to responsive or new peers, so long as they are available
numRequests := 50
for i := 0; i < numRequests; i++ {
peer, ok := p.GetAnyPeer(nil)
peer, ok, err := p.GetAnyPeer(nil)
require.NoError(err)
require.True(ok)
require.NotNil(peer)

Expand All @@ -78,7 +80,8 @@ func TestPeerTracker(t *testing.T) {
}

// Requests should fall back on non-responsive peers when no other choice is left
peer, ok := p.GetAnyPeer(nil)
peer, ok, err := p.GetAnyPeer(nil)
require.NoError(err)
require.True(ok)
require.NotNil(peer)

Expand Down
2 changes: 1 addition & 1 deletion plugin/evm/customtypes/header_ext_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ func allFieldsSet[T interface {
if fieldValue.Kind() == reflect.Ptr {
require.Falsef(t, fieldValue.IsNil(), "field %q is nil", field.Name)
}
fieldValue = reflect.NewAt(fieldValue.Type(), unsafe.Pointer(fieldValue.UnsafeAddr())).Elem() //nolint:gosec
fieldValue = reflect.NewAt(fieldValue.Type(), unsafe.Pointer(fieldValue.UnsafeAddr())).Elem()
}

switch f := fieldValue.Interface().(type) {
Expand Down
3 changes: 0 additions & 3 deletions plugin/evm/message/block_request_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,10 @@ func TestMarshalBlockResponse(t *testing.T) {
_, err := rand.Read(blocksBytes[i])
require.NoError(t, err)
}

blockResponse := BlockResponse{
Blocks: blocksBytes,
}

base64BlockResponse := "AAAAAAAgAAAAIU8WP18PmmIdcpVmx00QA3xNe7sEB9HixkmBhVrYaB0NhgAAADnR6ZTSxCKs0gigByk5SH9pmeudGKRHhARdh/PGfPInRumVr1olNnlRuqL/bNRxxIPxX7kLrbN8WCEAAAA6tmgLTnyLdjobHUnUlVyEhiFjJSU/7HON16nii/khEZwWDwcCRIYVu9oIMT9qjrZo0gv1BZh1kh5migAAACtb3yx/xIRo0tbFL1BU4tCDa/hMcXTLdHY2TMPb2Wiw9xcu2FeUuzWLDDtSAAAAO12heG+f69ehnQ97usvgJVqlt9RL7ED4TIkrm//UNimwIjvupfT3Q5H0RdFa/UKUBAN09pJLmMv4cT+NAAAAMpYtJOLK/Mrjph+1hrFDI6a8j5598dkpMz/5k5M76m9bOvbeA3Q2bEcZ5DobBn2JvH8BAAAAOfHxekxyFaO1OeseWEnGB327VyL1cXoomiZvl2R5gZmOvqicC0s3OXARXoLtb0ElyPpzEeTX3vqSLQAAACc2zU8kq/ffhmuqVgODZ61hRd4e6PSosJk+vfiIOgrYvpw5eLBIg+UAAAAkahVqnexqQOmh0AfwM8KCMGG90Oqln45NpkMBBSINCyloi3NLAAAAKI6gENd8luqAp6Zl9gb2pjt/Pf0lZ8GJeeTWDyZobZvy+ybJAf81TN4AAAA8FgfuKbpk+Eq0PKDG5rkcH9O+iZBDQXnTr0SRo2kBLbktGE/DnRc0/1cWQolTu2hl/PkrDDoXyQKL6ZFOAAAAMwl50YMDVvKlTD3qsqS0R11jr76PtWmHx39YGFJvGBS+gjNQ6rE5NfMdhEhFF+kkrveK4QAAADhRwAdVkgww7CmjcDk0v1CijaECl13tp351hXnqPf5BNqv3UrO4Jx0D6USzyds2a3UEX479adIq5QAAADpBGUfLVbzqQGsy1hCL1oWE9X43yqxuM/6qMmOjmUNwJLqcmxRniidPAakQrilfbvv+X1q/RMzeJjtWAAAAKAZjPn05Bp8BojnENlhUw69/a0HWMfkrmo0S9BJXMl//My91drBiBVYAAAAqMEo+Pq6QGlJyDahcoeSzjq8/RMbG74Ni8vVPwA4J1vwlZAhUwV38rKqKAAAAOyzszlo6lLTTOKUUPmNAjYcksM8/rhej95vhBy+2PDXWBCxBYPOO6eKp8/tP+wAZtFTVIrX/oXYEGT+4AAAAMpZnz1PD9SDIibeb9QTPtXx2ASMtWJuszqnW4mPiXCd0HT9sYsu7FdmvvL9/faQasECOAAAALzk4vxd0rOdwmk8JHpqD/erg7FXrIzqbU5TLPHhWtUbTE8ijtMHA4FRH9Lo3DrNtAAAAPLz97PUi4qbx7Qr+wfjiD6q+32sWLnF9OnSKWGd6DFY0j4khomaxHQ8zTGL+UrpTrxl3nLKUi2Vw/6C3cwAAADqWPBMK15dRJSEPDvHDFAkPB8eab1ccJG8+msC3QT7xEL1YsAznO/9wb3/0tvRAkKMnEfMgjk5LictRAAAAJ2XOZAA98kaJKNWiO5ynQPgMk4LZxgNK0pYMeWUD4c4iFyX1DK8fvwAAADtcR6U9v459yvyeE4ZHpLRO1LzpZO1H90qllEaM7TI8t28NP6xHbJ+wP8kij7roj9WAZjoEVLaDEiB/CgAAADc7WExi1QJ84VpPClglDY+1Dnfyv08BUuXUlDWAf51Ll75vt3lwRmpWJv4zQIz56I4seXQIoy0pAAAAKkFrryBqmDIJgsharXA4SFnAWksTodWy9b/vWm7ZLaSCyqlWjltv6dip3QAAAC7Z6wkne1AJRMvoAKCxUn6mRymoYdL2SXoyNcN/QZJ3nsHZazscVCT84LcnsDByAAAAI+ZAq8lEj93rIZHZRcBHZ6+Eev0O212IV7eZrLGOSv+r4wN/AAAAL/7MQW5zTTc8Xr68nNzFlbzOPHvT2N+T+rfhJd3rr+ZaMb1dQeLSzpwrF4kvD+oZAAAAMTGikNy/poQG6HcHP/CINOGXpANKpIr6P4W4picIyuu6yIC1uJuT2lOBAWRAIQTmSLYAAAA1ImobDzE6id38RUxfj3KsibOLGfU3hMGem+rAPIdaJ9sCneN643pCMYgTSHaFkpNZyoxeuU4AAAA9FS3Br0LquOKSXG2u5N5e+fnc8I38vQK4CAk5hYWSig995QvhptwdV2joU3mI/dzlYum5SMkYu6PpM+XEAAAAAC3Nrne6HSWbGIpLIchvvCPXKLRTR+raZQryTFbQgAqGkTMgiKgFvVXERuJesHU="

blockResponseBytes, err := Codec.Marshal(Version, blockResponse)
require.NoError(t, err)
require.Equal(t, base64BlockResponse, base64.StdEncoding.EncodeToString(blockResponseBytes))
Expand Down
2 changes: 1 addition & 1 deletion plugin/evm/message/code_request_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ func TestMarshalCodeResponse(t *testing.T) {
// generate some random code data
// set random seed for deterministic random
rand := rand.New(rand.NewSource(1))

codeData := make([]byte, 50)
_, err := rand.Read(codeData)
require.NoError(t, err)
Expand All @@ -46,7 +47,6 @@ func TestMarshalCodeResponse(t *testing.T) {
}

base64CodeResponse := "AAAAAAABAAAAMlL9/AchgmVPFj9fD5piHXKVZsdNEAN8TXu7BAfR4sZJgYVa2GgdDYbR6R4AFnk5y2aU"

codeResponseBytes, err := Codec.Marshal(Version, codeResponse)
require.NoError(t, err)
require.Equal(t, base64CodeResponse, base64.StdEncoding.EncodeToString(codeResponseBytes))
Expand Down
4 changes: 2 additions & 2 deletions plugin/evm/vmtest/test_syncervm.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ func StateSyncToggleEnabledToDisabledTest(t *testing.T, testSetup *SyncTestSetup
require := require.New(t)
reqCount := 0
test := SyncTestParams{
SyncableInterval: 256,
SyncableInterval: vmsync.BlocksToFetch,
StateSyncMinBlocks: 50, // must be less than [syncableInterval] to perform sync
SyncMode: block.StateSyncStatic,
responseIntercept: func(syncerVM extension.InnerVM, nodeID ids.NodeID, requestID uint32, response []byte) {
Expand Down Expand Up @@ -251,7 +251,7 @@ func VMShutdownWhileSyncingTest(t *testing.T, testSetup *SyncTestSetup) {
)
reqCount := 0
test := SyncTestParams{
SyncableInterval: 256,
SyncableInterval: vmsync.BlocksToFetch,
StateSyncMinBlocks: 50, // must be less than [syncableInterval] to perform sync
SyncMode: block.StateSyncStatic,
responseIntercept: func(syncerVM extension.InnerVM, nodeID ids.NodeID, requestID uint32, response []byte) {
Expand Down
32 changes: 32 additions & 0 deletions utils/rand/rand.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright (C) 2019-2025, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package rand

import (
"crypto/rand"
"math/big"
)

// Credit to Brandur Leach (@Brandur) for this implementation.
// https://brandur.org/fragments/crypto-rand-float64

// Intn is a shortcut for generating a random integer between 0 and
// n using crypto/rand.
func Intn(n int64) (int64, error) {
nBig, err := rand.Int(rand.Reader, big.NewInt(n))
if err != nil {
return 0, err
}
return nBig.Int64(), nil
}

// SecureFloat64 is a shortcut for generating a random float between 0 and
// 1 using crypto/rand.
func SecureFloat64() (float64, error) {
n, err := Intn(1 << 53)
if err != nil {
return 0, err
}
return float64(n) / (1 << 53), nil
}
Loading