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

test(e2e): fix proposer selection test #926

Merged
merged 8 commits into from
Sep 26, 2024
Merged
Show file tree
Hide file tree
Changes from 6 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
2 changes: 2 additions & 0 deletions abci/example/kvstore/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ type Config struct {
ChainLockUpdates map[string]string `toml:"chainlock_updates"`
PrivValServerType string `toml:"privval_server_type"`
InitAppInitialCoreHeight uint32 `toml:"init_app_core_chain_locked_height"`
// ConsenusVersionUpdates is a map of heights to consensus version ; ONLY SUPPORTED BY e2e.Application
ConsenusVersionUpdates map[string]int32 `toml:"consensus_version_updates"`
}

func DefaultConfig(dir string) Config {
Expand Down
16 changes: 15 additions & 1 deletion test/e2e/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,20 @@ func NewApplication(cfg kvstore.Config, opts ...kvstore.OptFunc) (*Application,
return nil, err
}

for h, ver := range cfg.ConsenusVersionUpdates {
height, err := strconv.Atoi(h)
if err != nil {
return nil, fmt.Errorf("consensus_version_updates: failed to parse height %s: %w", h, err)
}
params := types1.ConsensusParams{
Version: &types1.VersionParams{
ConsensusVersion: types1.VersionParams_ConsensusVersion(ver),
AppVersion: kvstore.ProtocolVersion,
},
}
app.AddConsensusParamsUpdate(params, int64(height))
}

return &app, nil
}

Expand Down Expand Up @@ -146,7 +160,7 @@ func (app *Application) VerifyVoteExtension(_ context.Context, req *abci.Request
}

if app.cfg.VoteExtensionDelayMS != 0 {
time.Sleep(time.Duration(app.cfg.VoteExtensionDelayMS) * time.Millisecond)
time.Sleep(time.Duration(app.cfg.VoteExtensionDelayMS) * time.Millisecond) //#nosec G115
}

app.logger.Info("verified vote extension value", "req", req, "nums", nums)
Expand Down
22 changes: 22 additions & 0 deletions test/e2e/networks/rotate.toml
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,28 @@ validator04 = 100
validator05 = 100
validator11 = 100


[validator_update.1070]
validator01 = 100
validator02 = 100
validator03 = 100
validator04 = 100
validator05 = 100


[validator_update.1077]
validator01 = 100
validator07 = 100
validator08 = 100
validator10 = 100
validator11 = 100

[consensus_version_updates]

1070 = 1
1076 = 0
1079 = 1

[node.seed01]
mode = "seed"
perturb = ["restart"]
Expand Down
2 changes: 2 additions & 0 deletions test/e2e/node/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ type Config struct {
QuorumHashUpdate map[string]string `toml:"quorum_hash_update"`
ChainLockUpdates map[string]string `toml:"chainlock_updates"`
PrivValServerType string `toml:"privval_server_type"`
ConsenusVersionUpdates map[string]int32 `toml:"consensus_version_updates"`
}

// App extracts out the application specific configuration parameters
Expand All @@ -46,6 +47,7 @@ func (cfg *Config) App() *kvstore.Config {
QuorumHashUpdate: cfg.QuorumHashUpdate,
ChainLockUpdates: cfg.ChainLockUpdates,
PrivValServerType: cfg.PrivValServerType,
ConsenusVersionUpdates: cfg.ConsenusVersionUpdates,
}
}

