From 10bbf568b560f9697066382bd2f4730ba8a3f458 Mon Sep 17 00:00:00 2001
From: Philip Offtermatt
Date: Thu, 8 Feb 2024 11:23:57 +0100
Subject: [PATCH 1/9] Port key assignment to MBT driver
---
tests/mbt/driver/core.go | 15 ++-
tests/mbt/driver/generate_more_traces.sh | 3 +-
tests/mbt/driver/generate_traces.sh | 3 +-
tests/mbt/driver/mbt_test.go | 125 ++++++++++++++++++-----
tests/mbt/driver/stats.go | 2 +
5 files changed, 118 insertions(+), 30 deletions(-)
diff --git a/tests/mbt/driver/core.go b/tests/mbt/driver/core.go
index f9f1e12e05..b9a4293df1 100644
--- a/tests/mbt/driver/core.go
+++ b/tests/mbt/driver/core.go
@@ -20,6 +20,7 @@ import (
abcitypes "github.com/cometbft/cometbft/abci/types"
cmttypes "github.com/cometbft/cometbft/types"
+ "github.com/cometbft/cometbft/proto/tendermint/crypto"
appConsumer "github.com/cosmos/interchain-security/v4/app/consumer"
appProvider "github.com/cosmos/interchain-security/v4/app/provider"
simibc "github.com/cosmos/interchain-security/v4/testutil/simibc"
@@ -123,9 +124,13 @@ func (s *Driver) consumerPower(i int64, chain ChainId) (int64, error) {
return v.Power, nil
}
+func (s *Driver) stakingValidator(i int64) (stakingtypes.Validator, bool) {
+ return s.providerStakingKeeper().GetValidator(s.ctx(PROVIDER), s.validator(i))
+}
+
// providerPower returns the power(=number of bonded tokens) of the i-th validator on the provider.
func (s *Driver) providerPower(i int64) (int64, error) {
- v, found := s.providerStakingKeeper().GetValidator(s.ctx(PROVIDER), s.validator(i))
+ v, found := s.stakingValidator(i)
if !found {
return 0, fmt.Errorf("validator with id %v not found on provider", i)
} else {
@@ -370,6 +375,14 @@ func (s *Driver) setTime(chain ChainId, newTime time.Time) {
testChain.App.BeginBlock(abcitypes.RequestBeginBlock{Header: testChain.CurrentHeader})
}
+func (s *Driver) AssignKey(chain ChainId, valIndex int64, value crypto.PublicKey) error {
+ stakingVal, found := s.stakingValidator(valIndex)
+ if !found {
+ return fmt.Errorf("validator with id %v not found on provider", valIndex)
+ }
+ return s.providerKeeper().AssignConsumerKey(s.providerCtx(), string(chain), stakingVal, value)
+}
+
// DeliverPacketToConsumer delivers a packet from the provider to the given consumer recipient.
// It updates the client before delivering the packet.
// Since the channel is ordered, the packet that is delivered is the first packet in the outbox.
diff --git a/tests/mbt/driver/generate_more_traces.sh b/tests/mbt/driver/generate_more_traces.sh
index 9af4da82e9..40589bb83b 100755
--- a/tests/mbt/driver/generate_more_traces.sh
+++ b/tests/mbt/driver/generate_more_traces.sh
@@ -9,4 +9,5 @@ go run ./... -modelPath=../model/ccv_boundeddrift.qnt -step stepBoundedDrift -in
echo "Generating synced traces with maturations"
go run ./... -modelPath=../model/ccv_sync.qnt -init initSync -step stepSync -invariant CanReceiveMaturations -traceFolder traces/sync_mat -numTraces 20 -numSteps 300 -numSamples 20
echo "Generating long synced traces without invariants"
-go run ./... -modelPath=../model/ccv_sync.qnt -init initSync -step stepSync -traceFolder traces/sync_noinv -numTraces 20 -numSteps 500 -numSamples 1
\ No newline at end of file
+go run ./... -modelPath=../model/ccv_sync.qnt -init initSync -step stepSync -traceFolder traces/sync_noinv -numTraces 20 -numSteps 500 -numSamples 1
+go run ./... -modelPath=../model/ccv_boundeddrift.qnt --step stepBoundedDriftKeyAssignment --traceFolder traces/bound_key -numTraces 20 -numSteps 100 -numSamples 20
\ No newline at end of file
diff --git a/tests/mbt/driver/generate_traces.sh b/tests/mbt/driver/generate_traces.sh
index ca0a6ba973..9f1134fb26 100755
--- a/tests/mbt/driver/generate_traces.sh
+++ b/tests/mbt/driver/generate_traces.sh
@@ -9,4 +9,5 @@ go run ./... -modelPath=../model/ccv_boundeddrift.qnt -step stepBoundedDrift -in
echo "Generating synced traces with maturations"
go run ./... -modelPath=../model/ccv_sync.qnt -init initSync -step stepSync -invariant CanReceiveMaturations -traceFolder traces/sync_mat -numTraces 1 -numSteps 300 -numSamples 20
echo "Generating long synced traces without invariants"
-go run ./... -modelPath=../model/ccv_sync.qnt -init initSync -step stepSync -traceFolder traces/sync_noinv -numTraces 1 -numSteps 500 -numSamples 1
\ No newline at end of file
+go run ./... -modelPath=../model/ccv_sync.qnt -init initSync -step stepSync -traceFolder traces/sync_noinv -numTraces 1 -numSteps 500 -numSamples 1
+go run ./... -modelPath=../model/ccv_boundeddrift.qnt --step stepBoundedDriftKeyAssignment --traceFolder traces/bound_key -numTraces 1 -numSteps 100 -numSamples 20
\ No newline at end of file
diff --git a/tests/mbt/driver/mbt_test.go b/tests/mbt/driver/mbt_test.go
index 78f9e7910f..a55d870dda 100644
--- a/tests/mbt/driver/mbt_test.go
+++ b/tests/mbt/driver/mbt_test.go
@@ -15,10 +15,13 @@ import (
"github.com/kylelemons/godebug/pretty"
"github.com/stretchr/testify/require"
- sdktypes "github.com/cosmos/cosmos-sdk/types"
-
cmttypes "github.com/cometbft/cometbft/types"
+ tmencoding "github.com/cometbft/cometbft/crypto/encoding"
+ "github.com/cosmos/interchain-security/v4/testutil/integration"
+
+ sdktypes "github.com/cosmos/cosmos-sdk/types"
+
providertypes "github.com/cosmos/interchain-security/v4/x/ccv/provider/types"
)
@@ -69,6 +72,7 @@ func TestMBT(t *testing.T) {
t.Logf("Number of sent packets: %v", stats.numSentPackets)
t.Logf("Number of blocks: %v", stats.numBlocks)
t.Logf("Number of transactions: %v", stats.numTxs)
+ t.Logf("Number of key assignments: %v", stats.numKeyAssignments)
t.Logf("Average summed block time delta passed per trace: %v", stats.totalBlockTimePassedPerTrace/time.Duration(numTraces))
}
@@ -117,6 +121,21 @@ func RunItfTrace(t *testing.T, path string) {
t.Log("Chains are: ", chains)
+ // generate keys that can be assigned on consumers, according to the ConsumerAddresses in the trace
+ consumerAddressesExpr := params["ConsumerAddresses"].Value.(itf.ListExprType)
+
+ _, _, consumerPrivVals, err := integration.CreateValidators(len(consumerAddressesExpr))
+ require.NoError(t, err, "Error creating consumer signers")
+
+ consumerAddrNamesToPrivVals := make(map[string]cmttypes.PrivValidator, len(consumerAddressesExpr))
+ realAddrsToModelConsAddrs := make(map[string]string, len(consumerAddressesExpr))
+ i := 0
+ for address, privVal := range consumerPrivVals {
+ consumerAddrNamesToPrivVals[consumerAddressesExpr[i].Value.(string)] = privVal
+ realAddrsToModelConsAddrs[address] = consumerAddressesExpr[i].Value.(string)
+ i++
+ }
+
// create params struct
vscTimeout := time.Duration(params["VscTimeout"].Value.(int64)) * time.Second
@@ -145,6 +164,15 @@ func RunItfTrace(t *testing.T, path string) {
valSet, addressMap, signers, err := CreateValSet(initialValSet)
require.NoError(t, err, "Error creating validator set")
+ // get the set of signers for consumers: the validator signers, plus signers for the assignable addresses
+ consumerSigners := make(map[string]cmttypes.PrivValidator, 0)
+ for consAddr, consPrivVal := range consumerPrivVals {
+ consumerSigners[consAddr] = consPrivVal
+ }
+ for consAddr, signer := range signers {
+ consumerSigners[consAddr] = signer
+ }
+
// get a slice of validators in the right order
nodes := make([]*cmttypes.Validator, len(valNames))
for i, valName := range valNames {
@@ -211,6 +239,10 @@ func RunItfTrace(t *testing.T, path string) {
// and then increment the rest of the time
runningConsumersBefore := driver.runningConsumers()
driver.endAndBeginBlock("provider", 1*time.Nanosecond)
+ for _, consumer := range driver.runningConsumers() {
+ UpdateProviderClientOnConsumer(t, driver, consumer.ChainId)
+ }
+
driver.endAndBeginBlock("provider", time.Duration(timeAdvancement)*time.Second-1*time.Nanosecond)
runningConsumersAfter := driver.runningConsumers()
@@ -243,7 +275,7 @@ func RunItfTrace(t *testing.T, path string) {
consumer.Value.(string),
modelParams,
driver.providerChain().Vals,
- signers,
+ consumerSigners,
nodes,
valNames,
driver.providerChain(),
@@ -268,11 +300,8 @@ func RunItfTrace(t *testing.T, path string) {
if len(consumersToStart) > 0 && consumer.ChainId == consumersToStart[len(consumersToStart)-1].Value.(string) {
continue
}
- consumerChainId := consumer.ChainId
- driver.path(ChainId(consumerChainId)).AddClientHeader(PROVIDER, driver.providerHeader())
- err := driver.path(ChainId(consumerChainId)).UpdateClient(consumerChainId, false)
- require.True(t, err == nil, "Error updating client from %v on provider: %v", consumerChainId, err)
+ UpdateProviderClientOnConsumer(t, driver, consumer.ChainId)
}
case "EndAndBeginBlockForConsumer":
@@ -286,13 +315,12 @@ func RunItfTrace(t *testing.T, path string) {
_ = headerBefore
driver.endAndBeginBlock(ChainId(consumerChain), 1*time.Nanosecond)
+ UpdateConsumerClientOnProvider(t, driver, consumerChain)
+
driver.endAndBeginBlock(ChainId(consumerChain), time.Duration(timeAdvancement)*time.Second-1*time.Nanosecond)
// update the client on the provider
- consumerHeader := driver.chain(ChainId(consumerChain)).LastHeader
- driver.path(ChainId(consumerChain)).AddClientHeader(consumerChain, consumerHeader)
- err := driver.path(ChainId(consumerChain)).UpdateClient(PROVIDER, false)
- require.True(t, err == nil, "Error updating client from %v on provider: %v", consumerChain, err)
+ UpdateConsumerClientOnProvider(t, driver, consumerChain)
case "DeliverVscPacket":
consumerChain := lastAction["consumerChain"].Value.(string)
@@ -328,8 +356,26 @@ func RunItfTrace(t *testing.T, path string) {
expectError = false
driver.DeliverPacketFromConsumer(ChainId(consumerChain), expectError)
}
- default:
+ case "KeyAssignment":
+ consumerChain := lastAction["consumerChain"].Value.(string)
+ node := lastAction["validator"].Value.(string)
+ consumerAddr := lastAction["consumerAddr"].Value.(string)
+
+ t.Log("KeyAssignment", consumerChain, node, consumerAddr)
+ stats.numKeyAssignments++
+ valIndex := getIndexOfString(node, valNames)
+ assignedPrivVal := consumerAddrNamesToPrivVals[consumerAddr]
+ assignedKey, err := assignedPrivVal.GetPubKey()
+ require.NoError(t, err, "Error getting pubkey")
+
+ protoPubKey, err := tmencoding.PubKeyToProto(assignedKey)
+ require.NoError(t, err, "Error converting pubkey to proto")
+
+ error := driver.AssignKey(ChainId(consumerChain), int64(valIndex), protoPubKey)
+ require.NoError(t, error, "Error assigning key")
+
+ default:
log.Fatalf("Error loading trace file %s, step %v: do not know action type %s",
path, index, actionKind)
}
@@ -364,7 +410,7 @@ func RunItfTrace(t *testing.T, path string) {
require.Equal(t, modelRunningConsumers, actualRunningConsumers, "Running consumers do not match")
// check validator sets - provider current validator set should be the one from the staking keeper
- CompareValidatorSets(t, driver, currentModelState, actualRunningConsumers)
+ CompareValidatorSets(t, driver, currentModelState, actualRunningConsumers, realAddrsToModelConsAddrs)
// check times - sanity check that the block times match the ones from the model
CompareTimes(driver, actualRunningConsumers, currentModelState, timeOffset)
@@ -383,7 +429,27 @@ func RunItfTrace(t *testing.T, path string) {
t.Log("🟢 Trace is ok!")
}
-func CompareValidatorSets(t *testing.T, driver *Driver, currentModelState map[string]itf.Expr, consumers []string) {
+func UpdateProviderClientOnConsumer(t *testing.T, driver *Driver, consumerChainId string) {
+ driver.path(ChainId(consumerChainId)).AddClientHeader(PROVIDER, driver.providerHeader())
+ err := driver.path(ChainId(consumerChainId)).UpdateClient(consumerChainId, false)
+ require.True(t, err == nil, "Error updating client from %v on provider: %v", consumerChainId, err)
+}
+
+func UpdateConsumerClientOnProvider(t *testing.T, driver *Driver, consumerChain string) {
+ consumerHeader := driver.chain(ChainId(consumerChain)).LastHeader
+ driver.path(ChainId(consumerChain)).AddClientHeader(consumerChain, consumerHeader)
+ err := driver.path(ChainId(consumerChain)).UpdateClient(PROVIDER, false)
+ require.True(t, err == nil, "Error updating client from %v on provider: %v", consumerChain, err)
+}
+
+func CompareValidatorSets(
+ t *testing.T,
+ driver *Driver,
+ currentModelState map[string]itf.Expr,
+ consumers []string,
+ // a map from real addresses to the names of those consumer addresses in the model
+ keyAddrsToModelConsAddrName map[string]string,
+) {
t.Helper()
modelValSet := ValidatorSet(currentModelState, "provider")
@@ -407,23 +473,28 @@ func CompareValidatorSets(t *testing.T, driver *Driver, currentModelState map[st
pubkey, err := val.ConsPubKey()
require.NoError(t, err, "Error getting pubkey")
- consAddr := providertypes.NewConsumerConsAddress(sdktypes.ConsAddress(pubkey.Address().Bytes()))
+ consAddrModelName, ok := keyAddrsToModelConsAddrName[pubkey.Address().String()]
+ if ok { // the node has a key assigned, use the name of the consumer address in the model
+ consumerCurValSet[consAddrModelName] = val.Power
+ } else { // the node doesn't have a key assigned yet, get the validator moniker
+ consAddr := providertypes.NewConsumerConsAddress(sdktypes.ConsAddress(pubkey.Address().Bytes()))
- // the consumer vals right now are CrossChainValidators, for which we don't know their mnemonic
- // so we need to find the mnemonic of the consumer val now to enter it by name in the map
+ // the consumer vals right now are CrossChainValidators, for which we don't know their mnemonic
+ // so we need to find the mnemonic of the consumer val now to enter it by name in the map
- // get the address on the provider that corresponds to the consumer address
- providerConsAddr, found := driver.providerKeeper().GetValidatorByConsumerAddr(driver.providerCtx(), consumer, consAddr)
- if !found {
- providerConsAddr = providertypes.NewProviderConsAddress(consAddr.Address)
- }
+ // get the address on the provider that corresponds to the consumer address
+ providerConsAddr, found := driver.providerKeeper().GetValidatorByConsumerAddr(driver.providerCtx(), consumer, consAddr)
+ if !found {
+ providerConsAddr = providertypes.NewProviderConsAddress(consAddr.Address)
+ }
- // get the validator for that address on the provider
- providerVal, found := driver.providerStakingKeeper().GetValidatorByConsAddr(driver.providerCtx(), providerConsAddr.Address)
- require.True(t, found, "Error getting provider validator")
+ // get the validator for that address on the provider
+ providerVal, found := driver.providerStakingKeeper().GetValidatorByConsAddr(driver.providerCtx(), providerConsAddr.Address)
+ require.True(t, found, "Error getting provider validator")
- // use the moniker of that validator
- consumerCurValSet[providerVal.GetMoniker()] = val.Power
+ // use the moniker of that validator
+ consumerCurValSet[providerVal.GetMoniker()] = val.Power
+ }
}
require.NoError(t, CompareValSet(modelValSet, consumerCurValSet), "Validator sets do not match for consumer %v", consumer)
}
diff --git a/tests/mbt/driver/stats.go b/tests/mbt/driver/stats.go
index 0d397571be..8b4c95a3dd 100644
--- a/tests/mbt/driver/stats.go
+++ b/tests/mbt/driver/stats.go
@@ -16,4 +16,6 @@ type Stats struct {
numTxs int
totalBlockTimePassedPerTrace time.Duration
+
+ numKeyAssignments int
}
From a58c7fa1c524a162d8b43019caf39a0fb1da742f Mon Sep 17 00:00:00 2001
From: Philip Offtermatt
Date: Thu, 8 Feb 2024 13:35:41 +0100
Subject: [PATCH 2/9] Add PSS trace generation
---
tests/mbt/driver/generate_traces.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/mbt/driver/generate_traces.sh b/tests/mbt/driver/generate_traces.sh
index 9f1134fb26..df54b3f17c 100755
--- a/tests/mbt/driver/generate_traces.sh
+++ b/tests/mbt/driver/generate_traces.sh
@@ -10,4 +10,4 @@ echo "Generating synced traces with maturations"
go run ./... -modelPath=../model/ccv_sync.qnt -init initSync -step stepSync -invariant CanReceiveMaturations -traceFolder traces/sync_mat -numTraces 1 -numSteps 300 -numSamples 20
echo "Generating long synced traces without invariants"
go run ./... -modelPath=../model/ccv_sync.qnt -init initSync -step stepSync -traceFolder traces/sync_noinv -numTraces 1 -numSteps 500 -numSamples 1
-go run ./... -modelPath=../model/ccv_boundeddrift.qnt --step stepBoundedDriftKeyAssignment --traceFolder traces/bound_key -numTraces 1 -numSteps 100 -numSamples 20
\ No newline at end of file
+go run ./... -modelPath=../model/ccv_boundeddrift.qnt --step stepBoundedDriftKeyAndPSS --traceFolder traces/bound_pss -numTraces 1 -numSteps 100 -numSamples 20
\ No newline at end of file
From 46fc809d428dc597fbb4aed5ad1db186ea58332b Mon Sep 17 00:00:00 2001
From: Philip Offtermatt
Date: Thu, 8 Feb 2024 13:39:29 +0100
Subject: [PATCH 3/9] Add PSS trace gen to longer trace gen
---
tests/mbt/driver/generate_more_traces.sh | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/tests/mbt/driver/generate_more_traces.sh b/tests/mbt/driver/generate_more_traces.sh
index 40589bb83b..c97b194d27 100755
--- a/tests/mbt/driver/generate_more_traces.sh
+++ b/tests/mbt/driver/generate_more_traces.sh
@@ -10,4 +10,5 @@ echo "Generating synced traces with maturations"
go run ./... -modelPath=../model/ccv_sync.qnt -init initSync -step stepSync -invariant CanReceiveMaturations -traceFolder traces/sync_mat -numTraces 20 -numSteps 300 -numSamples 20
echo "Generating long synced traces without invariants"
go run ./... -modelPath=../model/ccv_sync.qnt -init initSync -step stepSync -traceFolder traces/sync_noinv -numTraces 20 -numSteps 500 -numSamples 1
-go run ./... -modelPath=../model/ccv_boundeddrift.qnt --step stepBoundedDriftKeyAssignment --traceFolder traces/bound_key -numTraces 20 -numSteps 100 -numSamples 20
\ No newline at end of file
+go run ./... -modelPath=../model/ccv_boundeddrift.qnt --step stepBoundedDriftKeyAssignment --traceFolder traces/bound_key -numTraces 20 -numSteps 100 -numSamples 20
+go run ./... -modelPath=../model/ccv_boundeddrift.qnt --step stepBoundedDriftKeyAndPSS --traceFolder traces/bound_pss -numTraces 20 -numSteps 100 -numSamples 20
\ No newline at end of file
From 91d54a415ed156f33c2e4633d9ada89a6611fb4f Mon Sep 17 00:00:00 2001
From: Philip Offtermatt
Date: Thu, 8 Feb 2024 13:56:37 +0100
Subject: [PATCH 4/9] Start handling top N parameter for new consumers
---
tests/mbt/driver/mbt_test.go | 5 ++++-
tests/mbt/driver/setup.go | 1 +
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/tests/mbt/driver/mbt_test.go b/tests/mbt/driver/mbt_test.go
index a55d870dda..bc6221282d 100644
--- a/tests/mbt/driver/mbt_test.go
+++ b/tests/mbt/driver/mbt_test.go
@@ -271,14 +271,17 @@ func RunItfTrace(t *testing.T, path string) {
driver.coordinator.CurrentTime = driver.runningTime("provider")
// start consumers
for _, consumer := range consumersToStart {
+ chainId := consumer.Value.(itf.MapExprType)["chain"].Value.(string)
+ topN := consumer.Value.(itf.MapExprType)["topN"].Value.(int64)
driver.setupConsumer(
- consumer.Value.(string),
+ chainId,
modelParams,
driver.providerChain().Vals,
consumerSigners,
nodes,
valNames,
driver.providerChain(),
+ topN,
)
}
diff --git a/tests/mbt/driver/setup.go b/tests/mbt/driver/setup.go
index 83fa6e0669..160ee0f4ce 100644
--- a/tests/mbt/driver/setup.go
+++ b/tests/mbt/driver/setup.go
@@ -433,6 +433,7 @@ func (s *Driver) setupConsumer(
nodes []*cmttypes.Validator, // the list of nodes, even ones that have no voting power initially
valNames []string,
providerChain *ibctesting.TestChain,
+ topN int64,
) {
s.t.Logf("Starting consumer %v", chain)
From c809296790d6d35d83dfa3061ba0b0de30780660 Mon Sep 17 00:00:00 2001
From: Philip Offtermatt
Date: Fri, 9 Feb 2024 12:46:23 +0100
Subject: [PATCH 5/9] Finish merge
---
tests/mbt/driver/core.go | 8 --------
tests/mbt/driver/generate_more_traces.sh | 4 ----
2 files changed, 12 deletions(-)
diff --git a/tests/mbt/driver/core.go b/tests/mbt/driver/core.go
index 4da1daeb2d..66413bafe9 100644
--- a/tests/mbt/driver/core.go
+++ b/tests/mbt/driver/core.go
@@ -375,20 +375,12 @@ func (s *Driver) setTime(chain ChainId, newTime time.Time) {
testChain.App.BeginBlock(abcitypes.RequestBeginBlock{Header: testChain.CurrentHeader})
}
-<<<<<<< HEAD
-func (s *Driver) AssignKey(chain ChainId, valIndex int64, value crypto.PublicKey) error {
-=======
func (s *Driver) AssignKey(chain ChainId, valIndex int64, key crypto.PublicKey) error {
->>>>>>> feat/partial-set-security
stakingVal, found := s.stakingValidator(valIndex)
if !found {
return fmt.Errorf("validator with id %v not found on provider", valIndex)
}
-<<<<<<< HEAD
- return s.providerKeeper().AssignConsumerKey(s.providerCtx(), string(chain), stakingVal, value)
-=======
return s.providerKeeper().AssignConsumerKey(s.providerCtx(), string(chain), stakingVal, key)
->>>>>>> feat/partial-set-security
}
// DeliverPacketToConsumer delivers a packet from the provider to the given consumer recipient.
diff --git a/tests/mbt/driver/generate_more_traces.sh b/tests/mbt/driver/generate_more_traces.sh
index ef99e525b9..905507a108 100755
--- a/tests/mbt/driver/generate_more_traces.sh
+++ b/tests/mbt/driver/generate_more_traces.sh
@@ -10,9 +10,5 @@ echo "Generating synced traces with maturations"
go run ./... -modelPath=../model/ccv_sync.qnt -init initSync -step stepSync -invariant CanReceiveMaturations -traceFolder traces/sync_mat -numTraces 20 -numSteps 300 -numSamples 20
echo "Generating long synced traces without invariants"
go run ./... -modelPath=../model/ccv_sync.qnt -init initSync -step stepSync -traceFolder traces/sync_noinv -numTraces 20 -numSteps 500 -numSamples 1
-<<<<<<< HEAD
go run ./... -modelPath=../model/ccv_boundeddrift.qnt --step stepBoundedDriftKeyAssignment --traceFolder traces/bound_key -numTraces 20 -numSteps 100 -numSamples 20
go run ./... -modelPath=../model/ccv_boundeddrift.qnt --step stepBoundedDriftKeyAndPSS --traceFolder traces/bound_pss -numTraces 20 -numSteps 100 -numSamples 20
-=======
-go run ./... -modelPath=../model/ccv_boundeddrift.qnt --step stepBoundedDriftKeyAssignment --traceFolder traces/bound_key -numTraces 20 -numSteps 100 -numSamples 20
->>>>>>> feat/partial-set-security
From 42b11d2508d302c12e3f4713cf985a2e17fee0c8 Mon Sep 17 00:00:00 2001
From: Philip Offtermatt
Date: Fri, 9 Feb 2024 15:06:07 +0100
Subject: [PATCH 6/9] Add handling for optin/optout steps
---
tests/mbt/driver/core.go | 28 ++++++++++++++++++++++++++++
tests/mbt/driver/mbt_test.go | 32 +++++++++++++++++++++++++++++---
2 files changed, 57 insertions(+), 3 deletions(-)
diff --git a/tests/mbt/driver/core.go b/tests/mbt/driver/core.go
index 66413bafe9..2a01d45bfc 100644
--- a/tests/mbt/driver/core.go
+++ b/tests/mbt/driver/core.go
@@ -383,6 +383,34 @@ func (s *Driver) AssignKey(chain ChainId, valIndex int64, key crypto.PublicKey)
return s.providerKeeper().AssignConsumerKey(s.providerCtx(), string(chain), stakingVal, key)
}
+// Opts the given validator into the given consumer chain on the provider.
+func (s *Driver) OptIn(chain ChainId, valIndex int64) error {
+ stakingVal, found := s.stakingValidator(valIndex)
+ if !found {
+ return fmt.Errorf("validator with id %v not found on provider", valIndex)
+ }
+ consPubKey, err := stakingVal.ConsPubKey()
+ if err != nil {
+ return err
+ }
+ consAddr := sdk.GetConsAddress(consPubKey)
+ return s.providerKeeper().HandleOptIn(s.providerCtx(), string(chain), providertypes.NewProviderConsAddress(consAddr), nil)
+}
+
+// Opts the given validator out of the given consumer chain on the provider.
+func (s *Driver) OptOut(chain ChainId, valIndex int64) error {
+ stakingVal, found := s.stakingValidator(valIndex)
+ if !found {
+ return fmt.Errorf("validator with id %v not found on provider", valIndex)
+ }
+ consPubKey, err := stakingVal.ConsPubKey()
+ if err != nil {
+ return err
+ }
+ consAddr := sdk.GetConsAddress(consPubKey)
+ return s.providerKeeper().HandleOptOut(s.providerCtx(), string(chain), providertypes.NewProviderConsAddress(consAddr))
+}
+
// DeliverPacketToConsumer delivers a packet from the provider to the given consumer recipient.
// It updates the client before delivering the packet.
// Since the channel is ordered, the packet that is delivered is the first packet in the outbox.
diff --git a/tests/mbt/driver/mbt_test.go b/tests/mbt/driver/mbt_test.go
index c399a47585..54135c575d 100644
--- a/tests/mbt/driver/mbt_test.go
+++ b/tests/mbt/driver/mbt_test.go
@@ -304,7 +304,8 @@ func RunItfTrace(t *testing.T, path string) {
// unless it was the last consumer to be started, in which case it already has the header
// as we called driver.setupConsumer
for _, consumer := range driver.runningConsumers() {
- if len(consumersToStart) > 0 && consumer.ChainId == consumersToStart[len(consumersToStart)-1].Value.(string) {
+ if len(consumersToStart) > 0 &&
+ consumer.ChainId == consumersToStart[len(consumersToStart)-1].Value.(itf.MapExprType)["chain"].Value.(string) {
continue
}
@@ -379,8 +380,33 @@ func RunItfTrace(t *testing.T, path string) {
protoPubKey, err := tmencoding.PubKeyToProto(assignedKey)
require.NoError(t, err, "Error converting pubkey to proto")
- error := driver.AssignKey(ChainId(consumerChain), int64(valIndex), protoPubKey)
- require.NoError(t, error, "Error assigning key")
+ err = driver.AssignKey(ChainId(consumerChain), int64(valIndex), protoPubKey)
+ require.NoError(t, err, "Error assigning key")
+ case "OptIn":
+ consumerChain := lastAction["consumerChain"].Value.(string)
+ validator := lastAction["validator"].Value.(string)
+ t.Log("OptIn", consumerChain, validator)
+
+ valIndex := getIndexOfString(validator, valNames)
+
+ err := driver.OptIn(ChainId(consumerChain), int64(valIndex))
+ require.NoError(t, err, "Error opting in")
+
+ case "OptOut":
+ consumerChain := lastAction["consumerChain"].Value.(string)
+ validator := lastAction["validator"].Value.(string)
+ expectedError := lastAction["expectedError"].Value.(string)
+ t.Log("OptOut", consumerChain, validator, expectedError)
+
+ valIndex := getIndexOfString(validator, valNames)
+
+ err := driver.OptOut(ChainId(consumerChain), int64(valIndex))
+
+ if expectedError != "" {
+ require.Error(t, err, "Expected an error: %v", expectedError)
+ } else {
+ require.NoError(t, err, "Error opting out, but expected no error")
+ }
default:
log.Fatalf("Error loading trace file %s, step %v: do not know action type %s",
From 50522f726c92358457d66d1c584566d3e072aa7c Mon Sep 17 00:00:00 2001
From: Philip Offtermatt
Date: Fri, 9 Feb 2024 15:10:33 +0100
Subject: [PATCH 7/9] Remove expected error from OptIn, which should not error
---
tests/mbt/model/ccv_pss_model.qnt | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/tests/mbt/model/ccv_pss_model.qnt b/tests/mbt/model/ccv_pss_model.qnt
index 76c4873b43..d2911a0989 100644
--- a/tests/mbt/model/ccv_pss_model.qnt
+++ b/tests/mbt/model/ccv_pss_model.qnt
@@ -22,8 +22,7 @@ module ccv_pss_model {
...emptyAction,
kind: "OptIn",
consumerChain: consumer,
- validator: validator,
- expectedError: res.error
+ validator: validator
}
),
params' = params,
From 6935373c5f839bcf910acbaa5ec5bc72c1c61e3e Mon Sep 17 00:00:00 2001
From: Philip Offtermatt
Date: Fri, 9 Feb 2024 15:22:21 +0100
Subject: [PATCH 8/9] set top N parameter during path setup
---
tests/mbt/driver/setup.go | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/tests/mbt/driver/setup.go b/tests/mbt/driver/setup.go
index 160ee0f4ce..5fc7097404 100644
--- a/tests/mbt/driver/setup.go
+++ b/tests/mbt/driver/setup.go
@@ -310,7 +310,7 @@ func newChain(
// Creates a path for cross-chain validation from the consumer to the provider and configures the channel config of the endpoints
// as well as the clients.
// this function stops when there is an initialized, ready-to-relay channel between the provider and consumer.
-func (s *Driver) ConfigureNewPath(consumerChain, providerChain *ibctesting.TestChain, params ModelParams) *ibctesting.Path {
+func (s *Driver) ConfigureNewPath(consumerChain, providerChain *ibctesting.TestChain, params ModelParams, topN uint32) *ibctesting.Path {
consumerChainId := ChainId(consumerChain.ChainID)
path := ibctesting.NewPath(consumerChain, providerChain)
@@ -362,6 +362,9 @@ func (s *Driver) ConfigureNewPath(consumerChain, providerChain *ibctesting.TestC
consumerGenesisForProvider)
require.NoError(s.t, err, "Error setting consumer genesis on provider for chain %v", consumerChain.ChainID)
+ // set the top N percentage
+ s.providerKeeper().SetTopN(providerChain.GetContext(), consumerChain.ChainID, topN)
+
// Client ID is set in InitGenesis and we treat it as a black box. So
// must query it to use it with the endpoint.
clientID, _ := s.consumerKeeper(consumerChainId).GetProviderClientID(s.ctx(consumerChainId))
@@ -437,6 +440,8 @@ func (s *Driver) setupConsumer(
) {
s.t.Logf("Starting consumer %v", chain)
+ // TODO: reuse the partial set computation logic to compute the initial validator set
+ // for top N chains
initValUpdates := cmttypes.TM2PB.ValidatorUpdates(valSet)
// start consumer chains
@@ -444,7 +449,7 @@ func (s *Driver) setupConsumer(
consumerChain := newChain(s.t, params, s.coordinator, icstestingutils.ConsumerAppIniter(initValUpdates), chain, valSet, signers, nodes, valNames)
s.coordinator.Chains[chain] = consumerChain
- path := s.ConfigureNewPath(consumerChain, providerChain, params)
+ path := s.ConfigureNewPath(consumerChain, providerChain, params, uint32(topN))
s.simibcs[ChainId(chain)] = simibc.MakeRelayedPath(s.t, path)
}
From b0152dd86c3fb25b1977965a1eb633e51cbcef19 Mon Sep 17 00:00:00 2001
From: Philip Offtermatt
Date: Fri, 9 Feb 2024 15:23:48 +0100
Subject: [PATCH 9/9] Add comment to setup.go
---
tests/mbt/driver/setup.go | 2 ++
1 file changed, 2 insertions(+)
diff --git a/tests/mbt/driver/setup.go b/tests/mbt/driver/setup.go
index 5fc7097404..ada9bddca3 100644
--- a/tests/mbt/driver/setup.go
+++ b/tests/mbt/driver/setup.go
@@ -363,6 +363,8 @@ func (s *Driver) ConfigureNewPath(consumerChain, providerChain *ibctesting.TestC
require.NoError(s.t, err, "Error setting consumer genesis on provider for chain %v", consumerChain.ChainID)
// set the top N percentage
+ // needs to be done before the provider queues the first vsc packet to the consumer
+ // TODO: might be able to move this into setupConsumer, need to test once more logic is here
s.providerKeeper().SetTopN(providerChain.GetContext(), consumerChain.ChainID, topN)
// Client ID is set in InitGenesis and we treat it as a black box. So