Skip to content

Commit

Permalink
Merge branch 'release/v0.46.x-celestia' into rp/delete-subspace
Browse files Browse the repository at this point in the history
  • Loading branch information
rootulp authored Apr 28, 2024
2 parents fd91fbf + 02244ae commit 3b01101
Show file tree
Hide file tree
Showing 10 changed files with 202 additions and 22 deletions.
2 changes: 1 addition & 1 deletion .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
# most precedence.

# Primary repo maintainers
* @liamsi @evan-forbes
* @celestiaorg/celestia-core
40 changes: 37 additions & 3 deletions baseapp/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/gogo/protobuf/proto"
abci "github.com/tendermint/tendermint/abci/types"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
tmversion "github.com/tendermint/tendermint/proto/tendermint/version"
"google.golang.org/grpc/codes"
grpcstatus "google.golang.org/grpc/status"

Expand All @@ -38,12 +39,15 @@ func (app *BaseApp) InitChain(req abci.RequestInitChain) (res abci.ResponseInitC
// On a new chain, we consider the init chain block height as 0, even though
// req.InitialHeight is 1 by default.
initHeader := tmproto.Header{ChainID: req.ChainId, Time: req.Time}
if req.ConsensusParams != nil && req.ConsensusParams.Version != nil {
initHeader.Version = tmversion.Consensus{App: req.ConsensusParams.Version.AppVersion}
}

// If req.InitialHeight is > 1, then we set the initial version in the
// stores.
if req.InitialHeight > 1 {
app.initialHeight = req.InitialHeight
initHeader = tmproto.Header{ChainID: req.ChainId, Height: req.InitialHeight, Time: req.Time}
initHeader.Height = req.InitialHeight
err := app.cms.SetInitialVersion(req.InitialHeight)
if err != nil {
panic(err)
Expand Down Expand Up @@ -131,8 +135,8 @@ func (app *BaseApp) Info(req abci.RequestInfo) abci.ResponseInfo {
if err != nil {
panic(err)
}
// get and set the app version
_ = app.AppVersion(ctx)
// initialise the app version by checking if it is already in state
app.InitAppVersion(ctx)
}
return abci.ResponseInfo{
Data: app.name,
Expand Down Expand Up @@ -339,6 +343,36 @@ func (app *BaseApp) Commit() abci.ResponseCommit {
// The write to the DeliverTx state writes all state transitions to the root
// MultiStore (app.cms) so when Commit() is called is persists those values.
app.deliverState.ms.Write()

// Check if there has been an app version change. If so and there is a migrator
// set, begin to run migrations. This needs to be done before the commit so
// that the migrations are part of the app hash
if header.Version.App < app.appVersion &&
app.migrator.storeMigrator != nil &&
app.migrator.moduleMigrator != nil {

// first update the stores themselves by adding and removing them as necessary
storeMigrations, err := app.migrator.storeMigrator(header.Version.App, app.appVersion)
if err != nil {
panic(fmt.Sprintf("failed to get store migrations: %v", err))
}
app.MountKVStores(storeMigrations.Added)
err = app.cms.LoadLatestVersionAndUpgrade(storeMigrations.ToStoreUpgrades())
if err != nil {
panic(fmt.Sprintf("failed to upgrade stores: %v", err))
}

// create a new cached branch of the store to apply migrations to
app.setDeliverState(header)
err = app.migrator.moduleMigrator(app.deliverState.ctx, header.Version.App, app.appVersion)
if err != nil {
panic(fmt.Sprintf("failed to migrate modules: %v", err))
}

// write the new state to the branch
app.deliverState.ms.Write()
}

commitID := app.cms.Commit()

res := abci.ResponseCommit{
Expand Down
42 changes: 37 additions & 5 deletions baseapp/baseapp.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,21 @@ type (
// an older version of the software. In particular, if a module changed the substore key name
// (or removed a substore) between two versions of the software.
StoreLoader func(ms sdk.CommitMultiStore) error

// MigrateModuleFn gets called when there is a change in the app version. It is
// triggered in the Commit stage after all state transitions have occurred.
MigrateModuleFn func(ctx sdk.Context, fromVersion, toVersion uint64) error

// MigrateStoreFn gets called when there is a change in the app version. It is
// triggered in the Commit stage after all state transitions have occurred.
MigrateStoreFn func(fromVersion, toVersion uint64) (StoreMigrations, error)

// StoreMigrations is a type that contains the added and removed stores for a
// migration.
StoreMigrations struct {
Added map[string]*storetypes.KVStoreKey
Deleted map[string]*storetypes.KVStoreKey
}
)

// BaseApp reflects the ABCI application implementation.
Expand All @@ -57,6 +72,7 @@ type BaseApp struct { // nolint: maligned
snapshotData
abciData
moduleRouter
migrator

// volatile states:
//
Expand Down Expand Up @@ -135,6 +151,11 @@ type appStore struct {
fauxMerkleMode bool // if true, IAVL MountStores uses MountStoresDB for simulation speed.
}

type migrator struct {
moduleMigrator MigrateModuleFn
storeMigrator MigrateStoreFn
}

type moduleRouter struct {
router sdk.Router // handle any kind of message
queryRouter sdk.QueryRouter // router for redirecting query calls
Expand Down Expand Up @@ -202,15 +223,17 @@ func (app *BaseApp) Name() string {
return app.name
}

// AppVersion returns the application's protocol version.
func (app *BaseApp) AppVersion(ctx sdk.Context) uint64 {
func (app *BaseApp) InitAppVersion(ctx sdk.Context) {
if app.appVersion == 0 && app.paramStore.Has(ctx, ParamStoreKeyVersionParams) {
var vp tmproto.VersionParams

app.paramStore.Get(ctx, ParamStoreKeyVersionParams, &vp)
// set the app version
app.appVersion = vp.AppVersion
}
}

// AppVersion returns the application's protocol version.
func (app *BaseApp) AppVersion() uint64 {
return app.appVersion
}

Expand Down Expand Up @@ -491,6 +514,8 @@ func (app *BaseApp) GetConsensusParams(ctx sdk.Context) *abci.ConsensusParams {

app.paramStore.Get(ctx, ParamStoreKeyVersionParams, &vp)
cp.Version = &vp
} else if app.appVersion != 0 {
cp.Version = &tmproto.VersionParams{AppVersion: app.appVersion}
}

return cp
Expand All @@ -516,12 +541,19 @@ func (app *BaseApp) StoreConsensusParams(ctx sdk.Context, cp *abci.ConsensusPara
app.paramStore.Set(ctx, ParamStoreKeyBlockParams, cp.Block)
app.paramStore.Set(ctx, ParamStoreKeyEvidenceParams, cp.Evidence)
app.paramStore.Set(ctx, ParamStoreKeyValidatorParams, cp.Validator)
// NOTE: we only persist the app version from v2 onwards
if cp.Version != nil && cp.Version.AppVersion >= 2 {
if app.paramStore.Has(ctx, ParamStoreKeyVersionParams) {
app.paramStore.Set(ctx, ParamStoreKeyVersionParams, cp.Version)
}
}

// SetInitialAppVersionInConsensusParams sets the initial app version
// in the consensus params if it has not yet been set.
func (app *BaseApp) SetInitialAppVersionInConsensusParams(ctx sdk.Context, version uint64) {
if !app.paramStore.Has(ctx, ParamStoreKeyVersionParams) {
app.paramStore.Set(ctx, ParamStoreKeyVersionParams, &tmproto.VersionParams{AppVersion: version})
}
}

// getMaximumBlockGas gets the maximum gas from the consensus params. It panics
// if maximum block gas is less than negative one and returns zero if negative
// one.
Expand Down
43 changes: 40 additions & 3 deletions baseapp/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package baseapp
import (
"fmt"
"io"
"sort"

tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
dbm "github.com/tendermint/tm-db"
Expand All @@ -12,6 +13,7 @@ import (
"github.com/cosmos/cosmos-sdk/snapshots"
snapshottypes "github.com/cosmos/cosmos-sdk/snapshots/types"
"github.com/cosmos/cosmos-sdk/store"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
sdk "github.com/cosmos/cosmos-sdk/types"
)

Expand Down Expand Up @@ -113,9 +115,7 @@ func (app *BaseApp) SetVersion(v string) {

// SetAppVersion sets the application's protocol version
func (app *BaseApp) SetAppVersion(ctx sdk.Context, version uint64) {
// TODO: could make this less hacky in the future since the SDK
// shouldn't have to know about the app versioning scheme
if version >= 2 {
if app.paramStore.Has(ctx, ParamStoreKeyVersionParams) {
vp := &tmproto.VersionParams{AppVersion: version}
app.paramStore.Set(ctx, ParamStoreKeyVersionParams, vp)
}
Expand Down Expand Up @@ -162,6 +162,20 @@ func (app *BaseApp) SetEndBlocker(endBlocker sdk.EndBlocker) {
app.endBlocker = endBlocker
}

func (app *BaseApp) SetMigrateModuleFn(migrator MigrateModuleFn) {
if app.sealed {
panic("cannot set migrate module fn: baseapp is sealed")
}
app.migrator.moduleMigrator = migrator
}

func (app *BaseApp) SetMigrateStoreFn(migrator MigrateStoreFn) {
if app.sealed {
panic("cannot set migrate store fn: baseapp is sealed")
}
app.migrator.storeMigrator = migrator
}

func (app *BaseApp) SetAnteHandler(ah sdk.AnteHandler) {
if app.sealed {
panic("SetAnteHandler() on sealed BaseApp")
Expand Down Expand Up @@ -265,3 +279,26 @@ func (app *BaseApp) SetQueryMultiStore(ms sdk.MultiStore) {
}
app.qms = ms
}

// ToStoreUpgrades converts the StoreMigrations to StoreUpgrades.
func (sm StoreMigrations) ToStoreUpgrades() *storetypes.StoreUpgrades {
added := make([]string, len(sm.Added))
deleted := make([]string, len(sm.Deleted))
i := 0
for name := range sm.Added {
added[i] = name
i++
}
i = 0
for name := range sm.Deleted {
deleted[i] = name
i++
}
// sort them to ensure deterministic order
sort.Strings(added)
sort.Strings(deleted)
return &storetypes.StoreUpgrades{
Added: added,
Deleted: deleted,
}
}
6 changes: 3 additions & 3 deletions client/v2/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ require (
github.com/google/go-cmp v0.5.6 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 // indirect
golang.org/x/sys v0.0.0-20210510120138-977fb7262007 // indirect
golang.org/x/text v0.3.5 // indirect
golang.org/x/net v0.23.0 // indirect
golang.org/x/sys v0.18.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
google.golang.org/genproto v0.0.0-20211223182754-3ac035c7e7cb // indirect
)
9 changes: 6 additions & 3 deletions client/v2/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,9 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
Expand All @@ -117,13 +118,15 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
Expand Down
10 changes: 9 additions & 1 deletion crypto/keyring/keyring.go
Original file line number Diff line number Diff line change
Expand Up @@ -585,13 +585,21 @@ func SignWithLedger(k *Record, msg []byte) (sig []byte, pub types.PubKey, err er
if err != nil {
return
}
ledgerPubKey := priv.PubKey()
pubKey, err := k.GetPubKey()
if err != nil {
return nil, nil, err
}
if !pubKey.Equals(ledgerPubKey) {
return nil, nil, fmt.Errorf("the public key that the user attempted to sign with does not match the public key on the ledger device. %v does not match %v", pubKey.String(), ledgerPubKey.String())
}

sig, err = priv.Sign(msg)
if err != nil {
return nil, nil, err
}

return sig, priv.PubKey(), nil
return sig, ledgerPubKey, nil
}

func newOSBackendKeyringConfig(appName, dir string, buf io.Reader) keyring.Config {
Expand Down
66 changes: 66 additions & 0 deletions crypto/keyring/keyring_ledger_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,13 @@ import (
"strings"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/cosmos/cosmos-sdk/crypto/hd"
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
"github.com/cosmos/cosmos-sdk/crypto/ledger"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
"github.com/cosmos/cosmos-sdk/types"
)

Expand Down Expand Up @@ -133,3 +137,65 @@ func TestAltKeyring_SaveLedgerKey(t *testing.T) {
path := ledgerInfo.GetPath()
require.Equal(t, "m/44'/118'/3'/0/1", path.String())
}

func TestSignWithLedger(t *testing.T) {
// Create two distinct Ledger records: recordA and recordB.
// RecordA is added to the Ledger but recordB is not added.
pathA := hd.NewFundraiserParams(0, types.CoinType, 0)
privA, _, err := ledger.NewPrivKeySecp256k1(*pathA, "cosmos")
require.NoError(t, err)
recordA, err := NewLedgerRecord("ledgerA", privA.PubKey(), pathA)
require.NoError(t, err)
pubA, err := recordA.GetPubKey()
require.NoError(t, err)

pathB := hd.NewFundraiserParams(0, types.CoinType, 1)
// privB won't be added to the Ledger because it doesn't use ledger.NewPrivKeySecp256k1
privB := secp256k1.GenPrivKey()
recordB, err := NewLedgerRecord("ledgerB", privB.PubKey(), pathB)
require.NoError(t, err)
pubB, err := recordB.GetPubKey()
require.NoError(t, err)

require.NotEqual(t, pubA, pubB)
type testCase struct {
name string
record *Record
msg []byte
wantSig []byte
wantPub cryptotypes.PubKey
wantErr bool
wantErrContains string
}
testCases := []testCase{
{
name: "ordinary ledger tx",
record: recordA,
msg: []byte("msg"),
wantSig: []byte{0xfb, 0x93, 0x1b, 0xb9, 0x75, 0x25, 0xe7, 0x99, 0x64, 0xc2, 0x78, 0xf7, 0x94, 0x9a, 0x63, 0x83, 0xe2, 0x59, 0x76, 0x48, 0x1d, 0x2, 0xbc, 0xc2, 0x83, 0x21, 0x24, 0x4b, 0x95, 0x99, 0x25, 0x8b, 0x30, 0x38, 0x6, 0x61, 0x79, 0x9a, 0x9e, 0x8, 0x98, 0xfd, 0x34, 0xc6, 0x7e, 0x47, 0x4d, 0x5f, 0xe, 0xf3, 0xc3, 0xe7, 0xdd, 0xe3, 0x89, 0x80, 0xda, 0x8b, 0x48, 0x15, 0x34, 0xce, 0xdf, 0x1c},
wantPub: pubA,
wantErr: false,
},
{
name: "want error when the public key the user attempted to sign with doesn't match the public key on the ledger",
record: recordB,
msg: []byte("msg"),
wantSig: []byte(nil),
wantPub: nil,
wantErr: true,
wantErrContains: "the public key that the user attempted to sign with does not match the public key on the ledger device",
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
sig, pub, err := SignWithLedger(tc.record, tc.msg)
assert.Equal(t, tc.wantSig, sig)
assert.Equal(t, tc.wantPub, pub)
if tc.wantErr {
assert.Error(t, err)
assert.Contains(t, err.Error(), tc.wantErrContains)
}
})
}
}
Loading

0 comments on commit 3b01101

Please sign in to comment.