From 09321d7ae50c94d341b5a9985023b414bf9db524 Mon Sep 17 00:00:00 2001 From: yihuang Date: Wed, 10 Aug 2022 05:12:43 +0800 Subject: [PATCH] fix: Use fixed length hex for pointer at FwdCapabilityKey (backport #11737) (#12818) * fix: Use fixed length hex for pointer at FwdCapabilityKey (backport #11737) * Update CHANGELOG.md * add comments and unit tests --- CHANGELOG.md | 1 + x/capability/types/keys.go | 9 ++++++++- x/capability/types/keys_test.go | 26 +++++++++++++++++++++++++- 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a8f95aca386..4e27656dc12 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,6 +58,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (x/mint) [#12384](https://github.com/cosmos/cosmos-sdk/pull/12384) Ensure `GoalBonded` must be positive when performing `x/mint` parameter validation. * (simapp) [#12437](https://github.com/cosmos/cosmos-sdk/pull/12437) fix the non-determinstic behavior in simulations caused by `GenTx` and check empty coins slice before it is used to create `banktype.MsgSend`. +* (x/capability) [12818](https://github.com/cosmos/cosmos-sdk/pull/12818) Use fixed length hex for pointer at FwdCapabilityKey. ## [v0.45.6](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.45.6) - 2022-06-28 diff --git a/x/capability/types/keys.go b/x/capability/types/keys.go index aefd13ba228..fadce73d397 100644 --- a/x/capability/types/keys.go +++ b/x/capability/types/keys.go @@ -39,7 +39,14 @@ func RevCapabilityKey(module, name string) []byte { // FwdCapabilityKey returns a forward lookup key for a given module and capability // reference. func FwdCapabilityKey(module string, cap *Capability) []byte { - return []byte(fmt.Sprintf("%s/fwd/%p", module, cap)) + // encode the key to a fixed length to avoid breaking consensus state machine + // it's a hacky backport of https://github.com/cosmos/cosmos-sdk/pull/11737 + // the length 10 is picked so it's backward compatible on common architectures. + key := fmt.Sprintf("%#010p", cap) + if len(key) > 10 { + key = key[len(key)-10:] + } + return []byte(fmt.Sprintf("%s/fwd/0x%s", module, key)) } // IndexToKey returns bytes to be used as a key for a given capability index. diff --git a/x/capability/types/keys_test.go b/x/capability/types/keys_test.go index e767c3d3422..8f1fca269a5 100644 --- a/x/capability/types/keys_test.go +++ b/x/capability/types/keys_test.go @@ -2,6 +2,7 @@ package types_test import ( "fmt" + "runtime" "testing" "github.com/stretchr/testify/require" @@ -16,7 +17,12 @@ func TestRevCapabilityKey(t *testing.T) { func TestFwdCapabilityKey(t *testing.T) { cap := types.NewCapability(23) - expected := []byte(fmt.Sprintf("bank/fwd/%p", cap)) + key := fmt.Sprintf("%#010p", cap) + if len(key) > 10 { + key = key[len(key)-10:] + } + require.Equal(t, 10, len(key)) + expected := []byte(fmt.Sprintf("bank/fwd/0x%s", key)) require.Equal(t, expected, types.FwdCapabilityKey("bank", cap)) } @@ -27,3 +33,21 @@ func TestIndexToKey(t *testing.T) { func TestIndexFromKey(t *testing.T) { require.Equal(t, uint64(3162), types.IndexFromKey([]byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x5a})) } + +// to test the backward compatibiltiy of the new function +func legacyFwdCapabilityKey(module string, cap *types.Capability) []byte { + return []byte(fmt.Sprintf("%s/fwd/%p", module, cap)) +} + +func TestFwdCapabilityKeyCompatibility(t *testing.T) { + cap := types.NewCapability(24) + new := types.FwdCapabilityKey("bank", cap) + old := legacyFwdCapabilityKey("bank", cap) + if runtime.GOOS == "darwin" && runtime.GOARCH == "arm" { + // the legacy version has 1 more byte on mac m1 + require.Equal(t, len(old), len(new)+1) + } else { + // otherwise, the new version is identical + require.Equal(t, new, old) + } +}