forked from cosmos/cosmos-sdk
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'develop' into greg/testnet-command-2
- Loading branch information
Showing
29 changed files
with
4,083 additions
and
63 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,243 @@ | ||
package main | ||
|
||
import ( | ||
"encoding/base64" | ||
"encoding/hex" | ||
"fmt" | ||
"os" | ||
"path" | ||
|
||
"github.com/spf13/cobra" | ||
abci "github.com/tendermint/abci/types" | ||
crypto "github.com/tendermint/go-crypto" | ||
cmn "github.com/tendermint/tmlibs/common" | ||
dbm "github.com/tendermint/tmlibs/db" | ||
"github.com/tendermint/tmlibs/log" | ||
|
||
bam "github.com/cosmos/cosmos-sdk/baseapp" | ||
sdk "github.com/cosmos/cosmos-sdk/types" | ||
|
||
"github.com/cosmos/cosmos-sdk/wire" | ||
"github.com/cosmos/cosmos-sdk/x/auth" | ||
"github.com/cosmos/cosmos-sdk/x/bank" | ||
"github.com/cosmos/cosmos-sdk/x/ibc" | ||
"github.com/cosmos/cosmos-sdk/x/slashing" | ||
"github.com/cosmos/cosmos-sdk/x/stake" | ||
|
||
gaia "github.com/cosmos/cosmos-sdk/cmd/gaia/app" | ||
) | ||
|
||
func runHackCmd(cmd *cobra.Command, args []string) error { | ||
|
||
if len(args) != 1 { | ||
return fmt.Errorf("Expected 1 arg") | ||
} | ||
|
||
// ".gaiad" | ||
dataDir := args[0] | ||
dataDir = path.Join(dataDir, "data") | ||
|
||
// load the app | ||
logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)) | ||
db, err := dbm.NewGoLevelDB("gaia", dataDir) | ||
if err != nil { | ||
fmt.Println(err) | ||
os.Exit(1) | ||
} | ||
app := NewGaiaApp(logger, db) | ||
|
||
// print some info | ||
id := app.LastCommitID() | ||
lastBlockHeight := app.LastBlockHeight() | ||
fmt.Println("ID", id) | ||
fmt.Println("LastBlockHeight", lastBlockHeight) | ||
|
||
//---------------------------------------------------- | ||
// XXX: start hacking! | ||
//---------------------------------------------------- | ||
// eg. gaia-6001 testnet bug | ||
// We paniced when iterating through the "bypower" keys. | ||
// The following powerKey was there, but the corresponding "trouble" validator did not exist. | ||
// So here we do a binary search on the past states to find when the powerKey first showed up ... | ||
|
||
// owner of the validator the bonds, gets revoked, later unbonds, and then later is still found in the bypower store | ||
trouble := hexToBytes("D3DC0FF59F7C3B548B7AFA365561B87FD0208AF8") | ||
// this is his "bypower" key | ||
powerKey := hexToBytes("05303030303030303030303033FFFFFFFFFFFF4C0C0000FFFED3DC0FF59F7C3B548B7AFA365561B87FD0208AF8") | ||
|
||
topHeight := lastBlockHeight | ||
bottomHeight := int64(0) | ||
checkHeight := topHeight | ||
for { | ||
// load the given version of the state | ||
err = app.LoadVersion(checkHeight, app.keyMain) | ||
if err != nil { | ||
fmt.Println(err) | ||
os.Exit(1) | ||
} | ||
ctx := app.NewContext(true, abci.Header{}) | ||
|
||
// check for the powerkey and the validator from the store | ||
store := ctx.KVStore(app.keyStake) | ||
res := store.Get(powerKey) | ||
val, _ := app.stakeKeeper.GetValidator(ctx, trouble) | ||
fmt.Println("checking height", checkHeight, res, val) | ||
if res == nil { | ||
bottomHeight = checkHeight | ||
} else { | ||
topHeight = checkHeight | ||
} | ||
checkHeight = (topHeight + bottomHeight) / 2 | ||
} | ||
} | ||
|
||
func base64ToPub(b64 string) crypto.PubKeyEd25519 { | ||
data, _ := base64.StdEncoding.DecodeString(b64) | ||
var pubKey crypto.PubKeyEd25519 | ||
copy(pubKey[:], data) | ||
return pubKey | ||
|
||
} | ||
|
||
func hexToBytes(h string) []byte { | ||
trouble, _ := hex.DecodeString(h) | ||
return trouble | ||
|
||
} | ||
|
||
//-------------------------------------------------------------------------------- | ||
// NOTE: This is all copied from gaia/app/app.go | ||
// so we can access internal fields! | ||
|
||
const ( | ||
appName = "GaiaApp" | ||
) | ||
|
||
// default home directories for expected binaries | ||
var ( | ||
DefaultCLIHome = os.ExpandEnv("$HOME/.gaiacli") | ||
DefaultNodeHome = os.ExpandEnv("$HOME/.gaiad") | ||
) | ||
|
||
// Extended ABCI application | ||
type GaiaApp struct { | ||
*bam.BaseApp | ||
cdc *wire.Codec | ||
|
||
// keys to access the substores | ||
keyMain *sdk.KVStoreKey | ||
keyAccount *sdk.KVStoreKey | ||
keyIBC *sdk.KVStoreKey | ||
keyStake *sdk.KVStoreKey | ||
keySlashing *sdk.KVStoreKey | ||
|
||
// Manage getting and setting accounts | ||
accountMapper auth.AccountMapper | ||
feeCollectionKeeper auth.FeeCollectionKeeper | ||
coinKeeper bank.Keeper | ||
ibcMapper ibc.Mapper | ||
stakeKeeper stake.Keeper | ||
slashingKeeper slashing.Keeper | ||
} | ||
|
||
func NewGaiaApp(logger log.Logger, db dbm.DB) *GaiaApp { | ||
cdc := MakeCodec() | ||
|
||
// create your application object | ||
var app = &GaiaApp{ | ||
BaseApp: bam.NewBaseApp(appName, cdc, logger, db), | ||
cdc: cdc, | ||
keyMain: sdk.NewKVStoreKey("main"), | ||
keyAccount: sdk.NewKVStoreKey("acc"), | ||
keyIBC: sdk.NewKVStoreKey("ibc"), | ||
keyStake: sdk.NewKVStoreKey("stake"), | ||
keySlashing: sdk.NewKVStoreKey("slashing"), | ||
} | ||
|
||
// define the accountMapper | ||
app.accountMapper = auth.NewAccountMapper( | ||
app.cdc, | ||
app.keyAccount, // target store | ||
&auth.BaseAccount{}, // prototype | ||
) | ||
|
||
// add handlers | ||
app.coinKeeper = bank.NewKeeper(app.accountMapper) | ||
app.ibcMapper = ibc.NewMapper(app.cdc, app.keyIBC, app.RegisterCodespace(ibc.DefaultCodespace)) | ||
app.stakeKeeper = stake.NewKeeper(app.cdc, app.keyStake, app.coinKeeper, app.RegisterCodespace(stake.DefaultCodespace)) | ||
app.slashingKeeper = slashing.NewKeeper(app.cdc, app.keySlashing, app.stakeKeeper, app.RegisterCodespace(slashing.DefaultCodespace)) | ||
|
||
// register message routes | ||
app.Router(). | ||
AddRoute("bank", bank.NewHandler(app.coinKeeper)). | ||
AddRoute("ibc", ibc.NewHandler(app.ibcMapper, app.coinKeeper)). | ||
AddRoute("stake", stake.NewHandler(app.stakeKeeper)) | ||
|
||
// initialize BaseApp | ||
app.SetInitChainer(app.initChainer) | ||
app.SetBeginBlocker(app.BeginBlocker) | ||
app.SetEndBlocker(app.EndBlocker) | ||
app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper, app.feeCollectionKeeper)) | ||
app.MountStoresIAVL(app.keyMain, app.keyAccount, app.keyIBC, app.keyStake, app.keySlashing) | ||
err := app.LoadLatestVersion(app.keyMain) | ||
if err != nil { | ||
cmn.Exit(err.Error()) | ||
} | ||
|
||
return app | ||
} | ||
|
||
// custom tx codec | ||
func MakeCodec() *wire.Codec { | ||
var cdc = wire.NewCodec() | ||
ibc.RegisterWire(cdc) | ||
bank.RegisterWire(cdc) | ||
stake.RegisterWire(cdc) | ||
slashing.RegisterWire(cdc) | ||
auth.RegisterWire(cdc) | ||
sdk.RegisterWire(cdc) | ||
wire.RegisterCrypto(cdc) | ||
return cdc | ||
} | ||
|
||
// application updates every end block | ||
func (app *GaiaApp) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock { | ||
tags := slashing.BeginBlocker(ctx, req, app.slashingKeeper) | ||
|
||
return abci.ResponseBeginBlock{ | ||
Tags: tags.ToKVPairs(), | ||
} | ||
} | ||
|
||
// application updates every end block | ||
func (app *GaiaApp) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock { | ||
validatorUpdates := stake.EndBlocker(ctx, app.stakeKeeper) | ||
|
||
return abci.ResponseEndBlock{ | ||
ValidatorUpdates: validatorUpdates, | ||
} | ||
} | ||
|
||
// custom logic for gaia initialization | ||
func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain { | ||
stateJSON := req.AppStateBytes | ||
// TODO is this now the whole genesis file? | ||
|
||
var genesisState gaia.GenesisState | ||
err := app.cdc.UnmarshalJSON(stateJSON, &genesisState) | ||
if err != nil { | ||
panic(err) // TODO https://github.com/cosmos/cosmos-sdk/issues/468 | ||
// return sdk.ErrGenesisParse("").TraceCause(err, "") | ||
} | ||
|
||
// load the accounts | ||
for _, gacc := range genesisState.Accounts { | ||
acc := gacc.ToAccount() | ||
app.accountMapper.SetAccount(ctx, acc) | ||
} | ||
|
||
// load the initial stake information | ||
stake.InitGenesis(ctx, app.stakeKeeper, genesisState.StakeData) | ||
return abci.ResponseInitChain{} | ||
|
||
} |
Oops, something went wrong.