From f927baa2071308b506b3b3890ca413a4e38a0ce7 Mon Sep 17 00:00:00 2001 From: Fangyu Gai Date: Fri, 26 Aug 2022 14:13:39 +0800 Subject: [PATCH 1/7] add bls signer --- x/checkpointing/abci.go | 5 ++- x/checkpointing/keeper/bls_signer.go | 50 ++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 x/checkpointing/keeper/bls_signer.go diff --git a/x/checkpointing/abci.go b/x/checkpointing/abci.go index 206180beb..e23a11fd6 100644 --- a/x/checkpointing/abci.go +++ b/x/checkpointing/abci.go @@ -41,6 +41,9 @@ func BeginBlocker(ctx sdk.Context, k keeper.Keeper, req abci.RequestBeginBlock) ), }) - // TODO: call BLS signer to send a BLS-sig transaction + err = k.SendBlsSig(ctx, epoch.EpochNumber-1, lch) + if err != nil { + ctx.Logger().Error("failed to send BLS signature") + } } } diff --git a/x/checkpointing/keeper/bls_signer.go b/x/checkpointing/keeper/bls_signer.go new file mode 100644 index 000000000..e775ee957 --- /dev/null +++ b/x/checkpointing/keeper/bls_signer.go @@ -0,0 +1,50 @@ +package keeper + +import ( + "github.com/babylonchain/babylon/crypto/bls12381" + "github.com/babylonchain/babylon/privval" + "github.com/babylonchain/babylon/x/checkpointing/types" + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/tx" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/spf13/pflag" + tmconfig "github.com/tendermint/tendermint/config" +) + +// SendBlsSig prepares a BLS signature message and sends it to Tendermint +func (k Keeper) SendBlsSig(ctx sdk.Context, epochNum uint64, lch types.LastCommitHash) error { + // get self address + curValSet := k.GetValidatorSet(ctx, epochNum) + conf := tmconfig.DefaultConfig() + conf.PrivValidatorKeyFile() + wrappedPV := privval.LoadWrappedFilePV(conf.PrivValidatorKey, conf.PrivValidatorState) + addr := sdk.ValAddress(wrappedPV.GetAddress()) + + // check if itself is the validator + _, _, err := curValSet.FindValidatorWithIndex(addr) + if err != nil { + return err + } + + // get BLS signature by signing + blsPrivKey := wrappedPV.GetBlsPrivKey() + signBytes := append(sdk.Uint64ToBigEndian(epochNum), lch...) + blsSig := bls12381.Sign(blsPrivKey, signBytes) + + // create MsgAddBlsSig message + msg := types.NewMsgAddBlsSig(epochNum, lch, blsSig, addr) + + // insert the message into the transaction + fs := pflag.NewFlagSet("checkpointing", pflag.ContinueOnError) + err = fs.Set(flags.FlagFrom, k.GetParams(ctx).String()) + if err != nil { + return err + } + err = tx.GenerateOrBroadcastTxCLI(client.Context{}, fs, msg) + if err != nil { + return err + } + + return nil +} From 9cfba3b611a0876eaf673a1ae457dfd7e99e3dc5 Mon Sep 17 00:00:00 2001 From: Fangyu Gai Date: Mon, 29 Aug 2022 17:15:45 +0800 Subject: [PATCH 2/7] added mocks --- Makefile | 10 + app/app.go | 5 +- cmd/babylond/cmd/root.go | 10 +- go.mod | 3 +- go.sum | 14 -- privval/file.go | 22 +- testutil/keeper/checkpointing.go | 6 +- testutil/mocks/bls_signer.go | 80 +++++++ .../mocks/checkpointing_expected_keepers.go | 216 ++++++++++++++++++ x/checkpointing/abci.go | 10 +- x/checkpointing/keeper/bls_signer.go | 39 ++-- x/checkpointing/keeper/bls_signer_test.go | 49 ++++ x/checkpointing/keeper/keeper.go | 8 +- x/checkpointing/keeper/keeper_test.go | 6 +- x/checkpointing/types/errors.go | 19 +- x/checkpointing/types/expected_keepers.go | 2 - x/checkpointing/types/msgs.go | 2 +- x/epoching/keeper/epoch_val_set.go | 13 -- 18 files changed, 437 insertions(+), 77 deletions(-) create mode 100644 testutil/mocks/bls_signer.go create mode 100644 testutil/mocks/checkpointing_expected_keepers.go create mode 100644 x/checkpointing/keeper/bls_signer_test.go diff --git a/Makefile b/Makefile index aa67e1a7a..a9c210612 100644 --- a/Makefile +++ b/Makefile @@ -120,6 +120,16 @@ $(BUILDDIR)/: .PHONY: build build-linux +mockgen_cmd=go run github.com/golang/mock/mockgen@v1.6.0 + +mocks: $(MOCKS_DIR) + $(mockgen_cmd) -source=x/checkpointing/types/expected_keepers.go -package mocks -destination testutil/mocks/checkpointing_expected_keepers.go + $(mockgen_cmd) -source=x/checkpointing/keeper/bls_signer.go -package mocks -destination testutil/mocks/bls_signer.go +.PHONY: mocks + +$(MOCKS_DIR): + mkdir -p $(MOCKS_DIR) + distclean: clean tools-clean clean: rm -rf \ diff --git a/app/app.go b/app/app.go index ada992432..3a9deb12c 100644 --- a/app/app.go +++ b/app/app.go @@ -2,6 +2,8 @@ package app import ( "encoding/json" + "github.com/babylonchain/babylon/privval" + tmconfig "github.com/tendermint/tendermint/config" "io" "net/http" "os" @@ -214,7 +216,7 @@ func init() { // NewBabylonApp returns a reference to an initialized BabylonApp. func NewBabylonApp( logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest bool, skipUpgradeHeights map[int64]bool, - homePath string, invCheckPeriod uint, encodingConfig appparams.EncodingConfig, + homePath string, invCheckPeriod uint, encodingConfig appparams.EncodingConfig, nodeCfg *tmconfig.Config, appOpts servertypes.AppOptions, baseAppOptions ...func(*baseapp.BaseApp), ) *BabylonApp { @@ -342,6 +344,7 @@ func NewBabylonApp( appCodec, keys[checkpointingtypes.StoreKey], keys[checkpointingtypes.MemStoreKey], + privval.LoadOrGenWrappedFilePV(nodeCfg.PrivValidatorKeyFile(), nodeCfg.PrivValidatorStateFile()), app.EpochingKeeper, app.GetSubspace(checkpointingtypes.ModuleName)) diff --git a/cmd/babylond/cmd/root.go b/cmd/babylond/cmd/root.go index e76b8fc22..13109ed56 100644 --- a/cmd/babylond/cmd/root.go +++ b/cmd/babylond/cmd/root.go @@ -2,6 +2,7 @@ package cmd import ( "errors" + tmconfig "github.com/tendermint/tendermint/config" "io" "os" "path/filepath" @@ -232,11 +233,14 @@ func (a appCreator) newApp(logger log.Logger, db dbm.DB, traceStore io.Writer, a panic(err) } + nodeCfg := tmconfig.DefaultConfig() + return app.NewBabylonApp( logger, db, traceStore, true, skipUpgradeHeights, cast.ToString(appOpts.Get(flags.FlagHome)), cast.ToUint(appOpts.Get(server.FlagInvCheckPeriod)), a.encCfg, + nodeCfg, appOpts, baseapp.SetPruning(pruningOpts), baseapp.SetMinGasPrices(cast.ToString(appOpts.Get(server.FlagMinGasPrices))), @@ -264,14 +268,16 @@ func (a appCreator) appExport( return servertypes.ExportedApp{}, errors.New("application home not set") } + nodeCfg := tmconfig.DefaultConfig() + if height != -1 { - babylonApp = app.NewBabylonApp(logger, db, traceStore, false, map[int64]bool{}, homePath, uint(1), a.encCfg, appOpts) + babylonApp = app.NewBabylonApp(logger, db, traceStore, false, map[int64]bool{}, homePath, uint(1), a.encCfg, nodeCfg, appOpts) if err := babylonApp.LoadHeight(height); err != nil { return servertypes.ExportedApp{}, err } } else { - babylonApp = app.NewBabylonApp(logger, db, traceStore, true, map[int64]bool{}, homePath, uint(1), a.encCfg, appOpts) + babylonApp = app.NewBabylonApp(logger, db, traceStore, true, map[int64]bool{}, homePath, uint(1), a.encCfg, nodeCfg, appOpts) } return babylonApp.ExportAppStateAndValidators(forZeroHeight, jailAllowedAddrs) diff --git a/go.mod b/go.mod index 16c2c95fe..2d2d58f0c 100644 --- a/go.mod +++ b/go.mod @@ -26,6 +26,7 @@ require ( require ( github.com/boljen/go-bitmap v0.0.0-20151001105940-23cd2fb0ce7d + github.com/golang/mock v1.6.0 github.com/regen-network/cosmos-proto v0.3.1 ) @@ -103,7 +104,7 @@ require ( github.com/sasha-s/go-deadlock v0.2.1-0.20190427202633-1595213edefa // indirect github.com/spf13/afero v1.6.0 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect - github.com/spf13/pflag v1.0.5 // indirect + github.com/spf13/pflag v1.0.5 github.com/subosito/gotenv v1.2.0 // indirect github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca // indirect github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c // indirect diff --git a/go.sum b/go.sum index cf427e63d..117150e22 100644 --- a/go.sum +++ b/go.sum @@ -452,7 +452,6 @@ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5m github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gordonklaus/ineffassign v0.0.0-20200309095847-7953dde2c7bf/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4= github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= @@ -556,7 +555,6 @@ github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e/go.mod h1:G1C github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jhump/protoreflect v1.9.0 h1:npqHz788dryJiR/l6K/RUQAyh2SwV91+d1dnh4RjO9w= -github.com/jhump/protoreflect v1.9.0/go.mod h1:7GcYQDdMU/O/BBrl/cX6PNHpXh6cenjd8pneu5yW7Tg= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= @@ -698,7 +696,6 @@ github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OS github.com/neilotoole/errgroup v0.1.5/go.mod h1:Q2nLGf+594h0CLBs/Mbg6qOr7GtqDK7C2S41udRnToE= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/nishanths/predeclared v0.0.0-20200524104333-86fad755b4d3/go.mod h1:nt3d53pc1VYcphSCIaYAJtnPYnr3Zyn8fMq2wvPGPso= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= @@ -714,7 +711,6 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108 github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E= github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= -github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= @@ -747,11 +743,6 @@ github.com/openzipkin/zipkin-go v0.2.5/go.mod h1:KpXfKdgRDnnhsxw4pNIH9Md5lyFqKUa github.com/ory/dockertest v3.3.5+incompatible h1:iLLK6SQwIhcbrG783Dghaaa3WPzGc+4Emza6EbVUUGA= github.com/ory/dockertest v3.3.5+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs= github.com/otiai10/copy v1.6.0 h1:IinKAryFFuPONZ7cm6T6E2QX/vcJwSnlaA5lfoaXIiQ= -github.com/otiai10/copy v1.6.0/go.mod h1:XWfuS3CrI0R6IE0FbgHsEazaXO8G0LpMp9o8tos0x4E= -github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= -github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= -github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= -github.com/otiai10/mint v1.3.2/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= @@ -1270,7 +1261,6 @@ golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d h1:Zu/JngovGLVi6t2J3nmAf3AoTDwuzw85YZ3b9o4yU7s= golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= @@ -1337,10 +1327,8 @@ golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWc golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200522201501-cb1345f3a375/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200717024301-6ddee64345a6/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= @@ -1474,7 +1462,6 @@ google.golang.org/genproto v0.0.0-20211028162531-8db9c33dc351/go.mod h1:5CzLGKJ6 google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211223182754-3ac035c7e7cb/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220719170305-83ca9fad585f h1:P8EiVSxZwC6xH2niv2N66aqwMtYFg+D54gbjpcqKJtM= google.golang.org/genproto v0.0.0-20220719170305-83ca9fad585f/go.mod h1:GkXuJDJ6aQ7lnJcRF+SJVgFdQhypqgl3LB1C9vabdRE= google.golang.org/grpc v1.33.2 h1:EQyQC3sa8M+p6Ulc8yy9SWSS2GVwyRc83gAbG8lrl4o= @@ -1490,7 +1477,6 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.25.1-0.20200805231151-a709e31e5d12/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= diff --git a/privval/file.go b/privval/file.go index be4e76019..57fc958f9 100644 --- a/privval/file.go +++ b/privval/file.go @@ -3,6 +3,8 @@ package privval import ( "fmt" "github.com/babylonchain/babylon/crypto/bls12381" + checkpointingtypes "github.com/babylonchain/babylon/x/checkpointing/types" + sdk "github.com/cosmos/cosmos-sdk/types" tmcrypto "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/ed25519" tmjson "github.com/tendermint/tendermint/libs/json" @@ -161,8 +163,8 @@ func LoadOrGenWrappedFilePV(keyFilePath, stateFilePath string) *WrappedFilePV { // TODO: implement SignBLS // GetAddress returns the address of the validator. // Implements PrivValidator. -func (pv *WrappedFilePV) GetAddress() types.Address { - return pv.Key.Address +func (pv *WrappedFilePV) GetAddress() sdk.ValAddress { + return sdk.ValAddress(pv.Key.Address) } // GetPubKey returns the public key of the validator. @@ -179,6 +181,22 @@ func (pv *WrappedFilePV) GetBlsPrivKey() bls12381.PrivateKey { return pv.Key.BlsPrivKey } +func (pv *WrappedFilePV) SignMsgWithBls(msg []byte) (bls12381.Signature, error) { + blsPrivKey := pv.GetBlsPrivKey() + if blsPrivKey == nil { + return nil, checkpointingtypes.ErrBlsPrivKeyDoesNotExist + } + return bls12381.Sign(blsPrivKey, msg), nil +} + +func (pv *WrappedFilePV) GetBlsPubkey() (bls12381.PublicKey, error) { + blsPrivKey := pv.GetBlsPrivKey() + if blsPrivKey == nil { + return nil, checkpointingtypes.ErrBlsPrivKeyDoesNotExist + } + return blsPrivKey.PubKey(), nil +} + // Save persists the FilePV to disk. func (pv *WrappedFilePV) Save() { pv.Key.Save() diff --git a/testutil/keeper/checkpointing.go b/testutil/keeper/checkpointing.go index 49a8850bf..8e38c8ec9 100644 --- a/testutil/keeper/checkpointing.go +++ b/testutil/keeper/checkpointing.go @@ -16,7 +16,7 @@ import ( "testing" ) -func CheckpointingKeeper(t testing.TB) (*keeper.Keeper, sdk.Context, *codec.ProtoCodec) { +func CheckpointingKeeper(t testing.TB, ek types.EpochingKeeper, signer keeper.BlsSigner) (*keeper.Keeper, sdk.Context, *codec.ProtoCodec) { storeKey := sdk.NewKVStoreKey(types.StoreKey) memStoreKey := storetypes.NewMemoryStoreKey(types.MemStoreKey) @@ -41,8 +41,8 @@ func CheckpointingKeeper(t testing.TB) (*keeper.Keeper, sdk.Context, *codec.Prot cdc, storeKey, memStoreKey, - // TODO: nil for now, will add epoching keeper for integrated testing - nil, + signer, + ek, paramsSubspace, ) diff --git a/testutil/mocks/bls_signer.go b/testutil/mocks/bls_signer.go new file mode 100644 index 000000000..d846b7d20 --- /dev/null +++ b/testutil/mocks/bls_signer.go @@ -0,0 +1,80 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: x/checkpointing/keeper/bls_signer.go + +// Package mocks is a generated GoMock package. +package mocks + +import ( + reflect "reflect" + + bls12381 "github.com/babylonchain/babylon/crypto/bls12381" + types "github.com/cosmos/cosmos-sdk/types" + gomock "github.com/golang/mock/gomock" +) + +// MockBlsSigner is a mock of BlsSigner interface. +type MockBlsSigner struct { + ctrl *gomock.Controller + recorder *MockBlsSignerMockRecorder +} + +// MockBlsSignerMockRecorder is the mock recorder for MockBlsSigner. +type MockBlsSignerMockRecorder struct { + mock *MockBlsSigner +} + +// NewMockBlsSigner creates a new mock instance. +func NewMockBlsSigner(ctrl *gomock.Controller) *MockBlsSigner { + mock := &MockBlsSigner{ctrl: ctrl} + mock.recorder = &MockBlsSignerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockBlsSigner) EXPECT() *MockBlsSignerMockRecorder { + return m.recorder +} + +// GetAddress mocks base method. +func (m *MockBlsSigner) GetAddress() types.ValAddress { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetAddress") + ret0, _ := ret[0].(types.ValAddress) + return ret0 +} + +// GetAddress indicates an expected call of GetAddress. +func (mr *MockBlsSignerMockRecorder) GetAddress() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAddress", reflect.TypeOf((*MockBlsSigner)(nil).GetAddress)) +} + +// GetBlsPubkey mocks base method. +func (m *MockBlsSigner) GetBlsPubkey() (bls12381.PublicKey, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBlsPubkey") + ret0, _ := ret[0].(bls12381.PublicKey) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBlsPubkey indicates an expected call of GetBlsPubkey. +func (mr *MockBlsSignerMockRecorder) GetBlsPubkey() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlsPubkey", reflect.TypeOf((*MockBlsSigner)(nil).GetBlsPubkey)) +} + +// SignMsgWithBls mocks base method. +func (m *MockBlsSigner) SignMsgWithBls(msg []byte) (bls12381.Signature, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SignMsgWithBls", msg) + ret0, _ := ret[0].(bls12381.Signature) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// SignMsgWithBls indicates an expected call of SignMsgWithBls. +func (mr *MockBlsSignerMockRecorder) SignMsgWithBls(msg interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SignMsgWithBls", reflect.TypeOf((*MockBlsSigner)(nil).SignMsgWithBls), msg) +} diff --git a/testutil/mocks/checkpointing_expected_keepers.go b/testutil/mocks/checkpointing_expected_keepers.go new file mode 100644 index 000000000..8d3543a1f --- /dev/null +++ b/testutil/mocks/checkpointing_expected_keepers.go @@ -0,0 +1,216 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: x/checkpointing/types/expected_keepers.go + +// Package mocks is a generated GoMock package. +package mocks + +import ( + reflect "reflect" + + types "github.com/babylonchain/babylon/x/epoching/types" + types0 "github.com/cosmos/cosmos-sdk/types" + types1 "github.com/cosmos/cosmos-sdk/x/auth/types" + gomock "github.com/golang/mock/gomock" +) + +// MockAccountKeeper is a mock of AccountKeeper interface. +type MockAccountKeeper struct { + ctrl *gomock.Controller + recorder *MockAccountKeeperMockRecorder +} + +// MockAccountKeeperMockRecorder is the mock recorder for MockAccountKeeper. +type MockAccountKeeperMockRecorder struct { + mock *MockAccountKeeper +} + +// NewMockAccountKeeper creates a new mock instance. +func NewMockAccountKeeper(ctrl *gomock.Controller) *MockAccountKeeper { + mock := &MockAccountKeeper{ctrl: ctrl} + mock.recorder = &MockAccountKeeperMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockAccountKeeper) EXPECT() *MockAccountKeeperMockRecorder { + return m.recorder +} + +// GetAccount mocks base method. +func (m *MockAccountKeeper) GetAccount(ctx types0.Context, addr types0.AccAddress) types1.AccountI { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetAccount", ctx, addr) + ret0, _ := ret[0].(types1.AccountI) + return ret0 +} + +// GetAccount indicates an expected call of GetAccount. +func (mr *MockAccountKeeperMockRecorder) GetAccount(ctx, addr interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAccount", reflect.TypeOf((*MockAccountKeeper)(nil).GetAccount), ctx, addr) +} + +// MockBankKeeper is a mock of BankKeeper interface. +type MockBankKeeper struct { + ctrl *gomock.Controller + recorder *MockBankKeeperMockRecorder +} + +// MockBankKeeperMockRecorder is the mock recorder for MockBankKeeper. +type MockBankKeeperMockRecorder struct { + mock *MockBankKeeper +} + +// NewMockBankKeeper creates a new mock instance. +func NewMockBankKeeper(ctrl *gomock.Controller) *MockBankKeeper { + mock := &MockBankKeeper{ctrl: ctrl} + mock.recorder = &MockBankKeeperMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockBankKeeper) EXPECT() *MockBankKeeperMockRecorder { + return m.recorder +} + +// SpendableCoins mocks base method. +func (m *MockBankKeeper) SpendableCoins(ctx types0.Context, addr types0.AccAddress) types0.Coins { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SpendableCoins", ctx, addr) + ret0, _ := ret[0].(types0.Coins) + return ret0 +} + +// SpendableCoins indicates an expected call of SpendableCoins. +func (mr *MockBankKeeperMockRecorder) SpendableCoins(ctx, addr interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SpendableCoins", reflect.TypeOf((*MockBankKeeper)(nil).SpendableCoins), ctx, addr) +} + +// MockEpochingKeeper is a mock of EpochingKeeper interface. +type MockEpochingKeeper struct { + ctrl *gomock.Controller + recorder *MockEpochingKeeperMockRecorder +} + +// MockEpochingKeeperMockRecorder is the mock recorder for MockEpochingKeeper. +type MockEpochingKeeperMockRecorder struct { + mock *MockEpochingKeeper +} + +// NewMockEpochingKeeper creates a new mock instance. +func NewMockEpochingKeeper(ctrl *gomock.Controller) *MockEpochingKeeper { + mock := &MockEpochingKeeper{ctrl: ctrl} + mock.recorder = &MockEpochingKeeperMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockEpochingKeeper) EXPECT() *MockEpochingKeeperMockRecorder { + return m.recorder +} + +// EnqueueMsg mocks base method. +func (m *MockEpochingKeeper) EnqueueMsg(ctx types0.Context, msg types.QueuedMessage) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "EnqueueMsg", ctx, msg) +} + +// EnqueueMsg indicates an expected call of EnqueueMsg. +func (mr *MockEpochingKeeperMockRecorder) EnqueueMsg(ctx, msg interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnqueueMsg", reflect.TypeOf((*MockEpochingKeeper)(nil).EnqueueMsg), ctx, msg) +} + +// GetEpoch mocks base method. +func (m *MockEpochingKeeper) GetEpoch(ctx types0.Context) types.Epoch { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetEpoch", ctx) + ret0, _ := ret[0].(types.Epoch) + return ret0 +} + +// GetEpoch indicates an expected call of GetEpoch. +func (mr *MockEpochingKeeperMockRecorder) GetEpoch(ctx interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetEpoch", reflect.TypeOf((*MockEpochingKeeper)(nil).GetEpoch), ctx) +} + +// GetTotalVotingPower mocks base method. +func (m *MockEpochingKeeper) GetTotalVotingPower(ctx types0.Context, epochNumber uint64) int64 { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetTotalVotingPower", ctx, epochNumber) + ret0, _ := ret[0].(int64) + return ret0 +} + +// GetTotalVotingPower indicates an expected call of GetTotalVotingPower. +func (mr *MockEpochingKeeperMockRecorder) GetTotalVotingPower(ctx, epochNumber interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTotalVotingPower", reflect.TypeOf((*MockEpochingKeeper)(nil).GetTotalVotingPower), ctx, epochNumber) +} + +// GetValidatorSet mocks base method. +func (m *MockEpochingKeeper) GetValidatorSet(ctx types0.Context, epochNumer uint64) types.ValidatorSet { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetValidatorSet", ctx, epochNumer) + ret0, _ := ret[0].(types.ValidatorSet) + return ret0 +} + +// GetValidatorSet indicates an expected call of GetValidatorSet. +func (mr *MockEpochingKeeperMockRecorder) GetValidatorSet(ctx, epochNumer interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetValidatorSet", reflect.TypeOf((*MockEpochingKeeper)(nil).GetValidatorSet), ctx, epochNumer) +} + +// MockCheckpointingHooks is a mock of CheckpointingHooks interface. +type MockCheckpointingHooks struct { + ctrl *gomock.Controller + recorder *MockCheckpointingHooksMockRecorder +} + +// MockCheckpointingHooksMockRecorder is the mock recorder for MockCheckpointingHooks. +type MockCheckpointingHooksMockRecorder struct { + mock *MockCheckpointingHooks +} + +// NewMockCheckpointingHooks creates a new mock instance. +func NewMockCheckpointingHooks(ctrl *gomock.Controller) *MockCheckpointingHooks { + mock := &MockCheckpointingHooks{ctrl: ctrl} + mock.recorder = &MockCheckpointingHooksMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockCheckpointingHooks) EXPECT() *MockCheckpointingHooksMockRecorder { + return m.recorder +} + +// AfterBlsKeyRegistered mocks base method. +func (m *MockCheckpointingHooks) AfterBlsKeyRegistered(ctx types0.Context, valAddr types0.ValAddress) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AfterBlsKeyRegistered", ctx, valAddr) + ret0, _ := ret[0].(error) + return ret0 +} + +// AfterBlsKeyRegistered indicates an expected call of AfterBlsKeyRegistered. +func (mr *MockCheckpointingHooksMockRecorder) AfterBlsKeyRegistered(ctx, valAddr interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AfterBlsKeyRegistered", reflect.TypeOf((*MockCheckpointingHooks)(nil).AfterBlsKeyRegistered), ctx, valAddr) +} + +// AfterRawCheckpointConfirmed mocks base method. +func (m *MockCheckpointingHooks) AfterRawCheckpointConfirmed(ctx types0.Context, epoch uint64) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AfterRawCheckpointConfirmed", ctx, epoch) + ret0, _ := ret[0].(error) + return ret0 +} + +// AfterRawCheckpointConfirmed indicates an expected call of AfterRawCheckpointConfirmed. +func (mr *MockCheckpointingHooksMockRecorder) AfterRawCheckpointConfirmed(ctx, epoch interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AfterRawCheckpointConfirmed", reflect.TypeOf((*MockCheckpointingHooks)(nil).AfterRawCheckpointConfirmed), ctx, epoch) +} diff --git a/x/checkpointing/abci.go b/x/checkpointing/abci.go index e23a11fd6..00382a148 100644 --- a/x/checkpointing/abci.go +++ b/x/checkpointing/abci.go @@ -41,9 +41,11 @@ func BeginBlocker(ctx sdk.Context, k keeper.Keeper, req abci.RequestBeginBlock) ), }) - err = k.SendBlsSig(ctx, epoch.EpochNumber-1, lch) - if err != nil { - ctx.Logger().Error("failed to send BLS signature") - } + go func() { + err = k.SendBlsSig(ctx, epoch.EpochNumber-1, lch) + if err != nil { + ctx.Logger().Error("failed to send BLS signature") + } + }() } } diff --git a/x/checkpointing/keeper/bls_signer.go b/x/checkpointing/keeper/bls_signer.go index e775ee957..3c1e7a18a 100644 --- a/x/checkpointing/keeper/bls_signer.go +++ b/x/checkpointing/keeper/bls_signer.go @@ -2,49 +2,54 @@ package keeper import ( "github.com/babylonchain/babylon/crypto/bls12381" - "github.com/babylonchain/babylon/privval" + "github.com/babylonchain/babylon/x/checkpointing/client/cli" "github.com/babylonchain/babylon/x/checkpointing/types" "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/client/tx" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/spf13/pflag" - tmconfig "github.com/tendermint/tendermint/config" ) +type BlsSigner interface { + GetAddress() sdk.ValAddress + SignMsgWithBls(msg []byte) (bls12381.Signature, error) + GetBlsPubkey() (bls12381.PublicKey, error) +} + // SendBlsSig prepares a BLS signature message and sends it to Tendermint func (k Keeper) SendBlsSig(ctx sdk.Context, epochNum uint64, lch types.LastCommitHash) error { // get self address curValSet := k.GetValidatorSet(ctx, epochNum) - conf := tmconfig.DefaultConfig() - conf.PrivValidatorKeyFile() - wrappedPV := privval.LoadWrappedFilePV(conf.PrivValidatorKey, conf.PrivValidatorState) - addr := sdk.ValAddress(wrappedPV.GetAddress()) + addr := k.blsSigner.GetAddress() // check if itself is the validator _, _, err := curValSet.FindValidatorWithIndex(addr) if err != nil { - return err + // only send the BLS sig when the node itself is a validator + return nil } // get BLS signature by signing - blsPrivKey := wrappedPV.GetBlsPrivKey() signBytes := append(sdk.Uint64ToBigEndian(epochNum), lch...) - blsSig := bls12381.Sign(blsPrivKey, signBytes) + blsSig, err := k.blsSigner.SignMsgWithBls(signBytes) + if err != nil { + return err + } // create MsgAddBlsSig message msg := types.NewMsgAddBlsSig(epochNum, lch, blsSig, addr) // insert the message into the transaction - fs := pflag.NewFlagSet("checkpointing", pflag.ContinueOnError) - err = fs.Set(flags.FlagFrom, k.GetParams(ctx).String()) + fs := pflag.NewFlagSet("", pflag.ContinueOnError) + cmd := cli.CmdTxAddBlsSig() + clientCtx := client.GetClientContextFromCmd(cmd) + err = tx.GenerateOrBroadcastTxCLI( + clientCtx, + fs, + msg) if err != nil { return err } - err = tx.GenerateOrBroadcastTxCLI(client.Context{}, fs, msg) - if err != nil { - return err - } - + return nil } diff --git a/x/checkpointing/keeper/bls_signer_test.go b/x/checkpointing/keeper/bls_signer_test.go new file mode 100644 index 000000000..577b67703 --- /dev/null +++ b/x/checkpointing/keeper/bls_signer_test.go @@ -0,0 +1,49 @@ +package keeper_test + +import ( + "github.com/babylonchain/babylon/crypto/bls12381" + testkeeper "github.com/babylonchain/babylon/testutil/keeper" + "github.com/babylonchain/babylon/testutil/mocks" + epochingtypes "github.com/babylonchain/babylon/x/epoching/types" + "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" + "github.com/tendermint/tendermint/crypto/tmhash" + "testing" +) + +var ( + pk1 = ed25519.GenPrivKey().PubKey() + pk2 = ed25519.GenPrivKey().PubKey() + addr1 = sdk.ValAddress(pk1.Address()) + addr2 = sdk.ValAddress(pk2.Address()) + val1 = epochingtypes.Validator{ + Addr: addr1, + Power: 10, + } + val2 = epochingtypes.Validator{ + Addr: addr2, + Power: 10, + } + valSet = epochingtypes.ValidatorSet{val1, val2} + blsPrivKey1 = bls12381.GenPrivKey() +) + +func TestKeeper_SendBlsSig(t *testing.T) { + epochNum := uint64(10) + lch := tmhash.Sum([]byte("last_commit_hash")) + signBytes := append(sdk.Uint64ToBigEndian(epochNum), lch...) + + ctrl := gomock.NewController(t) + defer ctrl.Finish() + ek := mocks.NewMockEpochingKeeper(ctrl) + signer := mocks.NewMockBlsSigner(ctrl) + ckptkeeper, ctx, _ := testkeeper.CheckpointingKeeper(t, ek, signer) + + ek.EXPECT().GetValidatorSet(ctx, gomock.Eq(epochNum)).Return(valSet) + signer.EXPECT().GetAddress().Return(addr1) + signer.EXPECT().SignMsgWithBls(gomock.Eq(signBytes)).Return(bls12381.Sign(blsPrivKey1, signBytes), nil) + err := ckptkeeper.SendBlsSig(ctx, epochNum, lch) + require.NoError(t, err) +} diff --git a/x/checkpointing/keeper/keeper.go b/x/checkpointing/keeper/keeper.go index 6b24b54a3..6ebff3fa6 100644 --- a/x/checkpointing/keeper/keeper.go +++ b/x/checkpointing/keeper/keeper.go @@ -7,7 +7,6 @@ import ( "github.com/babylonchain/babylon/x/checkpointing/types" epochingtypes "github.com/babylonchain/babylon/x/epoching/types" "github.com/cosmos/cosmos-sdk/codec" - cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" sdk "github.com/cosmos/cosmos-sdk/types" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" "github.com/tendermint/tendermint/libs/log" @@ -18,6 +17,7 @@ type ( cdc codec.BinaryCodec storeKey sdk.StoreKey memKey sdk.StoreKey + blsSigner BlsSigner epochingKeeper types.EpochingKeeper hooks types.CheckpointingHooks paramstore paramtypes.Subspace @@ -28,6 +28,7 @@ func NewKeeper( cdc codec.BinaryCodec, storeKey, memKey sdk.StoreKey, + signer BlsSigner, ek types.EpochingKeeper, ps paramtypes.Subspace, ) Keeper { @@ -40,6 +41,7 @@ func NewKeeper( cdc: cdc, storeKey: storeKey, memKey: memKey, + blsSigner: signer, epochingKeeper: ek, paramstore: ps, hooks: nil, @@ -262,7 +264,3 @@ func (k Keeper) GetValidatorSet(ctx sdk.Context, epochNumber uint64) epochingtyp func (k Keeper) GetTotalVotingPower(ctx sdk.Context, epochNumber uint64) int64 { return k.epochingKeeper.GetTotalVotingPower(ctx, epochNumber) } - -func (k Keeper) GetValidatorPubkey(ctx sdk.Context, valAddr sdk.ValAddress) (cryptotypes.PubKey, bool) { - return k.epochingKeeper.GetValidatorPubkey(ctx, valAddr) -} diff --git a/x/checkpointing/keeper/keeper_test.go b/x/checkpointing/keeper/keeper_test.go index 0a3c8c2b8..826e6e4cb 100644 --- a/x/checkpointing/keeper/keeper_test.go +++ b/x/checkpointing/keeper/keeper_test.go @@ -19,7 +19,7 @@ func FuzzKeeperAddRawCheckpoint(f *testing.F) { datagen.AddRandomSeedsToFuzzer(f, 1) f.Fuzz(func(t *testing.T, seed int64) { rand.Seed(seed) - ckptKeeper, ctx, _ := testkeeper.CheckpointingKeeper(t) + ckptKeeper, ctx, _ := testkeeper.CheckpointingKeeper(t, nil, nil) // test nil raw checkpoint err := ckptKeeper.AddRawCheckpoint(ctx, nil) @@ -59,7 +59,7 @@ func FuzzKeeperCheckpointEpoch(f *testing.F) { datagen.AddRandomSeedsToFuzzer(f, 1) f.Fuzz(func(t *testing.T, seed int64) { rand.Seed(seed) - ckptKeeper, ctx, cdc := testkeeper.CheckpointingKeeper(t) + ckptKeeper, ctx, cdc := testkeeper.CheckpointingKeeper(t, nil, nil) mockCkptWithMeta := datagen.GenRandomRawCheckpointWithMeta() ckptBytes := types.RawCkptToBytes(cdc, mockCkptWithMeta.Ckpt) @@ -84,7 +84,7 @@ func FuzzKeeperSetCheckpointStatus(f *testing.F) { datagen.AddRandomSeedsToFuzzer(f, 1) f.Fuzz(func(t *testing.T, seed int64) { rand.Seed(seed) - ckptKeeper, ctx, _ := testkeeper.CheckpointingKeeper(t) + ckptKeeper, ctx, _ := testkeeper.CheckpointingKeeper(t, nil, nil) mockCkptWithMeta := datagen.GenRandomRawCheckpointWithMeta() epoch := mockCkptWithMeta.Ckpt.EpochNum diff --git a/x/checkpointing/types/errors.go b/x/checkpointing/types/errors.go index 10c7c0414..b3c3266dc 100644 --- a/x/checkpointing/types/errors.go +++ b/x/checkpointing/types/errors.go @@ -4,13 +4,14 @@ import sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" // x/checkpointing module sentinel errors var ( - ErrCkptDoesNotExist = sdkerrors.Register(ModuleName, 1201, "raw checkpoint does not exist") - ErrCkptAlreadyExist = sdkerrors.Register(ModuleName, 1202, "raw checkpoint already exists") - ErrCkptHashNotEqual = sdkerrors.Register(ModuleName, 1203, "hash does not equal to raw checkpoint") - ErrCkptNotAccumulating = sdkerrors.Register(ModuleName, 1204, "raw checkpoint is no longer accumulating BLS sigs") - ErrCkptAlreadyVoted = sdkerrors.Register(ModuleName, 1205, "raw checkpoint already accumulated the validator") - ErrInvalidRawCheckpoint = sdkerrors.Register(ModuleName, 1206, "raw checkpoint is invalid") - ErrInvalidCkptStatus = sdkerrors.Register(ModuleName, 1207, "raw checkpoint's status is invalid") - ErrBlsKeyDoesNotExist = sdkerrors.Register(ModuleName, 1208, "BLS public key does not exist") - ErrBlsKeyAlreadyExist = sdkerrors.Register(ModuleName, 1209, "BLS public key already exists") + ErrCkptDoesNotExist = sdkerrors.Register(ModuleName, 1201, "raw checkpoint does not exist") + ErrCkptAlreadyExist = sdkerrors.Register(ModuleName, 1202, "raw checkpoint already exists") + ErrCkptHashNotEqual = sdkerrors.Register(ModuleName, 1203, "hash does not equal to raw checkpoint") + ErrCkptNotAccumulating = sdkerrors.Register(ModuleName, 1204, "raw checkpoint is no longer accumulating BLS sigs") + ErrCkptAlreadyVoted = sdkerrors.Register(ModuleName, 1205, "raw checkpoint already accumulated the validator") + ErrInvalidRawCheckpoint = sdkerrors.Register(ModuleName, 1206, "raw checkpoint is invalid") + ErrInvalidCkptStatus = sdkerrors.Register(ModuleName, 1207, "raw checkpoint's status is invalid") + ErrBlsKeyDoesNotExist = sdkerrors.Register(ModuleName, 1208, "BLS public key does not exist") + ErrBlsKeyAlreadyExist = sdkerrors.Register(ModuleName, 1209, "BLS public key already exists") + ErrBlsPrivKeyDoesNotExist = sdkerrors.Register(ModuleName, 1210, "BLS private key does not exist") ) diff --git a/x/checkpointing/types/expected_keepers.go b/x/checkpointing/types/expected_keepers.go index 62f51de45..57f54ed87 100644 --- a/x/checkpointing/types/expected_keepers.go +++ b/x/checkpointing/types/expected_keepers.go @@ -2,7 +2,6 @@ package types import ( epochingtypes "github.com/babylonchain/babylon/x/epoching/types" - cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth/types" ) @@ -25,7 +24,6 @@ type EpochingKeeper interface { EnqueueMsg(ctx sdk.Context, msg epochingtypes.QueuedMessage) GetValidatorSet(ctx sdk.Context, epochNumer uint64) epochingtypes.ValidatorSet GetTotalVotingPower(ctx sdk.Context, epochNumber uint64) int64 - GetValidatorPubkey(ctx sdk.Context, valAddr sdk.ValAddress) (cryptotypes.PubKey, bool) } // Event Hooks diff --git a/x/checkpointing/types/msgs.go b/x/checkpointing/types/msgs.go index 4177c965c..dcd9ab23f 100644 --- a/x/checkpointing/types/msgs.go +++ b/x/checkpointing/types/msgs.go @@ -38,7 +38,7 @@ func NewMsgWrappedCreateValidator(msgCreateVal *stakingtypes.MsgCreateValidator) func (m *MsgAddBlsSig) ValidateBasic() error { // This function validates stateless message elements - _, err := sdk.AccAddressFromBech32(m.BlsSig.SignerAddress) + _, err := sdk.ValAddressFromBech32(m.BlsSig.SignerAddress) if err != nil { return err } diff --git a/x/epoching/keeper/epoch_val_set.go b/x/epoching/keeper/epoch_val_set.go index c83b3a4df..24237c47e 100644 --- a/x/epoching/keeper/epoch_val_set.go +++ b/x/epoching/keeper/epoch_val_set.go @@ -2,7 +2,6 @@ package keeper import ( "github.com/babylonchain/babylon/x/epoching/types" - cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" @@ -31,18 +30,6 @@ func (k Keeper) GetValidatorSet(ctx sdk.Context, epochNumber uint64) types.Valid return types.NewSortedValidatorSet(vals) } -func (k Keeper) GetValidatorPubkey(ctx sdk.Context, valAddr sdk.ValAddress) (cryptotypes.PubKey, bool) { - validator, found := k.stk.GetValidator(ctx, valAddr) - if !found { - return nil, false - } - pubkey, err := validator.ConsPubKey() - if err != nil { - return nil, false - } - return pubkey, true -} - // InitValidatorSet stores the validator set in the beginning of the current epoch // This is called upon BeginBlock func (k Keeper) InitValidatorSet(ctx sdk.Context) { From f719b4f4c7b8491292b9ca1369cbed82a2a91026 Mon Sep 17 00:00:00 2001 From: Fangyu Gai Date: Mon, 29 Aug 2022 21:26:57 +0800 Subject: [PATCH 3/7] finished unit test of sendBlsSig --- app/app.go | 24 +++++++++++++++--- app/app_test.go | 7 +++--- app/config/priv_validator_key.json | 13 ++++++++++ app/data/priv_validator_state.json | 5 ++++ app/test_helpers.go | 3 ++- simapp/sim_bench_test.go | 5 ++-- simapp/sim_test.go | 13 +++++----- testutil/keeper/checkpointing.go | 5 +++- x/checkpointing/abci.go | 4 ++- .../config/priv_validator_key.json | 13 ++++++++++ .../data/priv_validator_state.json | 5 ++++ x/checkpointing/keeper/bls_signer.go | 10 ++------ x/checkpointing/keeper/bls_signer_test.go | 25 +++++++++++++++++-- x/checkpointing/keeper/keeper.go | 4 +++ x/checkpointing/keeper/keeper_test.go | 7 +++--- x/checkpointing/types/msgs.go | 4 +-- x/epoching/config/priv_validator_key.json | 13 ++++++++++ x/epoching/data/priv_validator_state.json | 5 ++++ .../keeper/config/priv_validator_key.json | 13 ++++++++++ .../keeper/data/priv_validator_state.json | 5 ++++ .../types/config/priv_validator_key.json | 13 ++++++++++ .../types/data/priv_validator_state.json | 5 ++++ 22 files changed, 169 insertions(+), 32 deletions(-) create mode 100644 app/config/priv_validator_key.json create mode 100644 app/data/priv_validator_state.json create mode 100644 x/checkpointing/config/priv_validator_key.json create mode 100644 x/checkpointing/data/priv_validator_state.json create mode 100644 x/epoching/config/priv_validator_key.json create mode 100644 x/epoching/data/priv_validator_state.json create mode 100644 x/epoching/keeper/config/priv_validator_key.json create mode 100644 x/epoching/keeper/data/priv_validator_state.json create mode 100644 x/epoching/types/config/priv_validator_key.json create mode 100644 x/epoching/types/data/priv_validator_state.json diff --git a/app/app.go b/app/app.go index 3a9deb12c..fac83bd98 100644 --- a/app/app.go +++ b/app/app.go @@ -154,7 +154,7 @@ var ( _ servertypes.Application = (*BabylonApp)(nil) ) -// App extends an ABCI application, but with most of its parameters exported. +// BabylonApp extends an ABCI application, but with most of its parameters exported. // They are exported for convenience in creating helper functions, as object // capabilities aren't needed for testing. type BabylonApp struct { @@ -339,14 +339,32 @@ func NewBabylonApp( keys[btclightclienttypes.MemStoreKey], app.GetSubspace(btclightclienttypes.ModuleName)) + pvKeyFile := nodeCfg.PrivValidatorKeyFile() + if err := tmos.EnsureDir(filepath.Dir(pvKeyFile), 0777); err != nil { + panic(err) + } + pvStateFile := nodeCfg.PrivValidatorStateFile() + if err := tmos.EnsureDir(filepath.Dir(pvStateFile), 0777); err != nil { + panic(err) + } + // TODO: currently, the client.Context is a placeholder, it should be injected from somewhere app.CheckpointingKeeper = checkpointingkeeper.NewKeeper( appCodec, keys[checkpointingtypes.StoreKey], keys[checkpointingtypes.MemStoreKey], - privval.LoadOrGenWrappedFilePV(nodeCfg.PrivValidatorKeyFile(), nodeCfg.PrivValidatorStateFile()), + privval.LoadOrGenWrappedFilePV(pvKeyFile, pvStateFile), app.EpochingKeeper, - app.GetSubspace(checkpointingtypes.ModuleName)) + app.GetSubspace(checkpointingtypes.ModuleName), + client.Context{}. + WithCodec(encodingConfig.Marshaler). + WithInterfaceRegistry(encodingConfig.InterfaceRegistry). + WithTxConfig(encodingConfig.TxConfig). + WithLegacyAmino(encodingConfig.Amino). + WithInput(os.Stdin). + WithAccountRetriever(authtypes.AccountRetriever{}). + WithViper(""), // In app, we don't use any prefix for env variables. + ) // TODO for now use mocks, as soon as Checkpoining and lightClient will have correct interfaces // change to correct implementations diff --git a/app/app_test.go b/app/app_test.go index 376507cc5..9871da625 100644 --- a/app/app_test.go +++ b/app/app_test.go @@ -2,6 +2,7 @@ package app import ( "encoding/json" + tmconfig "github.com/tendermint/tendermint/config" "os" "testing" @@ -15,7 +16,7 @@ import ( func TestBabylonBlockedAddrs(t *testing.T) { encCfg := MakeTestEncodingConfig() db := dbm.NewMemDB() - app := NewBabylonApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, map[int64]bool{}, DefaultNodeHome, 0, encCfg, EmptyAppOptions{}) + app := NewBabylonApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, map[int64]bool{}, DefaultNodeHome, 0, encCfg, tmconfig.DefaultConfig(), EmptyAppOptions{}) for acc := range maccPerms { require.True( @@ -39,7 +40,7 @@ func TestBabylonBlockedAddrs(t *testing.T) { app.Commit() // Making a new app object with the db, so that initchain hasn't been called - app2 := NewBabylonApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, map[int64]bool{}, DefaultNodeHome, 0, encCfg, EmptyAppOptions{}) + app2 := NewBabylonApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, map[int64]bool{}, DefaultNodeHome, 0, encCfg, tmconfig.DefaultConfig(), EmptyAppOptions{}) _, err = app2.ExportAppStateAndValidators(false, []string{}) require.NoError(t, err, "ExportAppStateAndValidators should not have an error") } @@ -52,7 +53,7 @@ func TestGetMaccPerms(t *testing.T) { func TestUpgradeStateOnGenesis(t *testing.T) { encCfg := MakeTestEncodingConfig() db := dbm.NewMemDB() - app := NewBabylonApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, map[int64]bool{}, DefaultNodeHome, 0, encCfg, EmptyAppOptions{}) + app := NewBabylonApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, map[int64]bool{}, DefaultNodeHome, 0, encCfg, tmconfig.DefaultConfig(), EmptyAppOptions{}) genesisState := NewDefaultGenesisState(encCfg.Marshaler) stateBytes, err := json.MarshalIndent(genesisState, "", " ") require.NoError(t, err) diff --git a/app/config/priv_validator_key.json b/app/config/priv_validator_key.json new file mode 100644 index 000000000..6fb4eee5e --- /dev/null +++ b/app/config/priv_validator_key.json @@ -0,0 +1,13 @@ +{ + "address": "99F5587BC8D39D825089EB3009C227EC07CD72B6", + "pub_key": { + "type": "tendermint/PubKeyEd25519", + "value": "rOhCRZVhITnIQrilPE3rtp1AHHA++Qq495v2101fUjE=" + }, + "priv_key": { + "type": "tendermint/PrivKeyEd25519", + "value": "xu5Vque40RQ1dWKFIdrjxhbVbHP145Gy+VyLHJi/pt6s6EJFlWEhOchCuKU8Teu2nUAccD75Crj3m/bXTV9SMQ==" + }, + "bls_pub_key": "mXg966FaX5/Eiqhd4GitMwvTlOa5Miy+fk71ShJhmCkxiYhsFcxrR3KeehvlXW4DAVSzK6Hq1a3aa3O/d4RaB5ueuW8am0B3IatmWKJN0ZoQvkMGJYSjlHZj1ND/2Y3I", + "bls_priv_key": "QuSQXt6f+itZsH9RiDvIt2J58D/84Nm1v27w7hmdalo=" +} \ No newline at end of file diff --git a/app/data/priv_validator_state.json b/app/data/priv_validator_state.json new file mode 100644 index 000000000..48f3b67e3 --- /dev/null +++ b/app/data/priv_validator_state.json @@ -0,0 +1,5 @@ +{ + "height": "0", + "round": 0, + "step": 0 +} \ No newline at end of file diff --git a/app/test_helpers.go b/app/test_helpers.go index 9d3a4f160..9b273a043 100644 --- a/app/test_helpers.go +++ b/app/test_helpers.go @@ -5,6 +5,7 @@ import ( "encoding/hex" "encoding/json" "fmt" + tmconfig "github.com/tendermint/tendermint/config" "strconv" "testing" "time" @@ -55,7 +56,7 @@ var DefaultConsensusParams = &abci.ConsensusParams{ func setup(withGenesis bool, invCheckPeriod uint) (*BabylonApp, GenesisState) { db := dbm.NewMemDB() encCdc := MakeTestEncodingConfig() - app := NewBabylonApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, DefaultNodeHome, invCheckPeriod, encCdc, sdksimapp.EmptyAppOptions{}) + app := NewBabylonApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, DefaultNodeHome, invCheckPeriod, encCdc, tmconfig.DefaultConfig(), sdksimapp.EmptyAppOptions{}) if withGenesis { return app, NewDefaultGenesisState(encCdc.Marshaler) } diff --git a/simapp/sim_bench_test.go b/simapp/sim_bench_test.go index 7f4497670..64137bf5c 100644 --- a/simapp/sim_bench_test.go +++ b/simapp/sim_bench_test.go @@ -2,6 +2,7 @@ package simapp import ( "fmt" + tmconfig "github.com/tendermint/tendermint/config" "os" "testing" @@ -35,7 +36,7 @@ func BenchmarkFullAppSimulation(b *testing.B) { } }() - babylon := app.NewBabylonApp(logger, db, nil, true, map[int64]bool{}, app.DefaultNodeHome, FlagPeriodValue, app.MakeTestEncodingConfig(), sdksimapp.EmptyAppOptions{}, interBlockCacheOpt()) + babylon := app.NewBabylonApp(logger, db, nil, true, map[int64]bool{}, app.DefaultNodeHome, FlagPeriodValue, app.MakeTestEncodingConfig(), tmconfig.DefaultConfig(), sdksimapp.EmptyAppOptions{}, interBlockCacheOpt()) // run randomized simulation _, simParams, simErr := simulation.SimulateFromSeed( @@ -85,7 +86,7 @@ func BenchmarkInvariants(b *testing.B) { } }() - babylon := app.NewBabylonApp(logger, db, nil, true, map[int64]bool{}, app.DefaultNodeHome, FlagPeriodValue, app.MakeTestEncodingConfig(), sdksimapp.EmptyAppOptions{}, interBlockCacheOpt()) + babylon := app.NewBabylonApp(logger, db, nil, true, map[int64]bool{}, app.DefaultNodeHome, FlagPeriodValue, app.MakeTestEncodingConfig(), tmconfig.DefaultConfig(), sdksimapp.EmptyAppOptions{}, interBlockCacheOpt()) // run randomized simulation _, simParams, simErr := simulation.SimulateFromSeed( diff --git a/simapp/sim_test.go b/simapp/sim_test.go index 7819bd71b..e6ec3fca4 100644 --- a/simapp/sim_test.go +++ b/simapp/sim_test.go @@ -3,6 +3,7 @@ package simapp import ( "encoding/json" "fmt" + tmconfig "github.com/tendermint/tendermint/config" "math/rand" "os" "testing" @@ -74,7 +75,7 @@ func TestFullAppSimulation(t *testing.T) { require.NoError(t, os.RemoveAll(dir)) }() - babylon := app.NewBabylonApp(logger, db, nil, true, map[int64]bool{}, app.DefaultNodeHome, FlagPeriodValue, app.MakeTestEncodingConfig(), sdksimapp.EmptyAppOptions{}, fauxMerkleModeOpt) + babylon := app.NewBabylonApp(logger, db, nil, true, map[int64]bool{}, app.DefaultNodeHome, FlagPeriodValue, app.MakeTestEncodingConfig(), tmconfig.DefaultConfig(), sdksimapp.EmptyAppOptions{}, fauxMerkleModeOpt) require.Equal(t, "BabylonApp", babylon.Name()) // run randomized simulation @@ -112,7 +113,7 @@ func TestAppImportExport(t *testing.T) { require.NoError(t, os.RemoveAll(dir)) }() - babylon := app.NewBabylonApp(logger, db, nil, true, map[int64]bool{}, app.DefaultNodeHome, FlagPeriodValue, app.MakeTestEncodingConfig(), sdksimapp.EmptyAppOptions{}, fauxMerkleModeOpt) + babylon := app.NewBabylonApp(logger, db, nil, true, map[int64]bool{}, app.DefaultNodeHome, FlagPeriodValue, app.MakeTestEncodingConfig(), tmconfig.DefaultConfig(), sdksimapp.EmptyAppOptions{}, fauxMerkleModeOpt) require.Equal(t, "BabylonApp", babylon.Name()) // Run randomized simulation @@ -152,7 +153,7 @@ func TestAppImportExport(t *testing.T) { require.NoError(t, os.RemoveAll(newDir)) }() - newBabylon := app.NewBabylonApp(log.NewNopLogger(), newDB, nil, true, map[int64]bool{}, app.DefaultNodeHome, FlagPeriodValue, app.MakeTestEncodingConfig(), sdksimapp.EmptyAppOptions{}, fauxMerkleModeOpt) + newBabylon := app.NewBabylonApp(log.NewNopLogger(), newDB, nil, true, map[int64]bool{}, app.DefaultNodeHome, FlagPeriodValue, app.MakeTestEncodingConfig(), tmconfig.DefaultConfig(), sdksimapp.EmptyAppOptions{}, fauxMerkleModeOpt) require.Equal(t, "BabylonApp", newBabylon.Name()) var genesisState app.GenesisState @@ -214,7 +215,7 @@ func TestAppSimulationAfterImport(t *testing.T) { require.NoError(t, os.RemoveAll(dir)) }() - babylon := app.NewBabylonApp(logger, db, nil, true, map[int64]bool{}, app.DefaultNodeHome, FlagPeriodValue, app.MakeTestEncodingConfig(), sdksimapp.EmptyAppOptions{}, fauxMerkleModeOpt) + babylon := app.NewBabylonApp(logger, db, nil, true, map[int64]bool{}, app.DefaultNodeHome, FlagPeriodValue, app.MakeTestEncodingConfig(), tmconfig.DefaultConfig(), sdksimapp.EmptyAppOptions{}, fauxMerkleModeOpt) require.Equal(t, "BabylonApp", babylon.Name()) // Run randomized simulation @@ -259,7 +260,7 @@ func TestAppSimulationAfterImport(t *testing.T) { require.NoError(t, os.RemoveAll(newDir)) }() - newBabylon := app.NewBabylonApp(log.NewNopLogger(), newDB, nil, true, map[int64]bool{}, app.DefaultNodeHome, FlagPeriodValue, app.MakeTestEncodingConfig(), sdksimapp.EmptyAppOptions{}, fauxMerkleModeOpt) + newBabylon := app.NewBabylonApp(log.NewNopLogger(), newDB, nil, true, map[int64]bool{}, app.DefaultNodeHome, FlagPeriodValue, app.MakeTestEncodingConfig(), tmconfig.DefaultConfig(), sdksimapp.EmptyAppOptions{}, fauxMerkleModeOpt) require.Equal(t, "BabylonApp", newBabylon.Name()) newBabylon.InitChain(abci.RequestInitChain{ @@ -310,7 +311,7 @@ func TestAppStateDeterminism(t *testing.T) { } db := dbm.NewMemDB() - babylon := app.NewBabylonApp(logger, db, nil, true, map[int64]bool{}, app.DefaultNodeHome, FlagPeriodValue, app.MakeTestEncodingConfig(), sdksimapp.EmptyAppOptions{}, interBlockCacheOpt()) + babylon := app.NewBabylonApp(logger, db, nil, true, map[int64]bool{}, app.DefaultNodeHome, FlagPeriodValue, app.MakeTestEncodingConfig(), tmconfig.DefaultConfig(), sdksimapp.EmptyAppOptions{}, interBlockCacheOpt()) fmt.Printf( "running non-determinism simulation; seed %d: %d/%d, attempt: %d/%d\n", diff --git a/testutil/keeper/checkpointing.go b/testutil/keeper/checkpointing.go index 8e38c8ec9..c002b0bf7 100644 --- a/testutil/keeper/checkpointing.go +++ b/testutil/keeper/checkpointing.go @@ -3,6 +3,7 @@ package keeper import ( "github.com/babylonchain/babylon/x/checkpointing/keeper" "github.com/babylonchain/babylon/x/checkpointing/types" + "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" codectypes "github.com/cosmos/cosmos-sdk/codec/types" "github.com/cosmos/cosmos-sdk/store" @@ -16,7 +17,7 @@ import ( "testing" ) -func CheckpointingKeeper(t testing.TB, ek types.EpochingKeeper, signer keeper.BlsSigner) (*keeper.Keeper, sdk.Context, *codec.ProtoCodec) { +func CheckpointingKeeper(t testing.TB, ek types.EpochingKeeper, signer keeper.BlsSigner, cliCtx client.Context) (*keeper.Keeper, sdk.Context, *codec.ProtoCodec) { storeKey := sdk.NewKVStoreKey(types.StoreKey) memStoreKey := storetypes.NewMemoryStoreKey(types.MemStoreKey) @@ -27,6 +28,7 @@ func CheckpointingKeeper(t testing.TB, ek types.EpochingKeeper, signer keeper.Bl require.NoError(t, stateStore.LoadLatestVersion()) registry := codectypes.NewInterfaceRegistry() + types.RegisterInterfaces(registry) cdc := codec.NewProtoCodec(registry) paramsSubspace := typesparams.NewSubspace( @@ -44,6 +46,7 @@ func CheckpointingKeeper(t testing.TB, ek types.EpochingKeeper, signer keeper.Bl signer, ek, paramsSubspace, + cliCtx, ) ctx := sdk.NewContext(stateStore, tmproto.Header{}, false, log.NewNopLogger()) diff --git a/x/checkpointing/abci.go b/x/checkpointing/abci.go index 00382a148..6137a0588 100644 --- a/x/checkpointing/abci.go +++ b/x/checkpointing/abci.go @@ -2,6 +2,7 @@ package checkpointing import ( "fmt" + "github.com/cosmos/cosmos-sdk/client" "time" "github.com/babylonchain/babylon/x/checkpointing/types" @@ -42,7 +43,8 @@ func BeginBlocker(ctx sdk.Context, k keeper.Keeper, req abci.RequestBeginBlock) }) go func() { - err = k.SendBlsSig(ctx, epoch.EpochNumber-1, lch) + // TODO: inject client.Context + err = k.SendBlsSig(ctx, epoch.EpochNumber-1, lch, client.Context{}) if err != nil { ctx.Logger().Error("failed to send BLS signature") } diff --git a/x/checkpointing/config/priv_validator_key.json b/x/checkpointing/config/priv_validator_key.json new file mode 100644 index 000000000..0f3d74042 --- /dev/null +++ b/x/checkpointing/config/priv_validator_key.json @@ -0,0 +1,13 @@ +{ + "address": "280CFFB697F860BCE28B92046646667C35ED1F1F", + "pub_key": { + "type": "tendermint/PubKeyEd25519", + "value": "9r0oObpoQXumTkLjHD6QvaYea6/STlLmagzYWrq2p5k=" + }, + "priv_key": { + "type": "tendermint/PrivKeyEd25519", + "value": "sho0sQXKQ7asi4pAvp6nIhTvmGuale5HQuZjDRRj8df2vSg5umhBe6ZOQuMcPpC9ph5rr9JOUuZqDNhauranmQ==" + }, + "bls_pub_key": "k03SjUF64skQE3QGx08qOZidXa5MVpKA4kbL5xsC8jB74POh+Elt+L2GVbFu50/WASPbFfpldKRMkxELksFbamkOovhFQ9pHIXebeq0i2EMeP4foPFeNmZFOEBT0kMlw", + "bls_priv_key": "V9O5z2ba9wbKzQm6ibif8eaOu0fy4DY7PT2suIF3ec0=" +} \ No newline at end of file diff --git a/x/checkpointing/data/priv_validator_state.json b/x/checkpointing/data/priv_validator_state.json new file mode 100644 index 000000000..48f3b67e3 --- /dev/null +++ b/x/checkpointing/data/priv_validator_state.json @@ -0,0 +1,5 @@ +{ + "height": "0", + "round": 0, + "step": 0 +} \ No newline at end of file diff --git a/x/checkpointing/keeper/bls_signer.go b/x/checkpointing/keeper/bls_signer.go index 3c1e7a18a..55d873798 100644 --- a/x/checkpointing/keeper/bls_signer.go +++ b/x/checkpointing/keeper/bls_signer.go @@ -2,7 +2,6 @@ package keeper import ( "github.com/babylonchain/babylon/crypto/bls12381" - "github.com/babylonchain/babylon/x/checkpointing/client/cli" "github.com/babylonchain/babylon/x/checkpointing/types" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/tx" @@ -17,7 +16,7 @@ type BlsSigner interface { } // SendBlsSig prepares a BLS signature message and sends it to Tendermint -func (k Keeper) SendBlsSig(ctx sdk.Context, epochNum uint64, lch types.LastCommitHash) error { +func (k Keeper) SendBlsSig(ctx sdk.Context, epochNum uint64, lch types.LastCommitHash, clientCtx client.Context) error { // get self address curValSet := k.GetValidatorSet(ctx, epochNum) addr := k.blsSigner.GetAddress() @@ -41,12 +40,7 @@ func (k Keeper) SendBlsSig(ctx sdk.Context, epochNum uint64, lch types.LastCommi // insert the message into the transaction fs := pflag.NewFlagSet("", pflag.ContinueOnError) - cmd := cli.CmdTxAddBlsSig() - clientCtx := client.GetClientContextFromCmd(cmd) - err = tx.GenerateOrBroadcastTxCLI( - clientCtx, - fs, - msg) + err = tx.GenerateOrBroadcastTxCLI(clientCtx, fs, msg) if err != nil { return err } diff --git a/x/checkpointing/keeper/bls_signer_test.go b/x/checkpointing/keeper/bls_signer_test.go index 577b67703..1fe1b56ab 100644 --- a/x/checkpointing/keeper/bls_signer_test.go +++ b/x/checkpointing/keeper/bls_signer_test.go @@ -1,11 +1,15 @@ package keeper_test import ( + "fmt" + "github.com/babylonchain/babylon/app" "github.com/babylonchain/babylon/crypto/bls12381" testkeeper "github.com/babylonchain/babylon/testutil/keeper" "github.com/babylonchain/babylon/testutil/mocks" epochingtypes "github.com/babylonchain/babylon/x/epoching/types" + "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" + "github.com/cosmos/cosmos-sdk/testutil/network" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" @@ -31,6 +35,23 @@ var ( ) func TestKeeper_SendBlsSig(t *testing.T) { + cfg := network.DefaultConfig() + encodingCfg := app.MakeTestEncodingConfig() + cfg.InterfaceRegistry = encodingCfg.InterfaceRegistry + cfg.TxConfig = encodingCfg.TxConfig + cfg.NumValidators = 1 + + network := network.New(t, cfg) + defer network.Cleanup() + + val := network.Validators[0] + nodeDirName := fmt.Sprintf("node%d", 0) + clientCtx := val.ClientCtx.WithHeight(2). + WithFromAddress(val.Address). + WithFromName(nodeDirName). + WithBroadcastMode(flags.BroadcastAsync) + clientCtx.SkipConfirm = true + epochNum := uint64(10) lch := tmhash.Sum([]byte("last_commit_hash")) signBytes := append(sdk.Uint64ToBigEndian(epochNum), lch...) @@ -39,11 +60,11 @@ func TestKeeper_SendBlsSig(t *testing.T) { defer ctrl.Finish() ek := mocks.NewMockEpochingKeeper(ctrl) signer := mocks.NewMockBlsSigner(ctrl) - ckptkeeper, ctx, _ := testkeeper.CheckpointingKeeper(t, ek, signer) + ckptkeeper, ctx, _ := testkeeper.CheckpointingKeeper(t, ek, signer, clientCtx) ek.EXPECT().GetValidatorSet(ctx, gomock.Eq(epochNum)).Return(valSet) signer.EXPECT().GetAddress().Return(addr1) signer.EXPECT().SignMsgWithBls(gomock.Eq(signBytes)).Return(bls12381.Sign(blsPrivKey1, signBytes), nil) - err := ckptkeeper.SendBlsSig(ctx, epochNum, lch) + err := ckptkeeper.SendBlsSig(ctx, epochNum, lch, clientCtx) require.NoError(t, err) } diff --git a/x/checkpointing/keeper/keeper.go b/x/checkpointing/keeper/keeper.go index 6ebff3fa6..78cee873d 100644 --- a/x/checkpointing/keeper/keeper.go +++ b/x/checkpointing/keeper/keeper.go @@ -6,6 +6,7 @@ import ( "github.com/babylonchain/babylon/crypto/bls12381" "github.com/babylonchain/babylon/x/checkpointing/types" epochingtypes "github.com/babylonchain/babylon/x/epoching/types" + "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" @@ -21,6 +22,7 @@ type ( epochingKeeper types.EpochingKeeper hooks types.CheckpointingHooks paramstore paramtypes.Subspace + clientCtx client.Context } ) @@ -31,6 +33,7 @@ func NewKeeper( signer BlsSigner, ek types.EpochingKeeper, ps paramtypes.Subspace, + clientCtx client.Context, ) Keeper { // set KeyTable if it has not already been set if !ps.HasKeyTable() { @@ -45,6 +48,7 @@ func NewKeeper( epochingKeeper: ek, paramstore: ps, hooks: nil, + clientCtx: clientCtx, } } diff --git a/x/checkpointing/keeper/keeper_test.go b/x/checkpointing/keeper/keeper_test.go index 826e6e4cb..ffe22de72 100644 --- a/x/checkpointing/keeper/keeper_test.go +++ b/x/checkpointing/keeper/keeper_test.go @@ -4,6 +4,7 @@ import ( "github.com/babylonchain/babylon/testutil/datagen" testkeeper "github.com/babylonchain/babylon/testutil/keeper" "github.com/babylonchain/babylon/x/checkpointing/types" + "github.com/cosmos/cosmos-sdk/client" "github.com/stretchr/testify/require" "math/rand" "testing" @@ -19,7 +20,7 @@ func FuzzKeeperAddRawCheckpoint(f *testing.F) { datagen.AddRandomSeedsToFuzzer(f, 1) f.Fuzz(func(t *testing.T, seed int64) { rand.Seed(seed) - ckptKeeper, ctx, _ := testkeeper.CheckpointingKeeper(t, nil, nil) + ckptKeeper, ctx, _ := testkeeper.CheckpointingKeeper(t, nil, nil, client.Context{}) // test nil raw checkpoint err := ckptKeeper.AddRawCheckpoint(ctx, nil) @@ -59,7 +60,7 @@ func FuzzKeeperCheckpointEpoch(f *testing.F) { datagen.AddRandomSeedsToFuzzer(f, 1) f.Fuzz(func(t *testing.T, seed int64) { rand.Seed(seed) - ckptKeeper, ctx, cdc := testkeeper.CheckpointingKeeper(t, nil, nil) + ckptKeeper, ctx, cdc := testkeeper.CheckpointingKeeper(t, nil, nil, client.Context{}) mockCkptWithMeta := datagen.GenRandomRawCheckpointWithMeta() ckptBytes := types.RawCkptToBytes(cdc, mockCkptWithMeta.Ckpt) @@ -84,7 +85,7 @@ func FuzzKeeperSetCheckpointStatus(f *testing.F) { datagen.AddRandomSeedsToFuzzer(f, 1) f.Fuzz(func(t *testing.T, seed int64) { rand.Seed(seed) - ckptKeeper, ctx, _ := testkeeper.CheckpointingKeeper(t, nil, nil) + ckptKeeper, ctx, _ := testkeeper.CheckpointingKeeper(t, nil, nil, client.Context{}) mockCkptWithMeta := datagen.GenRandomRawCheckpointWithMeta() epoch := mockCkptWithMeta.Ckpt.EpochNum diff --git a/x/checkpointing/types/msgs.go b/x/checkpointing/types/msgs.go index dcd9ab23f..be9ad6cc7 100644 --- a/x/checkpointing/types/msgs.go +++ b/x/checkpointing/types/msgs.go @@ -49,12 +49,12 @@ func (m *MsgAddBlsSig) ValidateBasic() error { } func (m *MsgAddBlsSig) GetSigners() []sdk.AccAddress { - signer, err := sdk.AccAddressFromBech32(m.BlsSig.SignerAddress) + signer, err := sdk.ValAddressFromBech32(m.BlsSig.SignerAddress) if err != nil { panic(err) } - return []sdk.AccAddress{signer} + return []sdk.AccAddress{sdk.AccAddress(signer)} } func (m *MsgWrappedCreateValidator) VerifyPoP(valPubkey cryptotypes.PubKey) bool { diff --git a/x/epoching/config/priv_validator_key.json b/x/epoching/config/priv_validator_key.json new file mode 100644 index 000000000..07e29368e --- /dev/null +++ b/x/epoching/config/priv_validator_key.json @@ -0,0 +1,13 @@ +{ + "address": "13CCD967C3227A2CB70457DC3C9C5EADB5CA0614", + "pub_key": { + "type": "tendermint/PubKeyEd25519", + "value": "26Q1C6iZDXAZvcXZa8ELswcxm6X9n/jzdD4LCmOdWZA=" + }, + "priv_key": { + "type": "tendermint/PrivKeyEd25519", + "value": "5DtfZOzGMkFIisrYjPib51h1up6jEdgmPXNCwuhnaUjbpDULqJkNcBm9xdlrwQuzBzGbpf2f+PN0PgsKY51ZkA==" + }, + "bls_pub_key": "kTPpchCWEwZT2dLPKbbBs4FcwU/Wqu8Hg+Z2mYWMACJ0Rs5CDjO+TXLnLc2JbsMnDYcrO62L/KpbnClVeg5cXMKt9ucymxXT/TuQX3cH3vyaEqzRYbKcek2QVKmfy5w9", + "bls_priv_key": "D5Plpi95Dv04EPuaA24tq23UG03TNXjwMVGeaXeBS1c=" +} \ No newline at end of file diff --git a/x/epoching/data/priv_validator_state.json b/x/epoching/data/priv_validator_state.json new file mode 100644 index 000000000..48f3b67e3 --- /dev/null +++ b/x/epoching/data/priv_validator_state.json @@ -0,0 +1,5 @@ +{ + "height": "0", + "round": 0, + "step": 0 +} \ No newline at end of file diff --git a/x/epoching/keeper/config/priv_validator_key.json b/x/epoching/keeper/config/priv_validator_key.json new file mode 100644 index 000000000..c9bf9bcea --- /dev/null +++ b/x/epoching/keeper/config/priv_validator_key.json @@ -0,0 +1,13 @@ +{ + "address": "0F2CD45CB094A9F988159441AFB80036AD5E75E5", + "pub_key": { + "type": "tendermint/PubKeyEd25519", + "value": "MGhWB3Uo/SdELV+42B7cy2NyEcuP3Y3iiNEAaetOBNY=" + }, + "priv_key": { + "type": "tendermint/PrivKeyEd25519", + "value": "XDlRV3UgwAgyf0M/R2h5LB4fD4ekndffh5qZs2K/PCEwaFYHdSj9J0QtX7jYHtzLY3IRy4/djeKI0QBp604E1g==" + }, + "bls_pub_key": "lsSNMwbn121LSHpFHYWrsUJtQMY9jCqIxmXqUL8UG2b1LrORGJ1EiF6od8mKyGRxBbotUE5WYd7pVi50lA2HboKhMmg7rnt+LIc0tSG04KLD97Enu4v7rEpUsUWlFcbj", + "bls_priv_key": "Ry/jyvDM1Fg/ZnMi+95P8xGrBzpUT9rwgnKqSQZ0Dj4=" +} \ No newline at end of file diff --git a/x/epoching/keeper/data/priv_validator_state.json b/x/epoching/keeper/data/priv_validator_state.json new file mode 100644 index 000000000..48f3b67e3 --- /dev/null +++ b/x/epoching/keeper/data/priv_validator_state.json @@ -0,0 +1,5 @@ +{ + "height": "0", + "round": 0, + "step": 0 +} \ No newline at end of file diff --git a/x/epoching/types/config/priv_validator_key.json b/x/epoching/types/config/priv_validator_key.json new file mode 100644 index 000000000..a3ac413f1 --- /dev/null +++ b/x/epoching/types/config/priv_validator_key.json @@ -0,0 +1,13 @@ +{ + "address": "2E0CFDD650C760EEEFE19E2DDA2C38F27CF43C26", + "pub_key": { + "type": "tendermint/PubKeyEd25519", + "value": "boSPmCTyGX0JLdW5zEuISn+4lnoxQ9Rpffn5GfyDohs=" + }, + "priv_key": { + "type": "tendermint/PrivKeyEd25519", + "value": "wGLQgpOI/hjnhtnvoKA0LBJwWd6+PLnjsWk4tDfZOt5uhI+YJPIZfQkt1bnMS4hKf7iWejFD1Gl9+fkZ/IOiGw==" + }, + "bls_pub_key": "iLRhsY4qQsitR/0aHrJvkIpPEn54UoKAw4whdb4KCjNjOZyfsA/xz2RQoD/p5MB6GPICOadJDpBQYNsDgXOjVzgliDW7g9OD+EVHF1/7R52Lp6QGT6YRfCUQfRLMtGxK", + "bls_priv_key": "RrY6tTwdLgKHw4N5bXbjWXmxdgcS7t75x0aXiAodloQ=" +} \ No newline at end of file diff --git a/x/epoching/types/data/priv_validator_state.json b/x/epoching/types/data/priv_validator_state.json new file mode 100644 index 000000000..48f3b67e3 --- /dev/null +++ b/x/epoching/types/data/priv_validator_state.json @@ -0,0 +1,5 @@ +{ + "height": "0", + "round": 0, + "step": 0 +} \ No newline at end of file From 146e95737c28cac061e61a80d673c94cd839de9d Mon Sep 17 00:00:00 2001 From: Fangyu Gai Date: Mon, 29 Aug 2022 21:28:58 +0800 Subject: [PATCH 4/7] rm unnecessary json --- app/config/priv_validator_key.json | 13 ------------- app/data/priv_validator_state.json | 5 ----- x/checkpointing/config/priv_validator_key.json | 13 ------------- x/checkpointing/data/priv_validator_state.json | 5 ----- x/epoching/config/priv_validator_key.json | 13 ------------- x/epoching/data/priv_validator_state.json | 5 ----- x/epoching/keeper/config/priv_validator_key.json | 13 ------------- x/epoching/keeper/data/priv_validator_state.json | 5 ----- x/epoching/types/config/priv_validator_key.json | 13 ------------- x/epoching/types/data/priv_validator_state.json | 5 ----- 10 files changed, 90 deletions(-) delete mode 100644 app/config/priv_validator_key.json delete mode 100644 app/data/priv_validator_state.json delete mode 100644 x/checkpointing/config/priv_validator_key.json delete mode 100644 x/checkpointing/data/priv_validator_state.json delete mode 100644 x/epoching/config/priv_validator_key.json delete mode 100644 x/epoching/data/priv_validator_state.json delete mode 100644 x/epoching/keeper/config/priv_validator_key.json delete mode 100644 x/epoching/keeper/data/priv_validator_state.json delete mode 100644 x/epoching/types/config/priv_validator_key.json delete mode 100644 x/epoching/types/data/priv_validator_state.json diff --git a/app/config/priv_validator_key.json b/app/config/priv_validator_key.json deleted file mode 100644 index 6fb4eee5e..000000000 --- a/app/config/priv_validator_key.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "address": "99F5587BC8D39D825089EB3009C227EC07CD72B6", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "rOhCRZVhITnIQrilPE3rtp1AHHA++Qq495v2101fUjE=" - }, - "priv_key": { - "type": "tendermint/PrivKeyEd25519", - "value": "xu5Vque40RQ1dWKFIdrjxhbVbHP145Gy+VyLHJi/pt6s6EJFlWEhOchCuKU8Teu2nUAccD75Crj3m/bXTV9SMQ==" - }, - "bls_pub_key": "mXg966FaX5/Eiqhd4GitMwvTlOa5Miy+fk71ShJhmCkxiYhsFcxrR3KeehvlXW4DAVSzK6Hq1a3aa3O/d4RaB5ueuW8am0B3IatmWKJN0ZoQvkMGJYSjlHZj1ND/2Y3I", - "bls_priv_key": "QuSQXt6f+itZsH9RiDvIt2J58D/84Nm1v27w7hmdalo=" -} \ No newline at end of file diff --git a/app/data/priv_validator_state.json b/app/data/priv_validator_state.json deleted file mode 100644 index 48f3b67e3..000000000 --- a/app/data/priv_validator_state.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "height": "0", - "round": 0, - "step": 0 -} \ No newline at end of file diff --git a/x/checkpointing/config/priv_validator_key.json b/x/checkpointing/config/priv_validator_key.json deleted file mode 100644 index 0f3d74042..000000000 --- a/x/checkpointing/config/priv_validator_key.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "address": "280CFFB697F860BCE28B92046646667C35ED1F1F", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "9r0oObpoQXumTkLjHD6QvaYea6/STlLmagzYWrq2p5k=" - }, - "priv_key": { - "type": "tendermint/PrivKeyEd25519", - "value": "sho0sQXKQ7asi4pAvp6nIhTvmGuale5HQuZjDRRj8df2vSg5umhBe6ZOQuMcPpC9ph5rr9JOUuZqDNhauranmQ==" - }, - "bls_pub_key": "k03SjUF64skQE3QGx08qOZidXa5MVpKA4kbL5xsC8jB74POh+Elt+L2GVbFu50/WASPbFfpldKRMkxELksFbamkOovhFQ9pHIXebeq0i2EMeP4foPFeNmZFOEBT0kMlw", - "bls_priv_key": "V9O5z2ba9wbKzQm6ibif8eaOu0fy4DY7PT2suIF3ec0=" -} \ No newline at end of file diff --git a/x/checkpointing/data/priv_validator_state.json b/x/checkpointing/data/priv_validator_state.json deleted file mode 100644 index 48f3b67e3..000000000 --- a/x/checkpointing/data/priv_validator_state.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "height": "0", - "round": 0, - "step": 0 -} \ No newline at end of file diff --git a/x/epoching/config/priv_validator_key.json b/x/epoching/config/priv_validator_key.json deleted file mode 100644 index 07e29368e..000000000 --- a/x/epoching/config/priv_validator_key.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "address": "13CCD967C3227A2CB70457DC3C9C5EADB5CA0614", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "26Q1C6iZDXAZvcXZa8ELswcxm6X9n/jzdD4LCmOdWZA=" - }, - "priv_key": { - "type": "tendermint/PrivKeyEd25519", - "value": "5DtfZOzGMkFIisrYjPib51h1up6jEdgmPXNCwuhnaUjbpDULqJkNcBm9xdlrwQuzBzGbpf2f+PN0PgsKY51ZkA==" - }, - "bls_pub_key": "kTPpchCWEwZT2dLPKbbBs4FcwU/Wqu8Hg+Z2mYWMACJ0Rs5CDjO+TXLnLc2JbsMnDYcrO62L/KpbnClVeg5cXMKt9ucymxXT/TuQX3cH3vyaEqzRYbKcek2QVKmfy5w9", - "bls_priv_key": "D5Plpi95Dv04EPuaA24tq23UG03TNXjwMVGeaXeBS1c=" -} \ No newline at end of file diff --git a/x/epoching/data/priv_validator_state.json b/x/epoching/data/priv_validator_state.json deleted file mode 100644 index 48f3b67e3..000000000 --- a/x/epoching/data/priv_validator_state.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "height": "0", - "round": 0, - "step": 0 -} \ No newline at end of file diff --git a/x/epoching/keeper/config/priv_validator_key.json b/x/epoching/keeper/config/priv_validator_key.json deleted file mode 100644 index c9bf9bcea..000000000 --- a/x/epoching/keeper/config/priv_validator_key.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "address": "0F2CD45CB094A9F988159441AFB80036AD5E75E5", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "MGhWB3Uo/SdELV+42B7cy2NyEcuP3Y3iiNEAaetOBNY=" - }, - "priv_key": { - "type": "tendermint/PrivKeyEd25519", - "value": "XDlRV3UgwAgyf0M/R2h5LB4fD4ekndffh5qZs2K/PCEwaFYHdSj9J0QtX7jYHtzLY3IRy4/djeKI0QBp604E1g==" - }, - "bls_pub_key": "lsSNMwbn121LSHpFHYWrsUJtQMY9jCqIxmXqUL8UG2b1LrORGJ1EiF6od8mKyGRxBbotUE5WYd7pVi50lA2HboKhMmg7rnt+LIc0tSG04KLD97Enu4v7rEpUsUWlFcbj", - "bls_priv_key": "Ry/jyvDM1Fg/ZnMi+95P8xGrBzpUT9rwgnKqSQZ0Dj4=" -} \ No newline at end of file diff --git a/x/epoching/keeper/data/priv_validator_state.json b/x/epoching/keeper/data/priv_validator_state.json deleted file mode 100644 index 48f3b67e3..000000000 --- a/x/epoching/keeper/data/priv_validator_state.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "height": "0", - "round": 0, - "step": 0 -} \ No newline at end of file diff --git a/x/epoching/types/config/priv_validator_key.json b/x/epoching/types/config/priv_validator_key.json deleted file mode 100644 index a3ac413f1..000000000 --- a/x/epoching/types/config/priv_validator_key.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "address": "2E0CFDD650C760EEEFE19E2DDA2C38F27CF43C26", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "boSPmCTyGX0JLdW5zEuISn+4lnoxQ9Rpffn5GfyDohs=" - }, - "priv_key": { - "type": "tendermint/PrivKeyEd25519", - "value": "wGLQgpOI/hjnhtnvoKA0LBJwWd6+PLnjsWk4tDfZOt5uhI+YJPIZfQkt1bnMS4hKf7iWejFD1Gl9+fkZ/IOiGw==" - }, - "bls_pub_key": "iLRhsY4qQsitR/0aHrJvkIpPEn54UoKAw4whdb4KCjNjOZyfsA/xz2RQoD/p5MB6GPICOadJDpBQYNsDgXOjVzgliDW7g9OD+EVHF1/7R52Lp6QGT6YRfCUQfRLMtGxK", - "bls_priv_key": "RrY6tTwdLgKHw4N5bXbjWXmxdgcS7t75x0aXiAodloQ=" -} \ No newline at end of file diff --git a/x/epoching/types/data/priv_validator_state.json b/x/epoching/types/data/priv_validator_state.json deleted file mode 100644 index 48f3b67e3..000000000 --- a/x/epoching/types/data/priv_validator_state.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "height": "0", - "round": 0, - "step": 0 -} \ No newline at end of file From 3ba03c8bf1a75103dbc35dca8583a74a803d5410 Mon Sep 17 00:00:00 2001 From: Fangyu Gai Date: Wed, 31 Aug 2022 00:17:13 +0800 Subject: [PATCH 5/7] inject client context into newApp --- app/app.go | 24 ++----------- app/app_test.go | 11 +++--- app/test_helpers.go | 27 +++++++++++++- app/utils.go | 44 +++++++++++++++++++++++ cmd/babylond/cmd/root.go | 25 +++++++++---- privval/file.go | 9 ++++- simapp/sim_bench_test.go | 13 +++++-- simapp/sim_test.go | 23 +++++++----- x/checkpointing/abci.go | 3 +- x/checkpointing/keeper/bls_signer.go | 5 ++- x/checkpointing/keeper/bls_signer_test.go | 8 ++--- 11 files changed, 138 insertions(+), 54 deletions(-) create mode 100644 app/utils.go diff --git a/app/app.go b/app/app.go index fac83bd98..b9070c135 100644 --- a/app/app.go +++ b/app/app.go @@ -2,8 +2,6 @@ package app import ( "encoding/json" - "github.com/babylonchain/babylon/privval" - tmconfig "github.com/tendermint/tendermint/config" "io" "net/http" "os" @@ -216,7 +214,7 @@ func init() { // NewBabylonApp returns a reference to an initialized BabylonApp. func NewBabylonApp( logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest bool, skipUpgradeHeights map[int64]bool, - homePath string, invCheckPeriod uint, encodingConfig appparams.EncodingConfig, nodeCfg *tmconfig.Config, + homePath string, invCheckPeriod uint, encodingConfig appparams.EncodingConfig, privSigner *PrivSigner, appOpts servertypes.AppOptions, baseAppOptions ...func(*baseapp.BaseApp), ) *BabylonApp { @@ -339,31 +337,15 @@ func NewBabylonApp( keys[btclightclienttypes.MemStoreKey], app.GetSubspace(btclightclienttypes.ModuleName)) - pvKeyFile := nodeCfg.PrivValidatorKeyFile() - if err := tmos.EnsureDir(filepath.Dir(pvKeyFile), 0777); err != nil { - panic(err) - } - pvStateFile := nodeCfg.PrivValidatorStateFile() - if err := tmos.EnsureDir(filepath.Dir(pvStateFile), 0777); err != nil { - panic(err) - } - // TODO: currently, the client.Context is a placeholder, it should be injected from somewhere app.CheckpointingKeeper = checkpointingkeeper.NewKeeper( appCodec, keys[checkpointingtypes.StoreKey], keys[checkpointingtypes.MemStoreKey], - privval.LoadOrGenWrappedFilePV(pvKeyFile, pvStateFile), + privSigner.WrappedPV, app.EpochingKeeper, app.GetSubspace(checkpointingtypes.ModuleName), - client.Context{}. - WithCodec(encodingConfig.Marshaler). - WithInterfaceRegistry(encodingConfig.InterfaceRegistry). - WithTxConfig(encodingConfig.TxConfig). - WithLegacyAmino(encodingConfig.Amino). - WithInput(os.Stdin). - WithAccountRetriever(authtypes.AccountRetriever{}). - WithViper(""), // In app, we don't use any prefix for env variables. + privSigner.ClientCtx, ) // TODO for now use mocks, as soon as Checkpoining and lightClient will have correct interfaces diff --git a/app/app_test.go b/app/app_test.go index 9871da625..cc5cf4d38 100644 --- a/app/app_test.go +++ b/app/app_test.go @@ -2,7 +2,6 @@ package app import ( "encoding/json" - tmconfig "github.com/tendermint/tendermint/config" "os" "testing" @@ -16,7 +15,9 @@ import ( func TestBabylonBlockedAddrs(t *testing.T) { encCfg := MakeTestEncodingConfig() db := dbm.NewMemDB() - app := NewBabylonApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, map[int64]bool{}, DefaultNodeHome, 0, encCfg, tmconfig.DefaultConfig(), EmptyAppOptions{}) + privSigner, err := SetupPrivSigner() + require.NoError(t, err) + app := NewBabylonApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, map[int64]bool{}, DefaultNodeHome, 0, encCfg, privSigner, EmptyAppOptions{}) for acc := range maccPerms { require.True( @@ -40,7 +41,7 @@ func TestBabylonBlockedAddrs(t *testing.T) { app.Commit() // Making a new app object with the db, so that initchain hasn't been called - app2 := NewBabylonApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, map[int64]bool{}, DefaultNodeHome, 0, encCfg, tmconfig.DefaultConfig(), EmptyAppOptions{}) + app2 := NewBabylonApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, map[int64]bool{}, DefaultNodeHome, 0, encCfg, privSigner, EmptyAppOptions{}) _, err = app2.ExportAppStateAndValidators(false, []string{}) require.NoError(t, err, "ExportAppStateAndValidators should not have an error") } @@ -53,7 +54,9 @@ func TestGetMaccPerms(t *testing.T) { func TestUpgradeStateOnGenesis(t *testing.T) { encCfg := MakeTestEncodingConfig() db := dbm.NewMemDB() - app := NewBabylonApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, map[int64]bool{}, DefaultNodeHome, 0, encCfg, tmconfig.DefaultConfig(), EmptyAppOptions{}) + privSigner, err := SetupPrivSigner() + require.NoError(t, err) + app := NewBabylonApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, map[int64]bool{}, DefaultNodeHome, 0, encCfg, privSigner, EmptyAppOptions{}) genesisState := NewDefaultGenesisState(encCfg.Marshaler) stateBytes, err := json.MarshalIndent(genesisState, "", " ") require.NoError(t, err) diff --git a/app/test_helpers.go b/app/test_helpers.go index 9b273a043..89ae9fe55 100644 --- a/app/test_helpers.go +++ b/app/test_helpers.go @@ -5,7 +5,10 @@ import ( "encoding/hex" "encoding/json" "fmt" + "github.com/cosmos/cosmos-sdk/crypto/keyring" tmconfig "github.com/tendermint/tendermint/config" + tmos "github.com/tendermint/tendermint/libs/os" + "path/filepath" "strconv" "testing" "time" @@ -56,7 +59,11 @@ var DefaultConsensusParams = &abci.ConsensusParams{ func setup(withGenesis bool, invCheckPeriod uint) (*BabylonApp, GenesisState) { db := dbm.NewMemDB() encCdc := MakeTestEncodingConfig() - app := NewBabylonApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, DefaultNodeHome, invCheckPeriod, encCdc, tmconfig.DefaultConfig(), sdksimapp.EmptyAppOptions{}) + privSigner, err := SetupPrivSigner() + if err != nil { + panic(err) + } + app := NewBabylonApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, DefaultNodeHome, invCheckPeriod, encCdc, privSigner, sdksimapp.EmptyAppOptions{}) if withGenesis { return app, NewDefaultGenesisState(encCdc.Marshaler) } @@ -86,6 +93,24 @@ func Setup(isCheckTx bool) *BabylonApp { return app } +// SetupPrivSigner sets up a PrivSigner for testing +func SetupPrivSigner() (*PrivSigner, error) { + nodeCfg := tmconfig.DefaultConfig() + pvKeyFile := nodeCfg.PrivValidatorKeyFile() + err := tmos.EnsureDir(filepath.Dir(pvKeyFile), 0777) + if err != nil { + return nil, err + } + pvStateFile := nodeCfg.PrivValidatorStateFile() + err = tmos.EnsureDir(filepath.Dir(pvStateFile), 0777) + if err != nil { + return nil, err + } + privSigner, _ := InitClientContext(client.Context{}, keyring.BackendMemory) + privSigner.WrappedPV.Clean(nodeCfg.PrivValidatorKeyFile(), nodeCfg.PrivValidatorStateFile()) + return privSigner, nil +} + // SetupWithGenesisValSet initializes a new BabylonApp with a validator set and genesis accounts // that also act as delegators. For simplicity, each validator is bonded with a delegation // of one consensus engine unit (10^6) in the default token of the babylon app from first genesis diff --git a/app/utils.go b/app/utils.go new file mode 100644 index 000000000..c7a9f20b8 --- /dev/null +++ b/app/utils.go @@ -0,0 +1,44 @@ +package app + +import ( + "github.com/babylonchain/babylon/privval" + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/crypto/keyring" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth/types" + tmconfig "github.com/tendermint/tendermint/config" + "os" +) + +type PrivSigner struct { + WrappedPV *privval.WrappedFilePV + ClientCtx client.Context +} + +func InitClientContext(clientCtx client.Context, backend string) (*PrivSigner, error) { + nodeCfg := tmconfig.DefaultConfig() + wrappedPV := privval.LoadOrGenWrappedFilePV(nodeCfg.PrivValidatorKeyFile(), nodeCfg.PrivValidatorStateFile()) + encodingCfg := MakeTestEncodingConfig() + clientCtx = client.Context{}. + WithHomeDir(DefaultNodeHome). + WithInterfaceRegistry(encodingCfg.InterfaceRegistry). + WithCodec(encodingCfg.Marshaler). + WithLegacyAmino(encodingCfg.Amino). + WithTxConfig(encodingCfg.TxConfig). + WithAccountRetriever(types.AccountRetriever{}). + WithInput(os.Stdin). + WithBroadcastMode(flags.BroadcastAsync). + WithFromAddress(sdk.AccAddress(wrappedPV.GetAddress())) + + kb, err := keyring.New(sdk.KeyringServiceName(), backend, DefaultNodeHome, clientCtx.Input) + if err != nil { + return nil, err + } + clientCtx.WithKeyring(kb) + + return &PrivSigner{ + WrappedPV: wrappedPV, + ClientCtx: clientCtx, + }, nil +} diff --git a/cmd/babylond/cmd/root.go b/cmd/babylond/cmd/root.go index 13109ed56..0a110f14d 100644 --- a/cmd/babylond/cmd/root.go +++ b/cmd/babylond/cmd/root.go @@ -2,7 +2,6 @@ package cmd import ( "errors" - tmconfig "github.com/tendermint/tendermint/config" "io" "os" "path/filepath" @@ -233,14 +232,22 @@ func (a appCreator) newApp(logger log.Logger, db dbm.DB, traceStore io.Writer, a panic(err) } - nodeCfg := tmconfig.DefaultConfig() + // TODO: add a new flag to check whether the node is validator + backend := appOpts.Get(flags.FlagKeyringBackend).(string) + clientCtx := client.Context{}. + WithChainID(appOpts.Get(flags.FlagChainID).(string)). + WithFromName(appOpts.Get(flags.FlagFrom).(string)) + privSigner, err := app.InitClientContext(clientCtx, backend) + if err != nil { + panic(err) + } return app.NewBabylonApp( logger, db, traceStore, true, skipUpgradeHeights, cast.ToString(appOpts.Get(flags.FlagHome)), cast.ToUint(appOpts.Get(server.FlagInvCheckPeriod)), a.encCfg, - nodeCfg, + privSigner, appOpts, baseapp.SetPruning(pruningOpts), baseapp.SetMinGasPrices(cast.ToString(appOpts.Get(server.FlagMinGasPrices))), @@ -268,16 +275,20 @@ func (a appCreator) appExport( return servertypes.ExportedApp{}, errors.New("application home not set") } - nodeCfg := tmconfig.DefaultConfig() - if height != -1 { - babylonApp = app.NewBabylonApp(logger, db, traceStore, false, map[int64]bool{}, homePath, uint(1), a.encCfg, nodeCfg, appOpts) + babylonApp = app.NewBabylonApp(logger, db, traceStore, false, map[int64]bool{}, homePath, uint(1), a.encCfg, &app.PrivSigner{ + WrappedPV: nil, + ClientCtx: client.Context{}, + }, appOpts) if err := babylonApp.LoadHeight(height); err != nil { return servertypes.ExportedApp{}, err } } else { - babylonApp = app.NewBabylonApp(logger, db, traceStore, true, map[int64]bool{}, homePath, uint(1), a.encCfg, nodeCfg, appOpts) + babylonApp = app.NewBabylonApp(logger, db, traceStore, true, map[int64]bool{}, homePath, uint(1), a.encCfg, &app.PrivSigner{ + WrappedPV: nil, + ClientCtx: client.Context{}, + }, appOpts) } return babylonApp.ExportAppStateAndValidators(forZeroHeight, jailAllowedAddrs) diff --git a/privval/file.go b/privval/file.go index 57fc958f9..680223e15 100644 --- a/privval/file.go +++ b/privval/file.go @@ -14,6 +14,8 @@ import ( tmproto "github.com/tendermint/tendermint/proto/tendermint/types" "github.com/tendermint/tendermint/types" "io/ioutil" + "os" + "path/filepath" ) // copied from github.com/tendermint/tendermint/privval/file.go" @@ -160,7 +162,6 @@ func LoadOrGenWrappedFilePV(keyFilePath, stateFilePath string) *WrappedFilePV { return pv } -// TODO: implement SignBLS // GetAddress returns the address of the validator. // Implements PrivValidator. func (pv *WrappedFilePV) GetAddress() sdk.ValAddress { @@ -215,6 +216,12 @@ func (pv *WrappedFilePV) Reset() { pv.Save() } +// Clean removes PVKey file and PVState file +func (pv *WrappedFilePV) Clean(keyFilePath, stateFilePath string) { + _ = os.RemoveAll(filepath.Dir(keyFilePath)) + _ = os.RemoveAll(filepath.Dir(stateFilePath)) +} + // String returns a string representation of the FilePV. func (pv *WrappedFilePV) String() string { return fmt.Sprintf( diff --git a/simapp/sim_bench_test.go b/simapp/sim_bench_test.go index 64137bf5c..7eb28b0d3 100644 --- a/simapp/sim_bench_test.go +++ b/simapp/sim_bench_test.go @@ -2,7 +2,6 @@ package simapp import ( "fmt" - tmconfig "github.com/tendermint/tendermint/config" "os" "testing" @@ -36,7 +35,11 @@ func BenchmarkFullAppSimulation(b *testing.B) { } }() - babylon := app.NewBabylonApp(logger, db, nil, true, map[int64]bool{}, app.DefaultNodeHome, FlagPeriodValue, app.MakeTestEncodingConfig(), tmconfig.DefaultConfig(), sdksimapp.EmptyAppOptions{}, interBlockCacheOpt()) + privSigner, err := app.SetupPrivSigner() + if err != nil { + b.Fatal(err) + } + babylon := app.NewBabylonApp(logger, db, nil, true, map[int64]bool{}, app.DefaultNodeHome, FlagPeriodValue, app.MakeTestEncodingConfig(), privSigner, sdksimapp.EmptyAppOptions{}, interBlockCacheOpt()) // run randomized simulation _, simParams, simErr := simulation.SimulateFromSeed( @@ -86,7 +89,11 @@ func BenchmarkInvariants(b *testing.B) { } }() - babylon := app.NewBabylonApp(logger, db, nil, true, map[int64]bool{}, app.DefaultNodeHome, FlagPeriodValue, app.MakeTestEncodingConfig(), tmconfig.DefaultConfig(), sdksimapp.EmptyAppOptions{}, interBlockCacheOpt()) + privSigner, err := app.SetupPrivSigner() + if err != nil { + b.Fatal(err) + } + babylon := app.NewBabylonApp(logger, db, nil, true, map[int64]bool{}, app.DefaultNodeHome, FlagPeriodValue, app.MakeTestEncodingConfig(), privSigner, sdksimapp.EmptyAppOptions{}, interBlockCacheOpt()) // run randomized simulation _, simParams, simErr := simulation.SimulateFromSeed( diff --git a/simapp/sim_test.go b/simapp/sim_test.go index e6ec3fca4..798899a6d 100644 --- a/simapp/sim_test.go +++ b/simapp/sim_test.go @@ -3,7 +3,6 @@ package simapp import ( "encoding/json" "fmt" - tmconfig "github.com/tendermint/tendermint/config" "math/rand" "os" "testing" @@ -75,7 +74,9 @@ func TestFullAppSimulation(t *testing.T) { require.NoError(t, os.RemoveAll(dir)) }() - babylon := app.NewBabylonApp(logger, db, nil, true, map[int64]bool{}, app.DefaultNodeHome, FlagPeriodValue, app.MakeTestEncodingConfig(), tmconfig.DefaultConfig(), sdksimapp.EmptyAppOptions{}, fauxMerkleModeOpt) + privSigner, err := app.SetupPrivSigner() + require.NoError(t, err) + babylon := app.NewBabylonApp(logger, db, nil, true, map[int64]bool{}, app.DefaultNodeHome, FlagPeriodValue, app.MakeTestEncodingConfig(), privSigner, sdksimapp.EmptyAppOptions{}, fauxMerkleModeOpt) require.Equal(t, "BabylonApp", babylon.Name()) // run randomized simulation @@ -113,7 +114,9 @@ func TestAppImportExport(t *testing.T) { require.NoError(t, os.RemoveAll(dir)) }() - babylon := app.NewBabylonApp(logger, db, nil, true, map[int64]bool{}, app.DefaultNodeHome, FlagPeriodValue, app.MakeTestEncodingConfig(), tmconfig.DefaultConfig(), sdksimapp.EmptyAppOptions{}, fauxMerkleModeOpt) + privSigner, err := app.SetupPrivSigner() + require.NoError(t, err) + babylon := app.NewBabylonApp(logger, db, nil, true, map[int64]bool{}, app.DefaultNodeHome, FlagPeriodValue, app.MakeTestEncodingConfig(), privSigner, sdksimapp.EmptyAppOptions{}, fauxMerkleModeOpt) require.Equal(t, "BabylonApp", babylon.Name()) // Run randomized simulation @@ -153,7 +156,7 @@ func TestAppImportExport(t *testing.T) { require.NoError(t, os.RemoveAll(newDir)) }() - newBabylon := app.NewBabylonApp(log.NewNopLogger(), newDB, nil, true, map[int64]bool{}, app.DefaultNodeHome, FlagPeriodValue, app.MakeTestEncodingConfig(), tmconfig.DefaultConfig(), sdksimapp.EmptyAppOptions{}, fauxMerkleModeOpt) + newBabylon := app.NewBabylonApp(log.NewNopLogger(), newDB, nil, true, map[int64]bool{}, app.DefaultNodeHome, FlagPeriodValue, app.MakeTestEncodingConfig(), privSigner, sdksimapp.EmptyAppOptions{}, fauxMerkleModeOpt) require.Equal(t, "BabylonApp", newBabylon.Name()) var genesisState app.GenesisState @@ -215,7 +218,9 @@ func TestAppSimulationAfterImport(t *testing.T) { require.NoError(t, os.RemoveAll(dir)) }() - babylon := app.NewBabylonApp(logger, db, nil, true, map[int64]bool{}, app.DefaultNodeHome, FlagPeriodValue, app.MakeTestEncodingConfig(), tmconfig.DefaultConfig(), sdksimapp.EmptyAppOptions{}, fauxMerkleModeOpt) + privSigner, err := app.SetupPrivSigner() + require.NoError(t, err) + babylon := app.NewBabylonApp(logger, db, nil, true, map[int64]bool{}, app.DefaultNodeHome, FlagPeriodValue, app.MakeTestEncodingConfig(), privSigner, sdksimapp.EmptyAppOptions{}, fauxMerkleModeOpt) require.Equal(t, "BabylonApp", babylon.Name()) // Run randomized simulation @@ -260,7 +265,7 @@ func TestAppSimulationAfterImport(t *testing.T) { require.NoError(t, os.RemoveAll(newDir)) }() - newBabylon := app.NewBabylonApp(log.NewNopLogger(), newDB, nil, true, map[int64]bool{}, app.DefaultNodeHome, FlagPeriodValue, app.MakeTestEncodingConfig(), tmconfig.DefaultConfig(), sdksimapp.EmptyAppOptions{}, fauxMerkleModeOpt) + newBabylon := app.NewBabylonApp(log.NewNopLogger(), newDB, nil, true, map[int64]bool{}, app.DefaultNodeHome, FlagPeriodValue, app.MakeTestEncodingConfig(), privSigner, sdksimapp.EmptyAppOptions{}, fauxMerkleModeOpt) require.Equal(t, "BabylonApp", newBabylon.Name()) newBabylon.InitChain(abci.RequestInitChain{ @@ -311,14 +316,16 @@ func TestAppStateDeterminism(t *testing.T) { } db := dbm.NewMemDB() - babylon := app.NewBabylonApp(logger, db, nil, true, map[int64]bool{}, app.DefaultNodeHome, FlagPeriodValue, app.MakeTestEncodingConfig(), tmconfig.DefaultConfig(), sdksimapp.EmptyAppOptions{}, interBlockCacheOpt()) + privSigner, err := app.SetupPrivSigner() + require.NoError(t, err) + babylon := app.NewBabylonApp(logger, db, nil, true, map[int64]bool{}, app.DefaultNodeHome, FlagPeriodValue, app.MakeTestEncodingConfig(), privSigner, sdksimapp.EmptyAppOptions{}, interBlockCacheOpt()) fmt.Printf( "running non-determinism simulation; seed %d: %d/%d, attempt: %d/%d\n", config.Seed, i+1, numSeeds, j+1, numTimesToRunPerSeed, ) - _, _, err := simulation.SimulateFromSeed( + _, _, err = simulation.SimulateFromSeed( t, os.Stdout, babylon.BaseApp, diff --git a/x/checkpointing/abci.go b/x/checkpointing/abci.go index 6137a0588..57f84f4a6 100644 --- a/x/checkpointing/abci.go +++ b/x/checkpointing/abci.go @@ -2,7 +2,6 @@ package checkpointing import ( "fmt" - "github.com/cosmos/cosmos-sdk/client" "time" "github.com/babylonchain/babylon/x/checkpointing/types" @@ -44,7 +43,7 @@ func BeginBlocker(ctx sdk.Context, k keeper.Keeper, req abci.RequestBeginBlock) go func() { // TODO: inject client.Context - err = k.SendBlsSig(ctx, epoch.EpochNumber-1, lch, client.Context{}) + err = k.SendBlsSig(ctx, epoch.EpochNumber-1, lch) if err != nil { ctx.Logger().Error("failed to send BLS signature") } diff --git a/x/checkpointing/keeper/bls_signer.go b/x/checkpointing/keeper/bls_signer.go index 55d873798..d599b060c 100644 --- a/x/checkpointing/keeper/bls_signer.go +++ b/x/checkpointing/keeper/bls_signer.go @@ -3,7 +3,6 @@ package keeper import ( "github.com/babylonchain/babylon/crypto/bls12381" "github.com/babylonchain/babylon/x/checkpointing/types" - "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/tx" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/spf13/pflag" @@ -16,7 +15,7 @@ type BlsSigner interface { } // SendBlsSig prepares a BLS signature message and sends it to Tendermint -func (k Keeper) SendBlsSig(ctx sdk.Context, epochNum uint64, lch types.LastCommitHash, clientCtx client.Context) error { +func (k Keeper) SendBlsSig(ctx sdk.Context, epochNum uint64, lch types.LastCommitHash) error { // get self address curValSet := k.GetValidatorSet(ctx, epochNum) addr := k.blsSigner.GetAddress() @@ -40,7 +39,7 @@ func (k Keeper) SendBlsSig(ctx sdk.Context, epochNum uint64, lch types.LastCommi // insert the message into the transaction fs := pflag.NewFlagSet("", pflag.ContinueOnError) - err = tx.GenerateOrBroadcastTxCLI(clientCtx, fs, msg) + err = tx.GenerateOrBroadcastTxCLI(k.clientCtx, fs, msg) if err != nil { return err } diff --git a/x/checkpointing/keeper/bls_signer_test.go b/x/checkpointing/keeper/bls_signer_test.go index 1fe1b56ab..b3de8943d 100644 --- a/x/checkpointing/keeper/bls_signer_test.go +++ b/x/checkpointing/keeper/bls_signer_test.go @@ -41,10 +41,10 @@ func TestKeeper_SendBlsSig(t *testing.T) { cfg.TxConfig = encodingCfg.TxConfig cfg.NumValidators = 1 - network := network.New(t, cfg) - defer network.Cleanup() + testNetwork := network.New(t, cfg) + defer testNetwork.Cleanup() - val := network.Validators[0] + val := testNetwork.Validators[0] nodeDirName := fmt.Sprintf("node%d", 0) clientCtx := val.ClientCtx.WithHeight(2). WithFromAddress(val.Address). @@ -65,6 +65,6 @@ func TestKeeper_SendBlsSig(t *testing.T) { ek.EXPECT().GetValidatorSet(ctx, gomock.Eq(epochNum)).Return(valSet) signer.EXPECT().GetAddress().Return(addr1) signer.EXPECT().SignMsgWithBls(gomock.Eq(signBytes)).Return(bls12381.Sign(blsPrivKey1, signBytes), nil) - err := ckptkeeper.SendBlsSig(ctx, epochNum, lch, clientCtx) + err := ckptkeeper.SendBlsSig(ctx, epochNum, lch) require.NoError(t, err) } From d842b713099d934b7effbd8f8ad1007e1fd0f79d Mon Sep 17 00:00:00 2001 From: Fangyu Gai Date: Wed, 31 Aug 2022 10:29:48 +0800 Subject: [PATCH 6/7] add some TODOs --- app/test_helpers.go | 2 +- app/utils.go | 11 ++++++++++- cmd/babylond/cmd/root.go | 31 ++++++++++++++++++------------- 3 files changed, 29 insertions(+), 15 deletions(-) diff --git a/app/test_helpers.go b/app/test_helpers.go index 8cac0d07c..e9fd897bd 100644 --- a/app/test_helpers.go +++ b/app/test_helpers.go @@ -107,7 +107,7 @@ func SetupPrivSigner() (*PrivSigner, error) { return nil, err } privSigner, _ := InitClientContext(client.Context{}, keyring.BackendMemory) - privSigner.WrappedPV.Clean(nodeCfg.PrivValidatorKeyFile(), nodeCfg.PrivValidatorStateFile()) + privSigner.WrappedPV.Clean(pvKeyFile, pvStateFile) return privSigner, nil } diff --git a/app/utils.go b/app/utils.go index c7a9f20b8..019bd3c04 100644 --- a/app/utils.go +++ b/app/utils.go @@ -8,7 +8,9 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth/types" tmconfig "github.com/tendermint/tendermint/config" + tmos "github.com/tendermint/tendermint/libs/os" "os" + "path/filepath" ) type PrivSigner struct { @@ -18,7 +20,14 @@ type PrivSigner struct { func InitClientContext(clientCtx client.Context, backend string) (*PrivSigner, error) { nodeCfg := tmconfig.DefaultConfig() - wrappedPV := privval.LoadOrGenWrappedFilePV(nodeCfg.PrivValidatorKeyFile(), nodeCfg.PrivValidatorStateFile()) + pvKeyFile := nodeCfg.PrivValidatorKeyFile() + err := tmos.EnsureDir(filepath.Dir(pvKeyFile), 0777) + if err != nil { + return nil, err + } + pvStateFile := nodeCfg.PrivValidatorStateFile() + err = tmos.EnsureDir(filepath.Dir(pvStateFile), 0777) + wrappedPV := privval.LoadOrGenWrappedFilePV(pvKeyFile, pvStateFile) encodingCfg := MakeTestEncodingConfig() clientCtx = client.Context{}. WithHomeDir(DefaultNodeHome). diff --git a/cmd/babylond/cmd/root.go b/cmd/babylond/cmd/root.go index 6a823039c..82193ab91 100644 --- a/cmd/babylond/cmd/root.go +++ b/cmd/babylond/cmd/root.go @@ -2,6 +2,7 @@ package cmd import ( "errors" + "github.com/cosmos/cosmos-sdk/crypto/keyring" "io" "os" "path/filepath" @@ -225,11 +226,13 @@ func (a appCreator) newApp(logger log.Logger, db dbm.DB, traceStore io.Writer, a } // TODO: add a new flag to check whether the node is validator - backend := appOpts.Get(flags.FlagKeyringBackend).(string) - clientCtx := client.Context{}. - WithChainID(appOpts.Get(flags.FlagChainID).(string)). - WithFromName(appOpts.Get(flags.FlagFrom).(string)) - privSigner, err := app.InitClientContext(clientCtx, backend) + //backend := appOpts.Get(flags.FlagKeyringBackend).(string) + clientCtx := client.Context{} + // TODO: comment the options below because those flags are not passed in integration test + //WithChainID(appOpts.Get(flags.FlagChainID).(string)). + //WithFromName(appOpts.Get(flags.FlagFrom).(string)) + // TODO: use BackendTest of keyring for now because the current integration test does not pass FlagKeryingBackend + privSigner, err := app.InitClientContext(clientCtx, keyring.BackendTest) if err != nil { panic(err) } @@ -267,20 +270,22 @@ func (a appCreator) appExport( return servertypes.ExportedApp{}, errors.New("application home not set") } + backend := appOpts.Get(flags.FlagKeyringBackend).(string) + clientCtx := client.Context{}. + WithChainID(appOpts.Get(flags.FlagChainID).(string)). + WithFromName(appOpts.Get(flags.FlagFrom).(string)) + privSigner, err := app.InitClientContext(clientCtx, backend) + if err != nil { + panic(err) + } if height != -1 { - babylonApp = app.NewBabylonApp(logger, db, traceStore, false, map[int64]bool{}, homePath, uint(1), a.encCfg, &app.PrivSigner{ - WrappedPV: nil, - ClientCtx: client.Context{}, - }, appOpts) + babylonApp = app.NewBabylonApp(logger, db, traceStore, false, map[int64]bool{}, homePath, uint(1), a.encCfg, privSigner, appOpts) if err := babylonApp.LoadHeight(height); err != nil { return servertypes.ExportedApp{}, err } } else { - babylonApp = app.NewBabylonApp(logger, db, traceStore, true, map[int64]bool{}, homePath, uint(1), a.encCfg, &app.PrivSigner{ - WrappedPV: nil, - ClientCtx: client.Context{}, - }, appOpts) + babylonApp = app.NewBabylonApp(logger, db, traceStore, true, map[int64]bool{}, homePath, uint(1), a.encCfg, privSigner, appOpts) } return babylonApp.ExportAppStateAndValidators(forZeroHeight, jailAllowedAddrs) From 56936c1dd556cdf07b649a1dcd4dde04be217c9a Mon Sep 17 00:00:00 2001 From: Fangyu Gai Date: Thu, 1 Sep 2022 10:11:13 +0800 Subject: [PATCH 7/7] minor --- app/test_helpers.go | 14 +------------- app/utils.go | 6 ++++++ 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/app/test_helpers.go b/app/test_helpers.go index e9fd897bd..11446bab0 100644 --- a/app/test_helpers.go +++ b/app/test_helpers.go @@ -7,8 +7,6 @@ import ( "fmt" "github.com/cosmos/cosmos-sdk/crypto/keyring" tmconfig "github.com/tendermint/tendermint/config" - tmos "github.com/tendermint/tendermint/libs/os" - "path/filepath" "strconv" "testing" "time" @@ -96,18 +94,8 @@ func Setup(isCheckTx bool) *BabylonApp { // SetupPrivSigner sets up a PrivSigner for testing func SetupPrivSigner() (*PrivSigner, error) { nodeCfg := tmconfig.DefaultConfig() - pvKeyFile := nodeCfg.PrivValidatorKeyFile() - err := tmos.EnsureDir(filepath.Dir(pvKeyFile), 0777) - if err != nil { - return nil, err - } - pvStateFile := nodeCfg.PrivValidatorStateFile() - err = tmos.EnsureDir(filepath.Dir(pvStateFile), 0777) - if err != nil { - return nil, err - } privSigner, _ := InitClientContext(client.Context{}, keyring.BackendMemory) - privSigner.WrappedPV.Clean(pvKeyFile, pvStateFile) + privSigner.WrappedPV.Clean(nodeCfg.PrivValidatorKeyFile(), nodeCfg.PrivValidatorStateFile()) return privSigner, nil } diff --git a/app/utils.go b/app/utils.go index 019bd3c04..5f60da75b 100644 --- a/app/utils.go +++ b/app/utils.go @@ -19,6 +19,7 @@ type PrivSigner struct { } func InitClientContext(clientCtx client.Context, backend string) (*PrivSigner, error) { + // setup private validator nodeCfg := tmconfig.DefaultConfig() pvKeyFile := nodeCfg.PrivValidatorKeyFile() err := tmos.EnsureDir(filepath.Dir(pvKeyFile), 0777) @@ -27,7 +28,12 @@ func InitClientContext(clientCtx client.Context, backend string) (*PrivSigner, e } pvStateFile := nodeCfg.PrivValidatorStateFile() err = tmos.EnsureDir(filepath.Dir(pvStateFile), 0777) + if err != nil { + return nil, err + } wrappedPV := privval.LoadOrGenWrappedFilePV(pvKeyFile, pvStateFile) + + // setup client context encodingCfg := MakeTestEncodingConfig() clientCtx = client.Context{}. WithHomeDir(DefaultNodeHome).