From b7c97ea176c6b1f6258f59f41901728fa22b204e Mon Sep 17 00:00:00 2001 From: ptrus Date: Fri, 31 Jan 2020 10:40:42 +0100 Subject: [PATCH] go/tendermint/keymanager: error Status() if keymanager doesn't exist --- .changelog/2628.bugfix.md | 4 ++++ .../tendermint/apps/keymanager/keymanager.go | 17 +++++++++-------- .../tendermint/apps/keymanager/state/state.go | 2 +- go/keymanager/api/api.go | 4 ++-- 4 files changed, 16 insertions(+), 11 deletions(-) create mode 100644 .changelog/2628.bugfix.md diff --git a/.changelog/2628.bugfix.md b/.changelog/2628.bugfix.md new file mode 100644 index 00000000000..f244e41c777 --- /dev/null +++ b/.changelog/2628.bugfix.md @@ -0,0 +1,4 @@ +go/tendermint/keymanager: error in Status() if keymanager doesn't exist + +This fixes panics in the key-manager client if keymanager for the specific +runtime doesn't exist. diff --git a/go/consensus/tendermint/apps/keymanager/keymanager.go b/go/consensus/tendermint/apps/keymanager/keymanager.go index 3610ca0e085..6dd143778f8 100644 --- a/go/consensus/tendermint/apps/keymanager/keymanager.go +++ b/go/consensus/tendermint/apps/keymanager/keymanager.go @@ -96,7 +96,15 @@ func (app *keymanagerApplication) onEpochChange(ctx *abci.Context, epoch epochti var forceEmit bool oldStatus, err := state.Status(rt.ID) - if err != nil { + switch err { + case nil: + case api.ErrNoSuchStatus: + // This must be a new key manager runtime. + forceEmit = true + oldStatus = &api.Status{ + ID: rt.ID, + } + default: // This is fatal, as it suggests state corruption. ctx.Logger().Error("failed to query key manager status", "id", rt.ID, @@ -104,13 +112,6 @@ func (app *keymanagerApplication) onEpochChange(ctx *abci.Context, epoch epochti ) return errors.Wrap(err, "failed to query key manager status") } - if oldStatus == nil { - // This must be a new key manager runtime. - forceEmit = true - oldStatus = &api.Status{ - ID: rt.ID, - } - } newStatus := app.generateStatus(ctx, rt, oldStatus, nodes) if forceEmit || !bytes.Equal(cbor.Marshal(oldStatus), cbor.Marshal(newStatus)) { diff --git a/go/consensus/tendermint/apps/keymanager/state/state.go b/go/consensus/tendermint/apps/keymanager/state/state.go index 9a9e1c8f575..57c1d0097c9 100644 --- a/go/consensus/tendermint/apps/keymanager/state/state.go +++ b/go/consensus/tendermint/apps/keymanager/state/state.go @@ -60,7 +60,7 @@ func (st *ImmutableState) getStatusesRaw() ([][]byte, error) { func (st *ImmutableState) Status(id common.Namespace) (*api.Status, error) { _, raw := st.Snapshot.Get(statusKeyFmt.Encode(&id)) if raw == nil { - return nil, nil + return nil, api.ErrNoSuchStatus } var status api.Status diff --git a/go/keymanager/api/api.go b/go/keymanager/api/api.go index 5a8a5203b47..ca5080f56b2 100644 --- a/go/keymanager/api/api.go +++ b/go/keymanager/api/api.go @@ -29,9 +29,9 @@ const ( ) var ( - // ErrNoSuchKeyManager is the error returned when a key manager does not + // ErrNoSuchStatus is the error returned when a key manager status does not // exist. - ErrNoSuchKeyManager = errors.New(ModuleName, 1, "keymanager: no such key manager") + ErrNoSuchStatus = errors.New(ModuleName, 1, "keymanager: no such status") // TestPublicKey is the insecure hardcoded key manager public key, used // in insecure builds when a RAK is unavailable.