Skip to content

Commit

Permalink
Merge pull request #1268 from HaoyangLiu/release0.12-distri
Browse files Browse the repository at this point in the history
R4R: implement coin flow record
  • Loading branch information
Haifeng Xi committed Feb 21, 2019
2 parents eb30126 + 2cd40ad commit 29266d8
Show file tree
Hide file tree
Showing 22 changed files with 195 additions and 36 deletions.
2 changes: 1 addition & 1 deletion app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ func NewIrisApp(logger log.Logger, db dbm.DB, config *cfg.InstrumentationConfig,
appPrometheusConfig := *config
//Change namespace to appName
appPrometheusConfig.Namespace = appPrometheusNamespace
engine.Add(v0.NewProtocolV0(0, logger, protocolKeeper, app.checkInvariant, &appPrometheusConfig))
engine.Add(v0.NewProtocolV0(0, logger, protocolKeeper, app.checkInvariant, app.trackCoinFlow, &appPrometheusConfig))
// engine.Add(v1.NewProtocolV1(1, ...))
// engine.Add(v2.NewProtocolV1(2, ...))

Expand Down
18 changes: 15 additions & 3 deletions app/baseapp.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package app

import (
"encoding/hex"
"fmt"
"io"
"runtime/debug"
Expand Down Expand Up @@ -73,6 +74,9 @@ type BaseApp struct {
// enable invariant check
checkInvariant bool

// enable track coin flow
trackCoinFlow bool

// flag for sealing
sealed bool
}
Expand Down Expand Up @@ -210,6 +214,9 @@ func (app *BaseApp) SetMinimumFees(fees sdk.Coins) { app.minimumFees = fees }
// SetInvariantCheck sets the invariant check config.
func (app *BaseApp) SetCheckInvariant(check bool) { app.checkInvariant = check }

// SetTrackCoinFlow sets the config about track coin flow
func (app *BaseApp) SetTrackCoinFlow(enable bool) { app.trackCoinFlow = enable }

// NewContext returns a new Context with the correct store, the given header, and nil txBytes.
func (app *BaseApp) NewContext(isCheckTx bool, header abci.Header) sdk.Context {
if isCheckTx {
Expand Down Expand Up @@ -312,7 +319,7 @@ func (app *BaseApp) InitChain(req abci.RequestInitChain) (res abci.ResponseInitC

// add block gas meter for any genesis transactions (allow infinite gas)
app.deliverState.ctx = app.deliverState.ctx.
WithBlockGasMeter(sdk.NewInfiniteGasMeter())
WithBlockGasMeter(sdk.NewInfiniteGasMeter()).WithCoinFlowTags(sdk.NewCoinFlowRecord(app.trackCoinFlow))

res = initChainer(app.deliverState.ctx, app.DeliverTx, req)

Expand Down Expand Up @@ -499,7 +506,7 @@ func (app *BaseApp) BeginBlock(req abci.RequestBeginBlock) (res abci.ResponseBeg
gasMeter = sdk.NewInfiniteGasMeter()
}
app.deliverState.ctx = app.deliverState.ctx.WithBlockGasMeter(gasMeter).
WithLogger(app.deliverState.ctx.Logger().With("height", app.deliverState.ctx.BlockHeight()))
WithLogger(app.deliverState.ctx.Logger().With("height", app.deliverState.ctx.BlockHeight())).WithCoinFlowTags(sdk.NewCoinFlowRecord(app.trackCoinFlow))

beginBlocker := app.Engine.GetCurrentProtocol().GetBeginBlocker()

Expand Down Expand Up @@ -588,10 +595,12 @@ func validateBasicTxMsgs(msgs []sdk.Msg) sdk.Error {

// retrieve the context for the tx w/ txBytes and other memoized values.
func (app *BaseApp) getContextForTx(mode RunTxMode, txBytes []byte) (ctx sdk.Context) {
txHash := hex.EncodeToString(tmhash.Sum(txBytes))
ctx = app.getState(mode).ctx.
WithTxBytes(txBytes).
WithVoteInfos(app.voteInfos).
WithConsensusParams(app.consensusParams)
WithConsensusParams(app.consensusParams).
WithCoinFlowTrigger(txHash)
if mode == RunTxModeSimulate {
ctx, _ = ctx.CacheContext()
}
Expand Down Expand Up @@ -826,6 +835,9 @@ func (app *BaseApp) runTx(mode RunTxMode, txBytes []byte, tx sdk.Tx) (result sdk
// only update state if all messages pass
if result.IsOK() {
msCache.Write()
ctx.CoinFlowTags().TagWrite()
} else {
ctx.CoinFlowTags().TagClean()
}

return
Expand Down
5 changes: 5 additions & 0 deletions app/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ func SetCheckInvariant(check bool) func(*BaseApp) {
return func(bap *BaseApp) { bap.SetCheckInvariant(check) }
}

// SetTrackCoinFlow sets the config about track coin flow
func SetTrackCoinFlow(enable bool) func(*BaseApp) {
return func(bap *BaseApp) { bap.SetTrackCoinFlow(enable) }
}

// nolint - Setter functions
func (app *BaseApp) SetName(name string) {
if app.sealed {
Expand Down
10 changes: 9 additions & 1 deletion app/v0/protocol_v0.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ type ProtocolV0 struct {
logger log.Logger
invariantLevel string
checkInvariant bool
trackCoinFlow bool

// Manage getting and setting accounts
accountMapper auth.AccountKeeper
Expand Down Expand Up @@ -66,13 +67,14 @@ type ProtocolV0 struct {
metrics *Metrics
}

func NewProtocolV0(version uint64, log log.Logger, pk sdk.ProtocolKeeper, checkInvariant bool, config *cfg.InstrumentationConfig) *ProtocolV0 {
func NewProtocolV0(version uint64, log log.Logger, pk sdk.ProtocolKeeper, checkInvariant bool, trackCoinFlow bool, config *cfg.InstrumentationConfig) *ProtocolV0 {
p0 := ProtocolV0{
version: version,
logger: log,
protocolKeeper: pk,
invariantLevel: strings.ToLower(sdk.InvariantLevel),
checkInvariant: checkInvariant,
trackCoinFlow: trackCoinFlow,
router: protocol.NewRouter(),
queryRouter: protocol.NewQueryRouter(),
config: config,
Expand Down Expand Up @@ -307,6 +309,8 @@ func (p *ProtocolV0) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) a

slashTags := slashing.BeginBlocker(ctx, req, p.slashingKeeper)

ctx.CoinFlowTags().TagWrite()

tags = tags.AppendTags(slashTags)
return abci.ResponseBeginBlock{
Tags: tags.ToKVPairs(),
Expand All @@ -320,6 +324,10 @@ func (p *ProtocolV0) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.
tags = tags.AppendTags(service.EndBlocker(ctx, p.serviceKeeper))
tags = tags.AppendTags(upgrade.EndBlocker(ctx, p.upgradeKeeper))
validatorUpdates := stake.EndBlocker(ctx, p.StakeKeeper)
if p.trackCoinFlow {
ctx.CoinFlowTags().TagWrite()
tags = tags.AppendTags(ctx.CoinFlowTags().GetTags())
}
p.assertRuntimeInvariants(ctx)

return abci.ResponseEndBlock{
Expand Down
1 change: 1 addition & 0 deletions cmd/iris/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ func newApp(logger log.Logger, db dbm.DB, traceStore io.Writer, config *cfg.Inst
bam.SetPruning(viper.GetString("pruning")),
bam.SetMinimumFees(viper.GetString("minimum_fees")),
bam.SetCheckInvariant(viper.GetBool("check_invariant")),
bam.SetTrackCoinFlow(viper.GetBool("track_coin_flow")),
)
}

Expand Down
2 changes: 1 addition & 1 deletion modules/bank/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func handleMsgBurn(ctx sdk.Context, k Keeper, msg MsgBurn) sdk.Result {
if err != nil {
return err.Result()
}

ctx.CoinFlowTags().AppendCoinFlowTag(ctx, msg.Owner.String(), "", msg.Coins.String(), sdk.BurnFlow)
return sdk.Result{
Tags: tags,
}
Expand Down
12 changes: 12 additions & 0 deletions modules/bank/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -328,12 +328,21 @@ func burnCoins(ctx sdk.Context, am auth.AccountKeeper, from string, amt sdk.Coin
func inputOutputCoins(ctx sdk.Context, am auth.AccountKeeper, inputs []Input, outputs []Output) (sdk.Tags, sdk.Error) {
allTags := sdk.EmptyTags()

multiInMultiOut := true
if len(inputs) == 1 && len(outputs) == 1 {
multiInMultiOut = false
ctx.CoinFlowTags().AppendCoinFlowTag(ctx, inputs[0].Address.String(), outputs[0].Address.String(), inputs[0].Coins.String(), sdk.TransferFlow)
}

for _, in := range inputs {
_, tags, err := subtractCoins(ctx, am, in.Address, in.Coins)
if err != nil {
return nil, err
}
allTags = allTags.AppendTags(tags)
if multiInMultiOut {
ctx.CoinFlowTags().AppendCoinFlowTag(ctx, in.Address.String(), ctx.CoinFlowTrigger(), in.Coins.String(), sdk.TransferFlow)
}
}

for _, out := range outputs {
Expand All @@ -342,6 +351,9 @@ func inputOutputCoins(ctx sdk.Context, am auth.AccountKeeper, inputs []Input, ou
return nil, err
}
allTags = allTags.AppendTags(tags)
if multiInMultiOut {
ctx.CoinFlowTags().AppendCoinFlowTag(ctx, ctx.CoinFlowTrigger(), out.Address.String(), out.Coins.String(), sdk.TransferFlow)
}
}

return allTags, nil
Expand Down
3 changes: 3 additions & 0 deletions modules/distribution/keeper/allocation.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@ func (k Keeper) AllocateFeeTax(ctx sdk.Context, destAddr sdk.AccAddress, percent
}
} else {
logger.Info("Grant community tax to account", "grant_amount", allocateCoins.String(), "grant_address", destAddr.String())
if !allocateCoins.IsZero() {
ctx.CoinFlowTags().AppendCoinFlowTag(ctx, "", destAddr.String(), allocateCoins.String(), sdk.CommunityTaxUseFlow)
}
_, _, err := k.bankKeeper.AddCoins(ctx, destAddr, allocateCoins)
if err != nil {
panic(err)
Expand Down
19 changes: 19 additions & 0 deletions modules/distribution/keeper/delegation.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,15 @@ func (k Keeper) withdrawDelegationReward(ctx sdk.Context,
validator.GetDelegatorShares(), delegation.GetShares())
logger.Debug("After withdraw", "validator_distInfo", valInfo.String())

recipient := k.GetDelegatorWithdrawAddr(ctx, delAddr)
coins, _ := withdraw.TruncateDecimal()
if !coins.IsZero() {
if delAddr.Equals(sdk.AccAddress(valAddr)){
ctx.CoinFlowTags().AppendCoinFlowTag(ctx, valAddr.String(), recipient.String(), coins.String(), sdk.ValidatorRewardFlow)
} else {
ctx.CoinFlowTags().AppendCoinFlowTag(ctx, valAddr.String(), recipient.String(), coins.String(), sdk.DelegatorRewardFlow)
}
}
return feePool, valInfo, delInfo, withdraw
}

Expand Down Expand Up @@ -219,6 +228,16 @@ func (k Keeper) withdrawDelegationRewardsAll(ctx sdk.Context,
diWithdrawTruncated, _ := diWithdraw.TruncateDecimal()
ctx.Logger().Debug("Withdraw delegation reward", "reward", diWithdrawTruncated.String(), "delegator", del.GetDelegatorAddr().String(), "validator", del.GetValidatorAddr().String())
tags = tags.AppendTag(fmt.Sprintf(sdk.TagRewardFromValidator, valAddr.String()), []byte(diWithdrawTruncated.String()))

recipient := k.GetDelegatorWithdrawAddr(ctx, delAddr)
coins, _ := diWithdraw.TruncateDecimal()
if !coins.IsZero() {
if delAddr.Equals(sdk.AccAddress(valAddr)){
ctx.CoinFlowTags().AppendCoinFlowTag(ctx, valAddr.String(), recipient.String(), coins.String(), sdk.ValidatorRewardFlow)
} else {
ctx.CoinFlowTags().AppendCoinFlowTag(ctx, valAddr.String(), recipient.String(), coins.String(), sdk.DelegatorRewardFlow)
}
}
return false
}
k.stakeKeeper.IterateDelegations(ctx, delAddr, operationAtDelegation)
Expand Down
6 changes: 6 additions & 0 deletions modules/distribution/keeper/hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,12 @@ func (k Keeper) onDelegationRemoved(ctx sdk.Context, delAddr sdk.AccAddress,
valAddr sdk.ValAddress) {
if valAddr.Equals(sdk.ValAddress(delAddr)) {
feePool, commission := k.withdrawValidatorCommission(ctx, valAddr)

recipient := k.GetDelegatorWithdrawAddr(ctx, delAddr)
coins, _ := commission.TruncateDecimal()
if !coins.IsZero() {
ctx.CoinFlowTags().AppendCoinFlowTag(ctx, valAddr.String(), recipient.String(), coins.String(), sdk.ValidatorCommissionFlow)
}
k.WithdrawToDelegator(ctx, feePool, delAddr, commission)
}
k.RemoveDelegationDistInfo(ctx, delAddr, valAddr)
Expand Down
5 changes: 5 additions & 0 deletions modules/distribution/keeper/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,11 @@ func (k Keeper) WithdrawValidatorRewardsAll(ctx sdk.Context, operatorAddr sdk.Va
commissionTruncated, _ := commission.TruncateDecimal()
resultTags = resultTags.AppendTag(sdk.TagRewardCommission, []byte(commissionTruncated.String()))

recipient := k.GetDelegatorWithdrawAddr(ctx, sdk.AccAddress(operatorAddr))
coins, _ := commission.TruncateDecimal()
if !coins.IsZero() {
ctx.CoinFlowTags().AppendCoinFlowTag(ctx, operatorAddr.String(), recipient.String(), coins.String(), sdk.ValidatorCommissionFlow)
}
k.WithdrawToDelegator(ctx, feePool, accAddr, withdraw)
return withdraw, resultTags, nil
}
Expand Down
2 changes: 1 addition & 1 deletion modules/gov/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ func handleMsgVote(ctx sdk.Context, keeper Keeper, msg MsgVote) sdk.Result {

// Called every block, process inflation, update validator set
func EndBlocker(ctx sdk.Context, keeper Keeper) (resTags sdk.Tags) {

ctx = ctx.WithCoinFlowTrigger(sdk.GovEndBlocker)
ctx = ctx.WithLogger(ctx.Logger().With("handler", "endBlock").With("module", "iris/gov"))
resTags = sdk.NewTags()

Expand Down
20 changes: 2 additions & 18 deletions modules/gov/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,7 @@ func (keeper Keeper) AddDeposit(ctx sdk.Context, proposalID uint64, depositorAdd
}

// Send coins from depositor's account to DepositedCoinsAccAddr account
ctx.CoinFlowTags().AppendCoinFlowTag(ctx, depositorAddr.String(), DepositedCoinsAccAddr.String(), depositAmount.String(), sdk.GovDepositFlow)
_, err := keeper.ck.SendCoins(ctx, depositorAddr, DepositedCoinsAccAddr, depositAmount)
if err != nil {
return err, false
Expand Down Expand Up @@ -491,24 +492,6 @@ func (keeper Keeper) GetDeposits(ctx sdk.Context, proposalID uint64) sdk.Iterato
return sdk.KVStorePrefixIterator(store, KeyDepositsSubspace(proposalID))
}

func (keeper Keeper) RefundDepositsWithoutFee(ctx sdk.Context, proposalID uint64) {
store := ctx.KVStore(keeper.storeKey)
depositsIterator := keeper.GetDeposits(ctx, proposalID)
defer depositsIterator.Close()

for ; depositsIterator.Valid(); depositsIterator.Next() {
deposit := &Deposit{}
keeper.cdc.MustUnmarshalBinaryLengthPrefixed(depositsIterator.Value(), deposit)

_, err := keeper.ck.SendCoins(ctx, DepositedCoinsAccAddr, deposit.Depositor, deposit.Amount)
if err != nil {
panic("should not happen")
}

store.Delete(depositsIterator.Key())
}
}

// Returns and deletes all the deposits on a specific proposal
func (keeper Keeper) RefundDeposits(ctx sdk.Context, proposalID uint64) {
store := ctx.KVStore(keeper.storeKey)
Expand All @@ -535,6 +518,7 @@ func (keeper Keeper) RefundDeposits(ctx sdk.Context, proposalID uint64) {
RefundSumInt = RefundSumInt.Add(RefundAmountInt)
deposit.Amount = sdk.Coins{sdk.NewCoin(stakeTypes.StakeDenom, RefundAmountInt)}

ctx.CoinFlowTags().AppendCoinFlowTag(ctx, DepositedCoinsAccAddr.String(), deposit.Depositor.String(), deposit.Amount.String(), sdk.GovDepositRefundFlow)
_, err := keeper.ck.SendCoins(ctx, DepositedCoinsAccAddr, deposit.Depositor, deposit.Amount)
if err != nil {
panic(err)
Expand Down
1 change: 1 addition & 0 deletions modules/service/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,7 @@ func (k Keeper) RefundFee(ctx sdk.Context, address sdk.AccAddress) sdk.Error {
if !found {
return ErrReturnFeeNotExists(k.Codespace(), address)
}

_, err := k.ck.SendCoins(ctx, RequestCoinsAccAddr, address, fee.Coins)
if err != nil {
return err
Expand Down
12 changes: 5 additions & 7 deletions modules/slashing/tick.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
package slashing

import (
"encoding/binary"
sdk "github.com/irisnet/irishub/types"
abci "github.com/tendermint/tendermint/abci/types"
tmtypes "github.com/tendermint/tendermint/types"
"strconv"
)

// slashing begin block functionality
func BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock, sk Keeper) (tags sdk.Tags) {
ctx = ctx.WithCoinFlowTrigger(sdk.SlashBeginBlocker)
ctx = ctx.WithLogger(ctx.Logger().With("handler", "beginBlock").With("module", "iris/slashing"))

// Tag the height
heightBytes := make([]byte, 8)
binary.LittleEndian.PutUint64(heightBytes, uint64(req.Header.Height))
tags = sdk.NewTags("height", heightBytes)
tags = sdk.NewTags("height", []byte(strconv.FormatInt(req.Header.Height, 10)))

// Iterate over all the validators which *should* have signed this block
// store whether or not they have actually signed it and slash/unbond any
Expand Down Expand Up @@ -42,11 +41,10 @@ func BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock, sk Keeper) (tags

// slashing end block functionality
func EndBlocker(ctx sdk.Context, req abci.RequestEndBlock, sk Keeper) (tags sdk.Tags) {
ctx = ctx.WithCoinFlowTrigger(sdk.SlashEndBlocker)
ctx = ctx.WithLogger(ctx.Logger().With("handler", "endBlock").With("module", "iris/slashing"))
// Tag the height
heightBytes := make([]byte, 8)
binary.LittleEndian.PutUint64(heightBytes, uint64(req.Height))
tags = sdk.NewTags("height", heightBytes)
tags = sdk.NewTags("height", []byte(strconv.FormatInt(req.Height, 10)))

if int64(ctx.CheckValidNum()) < ctx.BlockHeader().NumTxs {
proposalCensorshipTag := sk.handleProposerCensorship(ctx,
Expand Down
1 change: 1 addition & 0 deletions modules/stake/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ func NewHandler(k keeper.Keeper) sdk.Handler {

// Called every block, update validator set
func EndBlocker(ctx sdk.Context, k keeper.Keeper) (validatorUpdates []abci.ValidatorUpdate) {
ctx = ctx.WithCoinFlowTrigger(sdk.StakeEndBlocker)
ctx = ctx.WithLogger(ctx.Logger().With("handler", "endBlock").With("module", "iris/stake"))
endBlockerTags := sdk.EmptyTags()
// Calculate validator set changes.
Expand Down
5 changes: 4 additions & 1 deletion modules/stake/keeper/delegation.go
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,7 @@ func (k Keeper) Delegate(ctx sdk.Context, delAddr sdk.AccAddress, bondAmt sdk.Co

if subtractAccount {
// Account new shares, save
ctx.CoinFlowTags().AppendCoinFlowTag(ctx, delAddr.String(), validator.OperatorAddr.String(), bondAmt.String(), sdk.DelegationFlow)
_, _, err = k.bankKeeper.SubtractCoins(ctx, delegation.DelegatorAddr, sdk.Coins{bondAmt})
if err != nil {
return
Expand Down Expand Up @@ -566,7 +567,9 @@ func (k Keeper) CompleteUnbonding(ctx sdk.Context, delAddr sdk.AccAddress, valAd
if !found {
return types.ErrNoUnbondingDelegation(k.Codespace())
}

if !ubd.Balance.IsZero() {
ctx.CoinFlowTags().AppendCoinFlowTag(ctx, valAddr.String(), ubd.DelegatorAddr.String(), ubd.Balance.String(), sdk.UndelegationFlow)
}
_, _, err := k.bankKeeper.AddCoins(ctx, ubd.DelegatorAddr, sdk.Coins{ubd.Balance})
if err != nil {
return err
Expand Down
5 changes: 4 additions & 1 deletion server/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ type BaseConfig struct {

// Enable invariant check, ignore this flag on testnet
CheckInvariant bool `mapstructure:"check_invariant"`

// Enable track coin flow
TrackCoinFlow bool `mapstructure:"track_coin_flow"`
}

// Config defines the server's top level configuration
Expand All @@ -38,5 +41,5 @@ func (c *Config) MinimumFees() sdk.Coins {

// DefaultConfig returns server's default configuration.
func DefaultConfig() *Config {
return &Config{BaseConfig{MinFees: defaultMinimumFees, CheckInvariant: false}}
return &Config{BaseConfig{MinFees: defaultMinimumFees, CheckInvariant: false, TrackCoinFlow: false}}
}
Loading

0 comments on commit 29266d8

Please sign in to comment.