Expand Down
9 changes: 7 additions & 2 deletions test/e2e/pkg/manifest.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,13 @@ type Manifest struct {
// not specified are not changed.
ValidatorUpdates map[string]map[string]int64 `toml:"validator_update"`

// ConsensusVersionUpdates is a map of heights to consensus versions, and
// will be sent by the ABCI application as a consensus params update.
// For example, the following sets the consensus version to 1 at height 1000:
//
// [consensus_version_updates]
// 1000 = 1
ConsensusVersionUpdates map[string]int32 `toml:"consensus_version_updates"`
// ChainLockUpdates is a map of heights at which a new chain lock should be proposed
// The first number is the tendermint height, and the second is the
//
Expand All @@ -64,8 +71,6 @@ type Manifest struct {
// 1004 = 3451
// 1020 = 3454
// 1040 = 3500
//

ChainLockUpdates map[string]int64 `toml:"chainlock_updates"`

// Nodes specifies the network nodes. At least one node must be given.
Expand Down
27 changes: 19 additions & 8 deletions test/e2e/pkg/testnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ type Testnet struct {
QuorumType btcjson.LLMQType
QuorumHash crypto.QuorumHash
QuorumHashUpdates map[int64]crypto.QuorumHash
// ConsensusVersionUpdates maps height to new consensus version (ConsensusParams.Version.ConsensusVersion)
ConsensusVersionUpdates map[int64]int32
}

// Node represents a Tenderdash node in a testnet.
Expand Down Expand Up @@ -204,18 +206,19 @@ func LoadTestnet(file string) (*Testnet, error) {
LogLevel: manifest.LogLevel,
TxSize: manifest.TxSize,
ABCIProtocol: Protocol(manifest.ABCIProtocol),
PrepareProposalDelayMS: int(manifest.PrepareProposalDelayMS),
ProcessProposalDelayMS: int(manifest.ProcessProposalDelayMS),
CheckTxDelayMS: int(manifest.CheckTxDelayMS),
VoteExtensionDelayMS: int(manifest.VoteExtensionDelayMS),
FinalizeBlockDelayMS: int(manifest.FinalizeBlockDelayMS),
MaxBlockSize: int64(manifest.MaxBlockSize),
MaxEvidenceSize: int64(manifest.MaxEvidenceSize),
PrepareProposalDelayMS: int(manifest.PrepareProposalDelayMS), //#nosec G115
ProcessProposalDelayMS: int(manifest.ProcessProposalDelayMS), //#nosec G115
CheckTxDelayMS: int(manifest.CheckTxDelayMS), //#nosec G115
VoteExtensionDelayMS: int(manifest.VoteExtensionDelayMS), //#nosec G115
FinalizeBlockDelayMS: int(manifest.FinalizeBlockDelayMS), //#nosec G115
MaxBlockSize: int64(manifest.MaxBlockSize), //#nosec G115
MaxEvidenceSize: int64(manifest.MaxEvidenceSize), //#nosec G115
ThresholdPublicKey: ld.ThresholdPubKey,
ThresholdPublicKeyUpdates: map[int64]crypto.PubKey{},
QuorumType: btcjson.LLMQType(quorumType),
QuorumHash: quorumHash,
QuorumHashUpdates: map[int64]crypto.QuorumHash{},
ConsensusVersionUpdates: map[int64]int32{},
}
if len(manifest.KeyType) != 0 {
testnet.KeyType = manifest.KeyType
Expand Down Expand Up @@ -439,14 +442,22 @@ func LoadTestnet(file string) (*Testnet, error) {

sort.Ints(chainLockSetHeights)

// Set up validator updates.
// Set up chainlock updates.
for _, height := range chainLockSetHeights {
heightStr := strconv.FormatInt(int64(height), 10)
chainLockHeight := manifest.ChainLockUpdates[heightStr]
testnet.ChainLockUpdates[int64(height)] = chainLockHeight
fmt.Printf("Set chainlock at height %d / core height is %d\n", height, chainLockHeight)
}

for heightStr, cpUpdate := range manifest.ConsensusVersionUpdates {
height, err := strconv.Atoi(heightStr)
if err != nil {
return nil, fmt.Errorf("invalid consensus version update height %q: %w", height, err)
}
testnet.ConsensusVersionUpdates[int64(height)] = cpUpdate
}

return testnet, testnet.Validate()
}

Expand Down
8 changes: 8 additions & 0 deletions test/e2e/runner/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,14 @@ func MakeAppConfig(node *e2e.Node) ([]byte, error) {
cfg["chainlock_updates"] = chainLockUpdates
}

if len(node.Testnet.ConsensusVersionUpdates) > 0 {
consensusVersionUpdates := map[string]int32{}
for height, version := range node.Testnet.ConsensusVersionUpdates {
consensusVersionUpdates[strconv.Itoa(int(height))] = version //#nosec:G115
}
cfg["consensus_version_updates"] = consensusVersionUpdates
}

var buf bytes.Buffer
err := toml.NewEncoder(&buf).Encode(cfg)
if err != nil {
Expand Down
90 changes: 46 additions & 44 deletions test/e2e/tests/app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -242,68 +242,70 @@ func TestApp_TxTooBig(t *testing.T) {
outcome := make([]txPair, 0, len(nodes))

start := time.Now()
/// Send to each node more txs than we can fit into block
for _, node := range nodes {
ctx, cancel := context.WithTimeout(mainCtx, broadcastTimeout)
defer cancel()

if ctx.Err() != nil {
t.Fatalf("context canceled before broadcasting to all nodes")
}
node := *node
/// Send more txs than we can fit into block

if node.Stateless() {
continue
ctx, cancel := context.WithTimeout(mainCtx, broadcastTimeout)
defer cancel()

if ctx.Err() != nil {
t.Fatalf("context canceled before broadcasting to all nodes")
}
// find first non-stateless node
var node *e2e.Node
for _, node = range nodes {
if !node.Stateless() {
break
}
}

t.Logf("broadcasting to %s", node.Name)
t.Logf("broadcasting to %s", node.Name)

session := rand.Int63()
session := rand.Int63()

var err error
client, err = node.Client()
require.NoError(t, err)
var err error
client, err = node.Client()
require.NoError(t, err)

// FIXME: ConsensusParams is broken for last height, this is just workaround
status, err := client.Status(ctx)
assert.NoError(t, err)
cp, err := client.ConsensusParams(ctx, &status.SyncInfo.LatestBlockHeight)
assert.NoError(t, err)
// FIXME: ConsensusParams is broken for last height, this is just workaround
status, err := client.Status(ctx)
assert.NoError(t, err)
cp, err := client.ConsensusParams(ctx, &status.SyncInfo.LatestBlockHeight)
assert.NoError(t, err)

// ensure we have more txs than fits the block
TxPayloadSize := int(cp.ConsensusParams.Block.MaxBytes / 100) // 1% of block size
numTxs := 101
// ensure we have more txs than fits the block
TxPayloadSize := int(cp.ConsensusParams.Block.MaxBytes / 100) // 1% of block size
numTxs := 101

tx := make(types.Tx, TxPayloadSize) // first tx is just zeros
tx := make(types.Tx, TxPayloadSize) // first tx is just zeros

var firstTxHash []byte
var key string
var firstTxHash []byte
var key string

for i := 0; i < numTxs; i++ {
key = fmt.Sprintf("testapp-big-tx-%v-%08x-%d=", node.Name, session, i)
copy(tx, key)
for i := 0; i < numTxs; i++ {
key = fmt.Sprintf("testapp-big-tx-%v-%08x-%d=", node.Name, session, i)
copy(tx, key)

payloadOffset := len(tx) - 8 // where we put the `i` into the payload
assert.Greater(t, payloadOffset, len(key))
payloadOffset := len(tx) - 8 // where we put the `i` into the payload
assert.Greater(t, payloadOffset, len(key))

big.NewInt(int64(i)).FillBytes(tx[payloadOffset:])
assert.Len(t, tx, TxPayloadSize)
big.NewInt(int64(i)).FillBytes(tx[payloadOffset:])
assert.Len(t, tx, TxPayloadSize)

if i == 0 {
firstTxHash = tx.Hash()
}

_, err = client.BroadcastTxAsync(ctx, tx)

assert.NoError(t, err, "failed to broadcast tx %06x", i)
if i == 0 {
firstTxHash = tx.Hash()
}

outcome = append(outcome, txPair{
firstTxHash: firstTxHash,
lastTxHash: tx.Hash(),
})
_, err = client.BroadcastTxAsync(ctx, tx)

assert.NoError(t, err, "failed to broadcast tx %06x", i)
}

outcome = append(outcome, txPair{
firstTxHash: firstTxHash,
lastTxHash: tx.Hash(),
})

t.Logf("submitted txs in %s", time.Since(start).String())

successful := 0
Expand Down
8 changes: 8 additions & 0 deletions test/e2e/tests/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ import (
"github.com/dashpay/tenderdash/types"
)

// maxBlocks is the maximum number of blocks to fetch from the archive node.
// Use to limit test run time.
const maxBlocks = 500

func init() {
// This can be used to manually specify a testnet manifest and/or node to
// run tests against. The testnet must have been started by the runner first.
Expand Down Expand Up @@ -122,6 +126,10 @@ func fetchBlockChain(ctx context.Context, t *testing.T) []*types.Block {

from := status.SyncInfo.EarliestBlockHeight
to := status.SyncInfo.LatestBlockHeight
// limit blocks to fetch to avoid long test times
if to-from > maxBlocks {
to = from + maxBlocks
}
blocks, ok := blocksCache[testnet.Name]
if !ok {
blocks = make([]*types.Block, 0, to-from+1)
Expand Down
Loading
Loading