diff --git a/sei-cosmos/storev2/rootmulti/store.go b/sei-cosmos/storev2/rootmulti/store.go index baa0c14efc..1ead10c963 100644 --- a/sei-cosmos/storev2/rootmulti/store.go +++ b/sei-cosmos/storev2/rootmulti/store.go @@ -638,6 +638,19 @@ func (rs *Store) Query(req abci.RequestQuery) abci.ResponseQuery { res := store.Query(req) + // When serving from a historical read-only memiavl instance, the response + // byte slices (Key, Value) may point directly into mmap'd memory that will + // be unmapped when the deferred scStore.Close() runs. Copy them so the + // caller doesn't hit a use-after-free segfault during JSON marshaling. + if !latest { + if len(res.Key) > 0 { + res.Key = append([]byte{}, res.Key...) + } + if len(res.Value) > 0 { + res.Value = append([]byte{}, res.Value...) + } + } + // If underlying query failed (e.g. invalid height/path) or doesn' need proof, return as-is. if res.Code != 0 || !needProof { return res diff --git a/sei-tendermint/types/block.go b/sei-tendermint/types/block.go index 21acdea1de..a918ed7c43 100644 --- a/sei-tendermint/types/block.go +++ b/sei-tendermint/types/block.go @@ -89,7 +89,9 @@ func (b *Block) ValidateBasic() error { } if w, g := b.LastCommit.Hash(), b.LastCommitHash; !bytes.Equal(w, g) { - return fmt.Errorf("wrong Header.LastCommitHash. Expected %X, got %X", w, g) + if wLegacy := b.LastCommit.LegacyHash(); !bytes.Equal(wLegacy, g) { + return fmt.Errorf("wrong Header.LastCommitHash. Expected %X, got %X", w, g) + } } // NOTE: b.Data.Txs may be nil, but b.Data.Hash() still works fine. @@ -902,6 +904,25 @@ func (commit *Commit) Hash() tmbytes.HexBytes { return commit.hash } +// LegacyHash computes the commit hash using the pre-v6.4 algorithm, which +// only includes signatures (not Height, Round, or BlockID). This is needed +// to validate blocks that were created before the CommitHash change. +func (commit *Commit) LegacyHash() tmbytes.HexBytes { + if commit == nil { + return nil + } + bs := make([][]byte, len(commit.Signatures)) + for i, commitSig := range commit.Signatures { + pbcs := commitSig.ToProto() + bz, err := pbcs.Marshal() + if err != nil { + panic(err) + } + bs[i] = bz + } + return merkle.HashFromByteSlices(bs) +} + // StringIndented returns a string representation of the commit. func (commit *Commit) StringIndented(indent string) string { if commit == nil {