Skip to content

Commit

Permalink
Merge branch 'master' of github.com:desmos-labs/desmos
Browse files Browse the repository at this point in the history
� Conflicts:
�	app/upgrades/v441/upgrade.go
  • Loading branch information
RiccardoM committed Sep 8, 2022
2 parents be64afd + 8332e98 commit 39c879a
Show file tree
Hide file tree
Showing 8 changed files with 481 additions and 6 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/on-chain-upgrade.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
env:
GENESIS_DESMOS_VERSION: "v4.1.0"
GENESIS_URL: "https://raw.githubusercontent.com/RiccardoM/desmos-states/master/morpheus-apollo-2-6608740.json"
UPGRADE_NAME: "v4.3.0"
UPGRADE_NAME: "v4.4.1"
steps:
- name: Checkout 🛎️
uses: actions/checkout@v3
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
-->
## Version 4.4.1
### Features
- ([\#1002](https://github.com/desmos-labs/desmos/pull/1002)) Added missing on-chain upgrade handler

## Version 4.4.0
### Features
#### Posts
Expand Down
2 changes: 1 addition & 1 deletion app/upgrades/v441/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ var (
_ upgrades.Upgrade = &Upgrade{}
)

// Upgrade represents the v4.3.0 upgrade
// Upgrade represents the v4.4.1 upgrade
type Upgrade struct {
mm *module.Manager
configurator module.Configurator
Expand Down
33 changes: 30 additions & 3 deletions contrib/upgrade_testnet/setup_genesis.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,44 @@
import json
import os
import requests
import re
import sys

import requests

args = sys.argv[1:]

# Get the args
build_dir = args[0]
genesis_file = f"{build_dir}/node0/desmos/config/genesis.json"

chain_state_url = args[2]
genesis_url = args[2]
chain_state_file = f"{build_dir}/state.json"
output_file = f"{build_dir}/output_state.json"

# Get git LFS info
with requests.get(genesis_url) as r:
request_match = re.match(r"""version https://git-lfs.github.com/spec/v1
oid sha256:(?P<hash>.*?)
size (?P<size>.*?)
""", r.text)
genesis_file_hash = request_match.group('hash')
genesis_file_size = int(request_match.group('size'))

repo_match = re.match(r"https://raw.githubusercontent.com/(?P<organization>.*?)/(?P<name>.*?)/.*.json", genesis_url)
repo_organization, repo_name = repo_match.group('organization'), repo_match.group('name')
chain_state_lfs_url = f"https://github.com/{repo_organization}/{repo_name}.git/info/lfs/objects/batch"
chain_state_lfs_data = {
'operation': 'download',
'transfer': ['basic'],
'objects': [{'oid': genesis_file_hash, 'size': genesis_file_size}]
}
chain_state_lfs_headers = {'content-type': 'application/json', 'accept': 'application/vnd.git-lfs+json'}

# Get chain state url from LFS api
with requests.post(chain_state_lfs_url, headers=chain_state_lfs_headers, data=json.dumps(chain_state_lfs_data)) as r:
res = r.json()
chain_state_url = res['objects'][0]['actions']['download']['href']

# Get the chain state inside the build dir
with requests.get(chain_state_url) as r, open(chain_state_file, 'w') as f:
f.write(json.dumps(r.json()))
Expand Down Expand Up @@ -53,7 +79,8 @@
genesis['app_state']['ibc'] = chain_state['app_state']['ibc']
genesis['app_state']['profiles'] = chain_state['app_state']['profiles']

custom_modules = ['profiles', 'relationships', 'subspaces', 'posts', 'reports', 'reactions', 'fees', 'supply', 'wasm']
custom_modules = ['profiles', 'relationships', 'subspaces', 'posts', 'reports', 'reactions', 'fees', 'supply',
'wasm']
for module in custom_modules:
if module in chain_state['app_state']:
genesis['app_state'][module] = chain_state['app_state'][module]
Expand Down
6 changes: 6 additions & 0 deletions x/profiles/keeper/migrations.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
v5 "github.com/desmos-labs/desmos/v4/x/profiles/legacy/v5"
v6 "github.com/desmos-labs/desmos/v4/x/profiles/legacy/v6"
v7 "github.com/desmos-labs/desmos/v4/x/profiles/legacy/v7"
v8 "github.com/desmos-labs/desmos/v4/x/profiles/legacy/v8"
)

// DONTCOVER
Expand Down Expand Up @@ -45,3 +46,8 @@ func (m Migrator) Migrate6to7(ctx sdk.Context) error {
func (m Migrator) Migrate7to8(ctx sdk.Context) error {
return v7.MigrateStore(ctx, m.keeper.paramSubspace)
}

// Migrate8to9 migrates from version 8 to 9.
func (m Migrator) Migrate8to9(ctx sdk.Context) error {
return v8.MigrateStore(ctx, m.keeper.storeKey, m.keeper.cdc, m.keeper.legacyAmino)
}
136 changes: 136 additions & 0 deletions x/profiles/legacy/v8/store.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
package v6

import (
"bytes"
"encoding/hex"
"fmt"

codectypes "github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/store/prefix"
"github.com/cosmos/cosmos-sdk/x/auth/legacy/legacytx"

"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/tx"

"github.com/desmos-labs/desmos/v4/x/profiles/types"
)

// MigrateStore performs in-place store migrations from v8 to v9.
// The migration includes:
//
// - fixing the chain links so that their types are correct
func MigrateStore(ctx sdk.Context, storeKey sdk.StoreKey, cdc codec.BinaryCodec, amino *codec.LegacyAmino) error {
store := ctx.KVStore(storeKey)

// Migrate all the chain links
err := migrateChainLinks(store, cdc, amino)
if err != nil {
return err
}

return nil
}

// migrateChainLinks migrates the chain links from v8 to v9 by updating their signature value type accordingly.
// During the migration from v6 to v7 there was an error which ended up setting all chain link value types to
// SIGNATURE_VALUE_TYPE_COSMOS_DIRECT. This script fixes that by setting the proper value type based on the plain
// text encode that has been used when creating the signature.
func migrateChainLinks(store sdk.KVStore, cdc codec.BinaryCodec, amino *codec.LegacyAmino) error {
chainLinksStore := prefix.NewStore(store, types.ChainLinksPrefix)
iterator := chainLinksStore.Iterator(nil, nil)

var chainLinks []types.ChainLink
for ; iterator.Valid(); iterator.Next() {
var chainLink types.ChainLink
err := cdc.Unmarshal(iterator.Value(), &chainLink)
if err != nil {
return err
}
chainLinks = append(chainLinks, chainLink)
}

for _, chainLink := range chainLinks {
// Avoid implicit memory aliasing
chainLink := chainLink

var signature types.Signature
err := cdc.UnpackAny(chainLink.Proof.Signature, &signature)
if err != nil {
return err
}

value, err := hex.DecodeString(chainLink.Proof.PlainText)
if err != nil {
return err
}

// Fix the signature
fixedSig, err := fixSignatureValue(signature, value, cdc, amino)
if err != nil {
return err
}

// Update the signature Any
sigAny, err := codectypes.NewAnyWithValue(fixedSig)
if err != nil {
return err
}
chainLink.Proof.Signature = sigAny

// Set the link inside the store to update it
store.Set(
types.ChainLinksStoreKey(chainLink.User, chainLink.ChainConfig.Name, chainLink.GetAddressData().GetValue()),
cdc.MustMarshal(&chainLink),
)
}

return nil
}

func fixSignatureValue(signature types.Signature, plainText []byte, cdc codec.BinaryCodec, amino *codec.LegacyAmino) (types.Signature, error) {
if sig, ok := signature.(*types.SingleSignature); ok {
return types.NewSingleSignature(getSignatureTypeFromPlainText(plainText, cdc, amino), sig.Signature), nil
} else if sig, ok := signature.(*types.CosmosMultiSignature); ok {
// Convert the signatures
signatures := make([]types.Signature, len(sig.Signatures))
for i, sigAny := range sig.Signatures {
var sig types.Signature
err := cdc.UnpackAny(sigAny, &sig)
if err != nil {
return nil, err
}

fixedSig, err := fixSignatureValue(sig, plainText, cdc, amino)
if err != nil {
return nil, err
}
signatures[i] = fixedSig
}

// Return the multi sig with the fixed signatures
return types.NewCosmosMultiSignature(sig.BitArray, signatures), nil
}

return nil, fmt.Errorf("invalid signature type: %T", signature)
}

func getSignatureTypeFromPlainText(plainText []byte, cdc codec.BinaryCodec, amino *codec.LegacyAmino) types.SignatureValueType {
// Check Amino value
var legacySignDoc legacytx.StdSignDoc
err := amino.UnmarshalJSON(plainText, &legacySignDoc)
if err == nil {
return types.SIGNATURE_VALUE_TYPE_COSMOS_AMINO
}

// Check direct value
var directSignDoc tx.SignDoc
err = cdc.Unmarshal(plainText, &directSignDoc)

// Check to make sure the value was a SignDoc. If that's not the case, the two arrays will not match
if err == nil && bytes.Equal(plainText, cdc.MustMarshal(&directSignDoc)) {
return types.SIGNATURE_VALUE_TYPE_COSMOS_DIRECT
}

return types.SIGNATURE_VALUE_TYPE_RAW
}
Loading

0 comments on commit 39c879a

Please sign in to comment.