From e3eff16060d158f6f8f70f115ded3edef3dbaf9d Mon Sep 17 00:00:00 2001
From: Philip Offtermatt
Date: Wed, 9 Aug 2023 14:37:47 +0200
Subject: [PATCH] Add support for equivocation
---
Makefile | 2 +-
tests/e2e/actions.go | 58 +++++++++++++++++++++++++++++---------------
tests/e2e/main.go | 11 ++++-----
tests/e2e/steps.go | 4 ++-
4 files changed, 47 insertions(+), 28 deletions(-)
diff --git a/Makefile b/Makefile
index 7ab6a4fa24..edbacbc0e0 100644
--- a/Makefile
+++ b/Makefile
@@ -36,7 +36,7 @@ test-e2e-short:
# run only happy path E2E tests with cometmock
# this set of traces does not test equivocation but it does check downtime
test-e2e-short-cometmock:
- go run ./tests/e2e/... --short-happy-path --use-cometmock --use-gorelayer
+ go run ./tests/e2e/... --cometmock-happy-path --use-cometmock --use-gorelayer
# run full E2E tests in sequence (including multiconsumer)
test-e2e-multi-consumer:
diff --git a/tests/e2e/actions.go b/tests/e2e/actions.go
index 2cae615f70..e5ac465aa0 100644
--- a/tests/e2e/actions.go
+++ b/tests/e2e/actions.go
@@ -1604,18 +1604,7 @@ func (tr TestRun) setValidatorDowntime(chain chainID, validator validatorID, dow
if tr.useCometmock {
// send set_signing_status either to down or up for validator
- var validatorAddress string
- if chain == chainID("provi") {
- validatorAddress = tr.getValidatorKeyAddressFromString(tr.validatorConfigs[validator].privValidatorKey)
- } else {
- var valAddressString string
- if tr.validatorConfigs[validator].useConsumerKey {
- valAddressString = tr.validatorConfigs[validator].consumerPrivValidatorKey
- } else {
- valAddressString = tr.validatorConfigs[validator].privValidatorKey
- }
- validatorAddress = tr.getValidatorKeyAddressFromString(valAddressString)
- }
+ validatorAddress := tr.GetValidatorAddress(chain, validator)
method := "set_signing_status"
params := fmt.Sprintf(`{"private_key_address":"%s","status":"%s"}`, validatorAddress, lastArg)
@@ -1648,6 +1637,22 @@ func (tr TestRun) setValidatorDowntime(chain chainID, validator validatorID, dow
}
}
+func (tr TestRun) GetValidatorAddress(chain chainID, validator validatorID) string {
+ var validatorAddress string
+ if chain == chainID("provi") {
+ validatorAddress = tr.getValidatorKeyAddressFromString(tr.validatorConfigs[validator].privValidatorKey)
+ } else {
+ var valAddressString string
+ if tr.validatorConfigs[validator].useConsumerKey {
+ valAddressString = tr.validatorConfigs[validator].consumerPrivValidatorKey
+ } else {
+ valAddressString = tr.validatorConfigs[validator].privValidatorKey
+ }
+ validatorAddress = tr.getValidatorKeyAddressFromString(valAddressString)
+ }
+ return validatorAddress
+}
+
type unjailValidatorAction struct {
provider chainID
validator validatorID
@@ -1795,15 +1800,28 @@ func (tr TestRun) invokeDoublesignSlash(
action doublesignSlashAction,
verbose bool,
) {
- chainConfig := tr.chainConfigs[action.chain]
- //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments.
- bz, err := exec.Command("docker", "exec", tr.containerConfig.instanceName, "/bin/bash",
- "/testnet-scripts/cause-doublesign.sh", chainConfig.binaryName, string(action.validator),
- string(chainConfig.chainId), chainConfig.ipPrefix).CombinedOutput()
- if err != nil {
- log.Fatal(err, "\n", string(bz))
+ if !tr.useCometmock {
+ chainConfig := tr.chainConfigs[action.chain]
+ //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments.
+ bz, err := exec.Command("docker", "exec", tr.containerConfig.instanceName, "/bin/bash",
+ "/testnet-scripts/cause-doublesign.sh", chainConfig.binaryName, string(action.validator),
+ string(chainConfig.chainId), chainConfig.ipPrefix).CombinedOutput()
+ if err != nil {
+ log.Fatal(err, "\n", string(bz))
+ }
+ tr.waitBlocks("provi", 10, 2*time.Minute)
+ } else { // tr.useCometMock
+ validatorAddress := tr.GetValidatorAddress(action.chain, action.validator)
+
+ method := "cause_double_sign"
+ params := fmt.Sprintf(`{"private_key_address":"%s"}`, validatorAddress)
+
+ address := tr.getQueryNodeRPCAddress(action.chain)
+
+ tr.curlJsonRPCRequest(method, params, address)
+ tr.waitBlocks(action.chain, 1, 10*time.Second)
+ return
}
- tr.waitBlocks("provi", 10, 2*time.Minute)
}
type assignConsumerPubKeyAction struct {
diff --git a/tests/e2e/main.go b/tests/e2e/main.go
index 9943d6f9bd..58bb065c26 100644
--- a/tests/e2e/main.go
+++ b/tests/e2e/main.go
@@ -16,12 +16,11 @@ import (
)
var (
- verbose = flag.Bool("verbose", false, "turn verbose logging on/off")
- happyPathOnly = flag.Bool("happy-path-only", false, "run happy path tests only")
- shortHappyPathOnly = flag.Bool("short-happy-path", false, `run abridged happy path tests only.
+ verbose = flag.Bool("verbose", false, "turn verbose logging on/off")
+ happyPathOnly = flag.Bool("happy-path-only", false, "run happy path tests only")
+ cometmockCompatibleHappyPath = flag.Bool("cometmock-happy-path", false, `run cometmock compatible happy path tests only.
This is like the happy path, but skips steps
that involve starting or stopping nodes for the same chain outside of the chain setup or teardown.
-In particular, this skips steps related to downtime and double signing.
This is suited for CometMock+Gorelayer testing`)
includeMultiConsumer = flag.Bool("include-multi-consumer", false, "include multiconsumer tests in run")
parallel = flag.Bool("parallel", false, "run all tests in parallel")
@@ -42,10 +41,10 @@ var (
func main() {
flag.Parse()
- if shortHappyPathOnly != nil && *shortHappyPathOnly {
+ if cometmockCompatibleHappyPath != nil && *cometmockCompatibleHappyPath {
fmt.Println("=============== running short happy path only ===============")
tr := DefaultTestRun()
- tr.Run(shortHappyPathSteps, *localSdkPath, *useGaia, *gaiaTag)
+ tr.Run(cometmockCompatibleHappyPathSteps, *localSdkPath, *useGaia, *gaiaTag)
return
}
diff --git a/tests/e2e/steps.go b/tests/e2e/steps.go
index aa08426103..770ac45dda 100644
--- a/tests/e2e/steps.go
+++ b/tests/e2e/steps.go
@@ -31,12 +31,14 @@ var happyPathSteps = concatSteps(
stepsStopChain("consu", 4), // stop chain
)
-var shortHappyPathSteps = concatSteps(
+var cometmockCompatibleHappyPathSteps = concatSteps(
stepsStartChains([]string{"consu"}, false),
stepsDelegate("consu"),
stepsUnbond("consu"),
stepsRedelegateShort("consu"),
stepsDowntime("consu"),
+ stepsRejectEquivocationProposal("consu", 2), // prop to tombstone bob is rejected
+ stepsDoubleSignOnProviderAndConsumer("consu"), // carol double signs on provider, bob double signs on consumer
stepsStartRelayer(),
stepsConsumerRemovalPropNotPassing("consu", 2), // submit removal prop but vote no on it - chain should stay
stepsStopChain("consu", 3), // stop chain