Skip to content

Commit

Permalink
fix: Use fixed length hex for pointer at FwdCapabilityKey (backport #…
Browse files Browse the repository at this point in the history
…11737) (#12818)

* fix: Use fixed length hex for pointer at FwdCapabilityKey (backport #11737)

* Update CHANGELOG.md

* add comments and unit tests
  • Loading branch information
yihuang committed Aug 9, 2022
1 parent b09fc03 commit 09321d7
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -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

Expand Down
9 changes: 8 additions & 1 deletion x/capability/types/keys.go
Expand Up @@ -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.
Expand Down
26 changes: 25 additions & 1 deletion x/capability/types/keys_test.go
Expand Up @@ -2,6 +2,7 @@ package types_test

import (
"fmt"
"runtime"
"testing"

"github.com/stretchr/testify/require"
Expand All @@ -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))
}

Expand All @@ -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)
}
}

0 comments on commit 09321d7

Please sign in to comment.