Skip to content

Commit

Permalink
feat: update btcd dep + add migration for upgrade + snyk ci
Browse files Browse the repository at this point in the history
  • Loading branch information
kioqq committed Dec 18, 2023
1 parent 5dcc575 commit 8cc4482
Show file tree
Hide file tree
Showing 17 changed files with 314 additions and 40 deletions.
20 changes: 20 additions & 0 deletions .github/workflows/snyk.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: Snyk check

on: push

jobs:
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- name: Run Snyk to check for vulnerabilities
uses: snyk/actions/golang@master
continue-on-error: true # To make sure that SARIF upload gets called
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
with:
args: --sarif-file-output=snyk.sarif
- name: Upload result to GitHub Code Scanning
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: snyk.sarif
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,5 @@ swagger-proto
tmp-swagger-gen
.devenv
.secrets
.env
.env
.dccache
9 changes: 8 additions & 1 deletion app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -1143,7 +1143,14 @@ func (app *Haqq) setupUpgradeHandlers() {
// v1.6.4 Coinomics v2
app.UpgradeKeeper.SetUpgradeHandler(
v164.UpgradeName,
v164.CreateUpgradeHandler(app.mm, app.configurator),
v164.CreateUpgradeHandler(
app.mm,
app.configurator,
app.GetKey(coinomicstypes.StoreKey),
app.GetKey(paramstypes.StoreKey),
app.DistrKeeper,
app.CoinomicsKeeper,
),
)

// When a planned update height is reached, the old binary will panic
Expand Down
48 changes: 46 additions & 2 deletions app/upgrades/v1.6.4/upgrades.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,64 @@
package v164

import (
"strings"

"cosmossdk.io/math"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"

distrkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper"
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
coinomicskeeper "github.com/haqq-network/haqq/x/coinomics/keeper"
coinomicstypes "github.com/haqq-network/haqq/x/coinomics/types"
)

// CreateUpgradeHandler creates an SDK upgrade handler for v1.6.4
func CreateUpgradeHandler(
mm *module.Manager,
configurator module.Configurator,
storeKey storetypes.StoreKey,
paramsStoreKey storetypes.StoreKey,
dk distrkeeper.Keeper,
ck coinomicskeeper.Keeper,
) upgradetypes.UpgradeHandler {
return func(ctx sdk.Context, _ upgradetypes.Plan, vm module.VersionMap) (module.VersionMap, error) {
logger := ctx.Logger()
logger.Info("run migration v1.6.4")
MigrateStore(ctx, storeKey, paramsStoreKey, dk, ck)

return mm.RunMigrations(ctx, configurator, vm)
}
}

// MigrateStore migrates the x/coinomics module state
func MigrateStore(ctx sdk.Context,
storeKey storetypes.StoreKey,
paramsStoreKey storetypes.StoreKey,
dk distrkeeper.Keeper,
ck coinomicskeeper.Keeper,
) {
// clean module state
store := ctx.KVStore(storeKey)
iterator := sdk.KVStorePrefixIterator(store, nil)

for ; iterator.Valid(); iterator.Next() {
store.Delete(iterator.Key())
}

// clean params
paramsStore := ctx.KVStore(paramsStoreKey)
paramsIterator := sdk.KVStorePrefixIterator(paramsStore, nil)

for ; paramsIterator.Valid(); paramsIterator.Next() {
if strings.Contains(string(paramsIterator.Key()), "coinomics/") {
paramsStore.Delete(paramsIterator.Key())
}
}

// reset coinomics params
defaultParams := coinomicstypes.DefaultParams()
maxSupply := sdk.Coin{Denom: "aISLM", Amount: math.NewIntWithDecimal(100_000_000_000, 18)} // 100bn ISLM

ck.SetMaxSupply(ctx, maxSupply)
ck.SetParams(ctx, defaultParams)
}
10 changes: 6 additions & 4 deletions crypto/hd/algorithm.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
package hd

import (
"github.com/btcsuite/btcd/btcutil/hdkeychain"
"github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btcutil/hdkeychain"
bip39 "github.com/tyler-smith/go-bip39"

"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/crypto"

"github.com/cosmos/cosmos-sdk/crypto/hd"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/crypto"
bip39 "github.com/tyler-smith/go-bip39"

"github.com/haqq-network/haqq/crypto/ethsecp256k1"
)
Expand Down
20 changes: 10 additions & 10 deletions crypto/hd/algorithm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ import (

"github.com/stretchr/testify/require"

"github.com/ethereum/go-ethereum/common"

amino "github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
"github.com/ethereum/go-ethereum/common"
hdwallet "github.com/miguelmota/go-ethereum-hdwallet"

cryptocodec "github.com/haqq-network/haqq/crypto/codec"
enccodec "github.com/haqq-network/haqq/encoding/codec"
Expand Down Expand Up @@ -73,11 +73,11 @@ func TestKeyring(t *testing.T) {
addr := common.BytesToAddress(privkey.PubKey().Address().Bytes())

os.Setenv(hdWalletFixEnv, "true")
wallet, err := hdwallet.NewFromMnemonic(mnemonic)
wallet, err := NewFromMnemonic(mnemonic)
os.Setenv(hdWalletFixEnv, "")
require.NoError(t, err)

path := hdwallet.MustParseDerivationPath(hdPath)
path := MustParseDerivationPath(hdPath)

account, err := wallet.Derive(path, false)
require.NoError(t, err)
Expand All @@ -100,14 +100,14 @@ func TestDerivation(t *testing.T) {

require.False(t, privkey.Equals(badPrivKey))

wallet, err := hdwallet.NewFromMnemonic(mnemonic)
wallet, err := NewFromMnemonic(mnemonic)
require.NoError(t, err)

path := hdwallet.MustParseDerivationPath(haqqtypes.BIP44HDPath)
path := MustParseDerivationPath(haqqtypes.BIP44HDPath)
account, err := wallet.Derive(path, false)
require.NoError(t, err)

badPath := hdwallet.MustParseDerivationPath("44'/60'/0'/0/0")
badPath := MustParseDerivationPath("44'/60'/0'/0/0")
badAccount, err := wallet.Derive(badPath, false)
require.NoError(t, err)

Expand All @@ -116,15 +116,15 @@ func TestDerivation(t *testing.T) {
require.Equal(t, badAccount.Address.String(), "0xF8D6FDf2B8b488ea37e54903750dcd13F67E71cb")
// Inequality of wrong derivation path address
require.NotEqual(t, account.Address.String(), badAccount.Address.String())
// Equality of Haqq Network implementation
// Equality of Haqq implementation
require.Equal(t, common.BytesToAddress(privkey.PubKey().Address().Bytes()).String(), "0xA588C66983a81e800Db4dF74564F09f91c026351")
require.Equal(t, common.BytesToAddress(badPrivKey.PubKey().Address().Bytes()).String(), "0xF8D6FDf2B8b488ea37e54903750dcd13F67E71cb")

// Equality of Eth and Haqq Network implementation
// Equality of Eth and Haqq implementation
require.Equal(t, common.BytesToAddress(privkey.PubKey().Address()).String(), account.Address.String())
require.Equal(t, common.BytesToAddress(badPrivKey.PubKey().Address()).String(), badAccount.Address.String())

// Inequality of wrong derivation path of Eth and Haqq Network implementation
// Inequality of wrong derivation path of Eth and Haqq implementation
require.NotEqual(t, common.BytesToAddress(privkey.PubKey().Address()).String(), badAccount.Address.String())
require.NotEqual(t, common.BytesToAddress(badPrivKey.PubKey().Address()).String(), account.Address.Hex())
}
1 change: 0 additions & 1 deletion crypto/hd/benchmark_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"testing"

"github.com/cosmos/cosmos-sdk/crypto/keyring"

"github.com/haqq-network/haqq/types"
)

Expand Down
181 changes: 181 additions & 0 deletions crypto/hd/utils_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
// NOTE: This code is being used as test helper functions.
package hd

import (
"crypto/ecdsa"
"errors"
"os"
"sync"

"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"

"github.com/btcsuite/btcd/btcutil/hdkeychain"
"github.com/btcsuite/btcd/chaincfg"
bip39 "github.com/tyler-smith/go-bip39"
)

const issue179FixEnvar = "GO_ETHEREUM_HDWALLET_FIX_ISSUE_179"

// Wallet is the underlying wallet struct.
type Wallet struct {
mnemonic string
masterKey *hdkeychain.ExtendedKey
seed []byte
paths map[common.Address]accounts.DerivationPath
accounts []accounts.Account
stateLock sync.RWMutex
fixIssue172 bool
}

// NewFromMnemonic returns a new wallet from a BIP-39 mnemonic.
func NewFromMnemonic(mnemonic string) (*Wallet, error) {
if mnemonic == "" {
return nil, errors.New("mnemonic is required")
}

if !bip39.IsMnemonicValid(mnemonic) {
return nil, errors.New("mnemonic is invalid")
}

seed, err := NewSeedFromMnemonic(mnemonic)
if err != nil {
return nil, err
}

wallet, err := newWallet(seed)
if err != nil {
return nil, err
}
wallet.mnemonic = mnemonic

return wallet, nil
}

// NewSeedFromMnemonic returns a BIP-39 seed based on a BIP-39 mnemonic.
func NewSeedFromMnemonic(mnemonic string) ([]byte, error) {
if mnemonic == "" {
return nil, errors.New("mnemonic is required")
}

return bip39.NewSeedWithErrorChecking(mnemonic, "")
}

func newWallet(seed []byte) (*Wallet, error) {
masterKey, err := hdkeychain.NewMaster(seed, &chaincfg.MainNetParams)
if err != nil {
return nil, err
}

return &Wallet{
masterKey: masterKey,
seed: seed,
accounts: []accounts.Account{},
paths: map[common.Address]accounts.DerivationPath{},
fixIssue172: false || len(os.Getenv(issue179FixEnvar)) > 0,
}, nil
}

// Derive implements accounts.Wallet, deriving a new account at the specific
// derivation path. If pin is set to true, the account will be added to the list
// of tracked accounts.
func (w *Wallet) Derive(path accounts.DerivationPath, pin bool) (accounts.Account, error) {
// Try to derive the actual account and update its URL if successful
w.stateLock.RLock() // Avoid device disappearing during derivation

address, err := w.deriveAddress(path)

w.stateLock.RUnlock()

// If an error occurred or no pinning was requested, return
if err != nil {
return accounts.Account{}, err
}

account := accounts.Account{
Address: address,
URL: accounts.URL{
Scheme: "",
Path: path.String(),
},
}

if !pin {
return account, nil
}

// Pinning needs to modify the state
w.stateLock.Lock()
defer w.stateLock.Unlock()

if _, ok := w.paths[address]; !ok {
w.accounts = append(w.accounts, account)
w.paths[address] = path
}

return account, nil
}

// MustParseDerivationPath parses the derivation path in string format into
// []uint32 but will panic if it can't parse it.
func MustParseDerivationPath(path string) accounts.DerivationPath {
parsed, err := accounts.ParseDerivationPath(path)
if err != nil {
panic(err)
}

return parsed
}

// DerivePrivateKey derives the private key of the derivation path.
func (w *Wallet) derivePrivateKey(path accounts.DerivationPath) (*ecdsa.PrivateKey, error) {
var err error
key := w.masterKey
for _, n := range path {
if w.fixIssue172 && key.IsAffectedByIssue172() {
key, err = key.Derive(n)
} else {
//lint:ignore SA1019 this is used for testing only
key, err = key.DeriveNonStandard(n) //nolint:staticcheck
}
if err != nil {
return nil, err
}
}

privateKey, err := key.ECPrivKey()
privateKeyECDSA := privateKey.ToECDSA()
if err != nil {
return nil, err
}

return privateKeyECDSA, nil
}

// derivePublicKey derives the public key of the derivation path.
func (w *Wallet) derivePublicKey(path accounts.DerivationPath) (*ecdsa.PublicKey, error) {
privateKeyECDSA, err := w.derivePrivateKey(path)
if err != nil {
return nil, err
}

publicKey := privateKeyECDSA.Public()
publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
if !ok {
return nil, errors.New("failed to get public key")
}

return publicKeyECDSA, nil
}

// DeriveAddress derives the account address of the derivation path.
func (w *Wallet) deriveAddress(path accounts.DerivationPath) (common.Address, error) {
publicKeyECDSA, err := w.derivePublicKey(path)
if err != nil {
return common.Address{}, err
}

address := crypto.PubkeyToAddress(*publicKeyECDSA)
return address, nil
}
Loading

0 comments on commit 8cc4482

Please sign in to comment.