Skip to content

Commit

Permalink
P-Chain SDK Gossip (#2487)
Browse files Browse the repository at this point in the history
Signed-off-by: Joshua Kim <[email protected]>
Signed-off-by: Stephen Buttolph <[email protected]>
Co-authored-by: Stephen Buttolph <[email protected]>
Co-authored-by: Dhruba Basu <[email protected]>
  • Loading branch information
3 people authored Dec 23, 2023
1 parent 653c2f1 commit 9fb61ab
Show file tree
Hide file tree
Showing 12 changed files with 706 additions and 104 deletions.
20 changes: 10 additions & 10 deletions vms/platformvm/block/builder/builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,7 @@ func TestBuildBlockInvalidStakingDurations(t *testing.T) {
require.ErrorIs(tx2DropReason, txexecutor.ErrStakeTooLong)
}

func TestPreviouslyDroppedTxsCanBeReAddedToMempool(t *testing.T) {
func TestPreviouslyDroppedTxsCannotBeReAddedToMempool(t *testing.T) {
require := require.New(t)

env := newEnvironment(t)
Expand All @@ -497,24 +497,24 @@ func TestPreviouslyDroppedTxsCanBeReAddedToMempool(t *testing.T) {

// Transaction should not be marked as dropped before being added to the
// mempool
reason := env.mempool.GetDropReason(txID)
require.NoError(reason)
require.NoError(env.mempool.GetDropReason(txID))

// Mark the transaction as dropped
errTestingDropped := errors.New("testing dropped")
env.mempool.MarkDropped(txID, errTestingDropped)
reason = env.mempool.GetDropReason(txID)
require.ErrorIs(reason, errTestingDropped)
err = env.mempool.GetDropReason(txID)
require.ErrorIs(err, errTestingDropped)

// Issue the transaction
env.ctx.Lock.Unlock()
require.NoError(env.network.IssueTx(context.Background(), tx))
err = env.network.IssueTx(context.Background(), tx)
require.ErrorIs(err, errTestingDropped)
_, ok := env.mempool.Get(txID)
require.True(ok)
require.False(ok)

// When issued again, the mempool should not be marked as dropped
reason = env.mempool.GetDropReason(txID)
require.NoError(reason)
// When issued again, the mempool should still be marked as dropped
err = env.mempool.GetDropReason(txID)
require.ErrorIs(err, errTestingDropped)
}

func TestNoErrorOnUnexpectedSetPreferenceDuringBootstrapping(t *testing.T) {
Expand Down
14 changes: 12 additions & 2 deletions vms/platformvm/block/builder/helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package builder

import (
"context"
"testing"
"time"

Expand Down Expand Up @@ -166,6 +167,9 @@ func newEnvironment(t *testing.T) *environment {

registerer := prometheus.NewRegistry()
res.sender = &common.SenderTest{T: t}
res.sender.SendAppGossipF = func(context.Context, []byte) error {
return nil
}

metrics, err := metrics.New("", registerer)
require.NoError(err)
Expand All @@ -182,13 +186,19 @@ func newEnvironment(t *testing.T) *environment {
)

txVerifier := network.NewLockedTxVerifier(&res.ctx.Lock, res.blkManager)
res.network = network.New(
logging.NoLog{},
res.network, err = network.New(
res.backend.Ctx.Log,
res.backend.Ctx.NodeID,
res.backend.Ctx.SubnetID,
res.backend.Ctx.ValidatorState,
txVerifier,
res.mempool,
res.backend.Config.PartialSyncPrimaryNetwork,
res.sender,
registerer,
network.DefaultConfig,
)
require.NoError(err)

res.Builder = New(
res.mempool,
Expand Down
21 changes: 12 additions & 9 deletions vms/platformvm/config/execution_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ import (
"encoding/json"

"github.com/ava-labs/avalanchego/utils/units"
"github.com/ava-labs/avalanchego/vms/platformvm/network"
)

var DefaultExecutionConfig = ExecutionConfig{
Network: network.DefaultConfig,
BlockCacheSize: 64 * units.MiB,
TxCacheSize: 128 * units.MiB,
TransformedSubnetTxCacheSize: 4 * units.MiB,
Expand All @@ -23,15 +25,16 @@ var DefaultExecutionConfig = ExecutionConfig{

// ExecutionConfig provides execution parameters of PlatformVM
type ExecutionConfig struct {
BlockCacheSize int `json:"block-cache-size"`
TxCacheSize int `json:"tx-cache-size"`
TransformedSubnetTxCacheSize int `json:"transformed-subnet-tx-cache-size"`
RewardUTXOsCacheSize int `json:"reward-utxos-cache-size"`
ChainCacheSize int `json:"chain-cache-size"`
ChainDBCacheSize int `json:"chain-db-cache-size"`
BlockIDCacheSize int `json:"block-id-cache-size"`
FxOwnerCacheSize int `json:"fx-owner-cache-size"`
ChecksumsEnabled bool `json:"checksums-enabled"`
Network network.Config `json:"network"`
BlockCacheSize int `json:"block-cache-size"`
TxCacheSize int `json:"tx-cache-size"`
TransformedSubnetTxCacheSize int `json:"transformed-subnet-tx-cache-size"`
RewardUTXOsCacheSize int `json:"reward-utxos-cache-size"`
ChainCacheSize int `json:"chain-cache-size"`
ChainDBCacheSize int `json:"chain-db-cache-size"`
BlockIDCacheSize int `json:"block-id-cache-size"`
FxOwnerCacheSize int `json:"fx-owner-cache-size"`
ChecksumsEnabled bool `json:"checksums-enabled"`
}

// GetExecutionConfig returns an ExecutionConfig
Expand Down
74 changes: 74 additions & 0 deletions vms/platformvm/config/execution_config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (
"testing"

"github.com/stretchr/testify/require"

"github.com/ava-labs/avalanchego/vms/platformvm/network"
)

func TestExecutionConfigUnmarshal(t *testing.T) {
Expand Down Expand Up @@ -39,6 +41,66 @@ func TestExecutionConfigUnmarshal(t *testing.T) {
t.Run("all values extracted from json", func(t *testing.T) {
require := require.New(t)
b := []byte(`{
"network": {
"max-validator-set-staleness": 1,
"target-gossip-size": 2,
"pull-gossip-poll-size": 3,
"pull-gossip-frequency": 4,
"pull-gossip-throttling-period": 5,
"pull-gossip-throttling-limit": 6,
"expected-bloom-filter-elements":7,
"expected-bloom-filter-false-positive-probability": 8,
"max-bloom-filter-false-positive-probability": 9,
"legacy-push-gossip-cache-size": 10
},
"block-cache-size": 1,
"tx-cache-size": 2,
"transformed-subnet-tx-cache-size": 3,
"reward-utxos-cache-size": 5,
"chain-cache-size": 6,
"chain-db-cache-size": 7,
"block-id-cache-size": 8,
"fx-owner-cache-size": 9,
"checksums-enabled": true
}`)
ec, err := GetExecutionConfig(b)
require.NoError(err)
expected := &ExecutionConfig{
Network: network.Config{
MaxValidatorSetStaleness: 1,
TargetGossipSize: 2,
PullGossipPollSize: 3,
PullGossipFrequency: 4,
PullGossipThrottlingPeriod: 5,
PullGossipThrottlingLimit: 6,
ExpectedBloomFilterElements: 7,
ExpectedBloomFilterFalsePositiveProbability: 8,
MaxBloomFilterFalsePositiveProbability: 9,
LegacyPushGossipCacheSize: 10,
},
BlockCacheSize: 1,
TxCacheSize: 2,
TransformedSubnetTxCacheSize: 3,
RewardUTXOsCacheSize: 5,
ChainCacheSize: 6,
ChainDBCacheSize: 7,
BlockIDCacheSize: 8,
FxOwnerCacheSize: 9,
ChecksumsEnabled: true,
}
require.Equal(expected, ec)
})

t.Run("default values applied correctly", func(t *testing.T) {
require := require.New(t)
b := []byte(`{
"network": {
"max-validator-set-staleness": 1,
"target-gossip-size": 2,
"pull-gossip-poll-size": 3,
"pull-gossip-frequency": 4,
"pull-gossip-throttling-period": 5
},
"block-cache-size": 1,
"tx-cache-size": 2,
"transformed-subnet-tx-cache-size": 3,
Expand All @@ -52,6 +114,18 @@ func TestExecutionConfigUnmarshal(t *testing.T) {
ec, err := GetExecutionConfig(b)
require.NoError(err)
expected := &ExecutionConfig{
Network: network.Config{
MaxValidatorSetStaleness: 1,
TargetGossipSize: 2,
PullGossipPollSize: 3,
PullGossipFrequency: 4,
PullGossipThrottlingPeriod: 5,
PullGossipThrottlingLimit: DefaultExecutionConfig.Network.PullGossipThrottlingLimit,
ExpectedBloomFilterElements: DefaultExecutionConfig.Network.ExpectedBloomFilterElements,
ExpectedBloomFilterFalsePositiveProbability: DefaultExecutionConfig.Network.ExpectedBloomFilterFalsePositiveProbability,
MaxBloomFilterFalsePositiveProbability: DefaultExecutionConfig.Network.MaxBloomFilterFalsePositiveProbability,
LegacyPushGossipCacheSize: DefaultExecutionConfig.Network.LegacyPushGossipCacheSize,
},
BlockCacheSize: 1,
TxCacheSize: 2,
TransformedSubnetTxCacheSize: 3,
Expand Down
66 changes: 66 additions & 0 deletions vms/platformvm/network/config.go
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"`
}
Loading

0 comments on commit 9fb61ab

Please sign in to comment.