-
Notifications
You must be signed in to change notification settings - Fork 714
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
X-chain SDK gossip #2490
Merged
Merged
X-chain SDK gossip #2490
Changes from 113 commits
Commits
Show all changes
116 commits
Select commit
Hold shift + click to select a range
972daa9
push gossiper implementation
joshua-kim 085e8aa
Update network/p2p/gossip/gossipable.go
joshua-kim 7204679
nit
joshua-kim 3bbe6cc
debug -> error
joshua-kim 636ec5a
tidy
joshua-kim 1699673
use vector for metrics
joshua-kim d2b146b
limit outbound size
joshua-kim 5a9171d
nit
joshua-kim 0249064
nit
joshua-kim 9b7e5bb
nit
joshua-kim 027155a
nit
joshua-kim b046fab
Update network/p2p/gossip/handler.go
joshua-kim 0500c5c
Update network/p2p/gossip/gossip.go
joshua-kim 2d3ad42
nit
joshua-kim 23f8072
nit
joshua-kim 2b4b8eb
nit
joshua-kim b43118f
nit
joshua-kim 1ff0bdd
nit
joshua-kim 0e89bd4
Update network/p2p/gossip/gossip.go
StephenButtolph 7a70bac
nit
joshua-kim 2290f87
nit
joshua-kim a283199
nit
joshua-kim 93df057
Update network/p2p/gossip/gossip.go
joshua-kim f38ef7e
nit
joshua-kim ac685a0
xchain gossip
joshua-kim 9e3ec8f
refactor marshalling
joshua-kim a68b26d
nit
joshua-kim 2f369ec
lint
joshua-kim d8ebd0f
Merge branch 'dev' into xchain-gossip
StephenButtolph 158292d
Update network/p2p/gossip/gossipable.go
joshua-kim 42d5d6a
Merge branch 'gossip-parser' into xchain-gossip
StephenButtolph aafcde5
nit
joshua-kim 00389df
Update network/p2p/gossip/handler.go
joshua-kim 4db166d
Update network/p2p/gossip/gossip.go
joshua-kim f7fc9f8
nit
joshua-kim 22f27f1
nit
joshua-kim 9d423da
wip
StephenButtolph bc0f912
Merge branch 'gossip-parser' into xchain-gossip
StephenButtolph 1be49a4
nit
joshua-kim 1cf29c3
nti
joshua-kim 20a2e28
Update network/p2p/gossip/gossipable.go
joshua-kim f7b9a67
nit
joshua-kim 6a6438a
nit
joshua-kim b717fe6
nit
joshua-kim eeb1bc7
nit
joshua-kim 59d3a6b
Merge branch 'gossip-parser' into xchain-gossip
StephenButtolph fc9c89c
wip
StephenButtolph 250ae11
Merge branch 'dev' into gossip-parser
StephenButtolph b94cc99
Merge branch 'gossip-parser' into xchain-gossip
StephenButtolph 8cc874c
wip
StephenButtolph e7beb7d
Merge branch 'xchain-gossip' of github.com:ava-labs/avalanchego into …
StephenButtolph fd71f2f
Merge branch 'dev' into xchain-gossip
StephenButtolph ff304c1
Initialize transactions once
StephenButtolph be3a7f0
Merge branch 'dev' into initialize-txs-once
StephenButtolph e71f642
wip
StephenButtolph 68d2ffa
wip
StephenButtolph 0fbf797
wip
StephenButtolph 95d0331
Move context lock into issueTx
StephenButtolph cc97faa
Rework X-chain locking in tests
StephenButtolph 9bfa50d
ok
StephenButtolph cedb056
merged
StephenButtolph da814b3
merged
StephenButtolph a1f0b37
merged
StephenButtolph c258873
nit
StephenButtolph b24b89f
nit
StephenButtolph 11c50d3
nit
StephenButtolph 5cf5b96
nit
StephenButtolph 0811be2
nit
StephenButtolph 4cd2eae
nit
StephenButtolph 8e78fac
nit
StephenButtolph d41f3bc
nit
StephenButtolph e442f52
nit
StephenButtolph 7486b63
nit
StephenButtolph 0516dde
wip
StephenButtolph 4284e86
nit
StephenButtolph 3ccf17b
nit
StephenButtolph e5ec365
nit
StephenButtolph 7addc7c
fix test
StephenButtolph 505ae81
logging
StephenButtolph b7e2a96
remove gossipTx struct
StephenButtolph cef81cc
add VM context
StephenButtolph cad3395
Merge branch 'dev' into xchain-gossip
StephenButtolph 809a339
Merge branch 'dev' into xchain-gossip
StephenButtolph 7518e5a
nit
StephenButtolph eb863bb
Move locking into issueTx
StephenButtolph 3e8b3fc
whoopsie
StephenButtolph dac0b83
nit
StephenButtolph e0aa0e0
yessir
StephenButtolph 831720f
Introduce TxVerifier to network
StephenButtolph a5271af
move invariant
StephenButtolph 705cfd1
cleanup tests
StephenButtolph 7675248
wip merge
StephenButtolph 69c08e9
fix tests
StephenButtolph a0b1cb6
nit
StephenButtolph ff37ed0
nit
StephenButtolph a0b6525
nit
StephenButtolph 411d0a5
nit
StephenButtolph 25e7516
merged
StephenButtolph d666add
Merge branch 'tx-verifier' into xchain-gossip
StephenButtolph ea3f8c1
Use configs
StephenButtolph 05e83f4
nit
StephenButtolph 8389126
nit
StephenButtolph 1d96549
nit
StephenButtolph b7fb777
fix env tests
StephenButtolph bf02a21
Merge branch 'dev' into tx-verifier
StephenButtolph 4a35548
Merge branch 'tx-verifier' into xchain-gossip
StephenButtolph 052f0ac
reduce diff
StephenButtolph 2bee0c1
Merge branch 'xchain-gossip' of github.com:ava-labs/avalanchego into …
StephenButtolph 66ab0f6
reduce diff
StephenButtolph 4ae04a8
simplify table tests
StephenButtolph 5d4f63e
merged
StephenButtolph 7e7b5d1
merged
StephenButtolph 873ae4c
Merge branch 'dev' into xchain-gossip
dhrubabasu ccaaed2
Update vms/avm/network/network.go
StephenButtolph 9ba175d
nit
StephenButtolph 0ddeb97
Merge branch 'xchain-gossip' of github.com:ava-labs/avalanchego into …
StephenButtolph File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. | ||
// See the file LICENSE for licensing terms. | ||
|
||
package avm | ||
|
||
import ( | ||
"encoding/json" | ||
|
||
"github.com/ava-labs/avalanchego/vms/avm/network" | ||
) | ||
|
||
var DefaultConfig = Config{ | ||
Network: network.DefaultConfig, | ||
IndexTransactions: false, | ||
IndexAllowIncomplete: false, | ||
ChecksumsEnabled: false, | ||
} | ||
|
||
type Config struct { | ||
Network network.Config `json:"network"` | ||
IndexTransactions bool `json:"index-transactions"` | ||
IndexAllowIncomplete bool `json:"index-allow-incomplete"` | ||
ChecksumsEnabled bool `json:"checksums-enabled"` | ||
} | ||
|
||
func ParseConfig(configBytes []byte) (Config, error) { | ||
if len(configBytes) == 0 { | ||
return DefaultConfig, nil | ||
} | ||
|
||
config := DefaultConfig | ||
err := json.Unmarshal(configBytes, &config) | ||
return config, err | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. | ||
// See the file LICENSE for licensing terms. | ||
|
||
package avm | ||
|
||
import ( | ||
"testing" | ||
"time" | ||
|
||
"github.com/stretchr/testify/require" | ||
|
||
"github.com/ava-labs/avalanchego/vms/avm/network" | ||
) | ||
|
||
func TestParseConfig(t *testing.T) { | ||
tests := []struct { | ||
name string | ||
configBytes []byte | ||
expectedConfig Config | ||
}{ | ||
{ | ||
name: "unspecified config", | ||
configBytes: nil, | ||
expectedConfig: DefaultConfig, | ||
}, | ||
{ | ||
name: "manually specified checksums enabled", | ||
configBytes: []byte(`{"checksums-enabled":true}`), | ||
expectedConfig: Config{ | ||
Network: network.DefaultConfig, | ||
IndexTransactions: DefaultConfig.IndexTransactions, | ||
IndexAllowIncomplete: DefaultConfig.IndexAllowIncomplete, | ||
ChecksumsEnabled: true, | ||
}, | ||
}, | ||
{ | ||
name: "manually specified checksums enabled", | ||
configBytes: []byte(`{"network":{"max-validator-set-staleness":1}}`), | ||
expectedConfig: Config{ | ||
Network: network.Config{ | ||
MaxValidatorSetStaleness: time.Nanosecond, | ||
TargetGossipSize: network.DefaultConfig.TargetGossipSize, | ||
PullGossipPollSize: network.DefaultConfig.PullGossipPollSize, | ||
PullGossipFrequency: network.DefaultConfig.PullGossipFrequency, | ||
PullGossipThrottlingPeriod: network.DefaultConfig.PullGossipThrottlingPeriod, | ||
PullGossipThrottlingLimit: network.DefaultConfig.PullGossipThrottlingLimit, | ||
ExpectedBloomFilterElements: network.DefaultConfig.ExpectedBloomFilterElements, | ||
ExpectedBloomFilterFalsePositiveProbability: network.DefaultConfig.ExpectedBloomFilterFalsePositiveProbability, | ||
MaxBloomFilterFalsePositiveProbability: network.DefaultConfig.MaxBloomFilterFalsePositiveProbability, | ||
LegacyPushGossipCacheSize: network.DefaultConfig.LegacyPushGossipCacheSize, | ||
}, | ||
IndexTransactions: DefaultConfig.IndexTransactions, | ||
IndexAllowIncomplete: DefaultConfig.IndexAllowIncomplete, | ||
ChecksumsEnabled: DefaultConfig.ChecksumsEnabled, | ||
}, | ||
}, | ||
} | ||
for _, test := range tests { | ||
t.Run(test.name, func(t *testing.T) { | ||
require := require.New(t) | ||
|
||
config, err := ParseConfig(test.configBytes) | ||
require.NoError(err) | ||
require.Equal(test.expectedConfig, config) | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. | ||
// See the file LICENSE for licensing terms. | ||
|
||
package network | ||
|
||
import ( | ||
"time" | ||
|
||
"github.com/ava-labs/avalanchego/utils/units" | ||
) | ||
|
||
var DefaultConfig = Config{ | ||
MaxValidatorSetStaleness: time.Minute, | ||
TargetGossipSize: 20 * units.KiB, | ||
PullGossipPollSize: 1, | ||
PullGossipFrequency: 1500 * time.Millisecond, | ||
PullGossipThrottlingPeriod: 10 * time.Second, | ||
PullGossipThrottlingLimit: 2, | ||
ExpectedBloomFilterElements: 8 * 1024, | ||
ExpectedBloomFilterFalsePositiveProbability: .01, | ||
MaxBloomFilterFalsePositiveProbability: .05, | ||
LegacyPushGossipCacheSize: 512, | ||
} | ||
|
||
type Config struct { | ||
// MaxValidatorSetStaleness limits how old of a validator set the network | ||
// will use for peer sampling and rate limiting. | ||
MaxValidatorSetStaleness time.Duration `json:"max-validator-set-staleness"` | ||
// TargetGossipSize is the number of bytes that will be attempted to be | ||
// sent when pushing transactions and when responded to transaction pull | ||
// requests. | ||
TargetGossipSize int `json:"target-gossip-size"` | ||
// PullGossipPollSize is the number of validators to sample when performing | ||
// a round of pull gossip. | ||
PullGossipPollSize int `json:"pull-gossip-poll-size"` | ||
// PullGossipFrequency is how frequently rounds of pull gossip are | ||
// performed. | ||
PullGossipFrequency time.Duration `json:"pull-gossip-frequency"` | ||
// PullGossipThrottlingPeriod is how large of a window the throttler should | ||
// use. | ||
PullGossipThrottlingPeriod time.Duration `json:"pull-gossip-throttling-period"` | ||
// PullGossipThrottlingLimit is the number of pull querys that are allowed | ||
// by a validator in every throttling window. | ||
PullGossipThrottlingLimit int `json:"pull-gossip-throttling-limit"` | ||
// ExpectedBloomFilterElements is the number of elements to expect when | ||
// creating a new bloom filter. The larger this number is, the larger the | ||
// bloom filter will be. | ||
ExpectedBloomFilterElements uint64 `json:"expected-bloom-filter-elements"` | ||
// ExpectedBloomFilterFalsePositiveProbability is the expected probability | ||
// of a false positive after having inserted ExpectedBloomFilterElements | ||
// into a bloom filter. The smaller this number is, the larger the bloom | ||
// filter will be. | ||
ExpectedBloomFilterFalsePositiveProbability float64 `json:"expected-bloom-filter-false-positive-probability"` | ||
// MaxBloomFilterFalsePositiveProbability is used to determine when the | ||
// bloom filter should be refreshed. Once the expected probability of a | ||
// false positive exceeds this value, the bloom filter will be regenerated. | ||
// The smaller this number is, the more frequently that the bloom filter | ||
// will be regenerated. | ||
MaxBloomFilterFalsePositiveProbability float64 `json:"max-bloom-filter-false-positive-probability"` | ||
// LegacyPushGossipCacheSize tracks the most recently received transactions | ||
// and ensures to only gossip them once. | ||
// | ||
// Deprecated: The legacy push gossip mechanism is deprecated in favor of | ||
// the p2p SDK's push gossip mechanism. | ||
LegacyPushGossipCacheSize int `json:"legacy-push-gossip-cache-size"` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,162 @@ | ||
// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. | ||
// See the file LICENSE for licensing terms. | ||
|
||
package network | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"sync" | ||
"time" | ||
|
||
"go.uber.org/zap" | ||
|
||
"github.com/ava-labs/avalanchego/ids" | ||
"github.com/ava-labs/avalanchego/network/p2p" | ||
"github.com/ava-labs/avalanchego/network/p2p/gossip" | ||
"github.com/ava-labs/avalanchego/utils/logging" | ||
"github.com/ava-labs/avalanchego/vms/avm/txs" | ||
"github.com/ava-labs/avalanchego/vms/avm/txs/mempool" | ||
) | ||
|
||
var ( | ||
_ p2p.Handler = (*txGossipHandler)(nil) | ||
_ gossip.Set[*txs.Tx] = (*gossipMempool)(nil) | ||
_ gossip.Marshaller[*txs.Tx] = (*txParser)(nil) | ||
) | ||
|
||
// txGossipHandler is the handler called when serving gossip messages | ||
type txGossipHandler struct { | ||
p2p.NoOpHandler | ||
appGossipHandler p2p.Handler | ||
appRequestHandler p2p.Handler | ||
} | ||
|
||
func (t txGossipHandler) AppGossip( | ||
ctx context.Context, | ||
nodeID ids.NodeID, | ||
gossipBytes []byte, | ||
) { | ||
t.appGossipHandler.AppGossip(ctx, nodeID, gossipBytes) | ||
} | ||
|
||
func (t txGossipHandler) AppRequest( | ||
ctx context.Context, | ||
nodeID ids.NodeID, | ||
deadline time.Time, | ||
requestBytes []byte, | ||
) ([]byte, error) { | ||
return t.appRequestHandler.AppRequest(ctx, nodeID, deadline, requestBytes) | ||
} | ||
|
||
type txParser struct { | ||
parser txs.Parser | ||
} | ||
|
||
func (*txParser) MarshalGossip(tx *txs.Tx) ([]byte, error) { | ||
return tx.Bytes(), nil | ||
} | ||
|
||
func (g *txParser) UnmarshalGossip(bytes []byte) (*txs.Tx, error) { | ||
return g.parser.ParseTx(bytes) | ||
} | ||
|
||
func newGossipMempool( | ||
mempool mempool.Mempool, | ||
log logging.Logger, | ||
txVerifier TxVerifier, | ||
parser txs.Parser, | ||
maxExpectedElements uint64, | ||
falsePositiveProbability, | ||
maxFalsePositiveProbability float64, | ||
) (*gossipMempool, error) { | ||
bloom, err := gossip.NewBloomFilter(maxExpectedElements, falsePositiveProbability) | ||
return &gossipMempool{ | ||
Mempool: mempool, | ||
log: log, | ||
txVerifier: txVerifier, | ||
parser: parser, | ||
maxFalsePositiveProbability: maxFalsePositiveProbability, | ||
bloom: bloom, | ||
}, err | ||
} | ||
|
||
type gossipMempool struct { | ||
mempool.Mempool | ||
log logging.Logger | ||
txVerifier TxVerifier | ||
parser txs.Parser | ||
maxFalsePositiveProbability float64 | ||
|
||
lock sync.RWMutex | ||
bloom *gossip.BloomFilter | ||
} | ||
|
||
// Add is called by the p2p SDK when handling transactions that were pushed to | ||
// us and when handling transactions that were pulled from a peer. If this | ||
// returns a nil error while handling push gossip, the p2p SDK will queue the | ||
// transaction to push gossip as well. | ||
func (g *gossipMempool) Add(tx *txs.Tx) error { | ||
txID := tx.ID() | ||
if _, ok := g.Mempool.Get(txID); ok { | ||
return fmt.Errorf("attempted to issue %w: %s ", mempool.ErrDuplicateTx, txID) | ||
} | ||
|
||
if reason := g.Mempool.GetDropReason(txID); reason != nil { | ||
// If the tx is being dropped - just ignore it | ||
// | ||
// TODO: Should we allow re-verification of the transaction even if it | ||
// failed previously? | ||
return reason | ||
} | ||
|
||
// Verify the tx at the currently preferred state | ||
if err := g.txVerifier.VerifyTx(tx); err != nil { | ||
g.Mempool.MarkDropped(txID, err) | ||
return err | ||
} | ||
|
||
return g.AddVerified(tx) | ||
} | ||
|
||
func (g *gossipMempool) AddVerified(tx *txs.Tx) error { | ||
if err := g.Mempool.Add(tx); err != nil { | ||
g.Mempool.MarkDropped(tx.ID(), err) | ||
return err | ||
} | ||
|
||
g.lock.Lock() | ||
defer g.lock.Unlock() | ||
|
||
g.bloom.Add(tx) | ||
reset, err := gossip.ResetBloomFilterIfNeeded(g.bloom, g.maxFalsePositiveProbability) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if reset { | ||
g.log.Debug("resetting bloom filter", | ||
zap.String("reason", "reached max filled ratio"), | ||
StephenButtolph marked this conversation as resolved.
Show resolved
Hide resolved
|
||
) | ||
|
||
g.Mempool.Iterate(func(tx *txs.Tx) bool { | ||
g.bloom.Add(tx) | ||
return true | ||
}) | ||
} | ||
|
||
g.Mempool.RequestBuildBlock() | ||
return nil | ||
} | ||
|
||
func (g *gossipMempool) Iterate(f func(*txs.Tx) bool) { | ||
g.Mempool.Iterate(f) | ||
} | ||
|
||
func (g *gossipMempool) GetFilter() (bloom []byte, salt []byte, err error) { | ||
g.lock.RLock() | ||
defer g.lock.RUnlock() | ||
|
||
bloomBytes, err := g.bloom.Bloom.MarshalBinary() | ||
return bloomBytes, g.bloom.Salt[:], err | ||
} |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we check if
tx
is already in the mempool?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AddVerified
is expected to error if the tx is already in the mempool (which is what happens here)