diff --git a/go/shared/cosmossdk/cursor.go b/go/shared/cosmossdk/cursor.go index d9826fc16..3699973f4 100644 --- a/go/shared/cosmossdk/cursor.go +++ b/go/shared/cosmossdk/cursor.go @@ -40,5 +40,14 @@ func (c *Cursor) Decode(b64 string) error { return errors.Wrapf(err, "failed to unmarshal cursor: %s", bytes) } + // json.Unmarshal into the existing State map keeps caller-supplied keys and stores a JSON + // null pointer value as a nil *CursorState. Drop those nil entries so a malformed cursor + // (e.g. {"state":{"x":null}}) can't leave a nil pointer to be dereferenced downstream. + for source, state := range c.State { + if state == nil { + delete(c.State, source) + } + } + return nil } diff --git a/go/shared/cosmossdk/history.go b/go/shared/cosmossdk/history.go index e6f926d04..6c10c2bd9 100644 --- a/go/shared/cosmossdk/history.go +++ b/go/shared/cosmossdk/history.go @@ -81,6 +81,9 @@ func (h *History) filterByCursor(txs []HistoryTx) ([]HistoryTx, error) { if tx.GetHeight() == h.Cursor.BlockHeight { found := false for _, s := range h.Cursor.State { + if s == nil { + continue + } if tx.GetTxID() == s.TxID { found = true break