Merge PR #4541: Events Tracking / Tendermint v0.32.0 Update
* Update Tendermint to v0.32.0-dev0 * Initial refactor of tags * Update event types and add unit tests * Refactor context * Update module manager * Update result godoc * Implement ToABCIEvents * Update BaseApp * Minor cleanup * Fix typo * Update x/bank message handler * Update x/bank keeper * Update x/bank * Update x/bank events docs * Update x/crisis module events * Reset context with events on each message exec * Update x/distribution events and docs * Update BaseApp to not set empty events manually * Implement simple event manager * Update module manager * Update modules to use event manager * Update x/gov module to use events * Update events docs * Update gov queries and crisis app module * Update bank keeper * Add events to minting begin blocker * Update modules to use types/events.go * Cleanup x/mint * Update x/staking events * Update x/staking events * Update events to have sender part of message.sender * Fix build * Fix module unit tests * Add pending log entry * Update deps * Update x/crisis/types/events.go Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Update x/bank/internal/types/events.go Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Update x/distribution/types/events.go Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Update x/mint/internal/types/events.go Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Update x/slashing/types/events.go Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Update x/staking/types/events.go Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Update x/gov/handler.go Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Update x/gov/handler.go Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Update x/mint/abci.go Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Update x/mint/abci.go Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Update x/slashing/handler.go Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Update x/staking/handler.go Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Update x/slashing/handler.go Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Update x/staking/handler.go Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Update x/staking/handler.go Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Update x/staking/handler.go Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Upgrade TM to v0.32.0-dev1 * Update events as strings * Update Tendermint to v0.32.0-dev2 * Fix BaseApp unit tests * Fix unit tests * Bump tendermint version to v0.32.0 * typos
This commit is contained in:
parent
3950017bd9
commit
67f6b02118
15
.pending/breaking/sdk/4387-Refactor-the-us
Normal file
15
.pending/breaking/sdk/4387-Refactor-the-us
Normal file
@ -0,0 +1,15 @@
|
||||
#4387 Refactor the usage of tags (now called events) to reflect the
|
||||
new ABCI events semantics:
|
||||
|
||||
- Move `x/{module}/tags/tags.go` => `x/{module}/types/events.go`
|
||||
- Update `docs/specs`
|
||||
- Refactor tags in favor of new `Event(s)` type(s)
|
||||
- Update `Context` to use new `EventManager`
|
||||
- (Begin|End)Blocker no longer return tags, but rather uses new `EventManager`
|
||||
- Message handlers no longer return tags, but rather uses new `EventManager`
|
||||
|
||||
Any component (e.g. BeginBlocker, message handler, etc...) wishing to emit an event must do so
|
||||
through `ctx.EventManger().EmitEvent(s)`.
|
||||
|
||||
To reset or wipe emitted events: `ctx = ctx.WithEventManager(sdk.NewEventManager())`
|
||||
To get all emitted events: `events := ctx.EventManager().Events()`
|
||||
@ -627,14 +627,14 @@ func (app *BaseApp) BeginBlock(req abci.RequestBeginBlock) (res abci.ResponseBeg
|
||||
// the route match to see whether a handler exists.
|
||||
//
|
||||
// NOTE:CheckTx does not run the actual Msg handler function(s).
|
||||
func (app *BaseApp) CheckTx(txBytes []byte) (res abci.ResponseCheckTx) {
|
||||
func (app *BaseApp) CheckTx(req abci.RequestCheckTx) (res abci.ResponseCheckTx) {
|
||||
var result sdk.Result
|
||||
|
||||
tx, err := app.txDecoder(txBytes)
|
||||
tx, err := app.txDecoder(req.Tx)
|
||||
if err != nil {
|
||||
result = err.Result()
|
||||
} else {
|
||||
result = app.runTx(runTxModeCheck, txBytes, tx)
|
||||
result = app.runTx(runTxModeCheck, req.Tx, tx)
|
||||
}
|
||||
|
||||
return abci.ResponseCheckTx{
|
||||
@ -643,19 +643,19 @@ func (app *BaseApp) CheckTx(txBytes []byte) (res abci.ResponseCheckTx) {
|
||||
Log: result.Log,
|
||||
GasWanted: int64(result.GasWanted), // TODO: Should type accept unsigned ints?
|
||||
GasUsed: int64(result.GasUsed), // TODO: Should type accept unsigned ints?
|
||||
Tags: result.Tags,
|
||||
Events: result.Events.ToABCIEvents(),
|
||||
}
|
||||
}
|
||||
|
||||
// DeliverTx implements the ABCI interface.
|
||||
func (app *BaseApp) DeliverTx(txBytes []byte) (res abci.ResponseDeliverTx) {
|
||||
func (app *BaseApp) DeliverTx(req abci.RequestDeliverTx) (res abci.ResponseDeliverTx) {
|
||||
var result sdk.Result
|
||||
|
||||
tx, err := app.txDecoder(txBytes)
|
||||
tx, err := app.txDecoder(req.Tx)
|
||||
if err != nil {
|
||||
result = err.Result()
|
||||
} else {
|
||||
result = app.runTx(runTxModeDeliver, txBytes, tx)
|
||||
result = app.runTx(runTxModeDeliver, req.Tx, tx)
|
||||
}
|
||||
|
||||
return abci.ResponseDeliverTx{
|
||||
@ -665,7 +665,7 @@ func (app *BaseApp) DeliverTx(txBytes []byte) (res abci.ResponseDeliverTx) {
|
||||
Log: result.Log,
|
||||
GasWanted: int64(result.GasWanted), // TODO: Should type accept unsigned ints?
|
||||
GasUsed: int64(result.GasUsed), // TODO: Should type accept unsigned ints?
|
||||
Tags: result.Tags,
|
||||
Events: result.Events.ToABCIEvents(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -705,11 +705,15 @@ func (app *BaseApp) getContextForTx(mode runTxMode, txBytes []byte) (ctx sdk.Con
|
||||
func (app *BaseApp) runMsgs(ctx sdk.Context, msgs []sdk.Msg, mode runTxMode) (result sdk.Result) {
|
||||
idxLogs := make([]sdk.ABCIMessageLog, 0, len(msgs)) // a list of JSON-encoded logs with msg index
|
||||
|
||||
var data []byte // NOTE: we just append them all (?!)
|
||||
var tags sdk.Tags // also just append them all
|
||||
var code sdk.CodeType
|
||||
var codespace sdk.CodespaceType
|
||||
var (
|
||||
data []byte
|
||||
code sdk.CodeType
|
||||
codespace sdk.CodespaceType
|
||||
)
|
||||
|
||||
events := sdk.EmptyEvents()
|
||||
|
||||
// NOTE: GasWanted is determined by ante handler and GasUsed by the GasMeter.
|
||||
for msgIdx, msg := range msgs {
|
||||
// match message route
|
||||
msgRoute := msg.Route()
|
||||
@ -725,12 +729,13 @@ func (app *BaseApp) runMsgs(ctx sdk.Context, msgs []sdk.Msg, mode runTxMode) (re
|
||||
msgResult = handler(ctx, msg)
|
||||
}
|
||||
|
||||
// NOTE: GasWanted is determined by ante handler and GasUsed by the GasMeter.
|
||||
|
||||
// Result.Data must be length prefixed in order to separate each result
|
||||
// Each message result's Data must be length prefixed in order to separate
|
||||
// each result.
|
||||
data = append(data, msgResult.Data...)
|
||||
tags = append(tags, sdk.MakeTag(sdk.TagAction, msg.Type()))
|
||||
tags = append(tags, msgResult.Tags...)
|
||||
|
||||
// append events from the message's execution and a message action event
|
||||
events = events.AppendEvent(sdk.NewEvent(sdk.EventTypeMessage, sdk.NewAttribute(sdk.AttributeKeyAction, msg.Type())))
|
||||
events = events.AppendEvents(msgResult.Events)
|
||||
|
||||
idxLog := sdk.ABCIMessageLog{MsgIndex: uint16(msgIdx), Log: msgResult.Log}
|
||||
|
||||
@ -755,7 +760,7 @@ func (app *BaseApp) runMsgs(ctx sdk.Context, msgs []sdk.Msg, mode runTxMode) (re
|
||||
Data: data,
|
||||
Log: strings.TrimSpace(string(logJSON)),
|
||||
GasUsed: ctx.GasMeter().GasConsumed(),
|
||||
Tags: tags,
|
||||
Events: events,
|
||||
}
|
||||
|
||||
return result
|
||||
|
||||
@ -552,7 +552,7 @@ func TestCheckTx(t *testing.T) {
|
||||
tx := newTxCounter(i, 0)
|
||||
txBytes, err := codec.MarshalBinaryLengthPrefixed(tx)
|
||||
require.NoError(t, err)
|
||||
r := app.CheckTx(txBytes)
|
||||
r := app.CheckTx(abci.RequestCheckTx{Tx: txBytes})
|
||||
assert.True(t, r.IsOK(), fmt.Sprintf("%v", r))
|
||||
}
|
||||
|
||||
@ -607,7 +607,7 @@ func TestDeliverTx(t *testing.T) {
|
||||
txBytes, err := codec.MarshalBinaryLengthPrefixed(tx)
|
||||
require.NoError(t, err)
|
||||
|
||||
res := app.DeliverTx(txBytes)
|
||||
res := app.DeliverTx(abci.RequestDeliverTx{Tx: txBytes})
|
||||
require.True(t, res.IsOK(), fmt.Sprintf("%v", res))
|
||||
}
|
||||
|
||||
@ -650,7 +650,7 @@ func TestMultiMsgDeliverTx(t *testing.T) {
|
||||
tx := newTxCounter(0, 0, 1, 2)
|
||||
txBytes, err := codec.MarshalBinaryLengthPrefixed(tx)
|
||||
require.NoError(t, err)
|
||||
res := app.DeliverTx(txBytes)
|
||||
res := app.DeliverTx(abci.RequestDeliverTx{Tx: txBytes})
|
||||
require.True(t, res.IsOK(), fmt.Sprintf("%v", res))
|
||||
|
||||
store := app.deliverState.ctx.KVStore(capKey1)
|
||||
@ -670,7 +670,7 @@ func TestMultiMsgDeliverTx(t *testing.T) {
|
||||
tx.Msgs = append(tx.Msgs, msgCounter2{1})
|
||||
txBytes, err = codec.MarshalBinaryLengthPrefixed(tx)
|
||||
require.NoError(t, err)
|
||||
res = app.DeliverTx(txBytes)
|
||||
res = app.DeliverTx(abci.RequestDeliverTx{Tx: txBytes})
|
||||
require.True(t, res.IsOK(), fmt.Sprintf("%v", res))
|
||||
|
||||
store = app.deliverState.ctx.KVStore(capKey1)
|
||||
@ -836,7 +836,7 @@ func TestRunInvalidTransaction(t *testing.T) {
|
||||
|
||||
txBytes, err := newCdc.MarshalBinaryLengthPrefixed(tx)
|
||||
require.NoError(t, err)
|
||||
res := app.DeliverTx(txBytes)
|
||||
res := app.DeliverTx(abci.RequestDeliverTx{Tx: txBytes})
|
||||
require.EqualValues(t, sdk.CodeTxDecode, res.Code)
|
||||
require.EqualValues(t, sdk.CodespaceRoot, res.Codespace)
|
||||
}
|
||||
@ -1055,7 +1055,7 @@ func TestBaseAppAnteHandler(t *testing.T) {
|
||||
tx.setFailOnAnte(true)
|
||||
txBytes, err := cdc.MarshalBinaryLengthPrefixed(tx)
|
||||
require.NoError(t, err)
|
||||
res := app.DeliverTx(txBytes)
|
||||
res := app.DeliverTx(abci.RequestDeliverTx{Tx: txBytes})
|
||||
require.False(t, res.IsOK(), fmt.Sprintf("%v", res))
|
||||
|
||||
ctx := app.getState(runTxModeDeliver).ctx
|
||||
@ -1070,7 +1070,7 @@ func TestBaseAppAnteHandler(t *testing.T) {
|
||||
txBytes, err = cdc.MarshalBinaryLengthPrefixed(tx)
|
||||
require.NoError(t, err)
|
||||
|
||||
res = app.DeliverTx(txBytes)
|
||||
res = app.DeliverTx(abci.RequestDeliverTx{Tx: txBytes})
|
||||
require.False(t, res.IsOK(), fmt.Sprintf("%v", res))
|
||||
|
||||
ctx = app.getState(runTxModeDeliver).ctx
|
||||
@ -1085,7 +1085,7 @@ func TestBaseAppAnteHandler(t *testing.T) {
|
||||
txBytes, err = cdc.MarshalBinaryLengthPrefixed(tx)
|
||||
require.NoError(t, err)
|
||||
|
||||
res = app.DeliverTx(txBytes)
|
||||
res = app.DeliverTx(abci.RequestDeliverTx{Tx: txBytes})
|
||||
require.True(t, res.IsOK(), fmt.Sprintf("%v", res))
|
||||
|
||||
ctx = app.getState(runTxModeDeliver).ctx
|
||||
@ -1161,7 +1161,7 @@ func TestGasConsumptionBadTx(t *testing.T) {
|
||||
txBytes, err := cdc.MarshalBinaryLengthPrefixed(tx)
|
||||
require.NoError(t, err)
|
||||
|
||||
res := app.DeliverTx(txBytes)
|
||||
res := app.DeliverTx(abci.RequestDeliverTx{Tx: txBytes})
|
||||
require.False(t, res.IsOK(), fmt.Sprintf("%v", res))
|
||||
|
||||
// require next tx to fail due to black gas limit
|
||||
@ -1169,7 +1169,7 @@ func TestGasConsumptionBadTx(t *testing.T) {
|
||||
txBytes, err = cdc.MarshalBinaryLengthPrefixed(tx)
|
||||
require.NoError(t, err)
|
||||
|
||||
res = app.DeliverTx(txBytes)
|
||||
res = app.DeliverTx(abci.RequestDeliverTx{Tx: txBytes})
|
||||
require.False(t, res.IsOK(), fmt.Sprintf("%v", res))
|
||||
}
|
||||
|
||||
|
||||
23
docs/spec/bank/04_events.md
Normal file
23
docs/spec/bank/04_events.md
Normal file
@ -0,0 +1,23 @@
|
||||
# Events
|
||||
|
||||
The bank module emits the following events:
|
||||
|
||||
## Handlers
|
||||
|
||||
### MsgSend
|
||||
|
||||
| Type | Attribute Key | Attribute Value |
|
||||
|----------|---------------|--------------------|
|
||||
| transfer | recipient | {recipientAddress} |
|
||||
| message | module | bank |
|
||||
| message | action | send |
|
||||
| message | sender | {senderAddress} |
|
||||
|
||||
### MsgMultiSend
|
||||
|
||||
| Type | Attribute Key | Attribute Value |
|
||||
|----------|---------------|--------------------|
|
||||
| transfer | recipient | {recipientAddress} |
|
||||
| message | module | bank |
|
||||
| message | action | multisend |
|
||||
| message | sender | {senderAddress} |
|
||||
@ -1,23 +0,0 @@
|
||||
# Tags
|
||||
|
||||
The bank module emits the following events/tags:
|
||||
|
||||
## Handlers
|
||||
|
||||
### MsgSend
|
||||
|
||||
| Key | Value |
|
||||
|-------------|---------------------------|
|
||||
| `action` | `send` |
|
||||
| `category` | `bank` |
|
||||
| `sender` | {senderAccountAddress} |
|
||||
| `recipient` | {recipientAccountAddress} |
|
||||
|
||||
### MsgMultiSend
|
||||
|
||||
| Key | Value |
|
||||
|-------------|---------------------------|
|
||||
| `action` | `multisend` |
|
||||
| `category` | `bank` |
|
||||
| `sender` | {senderAccountAddress} |
|
||||
| `recipient` | {recipientAccountAddress} |
|
||||
@ -22,6 +22,6 @@ This module will be used in the Cosmos Hub.
|
||||
- [ViewKeeper](02_keepers.md#viewkeeper)
|
||||
3. **[Messages](03_messages.md)**
|
||||
- [MsgSend](03_messages.md#msgsend)
|
||||
4. **[Tags](04_tags.md)**
|
||||
- [Handlers](04_tags.md#handlers)
|
||||
4. **[Events](04_events.md)**
|
||||
- [Handlers](04_events.md#handlers)
|
||||
5. **[Parameters](05_params.md)**
|
||||
|
||||
14
docs/spec/crisis/03_events.md
Normal file
14
docs/spec/crisis/03_events.md
Normal file
@ -0,0 +1,14 @@
|
||||
# Events
|
||||
|
||||
The crisis module emits the following events:
|
||||
|
||||
## Handlers
|
||||
|
||||
### MsgVerifyInvariance
|
||||
|
||||
| Type | Attribute Key | Attribute Value |
|
||||
|-----------|---------------|------------------|
|
||||
| invariant | route | {invariantRoute} |
|
||||
| message | module | crisis |
|
||||
| message | action | verify_invariant |
|
||||
| message | sender | {senderAddress} |
|
||||
@ -1,14 +0,0 @@
|
||||
# Tags
|
||||
|
||||
The crisis module emits the following events/tags:
|
||||
|
||||
## Handlers
|
||||
|
||||
### MsgVerifyInvariance
|
||||
|
||||
| Key | Value |
|
||||
|-------------|--------------------|
|
||||
| `action` | `verify_invariant` |
|
||||
| `category` | `crisis` |
|
||||
| `sender` | {message-sender} |
|
||||
| `invariant` | {invariant-route} |
|
||||
@ -12,6 +12,6 @@ application initialization process.
|
||||
- [ConstantFee](01_state.md#constantfee)
|
||||
2. **[Messages](02_messages.md)**
|
||||
- [MsgVerifyInvariant](02_messages.md#msgverifyinvariant)
|
||||
3. **[Tags](03_tags.md)**
|
||||
- [Handlers](03_tags.md#handlers)
|
||||
3. **[Events](03_events.md)**
|
||||
- [Handlers](03_events.md#handlers)
|
||||
4. **[Parameters](04_params.md)**
|
||||
|
||||
44
docs/spec/distribution/06_events.md
Normal file
44
docs/spec/distribution/06_events.md
Normal file
@ -0,0 +1,44 @@
|
||||
# Events
|
||||
|
||||
The distribution module emits the following events:
|
||||
|
||||
## BeginBlocker
|
||||
|
||||
| Type | Attribute Key | Attribute Value |
|
||||
|-----------------|---------------|--------------------|
|
||||
| proposer_reward | validator | {validatorAddress} |
|
||||
| proposer_reward | reward | {proposerReward} |
|
||||
| commission | amount | {commissionAmount} |
|
||||
| commission | validator | {validatorAddress} |
|
||||
| rewards | amount | {rewardAmount} |
|
||||
| rewards | validator | {validatorAddress} |
|
||||
|
||||
## Handlers
|
||||
|
||||
### MsgSetWithdrawAddress
|
||||
|
||||
| Type | Attribute Key | Attribute Value |
|
||||
|----------------------|------------------|----------------------|
|
||||
| set_withdraw_address | withdraw_address | {withdrawAddress} |
|
||||
| message | module | distribution |
|
||||
| message | action | set_withdraw_address |
|
||||
| message | sender | {senderAddress} |
|
||||
|
||||
### MsgWithdrawDelegatorReward
|
||||
|
||||
| Type | Attribute Key | Attribute Value |
|
||||
|---------|---------------|---------------------------|
|
||||
| withdraw_rewards | amount | {rewardAmount} |
|
||||
| withdraw_rewards | validator | {validatorAddress} |
|
||||
| message | module | distribution |
|
||||
| message | action | withdraw_delegator_reward |
|
||||
| message | sender | {senderAddress} |
|
||||
|
||||
### MsgWithdrawValidatorCommission
|
||||
|
||||
| Type | Attribute Key | Attribute Value |
|
||||
|------------|---------------|-------------------------------|
|
||||
| withdraw_commission | amount | {commissionAmount} |
|
||||
| message | module | distribution |
|
||||
| message | action | withdraw_validator_commission |
|
||||
| message | sender | {senderAddress} |
|
||||
@ -1,32 +0,0 @@
|
||||
# Tags
|
||||
|
||||
The distribution module emits the following events/tags:
|
||||
|
||||
## Handlers
|
||||
|
||||
### MsgSetWithdrawAddress
|
||||
|
||||
| Key | Value |
|
||||
|------------|---------------------------|
|
||||
| `action` | `set_withdraw_address` |
|
||||
| `category` | `distribution` |
|
||||
| `sender` | {delegatorAccountAddress} |
|
||||
|
||||
### MsgWithdrawDelegatorReward
|
||||
|
||||
| Key | Value |
|
||||
|--------------------|-----------------------------|
|
||||
| `action` | `withdraw_delegator_reward` |
|
||||
| `category` | `distribution` |
|
||||
| `rewards` | {rewards} |
|
||||
| `sender` | {delegatorAccountAddress} |
|
||||
| `source-validator` | {srcOperatorAddress} |
|
||||
|
||||
### MsgWithdrawValidatorCommission
|
||||
|
||||
| Key | Value |
|
||||
|--------------|---------------------------------|
|
||||
| `action` | `withdraw_validator_commission` |
|
||||
| `category` | `distribution` |
|
||||
| `commission` | {commission} |
|
||||
| `sender` | {srcOperatorAddress} |
|
||||
@ -90,6 +90,7 @@ to set up a script to periodically withdraw and rebond rewards.
|
||||
- [Create or modify delegation distribution](05_hooks.md#create-or-modify-delegation-distribution)
|
||||
- [Commission rate change](05_hooks.md#commission-rate-change)
|
||||
- [Change in Validator State](05_hooks.md#change-in-validator-state)
|
||||
6. **[Tags](06_tags.md)**
|
||||
- [Handlers](06_tags.md#handlers)
|
||||
6. **[Events](06_events.md)**
|
||||
- [BeginBlocker](06_events.md#beginblocker)
|
||||
- [Handlers](06_events.md#handlers)
|
||||
7. **[Parameters](07_params.md)**
|
||||
|
||||
51
docs/spec/governance/04_events.md
Normal file
51
docs/spec/governance/04_events.md
Normal file
@ -0,0 +1,51 @@
|
||||
# Events
|
||||
|
||||
The governance module emits the following events:
|
||||
|
||||
## EndBlocker
|
||||
|
||||
| Type | Attribute Key | Attribute Value |
|
||||
|-------------------|-----------------|------------------|
|
||||
| inactive_proposal | proposal_id | {proposalID} |
|
||||
| inactive_proposal | proposal_result | {proposalResult} |
|
||||
| active_proposal | proposal_id | {proposalID} |
|
||||
| active_proposal | proposal_result | {proposalResult} |
|
||||
|
||||
## Handlers
|
||||
|
||||
### MsgSubmitProposal
|
||||
|
||||
| Type | Attribute Key | Attribute Value |
|
||||
|---------------------|---------------------|-----------------|
|
||||
| submit_proposal | proposal_id | {proposalID} |
|
||||
| submit_proposal [0] | voting_period_start | {proposalID} |
|
||||
| proposal_deposit | amount | {depositAmount} |
|
||||
| proposal_deposit | proposal_id | {proposalID} |
|
||||
| message | module | governance |
|
||||
| message | action | submit_proposal |
|
||||
| message | sender | {senderAddress} |
|
||||
|
||||
* [0] Event only emitted if the voting period starts during the submission.
|
||||
|
||||
### MsgVote
|
||||
|
||||
| Type | Attribute Key | Attribute Value |
|
||||
|---------------|---------------|-----------------|
|
||||
| proposal_vote | option | {voteOption} |
|
||||
| proposal_vote | proposal_id | {proposalID} |
|
||||
| message | module | governance |
|
||||
| message | action | vote |
|
||||
| message | sender | {senderAddress} |
|
||||
|
||||
### MsgDeposit
|
||||
|
||||
| Type | Attribute Key | Attribute Value |
|
||||
|----------------------|---------------------|-----------------|
|
||||
| proposal_deposit | amount | {depositAmount} |
|
||||
| proposal_deposit | proposal_id | {proposalID} |
|
||||
| proposal_deposit [0] | voting_period_start | {proposalID} |
|
||||
| message | module | governance |
|
||||
| message | action | deposit |
|
||||
| message | sender | {senderAddress} |
|
||||
|
||||
* [0] Event only emitted if the voting period starts during the submission.
|
||||
@ -1,41 +0,0 @@
|
||||
# Tags
|
||||
|
||||
The governance module emits the following events/tags:
|
||||
|
||||
## EndBlocker
|
||||
|
||||
| Key | Value |
|
||||
|-------------------|------------------------------------------------------------|
|
||||
| `proposal-result` | `proposal-passed`\|`proposal-rejected`\|`proposal-dropped` |
|
||||
|
||||
## Handlers
|
||||
|
||||
### MsgSubmitProposal
|
||||
|
||||
| Key | Value |
|
||||
|---------------------------|--------------------------|
|
||||
| `action` | `submit_proposal` |
|
||||
| `category` | `governance` |
|
||||
| `sender` | {proposerAccountAddress} |
|
||||
| `proposal-id` | {proposalID} |
|
||||
| `voting-period-start` [0] | {proposalID} |
|
||||
|
||||
* [0] Tag only emitted if the voting period starts during the submission.
|
||||
|
||||
### MsgVote
|
||||
|
||||
| Key | Value |
|
||||
|---------------|-----------------------|
|
||||
| `action` | `vote` |
|
||||
| `category` | `governance` |
|
||||
| `sender` | {voterAccountAddress} |
|
||||
| `proposal-id` | {proposalID} |
|
||||
|
||||
### MsgDeposit
|
||||
|
||||
| Key | Value |
|
||||
|---------------|---------------------------|
|
||||
| `action` | `deposit` |
|
||||
| `category` | `governance` |
|
||||
| `sender` | {depositorAccountAddress} |
|
||||
| `proposal-id` | {proposalID} |
|
||||
@ -43,8 +43,8 @@ staking token of the chain.
|
||||
- [Proposal Submission](03_messages.md#proposal-submission)
|
||||
- [Deposit](03_messages.md#deposit)
|
||||
- [Vote](03_messages.md#vote)
|
||||
4. **[Tags](04_tags.md)**
|
||||
- [EndBlocker](04_tags.md#endblocker)
|
||||
- [Handlers](04_tags.md#handlers)
|
||||
4. **[Events](04_events.md)**
|
||||
- [EndBlocker](04_events.md#endblocker)
|
||||
- [Handlers](04_events.md#handlers)
|
||||
5. **[Future Improvements](05_future_improvements.md)**
|
||||
6. **[Parameters](06_params.md)**
|
||||
|
||||
12
docs/spec/mint/05_events.md
Normal file
12
docs/spec/mint/05_events.md
Normal file
@ -0,0 +1,12 @@
|
||||
# Events
|
||||
|
||||
The minting module emits the following events:
|
||||
|
||||
## BeginBlocker
|
||||
|
||||
| Type | Attribute Key | Attribute Value |
|
||||
|------|-------------------|--------------------|
|
||||
| mint | bonded_ratio | {bondedRatio} |
|
||||
| mint | inflation | {inflation} |
|
||||
| mint | annual_provisions | {annualProvisions} |
|
||||
| mint | amount | {amount} |
|
||||
@ -11,4 +11,6 @@
|
||||
- [NextAnnualProvisions](03_begin_block.md#nextannualprovisions)
|
||||
- [BlockProvision](03_begin_block.md#blockprovision)
|
||||
4. **[Parameters](04_params.md)**
|
||||
5. **[Events](05_events.md)**
|
||||
- [BeginBlocker](05_events.md#beginblocker)
|
||||
|
||||
|
||||
24
docs/spec/slashing/06_events.md
Normal file
24
docs/spec/slashing/06_events.md
Normal file
@ -0,0 +1,24 @@
|
||||
# Tags
|
||||
|
||||
The slashing module emits the following events/tags:
|
||||
|
||||
## BeginBlocker
|
||||
|
||||
| Type | Attribute Key | Attribute Value |
|
||||
|-------|---------------|-----------------------------|
|
||||
| slash | address | {validatorConsensusAddress} |
|
||||
| slash | power | {validatorPower} |
|
||||
| slash | reason | {slashReason} |
|
||||
| slash | jailed [0] | {validatorConsensusAddress} |
|
||||
|
||||
- [0] Only included if the validator is jailed.
|
||||
|
||||
## Handlers
|
||||
|
||||
### MsgUnjail
|
||||
|
||||
| Type | Attribute Key | Attribute Value |
|
||||
|---------|---------------|-----------------|
|
||||
| message | module | slashing |
|
||||
| message | action | unjail |
|
||||
| message | sender | {senderAddress} |
|
||||
@ -1,13 +0,0 @@
|
||||
# Tags
|
||||
|
||||
The slashing module emits the following events/tags:
|
||||
|
||||
## Handlers
|
||||
|
||||
### MsgUnjail
|
||||
|
||||
| Key | Value |
|
||||
|------------|----------------------------|
|
||||
| `action` | `unjail` |
|
||||
| `category` | `slashing` |
|
||||
| `sender` | {validatorOperatorAddress} |
|
||||
@ -29,8 +29,9 @@ This module will be used by the Cosmos Hub, the first hub in the Cosmos ecosyste
|
||||
- [Uptime tracking](04_begin_block.md#uptime-tracking)
|
||||
5. **[05_hooks.md](05_hooks.md)**
|
||||
- [Hooks](05_hooks.md#hooks)
|
||||
6. **[Tags](06_tags.md)**
|
||||
- [Handlers](06_tags.md#handlers)
|
||||
6. **[Events](06_events.md)**
|
||||
- [BeginBlocker](06_events.md#beginblocker)
|
||||
- [Handlers](06_events.md#handlers)
|
||||
7. **[Staking Tombstone](07_tombstone.md)**
|
||||
- [Abstract](07_tombstone.md#abstract)
|
||||
8. **[Parameters](08_params.md)**
|
||||
|
||||
72
docs/spec/staking/06_events.md
Normal file
72
docs/spec/staking/06_events.md
Normal file
@ -0,0 +1,72 @@
|
||||
# Events
|
||||
|
||||
The staking module emits the following events:
|
||||
|
||||
## EndBlocker
|
||||
|
||||
| Type | Attribute Key | Attribute Value |
|
||||
|-----------------------|-----------------------|-----------------------|
|
||||
| complete_unbonding | validator | {validatorAddress} |
|
||||
| complete_unbonding | delegator | {delegatorAddress} |
|
||||
| complete_redelegation | source_validator | {srcValidatorAddress} |
|
||||
| complete_redelegation | destination_validator | {dstValidatorAddress} |
|
||||
| complete_redelegation | delegator | {delegatorAddress} |
|
||||
|
||||
## Handlers
|
||||
|
||||
### MsgCreateValidator
|
||||
|
||||
| Type | Attribute Key | Attribute Value |
|
||||
|------------------|---------------|--------------------|
|
||||
| create_validator | validator | {validatorAddress} |
|
||||
| create_validator | amount | {delegationAmount} |
|
||||
| message | module | staking |
|
||||
| message | action | create_validator |
|
||||
| message | sender | {senderAddress} |
|
||||
|
||||
### MsgEditValidator
|
||||
|
||||
| Type | Attribute Key | Attribute Value |
|
||||
|----------------|---------------------|---------------------|
|
||||
| edit_validator | commission_rate | {commissionRate} |
|
||||
| edit_validator | min_self_delegation | {minSelfDelegation} |
|
||||
| message | module | staking |
|
||||
| message | action | edit_validator |
|
||||
| message | sender | {senderAddress} |
|
||||
|
||||
### MsgDelegate
|
||||
|
||||
| Type | Attribute Key | Attribute Value |
|
||||
|----------|---------------|--------------------|
|
||||
| delegate | validator | {validatorAddress} |
|
||||
| delegate | amount | {delegationAmount} |
|
||||
| message | module | staking |
|
||||
| message | action | delegate |
|
||||
| message | sender | {senderAddress} |
|
||||
|
||||
### MsgUndelegate
|
||||
|
||||
| Type | Attribute Key | Attribute Value |
|
||||
|---------|---------------------|--------------------|
|
||||
| unbond | validator | {validatorAddress} |
|
||||
| unbond | amount | {unbondAmount} |
|
||||
| unbond | completion_time [0] | {completionTime} |
|
||||
| message | module | staking |
|
||||
| message | action | begin_unbonding |
|
||||
| message | sender | {senderAddress} |
|
||||
|
||||
* [0] Time is formatted in the RFC3339 standard
|
||||
|
||||
### MsgBeginRedelegate
|
||||
|
||||
| Type | Attribute Key | Attribute Value |
|
||||
|------------|-----------------------|-----------------------|
|
||||
| redelegate | source_validator | {srcValidatorAddress} |
|
||||
| redelegate | destination_validator | {dstValidatorAddress} |
|
||||
| redelegate | amount | {unbondAmount} |
|
||||
| redelegate | completion_time [0] | {completionTime} |
|
||||
| message | module | staking |
|
||||
| message | action | begin_redelegate |
|
||||
| message | sender | {senderAddress} |
|
||||
|
||||
* [0] Time is formatted in the RFC3339 standard
|
||||
@ -1,65 +0,0 @@
|
||||
# Tags
|
||||
|
||||
The staking module emits the following events/tags:
|
||||
|
||||
## EndBlocker
|
||||
|
||||
| Key | Value |
|
||||
|-------------------------|-----------------------------------------------|
|
||||
| `action` | `complete-unbonding`\|`complete-redelegation` |
|
||||
| `category` | `staking` |
|
||||
| `delegator` | {delegatorAccountAddress} |
|
||||
| `source-validator` | {srcOperatorAddress} |
|
||||
| `destination-validator` | {dstOperatorAddress} |
|
||||
|
||||
## Handlers
|
||||
|
||||
### MsgCreateValidator
|
||||
|
||||
| Key | Value |
|
||||
|------------|----------------------|
|
||||
| `action` | `create_validator` |
|
||||
| `category` | `staking` |
|
||||
| `sender` | {dstOperatorAddress} |
|
||||
|
||||
### MsgEditValidator
|
||||
|
||||
| Key | Value |
|
||||
|------------|----------------------|
|
||||
| `action` | `edit_validator` |
|
||||
| `category` | `staking` |
|
||||
| `sender` | {dstOperatorAddress} |
|
||||
|
||||
### MsgDelegate
|
||||
|
||||
| Key | Value |
|
||||
|-------------------------|---------------------------|
|
||||
| `action` | `delegate` |
|
||||
| `category` | `staking` |
|
||||
| `sender` | {delegatorAccountAddress} |
|
||||
| `destination-validator` | {dstOperatorAddress} |
|
||||
|
||||
### MsgBeginRedelegate
|
||||
|
||||
| Key | Value |
|
||||
|-------------------------|---------------------------|
|
||||
| `action` | `begin_redelegate` |
|
||||
| `category` | `staking` |
|
||||
| `sender` | {delegatorAccountAddress} |
|
||||
| `source-validator` | {srcOperatorAddress} |
|
||||
| `destination-validator` | {dstOperatorAddress} |
|
||||
| `end-time` [0] | {delegationFinishTime} |
|
||||
|
||||
* [0] Time is formatted in the RFC3339 standard
|
||||
|
||||
### MsgUndelegate
|
||||
|
||||
| Key | Value |
|
||||
|--------------------|---------------------------|
|
||||
| `action` | `begin_unbonding` |
|
||||
| `category` | `staking` |
|
||||
| `sender` | {delegatorAccountAddress} |
|
||||
| `source-validator` | {srcOperatorAddress} |
|
||||
| `end-time` [0] | {delegationFinishTime} |
|
||||
|
||||
* [0] Time is formatted in the RFC3339 standard
|
||||
@ -39,7 +39,7 @@ network.
|
||||
- [Validator Set Changes](04_end_block.md#validator-set-changes)
|
||||
- [Queues ](04_end_block.md#queues-)
|
||||
5. **[Hooks](05_hooks.md)**
|
||||
6. **[Tags](06_tags.md)**
|
||||
- [EndBlocker](06_tags.md#endblocker)
|
||||
- [Handlers](06_tags.md#handlers)
|
||||
6. **[Events](06_events.md)**
|
||||
- [EndBlocker](06_events.md#endblocker)
|
||||
- [Handlers](06_events.md#handlers)
|
||||
7. **[Parameters](07_params.md)**
|
||||
|
||||
15
go.mod
15
go.mod
@ -1,25 +1,21 @@
|
||||
module github.com/cosmos/cosmos-sdk
|
||||
|
||||
require (
|
||||
github.com/VividCortex/gohistogram v1.0.0 // indirect
|
||||
github.com/aws/aws-lambda-go v1.11.1
|
||||
github.com/bartekn/go-bip39 v0.0.0-20171116152956-a05967ea095d
|
||||
github.com/bgentry/speakeasy v0.1.0
|
||||
github.com/bradleyfalzon/ghinstallation v0.1.2
|
||||
github.com/btcsuite/btcd v0.0.0-20190115013929-ed77733ec07d
|
||||
github.com/cosmos/go-bip39 v0.0.0-20180618194314-52158e4697b8
|
||||
github.com/cosmos/ledger-cosmos-go v0.10.3
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
|
||||
github.com/fortytw2/leaktest v1.3.0 // indirect
|
||||
github.com/go-logfmt/logfmt v0.4.0 // indirect
|
||||
github.com/gogo/protobuf v1.1.1
|
||||
github.com/gogo/protobuf v1.2.1
|
||||
github.com/golang/mock v1.3.1-0.20190508161146-9fa652df1129
|
||||
github.com/golang/protobuf v1.3.0
|
||||
github.com/golang/snappy v0.0.1 // indirect
|
||||
github.com/google/go-github/v26 v26.0.2
|
||||
github.com/gorilla/mux v1.7.0
|
||||
github.com/gorilla/websocket v1.4.0 // indirect
|
||||
github.com/jmhodges/levigo v1.0.0 // indirect
|
||||
github.com/lusis/go-slackbot v0.0.0-20180109053408-401027ccfef5 // indirect
|
||||
github.com/lusis/slack-test v0.0.0-20190426140909-c40012f20018 // indirect
|
||||
github.com/mattn/go-isatty v0.0.6
|
||||
github.com/nlopes/slack v0.5.0
|
||||
github.com/pelletier/go-toml v1.2.0
|
||||
@ -29,19 +25,16 @@ require (
|
||||
github.com/prometheus/common v0.2.0 // indirect
|
||||
github.com/prometheus/procfs v0.0.0-20190227231451-bbced9601137 // indirect
|
||||
github.com/rakyll/statik v0.1.4
|
||||
github.com/rcrowley/go-metrics v0.0.0-20180503174638-e2704e165165 // indirect
|
||||
github.com/rs/cors v1.6.0 // indirect
|
||||
github.com/spf13/afero v1.2.1 // indirect
|
||||
github.com/spf13/cobra v0.0.5
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
github.com/spf13/pflag v1.0.3
|
||||
github.com/spf13/viper v1.3.2
|
||||
github.com/stretchr/testify v1.3.0
|
||||
github.com/syndtr/goleveldb v0.0.0-20180708030551-c4c61651e9e3 // indirect
|
||||
github.com/tendermint/btcd v0.1.1
|
||||
github.com/tendermint/go-amino v0.15.0
|
||||
github.com/tendermint/iavl v0.12.2
|
||||
github.com/tendermint/tendermint v0.31.5
|
||||
github.com/tendermint/tendermint v0.32.0
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2
|
||||
google.golang.org/grpc v1.19.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.2.2
|
||||
|
||||
60
go.sum
60
go.sum
@ -6,8 +6,6 @@ github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/
|
||||
github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/aws/aws-lambda-go v1.11.1 h1:wuOnhS5aqzPOWns71FO35PtbtBKHr4MYsPVt5qXLSfI=
|
||||
github.com/aws/aws-lambda-go v1.11.1/go.mod h1:Rr2SMTLeSMKgD45uep9V/NP8tnbCcySgu04cx0k/6cw=
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
github.com/bartekn/go-bip39 v0.0.0-20171116152956-a05967ea095d h1:1aAija9gr0Hyv4KfQcRcwlmFIrhkDmIj2dz5bkg/s/8=
|
||||
github.com/bartekn/go-bip39 v0.0.0-20171116152956-a05967ea095d/go.mod h1:icNx/6QdFblhsEjZehARqbNumymUT/ydwlLojFdv7Sk=
|
||||
@ -15,8 +13,6 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLM
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY=
|
||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||
github.com/bradleyfalzon/ghinstallation v0.1.2 h1:9fdqVadlvEX/EUts5/aIGvx2ujKnGNIMcuCuUrM6s6Q=
|
||||
github.com/bradleyfalzon/ghinstallation v0.1.2/go.mod h1:VQsLlCoNa54/CNXcc2DuCfNZrZxqQcyPeqKUugF/2h8=
|
||||
github.com/btcsuite/btcd v0.0.0-20190115013929-ed77733ec07d h1:xG8Pj6Y6J760xwETNmMzmlt38QSwz0BLp1cZ09g27uw=
|
||||
github.com/btcsuite/btcd v0.0.0-20190115013929-ed77733ec07d/go.mod h1:d3C0AkH6BRcvO8T0UEPu53cnw4IbV63x1bEjildYhO0=
|
||||
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
|
||||
@ -27,7 +23,6 @@ github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVa
|
||||
github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc=
|
||||
github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY=
|
||||
github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs=
|
||||
github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
|
||||
@ -43,12 +38,14 @@ github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/etcd-io/bbolt v1.3.2 h1:RLRQ0TKLX7DlBRXAJHvbmXL17Q3KNnTBtZ9B6Qo+/Y0=
|
||||
github.com/etcd-io/bbolt v1.3.2/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw=
|
||||
github.com/fortytw2/leaktest v1.2.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
|
||||
github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw=
|
||||
github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
|
||||
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/go-kit/kit v0.6.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.8.0 h1:Wz+5lgoB0kkuqLEc6NVmwRknTKP6dTGbSqvhZtBI/j0=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
@ -56,28 +53,26 @@ github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80n
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/gogo/protobuf v1.1.1 h1:72R+M5VuhED/KujmZVcIquuo8mBgX4oVda//DQb3PXo=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE=
|
||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/mock v1.1.1 h1:G5FRp8JnTd7RQH5kemVNlMeyXQAztQ3mOWV95KxsXH8=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.3.1-0.20190508161146-9fa652df1129 h1:tT8iWCYw4uOem71yYA3htfH+LNopJvcqZQshm56G5L4=
|
||||
github.com/golang/mock v1.3.1-0.20190508161146-9fa652df1129/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
||||
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.0 h1:kbxbvI4Un1LUWKxufD+BiE6AEExYYgkQLQmLFqA1LFk=
|
||||
github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
|
||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/go-github/v26 v26.0.2 h1:tiPWJNapF2n6Mxbmue/g0uDkSuWf34nzlsNp4Ym7qb8=
|
||||
github.com/google/go-github/v26 v26.0.2/go.mod h1:v6/FmX9au22j4CtYxnMhJJkP+JfOQDXALk7hI+MPDNM=
|
||||
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf h1:+RRA9JqSOZFfKrOeqr2z77+8R2RKyh8PG66dcu1V0ck=
|
||||
github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
|
||||
github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/gorilla/mux v1.7.0 h1:tOSd0UKHQd6urX6ApfOn4XdBMY6Sh1MfxV3kmaazO+U=
|
||||
github.com/gorilla/mux v1.7.0/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/websocket v1.2.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
|
||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||
@ -86,16 +81,21 @@ github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89 h1:12K8AlpT0/6QUXSfV0yi4Q0jkbq8NDtIKFtF61AoqV0=
|
||||
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U=
|
||||
github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ=
|
||||
github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/lusis/go-slackbot v0.0.0-20180109053408-401027ccfef5 h1:AsEBgzv3DhuYHI/GiQh2HxvTP71HCCE9E/tzGUzGdtU=
|
||||
github.com/lusis/go-slackbot v0.0.0-20180109053408-401027ccfef5/go.mod h1:c2mYKRyMb1BPkO5St0c/ps62L4S0W2NAkaTXj9qEI+0=
|
||||
github.com/lusis/slack-test v0.0.0-20190426140909-c40012f20018 h1:MNApn+Z+fIT4NPZopPfCc1obT6aY3SVM6DOctz1A9ZU=
|
||||
github.com/lusis/slack-test v0.0.0-20190426140909-c40012f20018/go.mod h1:sFlOUpQL1YcjhFVXhg1CG8ZASEs/Mf1oVb6H75JL/zg=
|
||||
github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/mattn/go-isatty v0.0.6 h1:SrwhHcpV4nWrMGdNcC2kXpMfcBVYGDuTArqyhocJgvA=
|
||||
@ -115,7 +115,6 @@ github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
@ -127,6 +126,7 @@ github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/common v0.0.0-20181020173914-7e9e6cabbd39/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/common v0.2.0 h1:kUZDBDTdBVBYBj5Tmh2NZLlF60mfjA27rM34b+cVwNU=
|
||||
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
@ -147,6 +147,7 @@ github.com/spf13/afero v1.2.1 h1:qgMbHoJbPbw579P+1zVY+6n4nIFuIchaIjzZ/I/Yq8M=
|
||||
github.com/spf13/afero v1.2.1/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
|
||||
github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
|
||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cobra v0.0.1/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s=
|
||||
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
|
||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||
@ -154,45 +155,44 @@ github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmq
|
||||
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
||||
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
|
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/viper v1.0.0/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM=
|
||||
github.com/spf13/viper v1.3.2 h1:VUFqw5KcqRf7i70GOzW7N+Q7+gxVBkSSqiXB12+JQ4M=
|
||||
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/syndtr/goleveldb v0.0.0-20180708030551-c4c61651e9e3 h1:sAlSBRDl4psFR3ysKXRSE8ss6Mt90+ma1zRTroTNBJA=
|
||||
github.com/syndtr/goleveldb v0.0.0-20180708030551-c4c61651e9e3/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0=
|
||||
github.com/syndtr/goleveldb v0.0.0-20181012014443-6b91fda63f2e h1:91EeXI4y4ShkyzkMqZ7QP/ZTIqwXp3RuDu5WFzxcFAs=
|
||||
github.com/syndtr/goleveldb v0.0.0-20181012014443-6b91fda63f2e/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0=
|
||||
github.com/tendermint/btcd v0.1.1 h1:0VcxPfflS2zZ3RiOAHkBiFUcPvbtRj5O7zHmcJWHV7s=
|
||||
github.com/tendermint/btcd v0.1.1/go.mod h1:DC6/m53jtQzr/NFmMNEu0rxf18/ktVoVtMrnDD5pN+U=
|
||||
github.com/tendermint/crypto v0.0.0-20180820045704-3764759f34a5 h1:u8i49c+BxloX3XQ55cvzFNXplizZP/q00i+IlttUjAU=
|
||||
github.com/tendermint/crypto v0.0.0-20180820045704-3764759f34a5/go.mod h1:z4YtwM70uOnk8h0pjJYlj3zdYwi9l03By6iAIF5j/Pk=
|
||||
github.com/tendermint/go-amino v0.14.1/go.mod h1:i/UKE5Uocn+argJJBb12qTZsCDBcAYMbR92AaJVmKso=
|
||||
github.com/tendermint/go-amino v0.15.0 h1:TC4e66P59W7ML9+bxio17CPKnxW3nKIRAYskntMAoRk=
|
||||
github.com/tendermint/go-amino v0.15.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME=
|
||||
github.com/tendermint/iavl v0.12.2 h1:Ls5p5VINCM1HRT9g5Vvs2zmDOCU/CCIvIHzd/pZ8P0E=
|
||||
github.com/tendermint/iavl v0.12.2/go.mod h1:EoKMMv++tDOL5qKKVnoIqtVPshRrEPeJ0WsgDOLAauM=
|
||||
github.com/tendermint/tendermint v0.31.5 h1:vTet8tCq3B9/J9Yo11dNZ8pOB7NtSy++bVSfkP4KzR4=
|
||||
github.com/tendermint/tendermint v0.31.5/go.mod h1:ymcPyWblXCplCPQjbOYbrF1fWnpslATMVqiGgWbZrlc=
|
||||
github.com/tendermint/tendermint v0.32.0 h1:9MAnZpWjuA3DnAXWqjYxrBXOYC0Xk8zZJgV6IO3LdBw=
|
||||
github.com/tendermint/tendermint v0.32.0/go.mod h1:/5wKhXBcO1eS9qfBs2X4OcNys07c7ls+O11iODzCRhE=
|
||||
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
github.com/zondax/hid v0.9.0 h1:eiT3P6vNxAEVxXMw66eZUAAnU2zD33JBkfG/EnfAKl8=
|
||||
github.com/zondax/hid v0.9.0/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM=
|
||||
go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk=
|
||||
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc h1:a3CU5tJYVj92DY2LaA1kUkrsqD5/3mLDhx2NcNqyW+0=
|
||||
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6 h1:bjcUS9ztw9kFmmIxJInhon/0Is3p+EHBKNgquIzo1OI=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@ -205,14 +205,15 @@ golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpbl
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b h1:qMK98NmNCRVDIYFycQ5yVRkvgDUFfdP8Ip4KqmDEB7g=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/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-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20180831171423-11092d34479b h1:lohp5blsw53GBXtLyLNaTXPXS9pJ1tiTw61ZHUoE9Qw=
|
||||
google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2 h1:67iHsV9djwGdZpdZNbLuQj6FOzCaZe3w+vhLjn5AcFA=
|
||||
google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/grpc v1.13.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||
google.golang.org/grpc v1.19.0 h1:cfg4PD8YEdSFnm7qLV4++93WcmhH2nIUhMjhdCvl3j8=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
@ -222,7 +223,6 @@ gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
|
||||
@ -62,7 +62,7 @@ func TestDeliverTx(t *testing.T) {
|
||||
Height: 1,
|
||||
}
|
||||
app.BeginBlock(abci.RequestBeginBlock{Header: header})
|
||||
dres := app.DeliverTx(txBytes)
|
||||
dres := app.DeliverTx(abci.RequestDeliverTx{Tx: txBytes})
|
||||
require.Equal(t, uint32(0), dres.Code, dres.Log)
|
||||
app.EndBlock(abci.RequestEndBlock{})
|
||||
cres := app.Commit()
|
||||
|
||||
134
types/context.go
134
types/context.go
@ -41,6 +41,7 @@ func NewContext(ms MultiStore, header abci.Header, isCheckTx bool, logger log.Lo
|
||||
pst: newThePast(),
|
||||
gen: 0,
|
||||
}
|
||||
|
||||
c = c.WithMultiStore(ms)
|
||||
c = c.WithBlockHeader(header)
|
||||
c = c.WithChainID(header.ChainID)
|
||||
@ -51,6 +52,8 @@ func NewContext(ms MultiStore, header abci.Header, isCheckTx bool, logger log.Lo
|
||||
c = c.WithGasMeter(stypes.NewInfiniteGasMeter())
|
||||
c = c.WithMinGasPrices(DecCoins{})
|
||||
c = c.WithConsensusParams(nil)
|
||||
c = c.WithEventManager(NewEventManager())
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
@ -59,8 +62,26 @@ func (c Context) IsZero() bool {
|
||||
return c.Context == nil
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
// Getting a value
|
||||
// ----------------------------------------------------------------------------
|
||||
// Getters
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
type contextKey int // local to the context module
|
||||
|
||||
const (
|
||||
contextKeyMultiStore contextKey = iota
|
||||
contextKeyBlockHeader
|
||||
contextKeyChainID
|
||||
contextKeyIsCheckTx
|
||||
contextKeyTxBytes
|
||||
contextKeyLogger
|
||||
contextKeyVoteInfos
|
||||
contextKeyGasMeter
|
||||
contextKeyBlockGasMeter
|
||||
contextKeyMinGasPrices
|
||||
contextKeyConsensusParams
|
||||
contextKeyEventManager
|
||||
)
|
||||
|
||||
// context value for the provided key
|
||||
func (c Context) Value(key interface{}) interface{} {
|
||||
@ -74,20 +95,42 @@ func (c Context) Value(key interface{}) interface{} {
|
||||
return value
|
||||
}
|
||||
|
||||
// KVStore fetches a KVStore from the MultiStore.
|
||||
func (c Context) KVStore(key StoreKey) KVStore {
|
||||
return gaskv.NewStore(c.MultiStore().GetKVStore(key), c.GasMeter(), stypes.KVGasConfig())
|
||||
func (c Context) MultiStore() MultiStore {
|
||||
return c.Value(contextKeyMultiStore).(MultiStore)
|
||||
}
|
||||
|
||||
// TransientStore fetches a TransientStore from the MultiStore.
|
||||
func (c Context) TransientStore(key StoreKey) KVStore {
|
||||
return gaskv.NewStore(c.MultiStore().GetKVStore(key), c.GasMeter(), stypes.TransientGasConfig())
|
||||
func (c Context) BlockHeader() abci.Header { return c.Value(contextKeyBlockHeader).(abci.Header) }
|
||||
|
||||
func (c Context) BlockHeight() int64 { return c.BlockHeader().Height }
|
||||
|
||||
func (c Context) ChainID() string { return c.Value(contextKeyChainID).(string) }
|
||||
|
||||
func (c Context) TxBytes() []byte { return c.Value(contextKeyTxBytes).([]byte) }
|
||||
|
||||
func (c Context) Logger() log.Logger { return c.Value(contextKeyLogger).(log.Logger) }
|
||||
|
||||
func (c Context) VoteInfos() []abci.VoteInfo {
|
||||
return c.Value(contextKeyVoteInfos).([]abci.VoteInfo)
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
// With* (setting a value)
|
||||
func (c Context) GasMeter() GasMeter { return c.Value(contextKeyGasMeter).(GasMeter) }
|
||||
|
||||
func (c Context) BlockGasMeter() GasMeter { return c.Value(contextKeyBlockGasMeter).(GasMeter) }
|
||||
|
||||
func (c Context) IsCheckTx() bool { return c.Value(contextKeyIsCheckTx).(bool) }
|
||||
|
||||
func (c Context) MinGasPrices() DecCoins { return c.Value(contextKeyMinGasPrices).(DecCoins) }
|
||||
|
||||
func (c Context) ConsensusParams() *abci.ConsensusParams {
|
||||
return c.Value(contextKeyConsensusParams).(*abci.ConsensusParams)
|
||||
}
|
||||
|
||||
func (c Context) EventManager() *EventManager { return c.Value(contextKeyEventManager).(*EventManager) }
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Setters
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// nolint
|
||||
func (c Context) WithValue(key interface{}, value interface{}) Context {
|
||||
return c.withValue(key, value)
|
||||
}
|
||||
@ -127,55 +170,6 @@ func (c Context) withValue(key interface{}, value interface{}) Context {
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
// Values that require no key.
|
||||
|
||||
type contextKey int // local to the context module
|
||||
|
||||
const (
|
||||
contextKeyMultiStore contextKey = iota
|
||||
contextKeyBlockHeader
|
||||
contextKeyChainID
|
||||
contextKeyIsCheckTx
|
||||
contextKeyTxBytes
|
||||
contextKeyLogger
|
||||
contextKeyVoteInfos
|
||||
contextKeyGasMeter
|
||||
contextKeyBlockGasMeter
|
||||
contextKeyMinGasPrices
|
||||
contextKeyConsensusParams
|
||||
)
|
||||
|
||||
func (c Context) MultiStore() MultiStore {
|
||||
return c.Value(contextKeyMultiStore).(MultiStore)
|
||||
}
|
||||
|
||||
func (c Context) BlockHeader() abci.Header { return c.Value(contextKeyBlockHeader).(abci.Header) }
|
||||
|
||||
func (c Context) BlockHeight() int64 { return c.BlockHeader().Height }
|
||||
|
||||
func (c Context) ChainID() string { return c.Value(contextKeyChainID).(string) }
|
||||
|
||||
func (c Context) TxBytes() []byte { return c.Value(contextKeyTxBytes).([]byte) }
|
||||
|
||||
func (c Context) Logger() log.Logger { return c.Value(contextKeyLogger).(log.Logger) }
|
||||
|
||||
func (c Context) VoteInfos() []abci.VoteInfo {
|
||||
return c.Value(contextKeyVoteInfos).([]abci.VoteInfo)
|
||||
}
|
||||
|
||||
func (c Context) GasMeter() GasMeter { return c.Value(contextKeyGasMeter).(GasMeter) }
|
||||
|
||||
func (c Context) BlockGasMeter() GasMeter { return c.Value(contextKeyBlockGasMeter).(GasMeter) }
|
||||
|
||||
func (c Context) IsCheckTx() bool { return c.Value(contextKeyIsCheckTx).(bool) }
|
||||
|
||||
func (c Context) MinGasPrices() DecCoins { return c.Value(contextKeyMinGasPrices).(DecCoins) }
|
||||
|
||||
func (c Context) ConsensusParams() *abci.ConsensusParams {
|
||||
return c.Value(contextKeyConsensusParams).(*abci.ConsensusParams)
|
||||
}
|
||||
|
||||
func (c Context) WithMultiStore(ms MultiStore) Context {
|
||||
return c.withValue(contextKeyMultiStore, ms)
|
||||
}
|
||||
@ -231,6 +225,24 @@ func (c Context) WithConsensusParams(params *abci.ConsensusParams) Context {
|
||||
return c.withValue(contextKeyConsensusParams, params)
|
||||
}
|
||||
|
||||
func (c Context) WithEventManager(em *EventManager) Context {
|
||||
return c.WithValue(contextKeyEventManager, em)
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Store / Caching
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// KVStore fetches a KVStore from the MultiStore.
|
||||
func (c Context) KVStore(key StoreKey) KVStore {
|
||||
return gaskv.NewStore(c.MultiStore().GetKVStore(key), c.GasMeter(), stypes.KVGasConfig())
|
||||
}
|
||||
|
||||
// TransientStore fetches a TransientStore from the MultiStore.
|
||||
func (c Context) TransientStore(key StoreKey) KVStore {
|
||||
return gaskv.NewStore(c.MultiStore().GetKVStore(key), c.GasMeter(), stypes.TransientGasConfig())
|
||||
}
|
||||
|
||||
// Cache the multistore and return a new cached context. The cached context is
|
||||
// written to the context when writeCache is called.
|
||||
func (c Context) CacheContext() (cc Context, writeCache func()) {
|
||||
@ -299,4 +311,4 @@ func (pst *thePast) getOp(ver int64) (Op, bool) {
|
||||
return Op{}, false
|
||||
}
|
||||
return pst.ops[ver-1], true
|
||||
}
|
||||
}
|
||||
192
types/events.go
Normal file
192
types/events.go
Normal file
@ -0,0 +1,192 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
cmn "github.com/tendermint/tendermint/libs/common"
|
||||
)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Event Manager
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// EventManager implements a simple wrapper around a slice of Event objects that
|
||||
// can be emitted from.
|
||||
type EventManager struct {
|
||||
events Events
|
||||
}
|
||||
|
||||
func NewEventManager() *EventManager {
|
||||
return &EventManager{EmptyEvents()}
|
||||
}
|
||||
|
||||
func (em *EventManager) Events() Events { return em.events }
|
||||
|
||||
// EmitEvent stores a single Event object.
|
||||
func (em *EventManager) EmitEvent(event Event) {
|
||||
em.events = em.events.AppendEvent(event)
|
||||
}
|
||||
|
||||
// EmitEvents stores a series of Event objects.
|
||||
func (em *EventManager) EmitEvents(events Events) {
|
||||
em.events = em.events.AppendEvents(events)
|
||||
}
|
||||
|
||||
// ABCIEvents returns all stored Event objects as abci.Event objects.
|
||||
func (em EventManager) ABCIEvents() []abci.Event {
|
||||
return em.events.ToABCIEvents()
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Events
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
type (
|
||||
// Event is a type alias for an ABCI Event
|
||||
Event abci.Event
|
||||
|
||||
// Attribute defines an attribute wrapper where the key and value are
|
||||
// strings instead of raw bytes.
|
||||
Attribute struct {
|
||||
Key string `json:"key"`
|
||||
Value string `json:"value,omitempty"`
|
||||
}
|
||||
|
||||
// Events defines a slice of Event objects
|
||||
Events []Event
|
||||
)
|
||||
|
||||
// NewEvent creates a new Event object with a given type and slice of one or more
|
||||
// attributes.
|
||||
func NewEvent(ty string, attrs ...Attribute) Event {
|
||||
e := Event{Type: ty}
|
||||
|
||||
for _, attr := range attrs {
|
||||
e.Attributes = append(e.Attributes, NewAttribute(attr.Key, attr.Value).ToKVPair())
|
||||
}
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
// NewAttribute returns a new key/value Attribute object.
|
||||
func NewAttribute(k, v string) Attribute {
|
||||
return Attribute{k, v}
|
||||
}
|
||||
|
||||
// EmptyEvents returns an empty slice of events.
|
||||
func EmptyEvents() Events {
|
||||
return make(Events, 0)
|
||||
}
|
||||
|
||||
func (a Attribute) String() string {
|
||||
return fmt.Sprintf("%s: %s", a.Key, a.Value)
|
||||
}
|
||||
|
||||
// ToKVPair converts an Attribute object into a Tendermint key/value pair.
|
||||
func (a Attribute) ToKVPair() cmn.KVPair {
|
||||
return cmn.KVPair{Key: toBytes(a.Key), Value: toBytes(a.Value)}
|
||||
}
|
||||
|
||||
// AppendAttributes adds one or more attributes to an Event.
|
||||
func (e Event) AppendAttributes(attrs ...Attribute) Event {
|
||||
for _, attr := range attrs {
|
||||
e.Attributes = append(e.Attributes, attr.ToKVPair())
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
||||
// AppendEvent adds an Event to a slice of events.
|
||||
func (e Events) AppendEvent(event Event) Events {
|
||||
return append(e, event)
|
||||
}
|
||||
|
||||
// AppendEvents adds a slice of Event objects to an exist slice of Event objects.
|
||||
func (e Events) AppendEvents(events Events) Events {
|
||||
return append(e, events...)
|
||||
}
|
||||
|
||||
// ToABCIEvents converts a slice of Event objects to a slice of abci.Event
|
||||
// objects.
|
||||
func (e Events) ToABCIEvents() []abci.Event {
|
||||
res := make([]abci.Event, len(e), len(e))
|
||||
for i, ev := range e {
|
||||
res[i] = abci.Event{Type: ev.Type, Attributes: ev.Attributes}
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func toBytes(i interface{}) []byte {
|
||||
switch x := i.(type) {
|
||||
case []uint8:
|
||||
return x
|
||||
case string:
|
||||
return []byte(x)
|
||||
default:
|
||||
panic(i)
|
||||
}
|
||||
}
|
||||
|
||||
// Common event types and attribute keys
|
||||
var (
|
||||
EventTypeMessage = "message"
|
||||
|
||||
AttributeKeyAction = "action"
|
||||
AttributeKeyModule = "module"
|
||||
AttributeKeySender = "sender"
|
||||
)
|
||||
|
||||
type (
|
||||
// StringAttribute defines en Event object wrapper where all the attributes
|
||||
// contain key/value pairs that are strings instead of raw bytes.
|
||||
StringEvent struct {
|
||||
Type string `json:"type,omitempty"`
|
||||
Attributes []Attribute `json:"attributes,omitempty"`
|
||||
}
|
||||
|
||||
// StringAttributes defines a slice of StringEvents objects.
|
||||
StringEvents []StringEvent
|
||||
)
|
||||
|
||||
func (se StringEvents) String() string {
|
||||
var sb strings.Builder
|
||||
|
||||
for _, e := range se {
|
||||
sb.WriteString(fmt.Sprintf("\t\t- %s\n", e.Type))
|
||||
|
||||
for _, attr := range e.Attributes {
|
||||
sb.WriteString(fmt.Sprintf("\t\t\t- %s\n", attr.String()))
|
||||
}
|
||||
}
|
||||
|
||||
return strings.TrimRight(sb.String(), "\n")
|
||||
}
|
||||
|
||||
// StringifyEvent converts an Event object to a StringEvent object.
|
||||
func StringifyEvent(e abci.Event) StringEvent {
|
||||
res := StringEvent{}
|
||||
res.Type = e.Type
|
||||
|
||||
for _, attr := range e.Attributes {
|
||||
res.Attributes = append(
|
||||
res.Attributes,
|
||||
Attribute{string(attr.Key), string(attr.Value)},
|
||||
)
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
// StringifyEvents converts a slice of Event objects into a slice of StringEvent
|
||||
// objects.
|
||||
func StringifyEvents(events []abci.Event) StringEvents {
|
||||
var res StringEvents
|
||||
|
||||
for _, e := range events {
|
||||
res = append(res, StringifyEvent(e))
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
53
types/events_test.go
Normal file
53
types/events_test.go
Normal file
@ -0,0 +1,53 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestAppendEvents(t *testing.T) {
|
||||
e1 := NewEvent("transfer", NewAttribute("sender", "foo"))
|
||||
e2 := NewEvent("transfer", NewAttribute("sender", "bar"))
|
||||
a := Events{e1}
|
||||
b := Events{e2}
|
||||
c := a.AppendEvents(b)
|
||||
require.Equal(t, c, Events{e1, e2})
|
||||
require.Equal(t, c, Events{e1}.AppendEvent(NewEvent("transfer", NewAttribute("sender", "bar"))))
|
||||
require.Equal(t, c, Events{e1}.AppendEvents(Events{e2}))
|
||||
}
|
||||
|
||||
func TestAppendAttributes(t *testing.T) {
|
||||
e := NewEvent("transfer", NewAttribute("sender", "foo"))
|
||||
e = e.AppendAttributes(NewAttribute("recipient", "bar"))
|
||||
require.Len(t, e.Attributes, 2)
|
||||
require.Equal(t, e, NewEvent("transfer", NewAttribute("sender", "foo"), NewAttribute("recipient", "bar")))
|
||||
}
|
||||
|
||||
func TestEmptyEvents(t *testing.T) {
|
||||
require.Equal(t, EmptyEvents(), Events{})
|
||||
}
|
||||
|
||||
func TestAttributeString(t *testing.T) {
|
||||
require.Equal(t, "foo: bar", NewAttribute("foo", "bar").String())
|
||||
}
|
||||
|
||||
func TestToABCIEvents(t *testing.T) {
|
||||
e := Events{NewEvent("transfer", NewAttribute("sender", "foo"))}
|
||||
abciEvents := e.ToABCIEvents()
|
||||
require.Len(t, abciEvents, 1)
|
||||
require.Equal(t, abciEvents[0].Type, e[0].Type)
|
||||
require.Equal(t, abciEvents[0].Attributes, e[0].Attributes)
|
||||
}
|
||||
|
||||
func TestEventManager(t *testing.T) {
|
||||
em := NewEventManager()
|
||||
event := NewEvent("reward", NewAttribute("x", "y"))
|
||||
events := Events{NewEvent("transfer", NewAttribute("sender", "foo"))}
|
||||
|
||||
em.EmitEvents(events)
|
||||
em.EmitEvent(event)
|
||||
|
||||
require.Len(t, em.Events(), 2)
|
||||
require.Equal(t, em.Events(), events.AppendEvent(event))
|
||||
}
|
||||
@ -139,8 +139,8 @@ type AppModule interface {
|
||||
QuerierRoute() string
|
||||
NewQuerierHandler() sdk.Querier
|
||||
|
||||
BeginBlock(sdk.Context, abci.RequestBeginBlock) sdk.Tags
|
||||
EndBlock(sdk.Context, abci.RequestEndBlock) ([]abci.ValidatorUpdate, sdk.Tags)
|
||||
BeginBlock(sdk.Context, abci.RequestBeginBlock)
|
||||
EndBlock(sdk.Context, abci.RequestEndBlock) []abci.ValidatorUpdate
|
||||
}
|
||||
|
||||
//___________________________
|
||||
@ -172,13 +172,11 @@ func (GenesisOnlyAppModule) QuerierRoute() string { return "" }
|
||||
func (gam GenesisOnlyAppModule) NewQuerierHandler() sdk.Querier { return nil }
|
||||
|
||||
// module begin-block
|
||||
func (gam GenesisOnlyAppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) sdk.Tags {
|
||||
return sdk.EmptyTags()
|
||||
}
|
||||
func (gam GenesisOnlyAppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) {}
|
||||
|
||||
// module end-block
|
||||
func (GenesisOnlyAppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) ([]abci.ValidatorUpdate, sdk.Tags) {
|
||||
return []abci.ValidatorUpdate{}, sdk.EmptyTags()
|
||||
func (GenesisOnlyAppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate {
|
||||
return []abci.ValidatorUpdate{}
|
||||
}
|
||||
|
||||
//____________________________________________________________________________
|
||||
@ -282,26 +280,30 @@ func (m *Manager) ExportGenesis(ctx sdk.Context) map[string]json.RawMessage {
|
||||
return genesisData
|
||||
}
|
||||
|
||||
// perform begin block functionality for modules
|
||||
// BeginBlock performs begin block functionality for all modules. It creates a
|
||||
// child context with an event manager to aggregate events emitted from all
|
||||
// modules.
|
||||
func (m *Manager) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock {
|
||||
tags := sdk.EmptyTags()
|
||||
ctx = ctx.WithEventManager(sdk.NewEventManager())
|
||||
|
||||
for _, moduleName := range m.OrderBeginBlockers {
|
||||
moduleTags := m.Modules[moduleName].BeginBlock(ctx, req)
|
||||
tags = tags.AppendTags(moduleTags)
|
||||
m.Modules[moduleName].BeginBlock(ctx, req)
|
||||
}
|
||||
|
||||
return abci.ResponseBeginBlock{
|
||||
Tags: tags.ToKVPairs(),
|
||||
Events: ctx.EventManager().ABCIEvents(),
|
||||
}
|
||||
}
|
||||
|
||||
// perform end block functionality for modules
|
||||
// EndBlock performs end block functionality for all modules. It creates a
|
||||
// child context with an event manager to aggregate events emitted from all
|
||||
// modules.
|
||||
func (m *Manager) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock {
|
||||
ctx = ctx.WithEventManager(sdk.NewEventManager())
|
||||
validatorUpdates := []abci.ValidatorUpdate{}
|
||||
tags := sdk.EmptyTags()
|
||||
|
||||
for _, moduleName := range m.OrderEndBlockers {
|
||||
moduleValUpdates, moduleTags := m.Modules[moduleName].EndBlock(ctx, req)
|
||||
tags = tags.AppendTags(moduleTags)
|
||||
moduleValUpdates := m.Modules[moduleName].EndBlock(ctx, req)
|
||||
|
||||
// use these validator updates if provided, the module manager assumes
|
||||
// only one module will update the validator set
|
||||
@ -309,13 +311,14 @@ func (m *Manager) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) abci.Respo
|
||||
if len(validatorUpdates) > 0 {
|
||||
panic("validator EndBlock updates already set by a previous module")
|
||||
}
|
||||
|
||||
validatorUpdates = moduleValUpdates
|
||||
}
|
||||
}
|
||||
|
||||
return abci.ResponseEndBlock{
|
||||
ValidatorUpdates: validatorUpdates,
|
||||
Tags: tags,
|
||||
Events: ctx.EventManager().ABCIEvents(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -32,8 +32,9 @@ type Result struct {
|
||||
// GasUsed is the amount of gas actually consumed. NOTE: unimplemented
|
||||
GasUsed uint64
|
||||
|
||||
// Tags are used for transaction indexing and pubsub.
|
||||
Tags Tags
|
||||
// Events contains a slice of Event objects that were emitted during some
|
||||
// execution.
|
||||
Events Events
|
||||
}
|
||||
|
||||
// TODO: In the future, more codes may be OK.
|
||||
@ -75,7 +76,7 @@ type TxResponse struct {
|
||||
Info string `json:"info,omitempty"`
|
||||
GasWanted int64 `json:"gas_wanted,omitempty"`
|
||||
GasUsed int64 `json:"gas_used,omitempty"`
|
||||
Tags StringTags `json:"tags,omitempty"`
|
||||
Events StringEvents `json:"events,omitempty"`
|
||||
Codespace string `json:"codespace,omitempty"`
|
||||
Tx Tx `json:"tx,omitempty"`
|
||||
Timestamp string `json:"timestamp,omitempty"`
|
||||
@ -99,7 +100,7 @@ func NewResponseResultTx(res *ctypes.ResultTx, tx Tx, timestamp string) TxRespon
|
||||
Info: res.TxResult.Info,
|
||||
GasWanted: res.TxResult.GasWanted,
|
||||
GasUsed: res.TxResult.GasUsed,
|
||||
Tags: TagsToStringTags(res.TxResult.Tags),
|
||||
Events: StringifyEvents(res.TxResult.Events),
|
||||
Tx: tx,
|
||||
Timestamp: timestamp,
|
||||
}
|
||||
@ -141,7 +142,7 @@ func newTxResponseCheckTx(res *ctypes.ResultBroadcastTxCommit) TxResponse {
|
||||
Info: res.CheckTx.Info,
|
||||
GasWanted: res.CheckTx.GasWanted,
|
||||
GasUsed: res.CheckTx.GasUsed,
|
||||
Tags: TagsToStringTags(res.CheckTx.Tags),
|
||||
Events: StringifyEvents(res.CheckTx.Events),
|
||||
Codespace: res.CheckTx.Codespace,
|
||||
}
|
||||
}
|
||||
@ -168,7 +169,7 @@ func newTxResponseDeliverTx(res *ctypes.ResultBroadcastTxCommit) TxResponse {
|
||||
Info: res.DeliverTx.Info,
|
||||
GasWanted: res.DeliverTx.GasWanted,
|
||||
GasUsed: res.DeliverTx.GasUsed,
|
||||
Tags: TagsToStringTags(res.DeliverTx.Tags),
|
||||
Events: StringifyEvents(res.DeliverTx.Events),
|
||||
Codespace: res.DeliverTx.Codespace,
|
||||
}
|
||||
}
|
||||
@ -238,8 +239,8 @@ func (r TxResponse) String() string {
|
||||
sb.WriteString(fmt.Sprintf(" Timestamp: %s\n", r.Timestamp))
|
||||
}
|
||||
|
||||
if len(r.Tags) > 0 {
|
||||
sb.WriteString(fmt.Sprintf(" Tags: \n%s\n", r.Tags.String()))
|
||||
if len(r.Events) > 0 {
|
||||
sb.WriteString(fmt.Sprintf(" Tags: \n%s\n", r.Events.String()))
|
||||
}
|
||||
|
||||
return strings.TrimSpace(sb.String())
|
||||
|
||||
118
types/tags.go
118
types/tags.go
@ -1,118 +0,0 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
cmn "github.com/tendermint/tendermint/libs/common"
|
||||
)
|
||||
|
||||
// Type synonym for convenience
|
||||
type Tag = cmn.KVPair
|
||||
|
||||
// Type synonym for convenience
|
||||
type Tags cmn.KVPairs
|
||||
|
||||
// New empty tags
|
||||
func EmptyTags() Tags {
|
||||
return make(Tags, 0)
|
||||
}
|
||||
|
||||
// Append a single tag
|
||||
func (t Tags) AppendTag(k string, v string) Tags {
|
||||
return append(t, MakeTag(k, v))
|
||||
}
|
||||
|
||||
// Append two lists of tags
|
||||
func (t Tags) AppendTags(tags Tags) Tags {
|
||||
return append(t, tags...)
|
||||
}
|
||||
|
||||
// Turn tags into KVPair list
|
||||
func (t Tags) ToKVPairs() []cmn.KVPair {
|
||||
return []cmn.KVPair(t)
|
||||
}
|
||||
|
||||
// New variadic tags, must be k string, v []byte repeating
|
||||
func NewTags(tags ...interface{}) Tags {
|
||||
var ret Tags
|
||||
if len(tags)%2 != 0 {
|
||||
panic("must specify key-value pairs as varargs")
|
||||
}
|
||||
i := 0
|
||||
for {
|
||||
if i == len(tags) {
|
||||
break
|
||||
}
|
||||
ret = append(ret, Tag{Key: toBytes(tags[i]), Value: toBytes(tags[i+1])})
|
||||
i += 2
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func toBytes(i interface{}) []byte {
|
||||
switch x := i.(type) {
|
||||
case []uint8:
|
||||
return x
|
||||
case string:
|
||||
return []byte(x)
|
||||
default:
|
||||
panic(i)
|
||||
}
|
||||
}
|
||||
|
||||
// Make a tag from a key and a value
|
||||
func MakeTag(k string, v string) Tag {
|
||||
return Tag{Key: []byte(k), Value: []byte(v)}
|
||||
}
|
||||
|
||||
//__________________________________________________
|
||||
|
||||
// common tags
|
||||
var (
|
||||
TagAction = "action"
|
||||
TagCategory = "category"
|
||||
TagSender = "sender"
|
||||
TagSrcValidator = "source-validator"
|
||||
TagDstValidator = "destination-validator"
|
||||
TagDelegator = "delegator"
|
||||
)
|
||||
|
||||
// A KVPair where the Key and Value are both strings, rather than []byte
|
||||
type StringTag struct {
|
||||
Key string `json:"key"`
|
||||
Value string `json:"value,omitempty"`
|
||||
}
|
||||
|
||||
func (st StringTag) String() string {
|
||||
return fmt.Sprintf("%s = %s", st.Key, st.Value)
|
||||
}
|
||||
|
||||
// A slice of StringTag
|
||||
type StringTags []StringTag
|
||||
|
||||
func (st StringTags) String() string {
|
||||
var sb strings.Builder
|
||||
for _, t := range st {
|
||||
sb.WriteString(fmt.Sprintf(" - %s\n", t.String()))
|
||||
}
|
||||
|
||||
return strings.TrimRight(sb.String(), "\n")
|
||||
}
|
||||
|
||||
// Conversion function from a []byte tag to a string tag
|
||||
func TagToStringTag(tag Tag) StringTag {
|
||||
return StringTag{
|
||||
Key: string(tag.Key),
|
||||
Value: string(tag.Value),
|
||||
}
|
||||
}
|
||||
|
||||
// Conversion function from Tags to a StringTags
|
||||
func TagsToStringTags(tags Tags) StringTags {
|
||||
var stringTags StringTags
|
||||
for _, tag := range tags {
|
||||
stringTags = append(stringTags, TagToStringTag(tag))
|
||||
}
|
||||
return stringTags
|
||||
}
|
||||
@ -1,35 +0,0 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestAppendTags(t *testing.T) {
|
||||
a := NewTags("a", "1")
|
||||
b := NewTags("b", "2")
|
||||
c := a.AppendTags(b)
|
||||
require.Equal(t, c, Tags{MakeTag("a", "1"), MakeTag("b", "2")})
|
||||
require.Equal(t, c, Tags{MakeTag("a", "1")}.AppendTag("b", "2"))
|
||||
}
|
||||
|
||||
func TestEmptyTags(t *testing.T) {
|
||||
a := EmptyTags()
|
||||
require.Equal(t, a, Tags{})
|
||||
}
|
||||
|
||||
func TestNewTags(t *testing.T) {
|
||||
b := NewTags("a", "1")
|
||||
require.Equal(t, b, Tags{MakeTag("a", "1")})
|
||||
|
||||
require.Panics(t, func() { NewTags("a", "1", "b") })
|
||||
require.Panics(t, func() { NewTags("a", 1) })
|
||||
require.Panics(t, func() { NewTags(1, 1) })
|
||||
require.Panics(t, func() { NewTags(true, false) })
|
||||
}
|
||||
|
||||
func TestKVPairTags(t *testing.T) {
|
||||
a := NewTags("a", "1")
|
||||
require.Equal(t, a, Tags(a.ToKVPairs()))
|
||||
}
|
||||
@ -121,11 +121,9 @@ func (am AppModule) ExportGenesis(ctx sdk.Context) json.RawMessage {
|
||||
}
|
||||
|
||||
// module begin-block
|
||||
func (AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) sdk.Tags {
|
||||
return sdk.EmptyTags()
|
||||
}
|
||||
func (AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) {}
|
||||
|
||||
// module end-block
|
||||
func (AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) ([]abci.ValidatorUpdate, sdk.Tags) {
|
||||
return []abci.ValidatorUpdate{}, sdk.EmptyTags()
|
||||
func (AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate {
|
||||
return []abci.ValidatorUpdate{}
|
||||
}
|
||||
|
||||
@ -11,6 +11,8 @@ import (
|
||||
// NewHandler returns a handler for "bank" type messages.
|
||||
func NewHandler(k keeper.Keeper) sdk.Handler {
|
||||
return func(ctx sdk.Context, msg sdk.Msg) sdk.Result {
|
||||
ctx = ctx.WithEventManager(sdk.NewEventManager())
|
||||
|
||||
switch msg := msg.(type) {
|
||||
case types.MsgSend:
|
||||
return handleMsgSend(ctx, k, msg)
|
||||
@ -30,20 +32,20 @@ func handleMsgSend(ctx sdk.Context, k keeper.Keeper, msg types.MsgSend) sdk.Resu
|
||||
if !k.GetSendEnabled(ctx) {
|
||||
return types.ErrSendDisabled(k.Codespace()).Result()
|
||||
}
|
||||
|
||||
err := k.SendCoins(ctx, msg.FromAddress, msg.ToAddress, msg.Amount)
|
||||
if err != nil {
|
||||
return err.Result()
|
||||
}
|
||||
|
||||
resTags := sdk.NewTags(
|
||||
types.Category, types.TxCategory,
|
||||
types.Sender, msg.FromAddress.String(),
|
||||
types.Recipient, msg.ToAddress.String(),
|
||||
ctx.EventManager().EmitEvent(
|
||||
sdk.NewEvent(
|
||||
sdk.EventTypeMessage,
|
||||
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
|
||||
),
|
||||
)
|
||||
|
||||
return sdk.Result{
|
||||
Tags: resTags,
|
||||
}
|
||||
return sdk.Result{Events: ctx.EventManager().Events()}
|
||||
}
|
||||
|
||||
// Handle MsgMultiSend.
|
||||
@ -52,13 +54,18 @@ func handleMsgMultiSend(ctx sdk.Context, k keeper.Keeper, msg types.MsgMultiSend
|
||||
if !k.GetSendEnabled(ctx) {
|
||||
return types.ErrSendDisabled(k.Codespace()).Result()
|
||||
}
|
||||
resTags, err := k.InputOutputCoins(ctx, msg.Inputs, msg.Outputs)
|
||||
|
||||
err := k.InputOutputCoins(ctx, msg.Inputs, msg.Outputs)
|
||||
if err != nil {
|
||||
return err.Result()
|
||||
}
|
||||
|
||||
resTags = resTags.AppendTag(types.Category, types.TxCategory)
|
||||
return sdk.Result{
|
||||
Tags: resTags,
|
||||
}
|
||||
ctx.EventManager().EmitEvent(
|
||||
sdk.NewEvent(
|
||||
sdk.EventTypeMessage,
|
||||
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
|
||||
),
|
||||
)
|
||||
|
||||
return sdk.Result{Events: ctx.EventManager().Events()}
|
||||
}
|
||||
|
||||
@ -5,6 +5,7 @@ import (
|
||||
"testing"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
@ -12,7 +13,7 @@ import (
|
||||
func TestInvalidMsg(t *testing.T) {
|
||||
h := NewHandler(nil)
|
||||
|
||||
res := h(sdk.Context{}, sdk.NewTestMsg())
|
||||
res := h(sdk.NewContext(nil, abci.Header{}, false, nil), sdk.NewTestMsg())
|
||||
require.False(t, res.IsOK())
|
||||
require.True(t, strings.Contains(res.Log, "unrecognized bank message type"))
|
||||
}
|
||||
|
||||
@ -20,10 +20,10 @@ type Keeper interface {
|
||||
SetCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) sdk.Error
|
||||
SubtractCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) (sdk.Coins, sdk.Error)
|
||||
AddCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) (sdk.Coins, sdk.Error)
|
||||
InputOutputCoins(ctx sdk.Context, inputs []types.Input, outputs []types.Output) (sdk.Tags, sdk.Error)
|
||||
InputOutputCoins(ctx sdk.Context, inputs []types.Input, outputs []types.Output) sdk.Error
|
||||
|
||||
DelegateCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) (sdk.Tags, sdk.Error)
|
||||
UndelegateCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) (sdk.Tags, sdk.Error)
|
||||
DelegateCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) sdk.Error
|
||||
UndelegateCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) sdk.Error
|
||||
}
|
||||
|
||||
// BaseKeeper manages transfers between accounts. It implements the Keeper interface.
|
||||
@ -81,22 +81,16 @@ func (keeper BaseKeeper) AddCoins(
|
||||
}
|
||||
|
||||
// InputOutputCoins handles a list of inputs and outputs
|
||||
func (keeper BaseKeeper) InputOutputCoins(
|
||||
ctx sdk.Context, inputs []types.Input, outputs []types.Output,
|
||||
) (sdk.Tags, sdk.Error) {
|
||||
|
||||
func (keeper BaseKeeper) InputOutputCoins(ctx sdk.Context, inputs []types.Input, outputs []types.Output) sdk.Error {
|
||||
return inputOutputCoins(ctx, keeper.ak, inputs, outputs)
|
||||
}
|
||||
|
||||
// DelegateCoins performs delegation by deducting amt coins from an account with
|
||||
// address addr. For vesting accounts, delegations amounts are tracked for both
|
||||
// vesting and vested coins.
|
||||
func (keeper BaseKeeper) DelegateCoins(
|
||||
ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins,
|
||||
) (sdk.Tags, sdk.Error) {
|
||||
|
||||
func (keeper BaseKeeper) DelegateCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) sdk.Error {
|
||||
if !amt.IsValid() {
|
||||
return nil, sdk.ErrInvalidCoins(amt.String())
|
||||
return sdk.ErrInvalidCoins(amt.String())
|
||||
}
|
||||
return delegateCoins(ctx, keeper.ak, addr, amt)
|
||||
}
|
||||
@ -105,12 +99,9 @@ func (keeper BaseKeeper) DelegateCoins(
|
||||
// address addr. For vesting accounts, undelegation amounts are tracked for both
|
||||
// vesting and vested coins.
|
||||
// If any of the undelegation amounts are negative, an error is returned.
|
||||
func (keeper BaseKeeper) UndelegateCoins(
|
||||
ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins,
|
||||
) (sdk.Tags, sdk.Error) {
|
||||
|
||||
func (keeper BaseKeeper) UndelegateCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) sdk.Error {
|
||||
if !amt.IsValid() {
|
||||
return nil, sdk.ErrInvalidCoins(amt.String())
|
||||
return sdk.ErrInvalidCoins(amt.String())
|
||||
}
|
||||
return undelegateCoins(ctx, keeper.ak, addr, amt)
|
||||
}
|
||||
@ -156,6 +147,18 @@ func (keeper BaseSendKeeper) SendCoins(
|
||||
if !amt.IsValid() {
|
||||
return sdk.ErrInvalidCoins(amt.String())
|
||||
}
|
||||
|
||||
ctx.EventManager().EmitEvents(sdk.Events{
|
||||
sdk.NewEvent(
|
||||
types.EventTypeTransfer,
|
||||
sdk.NewAttribute(types.AttributeKeyRecipient, toAddr.String()),
|
||||
),
|
||||
sdk.NewEvent(
|
||||
sdk.EventTypeMessage,
|
||||
sdk.NewAttribute(types.AttributeKeySender, fromAddr.String()),
|
||||
),
|
||||
})
|
||||
|
||||
return sendCoins(ctx, keeper.ak, fromAddr, toAddr, amt)
|
||||
}
|
||||
|
||||
@ -209,34 +212,37 @@ func (keeper BaseViewKeeper) Codespace() sdk.CodespaceType {
|
||||
return keeper.codespace
|
||||
}
|
||||
|
||||
func getCoins(ctx sdk.Context, am types.AccountKeeper, addr sdk.AccAddress) sdk.Coins {
|
||||
acc := am.GetAccount(ctx, addr)
|
||||
func getCoins(ctx sdk.Context, ak types.AccountKeeper, addr sdk.AccAddress) sdk.Coins {
|
||||
acc := ak.GetAccount(ctx, addr)
|
||||
if acc == nil {
|
||||
return sdk.NewCoins()
|
||||
}
|
||||
return acc.GetCoins()
|
||||
}
|
||||
|
||||
func setCoins(ctx sdk.Context, am types.AccountKeeper, addr sdk.AccAddress, amt sdk.Coins) sdk.Error {
|
||||
func setCoins(ctx sdk.Context, ak types.AccountKeeper, addr sdk.AccAddress, amt sdk.Coins) sdk.Error {
|
||||
if !amt.IsValid() {
|
||||
return sdk.ErrInvalidCoins(amt.String())
|
||||
}
|
||||
acc := am.GetAccount(ctx, addr)
|
||||
|
||||
acc := ak.GetAccount(ctx, addr)
|
||||
if acc == nil {
|
||||
acc = am.NewAccountWithAddress(ctx, addr)
|
||||
acc = ak.NewAccountWithAddress(ctx, addr)
|
||||
}
|
||||
|
||||
err := acc.SetCoins(amt)
|
||||
if err != nil {
|
||||
// Handle w/ #870
|
||||
panic(err)
|
||||
}
|
||||
am.SetAccount(ctx, acc)
|
||||
|
||||
ak.SetAccount(ctx, acc)
|
||||
return nil
|
||||
}
|
||||
|
||||
// HasCoins returns whether or not an account has at least amt coins.
|
||||
func hasCoins(ctx sdk.Context, am types.AccountKeeper, addr sdk.AccAddress, amt sdk.Coins) bool {
|
||||
return getCoins(ctx, am, addr).IsAllGTE(amt)
|
||||
func hasCoins(ctx sdk.Context, ak types.AccountKeeper, addr sdk.AccAddress, amt sdk.Coins) bool {
|
||||
return getCoins(ctx, ak, addr).IsAllGTE(amt)
|
||||
}
|
||||
|
||||
func getAccount(ctx sdk.Context, ak types.AccountKeeper, addr sdk.AccAddress) exported.Account {
|
||||
@ -251,7 +257,6 @@ func setAccount(ctx sdk.Context, ak types.AccountKeeper, acc exported.Account) {
|
||||
//
|
||||
// CONTRACT: If the account is a vesting account, the amount has to be spendable.
|
||||
func subtractCoins(ctx sdk.Context, ak types.AccountKeeper, addr sdk.AccAddress, amt sdk.Coins) (sdk.Coins, sdk.Error) {
|
||||
|
||||
if !amt.IsValid() {
|
||||
return nil, sdk.ErrInvalidCoins(amt.String())
|
||||
}
|
||||
@ -280,13 +285,12 @@ func subtractCoins(ctx sdk.Context, ak types.AccountKeeper, addr sdk.AccAddress,
|
||||
}
|
||||
|
||||
// AddCoins adds amt to the coins at the addr.
|
||||
func addCoins(ctx sdk.Context, am types.AccountKeeper, addr sdk.AccAddress, amt sdk.Coins) (sdk.Coins, sdk.Error) {
|
||||
|
||||
func addCoins(ctx sdk.Context, ak types.AccountKeeper, addr sdk.AccAddress, amt sdk.Coins) (sdk.Coins, sdk.Error) {
|
||||
if !amt.IsValid() {
|
||||
return nil, sdk.ErrInvalidCoins(amt.String())
|
||||
}
|
||||
|
||||
oldCoins := getCoins(ctx, am, addr)
|
||||
oldCoins := getCoins(ctx, ak, addr)
|
||||
newCoins := oldCoins.Add(amt)
|
||||
|
||||
if newCoins.IsAnyNegative() {
|
||||
@ -295,25 +299,25 @@ func addCoins(ctx sdk.Context, am types.AccountKeeper, addr sdk.AccAddress, amt
|
||||
)
|
||||
}
|
||||
|
||||
err := setCoins(ctx, am, addr, newCoins)
|
||||
err := setCoins(ctx, ak, addr, newCoins)
|
||||
|
||||
return newCoins, err
|
||||
}
|
||||
|
||||
// SendCoins moves coins from one account to another
|
||||
// Returns ErrInvalidCoins if amt is invalid.
|
||||
func sendCoins(ctx sdk.Context, am types.AccountKeeper, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) sdk.Error {
|
||||
func sendCoins(ctx sdk.Context, ak types.AccountKeeper, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) sdk.Error {
|
||||
// Safety check ensuring that when sending coins the keeper must maintain the
|
||||
if !amt.IsValid() {
|
||||
return sdk.ErrInvalidCoins(amt.String())
|
||||
}
|
||||
|
||||
_, err := subtractCoins(ctx, am, fromAddr, amt)
|
||||
_, err := subtractCoins(ctx, ak, fromAddr, amt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = addCoins(ctx, am, toAddr, amt)
|
||||
_, err = addCoins(ctx, ak, toAddr, amt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -323,96 +327,87 @@ func sendCoins(ctx sdk.Context, am types.AccountKeeper, fromAddr sdk.AccAddress,
|
||||
|
||||
// InputOutputCoins handles a list of inputs and outputs
|
||||
// NOTE: Make sure to revert state changes from tx on error
|
||||
func inputOutputCoins(ctx sdk.Context, am types.AccountKeeper, inputs []types.Input, outputs []types.Output) (sdk.Tags, sdk.Error) {
|
||||
func inputOutputCoins(ctx sdk.Context, ak types.AccountKeeper, inputs []types.Input, outputs []types.Output) sdk.Error {
|
||||
// Safety check ensuring that when sending coins the keeper must maintain the
|
||||
// Check supply invariant and validity of Coins.
|
||||
if err := types.ValidateInputsOutputs(inputs, outputs); err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
|
||||
allTags := sdk.EmptyTags()
|
||||
|
||||
for _, in := range inputs {
|
||||
_, err := subtractCoins(ctx, am, in.Address, in.Coins)
|
||||
_, err := subtractCoins(ctx, ak, in.Address, in.Coins)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
|
||||
allTags = allTags.AppendTag(
|
||||
types.Sender, in.Address.String(),
|
||||
ctx.EventManager().EmitEvent(
|
||||
sdk.NewEvent(
|
||||
sdk.EventTypeMessage,
|
||||
sdk.NewAttribute(types.AttributeKeySender, in.Address.String()),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
for _, out := range outputs {
|
||||
_, err := addCoins(ctx, am, out.Address, out.Coins)
|
||||
_, err := addCoins(ctx, ak, out.Address, out.Coins)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
allTags = allTags.AppendTag(
|
||||
types.Recipient, out.Address.String(),
|
||||
|
||||
ctx.EventManager().EmitEvent(
|
||||
sdk.NewEvent(
|
||||
types.EventTypeTransfer,
|
||||
sdk.NewAttribute(types.AttributeKeyRecipient, out.Address.String()),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
return allTags, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
func delegateCoins(
|
||||
ctx sdk.Context, ak types.AccountKeeper, addr sdk.AccAddress, amt sdk.Coins,
|
||||
) (sdk.Tags, sdk.Error) {
|
||||
|
||||
func delegateCoins(ctx sdk.Context, ak types.AccountKeeper, addr sdk.AccAddress, amt sdk.Coins) sdk.Error {
|
||||
if !amt.IsValid() {
|
||||
return nil, sdk.ErrInvalidCoins(amt.String())
|
||||
return sdk.ErrInvalidCoins(amt.String())
|
||||
}
|
||||
|
||||
acc := getAccount(ctx, ak, addr)
|
||||
if acc == nil {
|
||||
return nil, sdk.ErrUnknownAddress(fmt.Sprintf("account %s does not exist", addr))
|
||||
return sdk.ErrUnknownAddress(fmt.Sprintf("account %s does not exist", addr))
|
||||
}
|
||||
|
||||
oldCoins := acc.GetCoins()
|
||||
|
||||
_, hasNeg := oldCoins.SafeSub(amt)
|
||||
if hasNeg {
|
||||
return nil, sdk.ErrInsufficientCoins(
|
||||
return sdk.ErrInsufficientCoins(
|
||||
fmt.Sprintf("insufficient account funds; %s < %s", oldCoins, amt),
|
||||
)
|
||||
}
|
||||
|
||||
if err := trackDelegation(acc, ctx.BlockHeader().Time, amt); err != nil {
|
||||
return nil, sdk.ErrInternal(fmt.Sprintf("failed to track delegation: %v", err))
|
||||
return sdk.ErrInternal(fmt.Sprintf("failed to track delegation: %v", err))
|
||||
}
|
||||
|
||||
setAccount(ctx, ak, acc)
|
||||
|
||||
return sdk.NewTags(
|
||||
sdk.TagAction, types.ActionDelegateCoins,
|
||||
sdk.TagDelegator, addr.String(),
|
||||
), nil
|
||||
return nil
|
||||
}
|
||||
|
||||
func undelegateCoins(
|
||||
ctx sdk.Context, ak types.AccountKeeper, addr sdk.AccAddress, amt sdk.Coins,
|
||||
) (sdk.Tags, sdk.Error) {
|
||||
|
||||
func undelegateCoins(ctx sdk.Context, ak types.AccountKeeper, addr sdk.AccAddress, amt sdk.Coins) sdk.Error {
|
||||
if !amt.IsValid() {
|
||||
return nil, sdk.ErrInvalidCoins(amt.String())
|
||||
return sdk.ErrInvalidCoins(amt.String())
|
||||
}
|
||||
|
||||
acc := getAccount(ctx, ak, addr)
|
||||
if acc == nil {
|
||||
return nil, sdk.ErrUnknownAddress(fmt.Sprintf("account %s does not exist", addr))
|
||||
return sdk.ErrUnknownAddress(fmt.Sprintf("account %s does not exist", addr))
|
||||
}
|
||||
|
||||
if err := trackUndelegation(acc, amt); err != nil {
|
||||
return nil, sdk.ErrInternal(fmt.Sprintf("failed to track undelegation: %v", err))
|
||||
return sdk.ErrInternal(fmt.Sprintf("failed to track undelegation: %v", err))
|
||||
}
|
||||
|
||||
setAccount(ctx, ak, acc)
|
||||
|
||||
return sdk.NewTags(
|
||||
sdk.TagAction, types.ActionUndelegateCoins,
|
||||
sdk.TagDelegator, addr.String(),
|
||||
), nil
|
||||
return nil
|
||||
}
|
||||
|
||||
// CONTRACT: assumes that amt is valid.
|
||||
|
||||
@ -295,13 +295,13 @@ func TestDelegateCoins(t *testing.T) {
|
||||
ctx = ctx.WithBlockTime(now.Add(12 * time.Hour))
|
||||
|
||||
// require the ability for a non-vesting account to delegate
|
||||
_, err := input.k.DelegateCoins(ctx, addr2, delCoins)
|
||||
err := input.k.DelegateCoins(ctx, addr2, delCoins)
|
||||
acc = input.ak.GetAccount(ctx, addr2)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, delCoins, acc.GetCoins())
|
||||
|
||||
// require the ability for a vesting account to delegate
|
||||
_, err = input.k.DelegateCoins(ctx, addr1, delCoins)
|
||||
err = input.k.DelegateCoins(ctx, addr1, delCoins)
|
||||
vacc = input.ak.GetAccount(ctx, addr1).(*auth.ContinuousVestingAccount)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, delCoins, vacc.GetCoins())
|
||||
@ -330,22 +330,22 @@ func TestUndelegateCoins(t *testing.T) {
|
||||
ctx = ctx.WithBlockTime(now.Add(12 * time.Hour))
|
||||
|
||||
// require the ability for a non-vesting account to delegate
|
||||
_, err := input.k.DelegateCoins(ctx, addr2, delCoins)
|
||||
err := input.k.DelegateCoins(ctx, addr2, delCoins)
|
||||
require.NoError(t, err)
|
||||
|
||||
// require the ability for a non-vesting account to undelegate
|
||||
_, err = input.k.UndelegateCoins(ctx, addr2, delCoins)
|
||||
err = input.k.UndelegateCoins(ctx, addr2, delCoins)
|
||||
require.NoError(t, err)
|
||||
|
||||
acc = input.ak.GetAccount(ctx, addr2)
|
||||
require.Equal(t, origCoins, acc.GetCoins())
|
||||
|
||||
// require the ability for a vesting account to delegate
|
||||
_, err = input.k.DelegateCoins(ctx, addr1, delCoins)
|
||||
err = input.k.DelegateCoins(ctx, addr1, delCoins)
|
||||
require.NoError(t, err)
|
||||
|
||||
// require the ability for a vesting account to undelegate
|
||||
_, err = input.k.UndelegateCoins(ctx, addr1, delCoins)
|
||||
err = input.k.UndelegateCoins(ctx, addr1, delCoins)
|
||||
require.NoError(t, err)
|
||||
|
||||
vacc = input.ak.GetAccount(ctx, addr1).(*auth.ContinuousVestingAccount)
|
||||
|
||||
11
x/bank/internal/types/events.go
Normal file
11
x/bank/internal/types/events.go
Normal file
@ -0,0 +1,11 @@
|
||||
package types
|
||||
|
||||
// Bank module event types
|
||||
var (
|
||||
EventTypeTransfer = "transfer"
|
||||
|
||||
AttributeKeyRecipient = "recipient"
|
||||
AttributeKeySender = "sender"
|
||||
|
||||
AttributeValueCategory = ModuleName
|
||||
)
|
||||
@ -1,17 +0,0 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
// Tag keys and values
|
||||
var (
|
||||
ActionUndelegateCoins = "undelegateCoins"
|
||||
ActionDelegateCoins = "delegateCoins"
|
||||
TxCategory = "bank"
|
||||
|
||||
Action = sdk.TagAction
|
||||
Category = sdk.TagCategory
|
||||
Recipient = "recipient"
|
||||
Sender = "sender"
|
||||
)
|
||||
@ -114,11 +114,9 @@ func (am AppModule) ExportGenesis(ctx sdk.Context) json.RawMessage {
|
||||
}
|
||||
|
||||
// module begin-block
|
||||
func (AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) sdk.Tags {
|
||||
return sdk.EmptyTags()
|
||||
}
|
||||
func (AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) {}
|
||||
|
||||
// module end-block
|
||||
func (AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) ([]abci.ValidatorUpdate, sdk.Tags) {
|
||||
return []abci.ValidatorUpdate{}, sdk.EmptyTags()
|
||||
func (AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate {
|
||||
return []abci.ValidatorUpdate{}
|
||||
}
|
||||
|
||||
@ -4,7 +4,6 @@ import (
|
||||
"fmt"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/crisis/tags"
|
||||
"github.com/cosmos/cosmos-sdk/x/crisis/types"
|
||||
)
|
||||
|
||||
@ -13,6 +12,8 @@ const RouterKey = ModuleName
|
||||
|
||||
func NewHandler(k Keeper) sdk.Handler {
|
||||
return func(ctx sdk.Context, msg sdk.Msg) sdk.Result {
|
||||
ctx = ctx.WithEventManager(sdk.NewEventManager())
|
||||
|
||||
switch msg := msg.(type) {
|
||||
case types.MsgVerifyInvariant:
|
||||
return handleMsgVerifyInvariant(ctx, msg, k)
|
||||
@ -25,21 +26,23 @@ func NewHandler(k Keeper) sdk.Handler {
|
||||
}
|
||||
|
||||
func handleMsgVerifyInvariant(ctx sdk.Context, msg types.MsgVerifyInvariant, k Keeper) sdk.Result {
|
||||
|
||||
// remove the constant fee
|
||||
constantFee := sdk.NewCoins(k.GetConstantFee(ctx))
|
||||
|
||||
_, err := k.bankKeeper.SubtractCoins(ctx, msg.Sender, constantFee)
|
||||
if err != nil {
|
||||
return err.Result()
|
||||
}
|
||||
|
||||
_ = k.feeCollectionKeeper.AddCollectedFees(ctx, constantFee)
|
||||
|
||||
// use a cached context to avoid gas costs during invariants
|
||||
cacheCtx, _ := ctx.CacheContext()
|
||||
|
||||
found := false
|
||||
var invarianceErr error
|
||||
msgFullRoute := msg.FullInvariantRoute()
|
||||
|
||||
var invarianceErr error
|
||||
for _, invarRoute := range k.routes {
|
||||
if invarRoute.FullRoute() == msgFullRoute {
|
||||
invarianceErr = invarRoute.Invar(cacheCtx)
|
||||
@ -47,12 +50,12 @@ func handleMsgVerifyInvariant(ctx sdk.Context, msg types.MsgVerifyInvariant, k K
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
return types.ErrUnknownInvariant(types.DefaultCodespace).Result()
|
||||
}
|
||||
|
||||
if invarianceErr != nil {
|
||||
|
||||
// NOTE currently, because the chain halts here, this transaction will never be included
|
||||
// in the blockchain thus the constant fee will have never been deducted. Thus no
|
||||
// refund is required.
|
||||
@ -72,11 +75,17 @@ func handleMsgVerifyInvariant(ctx sdk.Context, msg types.MsgVerifyInvariant, k K
|
||||
panic(invarianceErr)
|
||||
}
|
||||
|
||||
resTags := sdk.NewTags(
|
||||
tags.Sender, msg.Sender.String(),
|
||||
tags.Invariant, msg.InvariantRoute,
|
||||
)
|
||||
return sdk.Result{
|
||||
Tags: resTags,
|
||||
}
|
||||
ctx.EventManager().EmitEvents(sdk.Events{
|
||||
sdk.NewEvent(
|
||||
types.EventTypeInvariant,
|
||||
sdk.NewAttribute(types.AttributeKeyRoute, msg.InvariantRoute),
|
||||
),
|
||||
sdk.NewEvent(
|
||||
sdk.EventTypeMessage,
|
||||
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCrisis),
|
||||
sdk.NewAttribute(sdk.AttributeKeySender, msg.Sender.String()),
|
||||
),
|
||||
})
|
||||
|
||||
return sdk.Result{Events: ctx.EventManager().Events()}
|
||||
}
|
||||
|
||||
@ -7,6 +7,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
@ -105,7 +106,7 @@ func TestInvalidMsg(t *testing.T) {
|
||||
k := Keeper{}
|
||||
h := NewHandler(k)
|
||||
|
||||
res := h(sdk.Context{}, sdk.NewTestMsg())
|
||||
res := h(sdk.NewContext(nil, abci.Header{}, false, nil), sdk.NewTestMsg())
|
||||
require.False(t, res.IsOK())
|
||||
require.True(t, strings.Contains(res.Log, "unrecognized crisis message type"))
|
||||
}
|
||||
|
||||
@ -43,7 +43,7 @@ func (AppModuleBasic) DefaultGenesis() json.RawMessage {
|
||||
|
||||
// module validate genesis
|
||||
func (AppModuleBasic) ValidateGenesis(bz json.RawMessage) error {
|
||||
//TODO
|
||||
// TODO
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -116,12 +116,10 @@ func (am AppModule) ExportGenesis(ctx sdk.Context) json.RawMessage {
|
||||
}
|
||||
|
||||
// module begin-block
|
||||
func (AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) sdk.Tags {
|
||||
return sdk.EmptyTags()
|
||||
}
|
||||
func (AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) {}
|
||||
|
||||
// module end-block
|
||||
func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) ([]abci.ValidatorUpdate, sdk.Tags) {
|
||||
func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate {
|
||||
EndBlocker(ctx, am.keeper, am.logger)
|
||||
return []abci.ValidatorUpdate{}, sdk.EmptyTags()
|
||||
return []abci.ValidatorUpdate{}
|
||||
}
|
||||
|
||||
@ -1,11 +0,0 @@
|
||||
package tags
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
// Crisis module tags
|
||||
var (
|
||||
Sender = sdk.TagSender
|
||||
Invariant = "invariant"
|
||||
)
|
||||
9
x/crisis/types/events.go
Normal file
9
x/crisis/types/events.go
Normal file
@ -0,0 +1,9 @@
|
||||
package types
|
||||
|
||||
// Crisis module event types
|
||||
var (
|
||||
EventTypeInvariant = "invariant"
|
||||
|
||||
AttributeValueCrisis = ModuleName
|
||||
AttributeKeyRoute = "route"
|
||||
)
|
||||
@ -10,7 +10,6 @@ import (
|
||||
// set the proposer for determining distribution during endblock
|
||||
// and distribute rewards for the previous block
|
||||
func BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock, k keeper.Keeper) {
|
||||
|
||||
// determine the total power signing the block
|
||||
var previousTotalPower, sumPreviousPrecommitPower int64
|
||||
for _, voteInfo := range req.LastCommitInfo.GetVotes() {
|
||||
@ -30,5 +29,4 @@ func BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock, k keeper.Keeper)
|
||||
// record the proposer for when we payout on the next block
|
||||
consAddr := sdk.ConsAddress(req.Header.ProposerAddress)
|
||||
k.SetPreviousProposerConsAddr(ctx, consAddr)
|
||||
|
||||
}
|
||||
|
||||
@ -8,7 +8,6 @@ package distribution
|
||||
|
||||
import (
|
||||
"github.com/cosmos/cosmos-sdk/x/distribution/keeper"
|
||||
"github.com/cosmos/cosmos-sdk/x/distribution/tags"
|
||||
"github.com/cosmos/cosmos-sdk/x/distribution/types"
|
||||
)
|
||||
|
||||
@ -118,12 +117,10 @@ var (
|
||||
ParamStoreKeyBonusProposerReward = keeper.ParamStoreKeyBonusProposerReward
|
||||
ParamStoreKeyWithdrawAddrEnabled = keeper.ParamStoreKeyWithdrawAddrEnabled
|
||||
TestAddrs = keeper.TestAddrs
|
||||
Rewards = tags.Rewards
|
||||
Commission = tags.Commission
|
||||
TxCategory = tags.TxCategory
|
||||
Validator = tags.Validator
|
||||
Category = tags.Category
|
||||
Sender = tags.Sender
|
||||
EventTypeRewards = types.EventTypeRewards
|
||||
EventTypeCommission = types.EventTypeCommission
|
||||
AttributeValueCategory = types.AttributeValueCategory
|
||||
AttributeKeyValidator = types.AttributeKeyValidator
|
||||
ModuleCdc = types.ModuleCdc
|
||||
)
|
||||
|
||||
|
||||
@ -5,14 +5,14 @@ import (
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/distribution/keeper"
|
||||
"github.com/cosmos/cosmos-sdk/x/distribution/tags"
|
||||
"github.com/cosmos/cosmos-sdk/x/distribution/types"
|
||||
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
|
||||
)
|
||||
|
||||
func NewHandler(k keeper.Keeper) sdk.Handler {
|
||||
return func(ctx sdk.Context, msg sdk.Msg) sdk.Result {
|
||||
// NOTE msg already has validate basic run
|
||||
ctx = ctx.WithEventManager(sdk.NewEventManager())
|
||||
|
||||
switch msg := msg.(type) {
|
||||
case types.MsgSetWithdrawAddress:
|
||||
return handleMsgModifyWithdrawAddress(ctx, msg, k)
|
||||
@ -33,50 +33,54 @@ func NewHandler(k keeper.Keeper) sdk.Handler {
|
||||
// These functions assume everything has been authenticated (ValidateBasic passed, and signatures checked)
|
||||
|
||||
func handleMsgModifyWithdrawAddress(ctx sdk.Context, msg types.MsgSetWithdrawAddress, k keeper.Keeper) sdk.Result {
|
||||
|
||||
err := k.SetWithdrawAddr(ctx, msg.DelegatorAddress, msg.WithdrawAddress)
|
||||
if err != nil {
|
||||
return err.Result()
|
||||
}
|
||||
|
||||
resTags := sdk.NewTags(
|
||||
tags.Category, tags.TxCategory,
|
||||
tags.Sender, msg.DelegatorAddress.String(),
|
||||
ctx.EventManager().EmitEvent(
|
||||
sdk.NewEvent(
|
||||
sdk.EventTypeMessage,
|
||||
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
|
||||
sdk.NewAttribute(sdk.AttributeKeySender, msg.DelegatorAddress.String()),
|
||||
),
|
||||
)
|
||||
return sdk.Result{
|
||||
Tags: resTags,
|
||||
}
|
||||
|
||||
return sdk.Result{Events: ctx.EventManager().Events()}
|
||||
}
|
||||
|
||||
func handleMsgWithdrawDelegatorReward(ctx sdk.Context, msg types.MsgWithdrawDelegatorReward, k keeper.Keeper) sdk.Result {
|
||||
rewards, err := k.WithdrawDelegationRewards(ctx, msg.DelegatorAddress, msg.ValidatorAddress)
|
||||
_, err := k.WithdrawDelegationRewards(ctx, msg.DelegatorAddress, msg.ValidatorAddress)
|
||||
if err != nil {
|
||||
return err.Result()
|
||||
}
|
||||
|
||||
return sdk.Result{
|
||||
Tags: sdk.NewTags(
|
||||
tags.Rewards, rewards.String(),
|
||||
tags.Category, tags.TxCategory,
|
||||
tags.Sender, msg.DelegatorAddress.String(),
|
||||
tags.Validator, msg.ValidatorAddress.String(),
|
||||
ctx.EventManager().EmitEvent(
|
||||
sdk.NewEvent(
|
||||
sdk.EventTypeMessage,
|
||||
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
|
||||
sdk.NewAttribute(sdk.AttributeKeySender, msg.DelegatorAddress.String()),
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
return sdk.Result{Events: ctx.EventManager().Events()}
|
||||
}
|
||||
|
||||
func handleMsgWithdrawValidatorCommission(ctx sdk.Context, msg types.MsgWithdrawValidatorCommission, k keeper.Keeper) sdk.Result {
|
||||
commission, err := k.WithdrawValidatorCommission(ctx, msg.ValidatorAddress)
|
||||
_, err := k.WithdrawValidatorCommission(ctx, msg.ValidatorAddress)
|
||||
if err != nil {
|
||||
return err.Result()
|
||||
}
|
||||
|
||||
return sdk.Result{
|
||||
Tags: sdk.NewTags(
|
||||
tags.Commission, commission.String(),
|
||||
tags.Category, tags.TxCategory,
|
||||
tags.Sender, msg.ValidatorAddress.String(),
|
||||
ctx.EventManager().EmitEvent(
|
||||
sdk.NewEvent(
|
||||
sdk.EventTypeMessage,
|
||||
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
|
||||
sdk.NewAttribute(sdk.AttributeKeySender, msg.ValidatorAddress.String()),
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
return sdk.Result{Events: ctx.EventManager().Events()}
|
||||
}
|
||||
|
||||
func NewCommunityPoolSpendProposalHandler(k Keeper) govtypes.Handler {
|
||||
|
||||
@ -6,12 +6,15 @@ import (
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/distribution/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/staking/exported"
|
||||
)
|
||||
|
||||
// allocate fees handles distribution of the collected fees
|
||||
func (k Keeper) AllocateTokens(ctx sdk.Context, sumPreviousPrecommitPower, totalPreviousPower int64,
|
||||
previousProposer sdk.ConsAddress, previousVotes []abci.VoteInfo) {
|
||||
func (k Keeper) AllocateTokens(
|
||||
ctx sdk.Context, sumPreviousPrecommitPower, totalPreviousPower int64,
|
||||
previousProposer sdk.ConsAddress, previousVotes []abci.VoteInfo,
|
||||
) {
|
||||
|
||||
logger := k.Logger(ctx)
|
||||
|
||||
@ -45,6 +48,14 @@ func (k Keeper) AllocateTokens(ctx sdk.Context, sumPreviousPrecommitPower, total
|
||||
proposerValidator := k.stakingKeeper.ValidatorByConsAddr(ctx, previousProposer)
|
||||
|
||||
if proposerValidator != nil {
|
||||
ctx.EventManager().EmitEvent(
|
||||
sdk.NewEvent(
|
||||
types.EventTypeProposerReward,
|
||||
sdk.NewAttribute(types.AttributeKeyAmount, proposerReward.String()),
|
||||
sdk.NewAttribute(types.AttributeKeyValidator, proposerValidator.GetOperator().String()),
|
||||
),
|
||||
)
|
||||
|
||||
k.AllocateTokensToValidator(ctx, proposerValidator, proposerReward)
|
||||
remaining = remaining.Sub(proposerReward)
|
||||
} else {
|
||||
@ -80,17 +91,22 @@ func (k Keeper) AllocateTokens(ctx sdk.Context, sumPreviousPrecommitPower, total
|
||||
// allocate community funding
|
||||
feePool.CommunityPool = feePool.CommunityPool.Add(remaining)
|
||||
k.SetFeePool(ctx, feePool)
|
||||
|
||||
}
|
||||
|
||||
// AllocateTokensToValidator allocate tokens to a particular validator, splitting according to commission
|
||||
func (k Keeper) AllocateTokensToValidator(ctx sdk.Context, val exported.ValidatorI, tokens sdk.DecCoins) {
|
||||
|
||||
// split tokens between validator and delegators according to commission
|
||||
commission := tokens.MulDec(val.GetCommission())
|
||||
shared := tokens.Sub(commission)
|
||||
|
||||
// update current commission
|
||||
ctx.EventManager().EmitEvent(
|
||||
sdk.NewEvent(
|
||||
types.EventTypeCommission,
|
||||
sdk.NewAttribute(types.AttributeKeyAmount, commission.String()),
|
||||
sdk.NewAttribute(types.AttributeKeyValidator, val.GetOperator().String()),
|
||||
),
|
||||
)
|
||||
currentCommission := k.GetValidatorAccumulatedCommission(ctx, val.GetOperator())
|
||||
currentCommission = currentCommission.Add(commission)
|
||||
k.SetValidatorAccumulatedCommission(ctx, val.GetOperator(), currentCommission)
|
||||
@ -101,6 +117,13 @@ func (k Keeper) AllocateTokensToValidator(ctx sdk.Context, val exported.Validato
|
||||
k.SetValidatorCurrentRewards(ctx, val.GetOperator(), currentRewards)
|
||||
|
||||
// update outstanding rewards
|
||||
ctx.EventManager().EmitEvent(
|
||||
sdk.NewEvent(
|
||||
types.EventTypeRewards,
|
||||
sdk.NewAttribute(types.AttributeKeyAmount, tokens.String()),
|
||||
sdk.NewAttribute(types.AttributeKeyValidator, val.GetOperator().String()),
|
||||
),
|
||||
)
|
||||
outstanding := k.GetValidatorOutstandingRewards(ctx, val.GetOperator())
|
||||
outstanding = outstanding.Add(tokens)
|
||||
k.SetValidatorOutstandingRewards(ctx, val.GetOperator(), outstanding)
|
||||
|
||||
@ -46,8 +46,14 @@ func (k Keeper) SetWithdrawAddr(ctx sdk.Context, delegatorAddr sdk.AccAddress, w
|
||||
return types.ErrSetWithdrawAddrDisabled(k.codespace)
|
||||
}
|
||||
|
||||
k.SetDelegatorWithdrawAddr(ctx, delegatorAddr, withdrawAddr)
|
||||
ctx.EventManager().EmitEvent(
|
||||
sdk.NewEvent(
|
||||
types.EventTypeSetWithdrawAddress,
|
||||
sdk.NewAttribute(types.AttributeKeyWithdrawAddress, withdrawAddr.String()),
|
||||
),
|
||||
)
|
||||
|
||||
k.SetDelegatorWithdrawAddr(ctx, delegatorAddr, withdrawAddr)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -69,35 +75,49 @@ func (k Keeper) WithdrawDelegationRewards(ctx sdk.Context, delAddr sdk.AccAddres
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ctx.EventManager().EmitEvent(
|
||||
sdk.NewEvent(
|
||||
types.EventTypeWithdrawRewards,
|
||||
sdk.NewAttribute(types.AttributeKeyAmount, rewards.String()),
|
||||
sdk.NewAttribute(types.AttributeKeyValidator, valAddr.String()),
|
||||
),
|
||||
)
|
||||
|
||||
// reinitialize the delegation
|
||||
k.initializeDelegation(ctx, valAddr, delAddr)
|
||||
|
||||
return rewards, nil
|
||||
}
|
||||
|
||||
// withdraw validator commission
|
||||
func (k Keeper) WithdrawValidatorCommission(ctx sdk.Context, valAddr sdk.ValAddress) (sdk.Coins, sdk.Error) {
|
||||
// fetch validator accumulated commission
|
||||
commission := k.GetValidatorAccumulatedCommission(ctx, valAddr)
|
||||
if commission.IsZero() {
|
||||
accumCommission := k.GetValidatorAccumulatedCommission(ctx, valAddr)
|
||||
if accumCommission.IsZero() {
|
||||
return nil, types.ErrNoValidatorCommission(k.codespace)
|
||||
}
|
||||
|
||||
coins, remainder := commission.TruncateDecimal()
|
||||
commission, remainder := accumCommission.TruncateDecimal()
|
||||
k.SetValidatorAccumulatedCommission(ctx, valAddr, remainder) // leave remainder to withdraw later
|
||||
|
||||
// update outstanding
|
||||
outstanding := k.GetValidatorOutstandingRewards(ctx, valAddr)
|
||||
k.SetValidatorOutstandingRewards(ctx, valAddr, outstanding.Sub(sdk.NewDecCoins(coins)))
|
||||
k.SetValidatorOutstandingRewards(ctx, valAddr, outstanding.Sub(sdk.NewDecCoins(commission)))
|
||||
|
||||
if !coins.IsZero() {
|
||||
if !commission.IsZero() {
|
||||
accAddr := sdk.AccAddress(valAddr)
|
||||
withdrawAddr := k.GetDelegatorWithdrawAddr(ctx, accAddr)
|
||||
|
||||
if _, err := k.bankKeeper.AddCoins(ctx, withdrawAddr, coins); err != nil {
|
||||
if _, err := k.bankKeeper.AddCoins(ctx, withdrawAddr, commission); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return coins, nil
|
||||
ctx.EventManager().EmitEvent(
|
||||
sdk.NewEvent(
|
||||
types.EventTypeWithdrawCommission,
|
||||
sdk.NewAttribute(types.AttributeKeyAmount, commission.String()),
|
||||
),
|
||||
)
|
||||
|
||||
return commission, nil
|
||||
}
|
||||
|
||||
@ -123,12 +123,11 @@ func (am AppModule) ExportGenesis(ctx sdk.Context) json.RawMessage {
|
||||
}
|
||||
|
||||
// module begin-block
|
||||
func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) sdk.Tags {
|
||||
func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) {
|
||||
BeginBlocker(ctx, req, am.keeper)
|
||||
return sdk.EmptyTags()
|
||||
}
|
||||
|
||||
// module end-block
|
||||
func (AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) ([]abci.ValidatorUpdate, sdk.Tags) {
|
||||
return []abci.ValidatorUpdate{}, sdk.EmptyTags()
|
||||
func (AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate {
|
||||
return []abci.ValidatorUpdate{}
|
||||
}
|
||||
|
||||
@ -1,16 +0,0 @@
|
||||
package tags
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
// Distribution tx tags
|
||||
var (
|
||||
Rewards = "rewards"
|
||||
Commission = "commission"
|
||||
TxCategory = "distribution"
|
||||
|
||||
Validator = sdk.TagSrcValidator
|
||||
Category = sdk.TagCategory
|
||||
Sender = sdk.TagSender
|
||||
)
|
||||
17
x/distribution/types/events.go
Normal file
17
x/distribution/types/events.go
Normal file
@ -0,0 +1,17 @@
|
||||
package types
|
||||
|
||||
// Distribution module event types
|
||||
var (
|
||||
EventTypeSetWithdrawAddress = "set_withdraw_address"
|
||||
EventTypeRewards = "rewards"
|
||||
EventTypeCommission = "commission"
|
||||
EventTypeWithdrawRewards = "withdraw_rewards"
|
||||
EventTypeWithdrawCommission = "withdraw_commission"
|
||||
EventTypeProposerReward = "proposer_reward"
|
||||
|
||||
AttributeKeyWithdrawAddress = "withdraw_address"
|
||||
AttributeKeyAmount = "amount"
|
||||
AttributeKeyValidator = "validator"
|
||||
|
||||
AttributeValueCategory = ModuleName
|
||||
)
|
||||
@ -66,7 +66,7 @@ func ValidateAccountInGenesis(appGenesisState map[string]json.RawMessage,
|
||||
return nil
|
||||
}
|
||||
|
||||
type deliverTxfn func([]byte) abci.ResponseDeliverTx
|
||||
type deliverTxfn func(abci.RequestDeliverTx) abci.ResponseDeliverTx
|
||||
|
||||
// deliver a genesis transaction
|
||||
func DeliverGenTxs(ctx sdk.Context, cdc *codec.Codec, genTxs []json.RawMessage,
|
||||
@ -76,7 +76,7 @@ func DeliverGenTxs(ctx sdk.Context, cdc *codec.Codec, genTxs []json.RawMessage,
|
||||
var tx auth.StdTx
|
||||
cdc.MustUnmarshalJSON(genTx, &tx)
|
||||
bz := cdc.MustMarshalBinaryLengthPrefixed(tx)
|
||||
res := deliverTx(bz)
|
||||
res := deliverTx(abci.RequestDeliverTx{Tx: bz})
|
||||
if !res.IsOK() {
|
||||
panic(res.Log)
|
||||
}
|
||||
|
||||
@ -4,8 +4,8 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/context"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/client/utils"
|
||||
"github.com/cosmos/cosmos-sdk/x/gov/tags"
|
||||
"github.com/cosmos/cosmos-sdk/x/gov/types"
|
||||
)
|
||||
|
||||
@ -37,14 +37,14 @@ func (p Proposer) String() string {
|
||||
// NOTE: SearchTxs is used to facilitate the txs query which does not currently
|
||||
// support configurable pagination.
|
||||
func QueryDepositsByTxQuery(cliCtx context.CLIContext, params types.QueryProposalParams) ([]byte, error) {
|
||||
tags := []string{
|
||||
fmt.Sprintf("%s='%s'", tags.Action, types.MsgDeposit{}.Type()),
|
||||
fmt.Sprintf("%s='%s'", tags.ProposalID, []byte(fmt.Sprintf("%d", params.ProposalID))),
|
||||
events := []string{
|
||||
fmt.Sprintf("%s.%s='%s'", sdk.EventTypeMessage, sdk.AttributeKeyAction, types.TypeMsgDeposit),
|
||||
fmt.Sprintf("%s.%s='%s'", types.EventTypeProposalDeposit, types.AttributeKeyProposalID, []byte(fmt.Sprintf("%d", params.ProposalID))),
|
||||
}
|
||||
|
||||
// NOTE: SearchTxs is used to facilitate the txs query which does not currently
|
||||
// support configurable pagination.
|
||||
searchResult, err := utils.QueryTxsByTags(cliCtx, tags, defaultPage, defaultLimit)
|
||||
searchResult, err := utils.QueryTxsByTags(cliCtx, events, defaultPage, defaultLimit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -79,14 +79,14 @@ func QueryDepositsByTxQuery(cliCtx context.CLIContext, params types.QueryProposa
|
||||
// NOTE: SearchTxs is used to facilitate the txs query which does not currently
|
||||
// support configurable pagination.
|
||||
func QueryVotesByTxQuery(cliCtx context.CLIContext, params types.QueryProposalParams) ([]byte, error) {
|
||||
tags := []string{
|
||||
fmt.Sprintf("%s='%s'", tags.Action, types.MsgVote{}.Type()),
|
||||
fmt.Sprintf("%s='%s'", tags.ProposalID, []byte(fmt.Sprintf("%d", params.ProposalID))),
|
||||
events := []string{
|
||||
fmt.Sprintf("%s.%s='%s'", sdk.EventTypeMessage, sdk.AttributeKeyAction, types.TypeMsgVote),
|
||||
fmt.Sprintf("%s.%s='%s'", types.EventTypeProposalVote, types.AttributeKeyProposalID, []byte(fmt.Sprintf("%d", params.ProposalID))),
|
||||
}
|
||||
|
||||
// NOTE: SearchTxs is used to facilitate the txs query which does not currently
|
||||
// support configurable pagination.
|
||||
searchResult, err := utils.QueryTxsByTags(cliCtx, tags, defaultPage, defaultLimit)
|
||||
searchResult, err := utils.QueryTxsByTags(cliCtx, events, defaultPage, defaultLimit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -116,15 +116,15 @@ func QueryVotesByTxQuery(cliCtx context.CLIContext, params types.QueryProposalPa
|
||||
|
||||
// QueryVoteByTxQuery will query for a single vote via a direct txs tags query.
|
||||
func QueryVoteByTxQuery(cliCtx context.CLIContext, params types.QueryVoteParams) ([]byte, error) {
|
||||
tags := []string{
|
||||
fmt.Sprintf("%s='%s'", tags.Action, types.MsgVote{}.Type()),
|
||||
fmt.Sprintf("%s='%s'", tags.ProposalID, []byte(fmt.Sprintf("%d", params.ProposalID))),
|
||||
fmt.Sprintf("%s='%s'", tags.Sender, []byte(params.Voter.String())),
|
||||
events := []string{
|
||||
fmt.Sprintf("%s.%s='%s'", sdk.EventTypeMessage, sdk.AttributeKeyAction, types.TypeMsgVote),
|
||||
fmt.Sprintf("%s.%s='%s'", types.EventTypeProposalVote, types.AttributeKeyProposalID, []byte(fmt.Sprintf("%d", params.ProposalID))),
|
||||
fmt.Sprintf("%s.%s='%s'", sdk.EventTypeMessage, sdk.AttributeKeySender, []byte(params.Voter.String())),
|
||||
}
|
||||
|
||||
// NOTE: SearchTxs is used to facilitate the txs query which does not currently
|
||||
// support configurable pagination.
|
||||
searchResult, err := utils.QueryTxsByTags(cliCtx, tags, defaultPage, defaultLimit)
|
||||
searchResult, err := utils.QueryTxsByTags(cliCtx, events, defaultPage, defaultLimit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -156,15 +156,15 @@ func QueryVoteByTxQuery(cliCtx context.CLIContext, params types.QueryVoteParams)
|
||||
// QueryDepositByTxQuery will query for a single deposit via a direct txs tags
|
||||
// query.
|
||||
func QueryDepositByTxQuery(cliCtx context.CLIContext, params types.QueryDepositParams) ([]byte, error) {
|
||||
tags := []string{
|
||||
fmt.Sprintf("%s='%s'", tags.Action, types.MsgDeposit{}.Type()),
|
||||
fmt.Sprintf("%s='%s'", tags.ProposalID, []byte(fmt.Sprintf("%d", params.ProposalID))),
|
||||
fmt.Sprintf("%s='%s'", tags.Sender, []byte(params.Depositor.String())),
|
||||
events := []string{
|
||||
fmt.Sprintf("%s.%s='%s'", sdk.EventTypeMessage, sdk.AttributeKeyAction, types.TypeMsgDeposit),
|
||||
fmt.Sprintf("%s.%s='%s'", types.EventTypeProposalDeposit, types.AttributeKeyProposalID, []byte(fmt.Sprintf("%d", params.ProposalID))),
|
||||
fmt.Sprintf("%s.%s='%s'", sdk.EventTypeMessage, sdk.AttributeKeySender, []byte(params.Depositor.String())),
|
||||
}
|
||||
|
||||
// NOTE: SearchTxs is used to facilitate the txs query which does not currently
|
||||
// support configurable pagination.
|
||||
searchResult, err := utils.QueryTxsByTags(cliCtx, tags, defaultPage, defaultLimit)
|
||||
searchResult, err := utils.QueryTxsByTags(cliCtx, events, defaultPage, defaultLimit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -196,14 +196,14 @@ func QueryDepositByTxQuery(cliCtx context.CLIContext, params types.QueryDepositP
|
||||
// QueryProposerByTxQuery will query for a proposer of a governance proposal by
|
||||
// ID.
|
||||
func QueryProposerByTxQuery(cliCtx context.CLIContext, proposalID uint64) (Proposer, error) {
|
||||
tags := []string{
|
||||
fmt.Sprintf("%s='%s'", tags.Action, types.MsgSubmitProposal{}.Type()),
|
||||
fmt.Sprintf("%s='%s'", tags.ProposalID, []byte(fmt.Sprintf("%d", proposalID))),
|
||||
events := []string{
|
||||
fmt.Sprintf("%s.%s='%s'", sdk.EventTypeMessage, sdk.AttributeKeyAction, types.TypeMsgSubmitProposal),
|
||||
fmt.Sprintf("%s.%s='%s'", types.EventTypeSubmitProposal, types.AttributeKeyProposalID, []byte(fmt.Sprintf("%d", proposalID))),
|
||||
}
|
||||
|
||||
// NOTE: SearchTxs is used to facilitate the txs query which does not currently
|
||||
// support configurable pagination.
|
||||
searchResult, err := utils.QueryTxsByTags(cliCtx, tags, defaultPage, defaultLimit)
|
||||
searchResult, err := utils.QueryTxsByTags(cliCtx, events, defaultPage, defaultLimit)
|
||||
if err != nil {
|
||||
return Proposer{}, err
|
||||
}
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
package gov
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/gov/types"
|
||||
)
|
||||
@ -63,8 +65,15 @@ func (keeper Keeper) AddDeposit(ctx sdk.Context, proposalID uint64, depositorAdd
|
||||
deposit = NewDeposit(proposalID, depositorAddr, depositAmount)
|
||||
}
|
||||
|
||||
keeper.setDeposit(ctx, proposalID, depositorAddr, deposit)
|
||||
ctx.EventManager().EmitEvent(
|
||||
sdk.NewEvent(
|
||||
types.EventTypeProposalDeposit,
|
||||
sdk.NewAttribute(types.AttributeKeyAmount, depositAmount.String()),
|
||||
sdk.NewAttribute(types.AttributeKeyProposalID, fmt.Sprintf("%d", proposalID)),
|
||||
),
|
||||
)
|
||||
|
||||
keeper.setDeposit(ctx, proposalID, depositorAddr, deposit)
|
||||
return nil, activatedVotingPeriod
|
||||
}
|
||||
|
||||
|
||||
@ -4,21 +4,25 @@ import (
|
||||
"fmt"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/gov/tags"
|
||||
"github.com/cosmos/cosmos-sdk/x/gov/types"
|
||||
)
|
||||
|
||||
// EndBlocker called every block, process inflation, update validator set
|
||||
func EndBlocker(ctx sdk.Context, keeper Keeper) sdk.Tags {
|
||||
// EndBlocker called every block, process inflation, update validator set.
|
||||
func EndBlocker(ctx sdk.Context, keeper Keeper) {
|
||||
logger := keeper.Logger(ctx)
|
||||
resTags := sdk.NewTags()
|
||||
|
||||
// delete inactive proposal from store and its deposits
|
||||
keeper.IterateInactiveProposalsQueue(ctx, ctx.BlockHeader().Time, func(proposal Proposal) bool {
|
||||
keeper.DeleteProposal(ctx, proposal.ProposalID)
|
||||
keeper.DeleteDeposits(ctx, proposal.ProposalID)
|
||||
|
||||
resTags = resTags.AppendTag(tags.ProposalID, fmt.Sprintf("%d", proposal.ProposalID))
|
||||
resTags = resTags.AppendTag(tags.ProposalResult, tags.ActionProposalDropped)
|
||||
ctx.EventManager().EmitEvent(
|
||||
sdk.NewEvent(
|
||||
types.EventTypeInactiveProposal,
|
||||
sdk.NewAttribute(types.AttributeKeyProposalID, fmt.Sprintf("%d", proposal.ProposalID)),
|
||||
sdk.NewAttribute(types.AttributeKeyProposalResult, types.AttributeValueProposalDropped),
|
||||
),
|
||||
)
|
||||
|
||||
logger.Info(
|
||||
fmt.Sprintf("proposal %d (%s) didn't meet minimum deposit of %s (had only %s); deleted",
|
||||
@ -53,19 +57,19 @@ func EndBlocker(ctx sdk.Context, keeper Keeper) sdk.Tags {
|
||||
err := handler(cacheCtx, proposal.Content)
|
||||
if err == nil {
|
||||
proposal.Status = StatusPassed
|
||||
tagValue = tags.ActionProposalPassed
|
||||
tagValue = types.AttributeValueProposalPassed
|
||||
logMsg = "passed"
|
||||
|
||||
// write state to the underlying multi-store
|
||||
writeCache()
|
||||
} else {
|
||||
proposal.Status = StatusFailed
|
||||
tagValue = tags.ActionProposalFailed
|
||||
tagValue = types.AttributeValueProposalFailed
|
||||
logMsg = fmt.Sprintf("passed, but failed on execution: %s", err.ABCILog())
|
||||
}
|
||||
} else {
|
||||
proposal.Status = StatusRejected
|
||||
tagValue = tags.ActionProposalRejected
|
||||
tagValue = types.AttributeValueProposalRejected
|
||||
logMsg = "rejected"
|
||||
}
|
||||
|
||||
@ -81,11 +85,13 @@ func EndBlocker(ctx sdk.Context, keeper Keeper) sdk.Tags {
|
||||
),
|
||||
)
|
||||
|
||||
resTags = resTags.AppendTag(tags.ProposalID, fmt.Sprintf("%d", proposal.ProposalID))
|
||||
resTags = resTags.AppendTag(tags.ProposalResult, tagValue)
|
||||
|
||||
ctx.EventManager().EmitEvent(
|
||||
sdk.NewEvent(
|
||||
types.EventTypeActiveProposal,
|
||||
sdk.NewAttribute(types.AttributeKeyProposalID, fmt.Sprintf("%d", proposal.ProposalID)),
|
||||
sdk.NewAttribute(types.AttributeKeyProposalResult, tagValue),
|
||||
),
|
||||
)
|
||||
return false
|
||||
})
|
||||
|
||||
return resTags
|
||||
}
|
||||
|
||||
@ -9,7 +9,6 @@ import (
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/gov/tags"
|
||||
"github.com/cosmos/cosmos-sdk/x/staking"
|
||||
)
|
||||
|
||||
@ -276,8 +275,7 @@ func TestProposalPassedEndblocker(t *testing.T) {
|
||||
newHeader.Time = ctx.BlockHeader().Time.Add(input.keeper.GetDepositParams(ctx).MaxDepositPeriod).Add(input.keeper.GetVotingParams(ctx).VotingPeriod)
|
||||
ctx = ctx.WithBlockHeader(newHeader)
|
||||
|
||||
resTags := EndBlocker(ctx, input.keeper)
|
||||
require.Equal(t, sdk.MakeTag(tags.ProposalResult, tags.ActionProposalPassed), resTags[1])
|
||||
EndBlocker(ctx, input.keeper)
|
||||
}
|
||||
|
||||
func TestEndBlockerProposalHandlerFailed(t *testing.T) {
|
||||
@ -323,6 +321,5 @@ func TestEndBlockerProposalHandlerFailed(t *testing.T) {
|
||||
ctx = ctx.WithValue(contextKeyBadProposal, false)
|
||||
|
||||
// validate that the proposal fails/has been rejected
|
||||
resTags := EndBlocker(ctx, input.keeper)
|
||||
require.Equal(t, sdk.MakeTag(tags.ProposalResult, tags.ActionProposalFailed), resTags[1])
|
||||
EndBlocker(ctx, input.keeper)
|
||||
}
|
||||
|
||||
@ -4,12 +4,14 @@ import (
|
||||
"fmt"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/gov/tags"
|
||||
"github.com/cosmos/cosmos-sdk/x/gov/types"
|
||||
)
|
||||
|
||||
// Handle all "gov" type messages.
|
||||
func NewHandler(keeper Keeper) sdk.Handler {
|
||||
return func(ctx sdk.Context, msg sdk.Msg) sdk.Result {
|
||||
ctx = ctx.WithEventManager(sdk.NewEventManager())
|
||||
|
||||
switch msg := msg.(type) {
|
||||
case MsgDeposit:
|
||||
return handleMsgDeposit(ctx, keeper, msg)
|
||||
@ -38,20 +40,26 @@ func handleMsgSubmitProposal(ctx sdk.Context, keeper Keeper, msg MsgSubmitPropos
|
||||
return err.Result()
|
||||
}
|
||||
|
||||
proposalIDStr := fmt.Sprintf("%d", proposal.ProposalID)
|
||||
resTags := sdk.NewTags(
|
||||
tags.ProposalID, proposalIDStr,
|
||||
tags.Category, tags.TxCategory,
|
||||
tags.Sender, msg.Proposer.String(),
|
||||
ctx.EventManager().EmitEvent(
|
||||
sdk.NewEvent(
|
||||
sdk.EventTypeMessage,
|
||||
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
|
||||
sdk.NewAttribute(sdk.AttributeKeySender, msg.Proposer.String()),
|
||||
),
|
||||
)
|
||||
|
||||
if votingStarted {
|
||||
resTags = resTags.AppendTag(tags.VotingPeriodStart, proposalIDStr)
|
||||
ctx.EventManager().EmitEvent(
|
||||
sdk.NewEvent(
|
||||
types.EventTypeSubmitProposal,
|
||||
sdk.NewAttribute(types.AttributeKeyVotingPeriodStart, fmt.Sprintf("%d", proposal.ProposalID)),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
return sdk.Result{
|
||||
Data: keeper.cdc.MustMarshalBinaryLengthPrefixed(proposal.ProposalID),
|
||||
Tags: resTags,
|
||||
Data: keeper.cdc.MustMarshalBinaryLengthPrefixed(proposal.ProposalID),
|
||||
Events: ctx.EventManager().Events(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -61,21 +69,24 @@ func handleMsgDeposit(ctx sdk.Context, keeper Keeper, msg MsgDeposit) sdk.Result
|
||||
return err.Result()
|
||||
}
|
||||
|
||||
proposalIDStr := fmt.Sprintf("%d", msg.ProposalID)
|
||||
|
||||
resTags := sdk.NewTags(
|
||||
tags.ProposalID, proposalIDStr,
|
||||
tags.Category, tags.TxCategory,
|
||||
tags.Sender, msg.Depositor.String(),
|
||||
ctx.EventManager().EmitEvent(
|
||||
sdk.NewEvent(
|
||||
sdk.EventTypeMessage,
|
||||
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
|
||||
sdk.NewAttribute(sdk.AttributeKeySender, msg.Depositor.String()),
|
||||
),
|
||||
)
|
||||
|
||||
if votingStarted {
|
||||
resTags = resTags.AppendTag(tags.VotingPeriodStart, proposalIDStr)
|
||||
ctx.EventManager().EmitEvent(
|
||||
sdk.NewEvent(
|
||||
types.EventTypeProposalDeposit,
|
||||
sdk.NewAttribute(types.AttributeKeyVotingPeriodStart, fmt.Sprintf("%d", msg.ProposalID)),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
return sdk.Result{
|
||||
Tags: resTags,
|
||||
}
|
||||
return sdk.Result{Events: ctx.EventManager().Events()}
|
||||
}
|
||||
|
||||
func handleMsgVote(ctx sdk.Context, keeper Keeper, msg MsgVote) sdk.Result {
|
||||
@ -84,13 +95,14 @@ func handleMsgVote(ctx sdk.Context, keeper Keeper, msg MsgVote) sdk.Result {
|
||||
return err.Result()
|
||||
}
|
||||
|
||||
proposalIDStr := fmt.Sprintf("%d", msg.ProposalID)
|
||||
|
||||
return sdk.Result{
|
||||
Tags: sdk.NewTags(
|
||||
tags.ProposalID, proposalIDStr,
|
||||
tags.Category, tags.TxCategory,
|
||||
tags.Sender, msg.Voter.String(),
|
||||
ctx.EventManager().EmitEvent(
|
||||
sdk.NewEvent(
|
||||
sdk.EventTypeMessage,
|
||||
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
|
||||
sdk.NewAttribute(sdk.AttributeKeySender, msg.Voter.String()),
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
return sdk.Result{Events: ctx.EventManager().Events()}
|
||||
|
||||
}
|
||||
|
||||
@ -5,6 +5,7 @@ import (
|
||||
"testing"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
@ -13,7 +14,7 @@ func TestInvalidMsg(t *testing.T) {
|
||||
k := Keeper{}
|
||||
h := NewHandler(k)
|
||||
|
||||
res := h(sdk.Context{}, sdk.NewTestMsg())
|
||||
res := h(sdk.NewContext(nil, abci.Header{}, false, nil), sdk.NewTestMsg())
|
||||
require.False(t, res.IsOK())
|
||||
require.True(t, strings.Contains(res.Log, "unrecognized gov message type"))
|
||||
}
|
||||
|
||||
@ -146,12 +146,10 @@ func (am AppModule) ExportGenesis(ctx sdk.Context) json.RawMessage {
|
||||
}
|
||||
|
||||
// module begin-block
|
||||
func (AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) sdk.Tags {
|
||||
return sdk.EmptyTags()
|
||||
}
|
||||
func (AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) {}
|
||||
|
||||
// module end-block
|
||||
func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) ([]abci.ValidatorUpdate, sdk.Tags) {
|
||||
tags := EndBlocker(ctx, am.keeper)
|
||||
return []abci.ValidatorUpdate{}, tags
|
||||
func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate {
|
||||
EndBlocker(ctx, am.keeper)
|
||||
return []abci.ValidatorUpdate{}
|
||||
}
|
||||
|
||||
@ -36,6 +36,13 @@ func (keeper Keeper) SubmitProposal(ctx sdk.Context, content Content) (Proposal,
|
||||
keeper.InsertInactiveProposalQueue(ctx, proposalID, proposal.DepositEndTime)
|
||||
keeper.setProposalID(ctx, proposalID+1)
|
||||
|
||||
ctx.EventManager().EmitEvent(
|
||||
sdk.NewEvent(
|
||||
types.EventTypeSubmitProposal,
|
||||
sdk.NewAttribute(types.AttributeKeyProposalID, fmt.Sprintf("%d", proposalID)),
|
||||
),
|
||||
)
|
||||
|
||||
return proposal, nil
|
||||
}
|
||||
|
||||
|
||||
@ -1,25 +0,0 @@
|
||||
package tags
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
// Governance tags
|
||||
const (
|
||||
ActionProposalDropped = "proposal-dropped" // didn't meet min deposit
|
||||
ActionProposalPassed = "proposal-passed" // meet vote quorum
|
||||
ActionProposalRejected = "proposal-rejected" // didn't meet vote quorum
|
||||
ActionProposalFailed = "proposal-failed" // error on proposal handler
|
||||
TxCategory = "governance"
|
||||
|
||||
ProposalID = "proposal-id"
|
||||
VotingPeriodStart = "voting-period-start"
|
||||
ProposalResult = "proposal-result"
|
||||
)
|
||||
|
||||
// SDK tag aliases
|
||||
var (
|
||||
Action = sdk.TagAction
|
||||
Category = sdk.TagCategory
|
||||
Sender = sdk.TagSender
|
||||
)
|
||||
@ -80,10 +80,8 @@ func getMockApp(t *testing.T, numGenAccs int, genState GenesisState, genAccs []a
|
||||
// gov and staking endblocker
|
||||
func getEndBlocker(keeper Keeper) sdk.EndBlocker {
|
||||
return func(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock {
|
||||
tags := EndBlocker(ctx, keeper)
|
||||
return abci.ResponseEndBlock{
|
||||
Tags: tags,
|
||||
}
|
||||
EndBlocker(ctx, keeper)
|
||||
return abci.ResponseEndBlock{}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
21
x/gov/types/events.go
Normal file
21
x/gov/types/events.go
Normal file
@ -0,0 +1,21 @@
|
||||
package types
|
||||
|
||||
// Governance module event types
|
||||
const (
|
||||
EventTypeSubmitProposal = "submit_proposal"
|
||||
EventTypeProposalDeposit = "proposal_deposit"
|
||||
EventTypeProposalVote = "proposal_vote"
|
||||
EventTypeInactiveProposal = "inactive_proposal"
|
||||
EventTypeActiveProposal = "active_proposal"
|
||||
|
||||
AttributeKeyProposalResult = "proposal_result"
|
||||
AttributeKeyAmount = "amount"
|
||||
AttributeKeyOption = "option"
|
||||
AttributeKeyProposalID = "proposal_id"
|
||||
AttributeKeyVotingPeriodStart = "voting_period_start"
|
||||
AttributeValueCategory = "governance"
|
||||
AttributeValueProposalDropped = "proposal_dropped" // didn't meet min deposit
|
||||
AttributeValueProposalPassed = "proposal_passed" // met vote quorum
|
||||
AttributeValueProposalRejected = "proposal_rejected" // didn't meet vote quorum
|
||||
AttributeValueProposalFailed = "proposal_failed" // error on proposal handler
|
||||
)
|
||||
@ -1,6 +1,8 @@
|
||||
package gov
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/gov/types"
|
||||
)
|
||||
@ -22,6 +24,14 @@ func (keeper Keeper) AddVote(ctx sdk.Context, proposalID uint64, voterAddr sdk.A
|
||||
vote := NewVote(proposalID, voterAddr, option)
|
||||
keeper.setVote(ctx, proposalID, voterAddr, vote)
|
||||
|
||||
ctx.EventManager().EmitEvent(
|
||||
sdk.NewEvent(
|
||||
types.EventTypeProposalVote,
|
||||
sdk.NewAttribute(types.AttributeKeyOption, option.String()),
|
||||
sdk.NewAttribute(types.AttributeKeyProposalID, fmt.Sprintf("%d", proposalID)),
|
||||
),
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@ -2,6 +2,7 @@ package mint
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/mint/internal/types"
|
||||
)
|
||||
|
||||
// BeginBlocker mints new tokens for the previous block.
|
||||
@ -21,4 +22,14 @@ func BeginBlocker(ctx sdk.Context, k Keeper) {
|
||||
mintedCoin := minter.BlockProvision(params)
|
||||
k.AddCollectedFees(ctx, sdk.Coins{mintedCoin})
|
||||
k.InflateSupply(ctx, mintedCoin.Amount)
|
||||
|
||||
ctx.EventManager().EmitEvent(
|
||||
sdk.NewEvent(
|
||||
types.EventTypeMint,
|
||||
sdk.NewAttribute(types.AttributeKeyBondedRatio, bondedRatio.String()),
|
||||
sdk.NewAttribute(types.AttributeKeyInflation, minter.Inflation.String()),
|
||||
sdk.NewAttribute(types.AttributeKeyAnnualProvisions, minter.AnnualProvisions.String()),
|
||||
sdk.NewAttribute(types.AttributeKeyAmount, mintedCoin.Amount.String()),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
11
x/mint/internal/types/events.go
Normal file
11
x/mint/internal/types/events.go
Normal file
@ -0,0 +1,11 @@
|
||||
package types
|
||||
|
||||
// Minting module event types
|
||||
const (
|
||||
EventTypeMint = ModuleName
|
||||
|
||||
AttributeKeyBondedRatio = "bonded_ratio"
|
||||
AttributeKeyInflation = "inflation"
|
||||
AttributeKeyAnnualProvisions = "annual_provisions"
|
||||
AttributeKeyAmount = "amount"
|
||||
)
|
||||
@ -116,12 +116,11 @@ func (am AppModule) ExportGenesis(ctx sdk.Context) json.RawMessage {
|
||||
}
|
||||
|
||||
// module begin-block
|
||||
func (am AppModule) BeginBlock(ctx sdk.Context, _ abci.RequestBeginBlock) sdk.Tags {
|
||||
func (am AppModule) BeginBlock(ctx sdk.Context, _ abci.RequestBeginBlock) {
|
||||
BeginBlocker(ctx, am.keeper)
|
||||
return sdk.EmptyTags()
|
||||
}
|
||||
|
||||
// module end-block
|
||||
func (AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) ([]abci.ValidatorUpdate, sdk.Tags) {
|
||||
return []abci.ValidatorUpdate{}, sdk.EmptyTags()
|
||||
func (AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate {
|
||||
return []abci.ValidatorUpdate{}
|
||||
}
|
||||
|
||||
@ -10,8 +10,7 @@ import (
|
||||
)
|
||||
|
||||
// slashing begin block functionality
|
||||
func BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock, sk Keeper) sdk.Tags {
|
||||
|
||||
func BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock, sk Keeper) {
|
||||
// Iterate over all the validators which *should* have signed this block
|
||||
// store whether or not they have actually signed it and slash/unbond any
|
||||
// which have missed too many blocks in a row (downtime slashing)
|
||||
@ -30,6 +29,4 @@ func BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock, sk Keeper) sdk.Ta
|
||||
sk.Logger(ctx).Error(fmt.Sprintf("ignored unknown evidence type: %s", evidence.Type))
|
||||
}
|
||||
}
|
||||
|
||||
return sdk.EmptyTags()
|
||||
}
|
||||
|
||||
@ -49,10 +49,9 @@ func getMockApp(t *testing.T) (*mock.App, staking.Keeper, Keeper) {
|
||||
// staking endblocker
|
||||
func getEndBlocker(keeper staking.Keeper) sdk.EndBlocker {
|
||||
return func(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock {
|
||||
validatorUpdates, tags := staking.EndBlocker(ctx, keeper)
|
||||
validatorUpdates := staking.EndBlocker(ctx, keeper)
|
||||
return abci.ResponseEndBlock{
|
||||
ValidatorUpdates: validatorUpdates,
|
||||
Tags: tags,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,12 +4,13 @@ import (
|
||||
"fmt"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/slashing/tags"
|
||||
"github.com/cosmos/cosmos-sdk/x/slashing/types"
|
||||
)
|
||||
|
||||
func NewHandler(k Keeper) sdk.Handler {
|
||||
return func(ctx sdk.Context, msg sdk.Msg) sdk.Result {
|
||||
// NOTE msg already has validate basic run
|
||||
ctx = ctx.WithEventManager(sdk.NewEventManager())
|
||||
|
||||
switch msg := msg.(type) {
|
||||
case MsgUnjail:
|
||||
return handleMsgUnjail(ctx, msg, k)
|
||||
@ -61,15 +62,15 @@ func handleMsgUnjail(ctx sdk.Context, msg MsgUnjail, k Keeper) sdk.Result {
|
||||
return ErrValidatorJailed(k.codespace).Result()
|
||||
}
|
||||
|
||||
// unjail the validator
|
||||
k.sk.Unjail(ctx, consAddr)
|
||||
|
||||
tags := sdk.NewTags(
|
||||
tags.Category, tags.TxCategory,
|
||||
tags.Sender, msg.ValidatorAddr.String(),
|
||||
ctx.EventManager().EmitEvent(
|
||||
sdk.NewEvent(
|
||||
sdk.EventTypeMessage,
|
||||
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
|
||||
sdk.NewAttribute(sdk.AttributeKeySender, msg.ValidatorAddr.String()),
|
||||
),
|
||||
)
|
||||
|
||||
return sdk.Result{
|
||||
Tags: tags,
|
||||
}
|
||||
return sdk.Result{Events: ctx.EventManager().Events()}
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/staking"
|
||||
@ -127,7 +128,7 @@ func TestInvalidMsg(t *testing.T) {
|
||||
k := Keeper{}
|
||||
h := NewHandler(k)
|
||||
|
||||
res := h(sdk.Context{}, sdk.NewTestMsg())
|
||||
res := h(sdk.NewContext(nil, abci.Header{}, false, nil), sdk.NewTestMsg())
|
||||
require.False(t, res.IsOK())
|
||||
require.True(t, strings.Contains(res.Log, "unrecognized slashing message type"))
|
||||
}
|
||||
|
||||
@ -109,11 +109,25 @@ func (k Keeper) HandleDoubleSign(ctx sdk.Context, addr crypto.Address, infractio
|
||||
// Tendermint. This value is validator.Tokens as sent to Tendermint via
|
||||
// ABCI, and now received as evidence.
|
||||
// The fraction is passed in to separately to slash unbonding and rebonding delegations.
|
||||
ctx.EventManager().EmitEvent(
|
||||
sdk.NewEvent(
|
||||
types.EventTypeSlash,
|
||||
sdk.NewAttribute(types.AttributeKeyAddress, consAddr.String()),
|
||||
sdk.NewAttribute(types.AttributeKeyPower, fmt.Sprintf("%d", power)),
|
||||
sdk.NewAttribute(types.AttributeKeyReason, types.AttributeValueDoubleSign),
|
||||
),
|
||||
)
|
||||
k.sk.Slash(ctx, consAddr, distributionHeight, power, fraction)
|
||||
|
||||
// Jail validator if not already jailed
|
||||
// begin unbonding validator if not already unbonding (tombstone)
|
||||
if !validator.IsJailed() {
|
||||
ctx.EventManager().EmitEvent(
|
||||
sdk.NewEvent(
|
||||
types.EventTypeSlash,
|
||||
sdk.NewAttribute(types.AttributeKeyJailed, consAddr.String()),
|
||||
),
|
||||
)
|
||||
k.sk.Jail(ctx, consAddr)
|
||||
}
|
||||
|
||||
@ -189,8 +203,19 @@ func (k Keeper) HandleValidatorSignature(ctx sdk.Context, addr crypto.Address, p
|
||||
// i.e. at the end of the pre-genesis block (none) = at the beginning of the genesis block.
|
||||
// That's fine since this is just used to filter unbonding delegations & redelegations.
|
||||
distributionHeight := height - sdk.ValidatorUpdateDelay - 1
|
||||
|
||||
ctx.EventManager().EmitEvent(
|
||||
sdk.NewEvent(
|
||||
types.EventTypeSlash,
|
||||
sdk.NewAttribute(types.AttributeKeyAddress, consAddr.String()),
|
||||
sdk.NewAttribute(types.AttributeKeyPower, fmt.Sprintf("%d", power)),
|
||||
sdk.NewAttribute(types.AttributeKeyReason, types.AttributeValueMissingSignature),
|
||||
sdk.NewAttribute(types.AttributeKeyJailed, consAddr.String()),
|
||||
),
|
||||
)
|
||||
k.sk.Slash(ctx, consAddr, distributionHeight, power, k.SlashFractionDowntime(ctx))
|
||||
k.sk.Jail(ctx, consAddr)
|
||||
|
||||
signInfo.JailedUntil = ctx.BlockHeader().Time.Add(k.DowntimeJailDuration(ctx))
|
||||
|
||||
// We need to reset the counter & array so that the validator won't be immediately slashed for downtime upon rebonding.
|
||||
|
||||
@ -395,7 +395,7 @@ func TestValidatorDippingInAndOut(t *testing.T) {
|
||||
newAmt := sdk.TokensFromConsensusPower(101)
|
||||
got = sh(ctx, NewTestMsgCreateValidator(addrs[1], pks[1], newAmt))
|
||||
require.True(t, got.IsOK())
|
||||
validatorUpdates, _ := staking.EndBlocker(ctx, sk)
|
||||
validatorUpdates := staking.EndBlocker(ctx, sk)
|
||||
require.Equal(t, 2, len(validatorUpdates))
|
||||
validator, _ := sk.GetValidator(ctx, addr)
|
||||
require.Equal(t, sdk.Unbonding, validator.Status)
|
||||
@ -408,7 +408,7 @@ func TestValidatorDippingInAndOut(t *testing.T) {
|
||||
delTokens := sdk.TokensFromConsensusPower(50)
|
||||
got = sh(ctx, newTestMsgDelegate(sdk.AccAddress(addrs[2]), addrs[0], delTokens))
|
||||
require.True(t, got.IsOK())
|
||||
validatorUpdates, _ = staking.EndBlocker(ctx, sk)
|
||||
validatorUpdates = staking.EndBlocker(ctx, sk)
|
||||
require.Equal(t, 2, len(validatorUpdates))
|
||||
validator, _ = sk.GetValidator(ctx, addr)
|
||||
require.Equal(t, sdk.Bonded, validator.Status)
|
||||
|
||||
@ -127,11 +127,11 @@ func (am AppModule) ExportGenesis(ctx sdk.Context) json.RawMessage {
|
||||
}
|
||||
|
||||
// module begin-block
|
||||
func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) sdk.Tags {
|
||||
return BeginBlocker(ctx, req, am.keeper)
|
||||
func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) {
|
||||
BeginBlocker(ctx, req, am.keeper)
|
||||
}
|
||||
|
||||
// module end-block
|
||||
func (AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) ([]abci.ValidatorUpdate, sdk.Tags) {
|
||||
return []abci.ValidatorUpdate{}, sdk.EmptyTags()
|
||||
func (AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate {
|
||||
return []abci.ValidatorUpdate{}
|
||||
}
|
||||
|
||||
@ -1,13 +0,0 @@
|
||||
package tags
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
// Slashing tags
|
||||
var (
|
||||
TxCategory = "slashing"
|
||||
|
||||
Category = sdk.TagCategory
|
||||
Sender = sdk.TagSender
|
||||
)
|
||||
15
x/slashing/types/events.go
Normal file
15
x/slashing/types/events.go
Normal file
@ -0,0 +1,15 @@
|
||||
package types
|
||||
|
||||
// Slashing module event types
|
||||
var (
|
||||
EventTypeSlash = "slash"
|
||||
|
||||
AttributeKeyAddress = "address"
|
||||
AttributeKeyPower = "power"
|
||||
AttributeKeyReason = "reason"
|
||||
AttributeKeyJailed = "jailed"
|
||||
|
||||
AttributeValueDoubleSign = "double_sign"
|
||||
AttributeValueMissingSignature = "missing_signature"
|
||||
AttributeValueCategory = ModuleName
|
||||
)
|
||||
@ -36,11 +36,10 @@ func getMockApp(t *testing.T) (*mock.App, Keeper) {
|
||||
// getEndBlocker returns a staking endblocker.
|
||||
func getEndBlocker(keeper Keeper) sdk.EndBlocker {
|
||||
return func(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock {
|
||||
validatorUpdates, tags := EndBlocker(ctx, keeper)
|
||||
validatorUpdates := EndBlocker(ctx, keeper)
|
||||
|
||||
return abci.ResponseEndBlock{
|
||||
ValidatorUpdates: validatorUpdates,
|
||||
Tags: tags,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -138,20 +138,27 @@ func delegatorTxsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
||||
isBondTx := contains(typesQuerySlice, "bond")
|
||||
isUnbondTx := contains(typesQuerySlice, "unbond")
|
||||
isRedTx := contains(typesQuerySlice, "redelegate")
|
||||
var txs []*sdk.SearchTxsResult
|
||||
var actions []string
|
||||
|
||||
var (
|
||||
txs []*sdk.SearchTxsResult
|
||||
actions []string
|
||||
)
|
||||
|
||||
switch {
|
||||
case isBondTx:
|
||||
actions = append(actions, types.MsgDelegate{}.Type())
|
||||
|
||||
case isUnbondTx:
|
||||
actions = append(actions, types.MsgUndelegate{}.Type())
|
||||
|
||||
case isRedTx:
|
||||
actions = append(actions, types.MsgBeginRedelegate{}.Type())
|
||||
|
||||
case noQuery:
|
||||
actions = append(actions, types.MsgDelegate{}.Type())
|
||||
actions = append(actions, types.MsgUndelegate{}.Type())
|
||||
actions = append(actions, types.MsgBeginRedelegate{}.Type())
|
||||
|
||||
default:
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
return
|
||||
|
||||
@ -10,7 +10,6 @@ import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/rest"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/client/utils"
|
||||
"github.com/cosmos/cosmos-sdk/x/staking/tags"
|
||||
"github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||
)
|
||||
|
||||
@ -25,15 +24,15 @@ func contains(stringSlice []string, txType string) bool {
|
||||
}
|
||||
|
||||
// queries staking txs
|
||||
func queryTxs(cliCtx context.CLIContext, tag string, delegatorAddr string) (*sdk.SearchTxsResult, error) {
|
||||
func queryTxs(cliCtx context.CLIContext, action string, delegatorAddr string) (*sdk.SearchTxsResult, error) {
|
||||
page := 1
|
||||
limit := 100
|
||||
tags := []string{
|
||||
fmt.Sprintf("%s='%s'", tags.Action, tag),
|
||||
fmt.Sprintf("%s='%s'", tags.Sender, delegatorAddr),
|
||||
events := []string{
|
||||
fmt.Sprintf("%s.%s='%s'", sdk.EventTypeMessage, sdk.AttributeKeyAction, action),
|
||||
fmt.Sprintf("%s.%s='%s'", sdk.EventTypeMessage, sdk.AttributeKeySender, delegatorAddr),
|
||||
}
|
||||
|
||||
return utils.QueryTxsByTags(cliCtx, tags, page, limit)
|
||||
return utils.QueryTxsByTags(cliCtx, events, page, limit)
|
||||
}
|
||||
|
||||
func queryBonds(cliCtx context.CLIContext, endpoint string) http.HandlerFunc {
|
||||
|
||||
@ -10,13 +10,13 @@ import (
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/staking/keeper"
|
||||
"github.com/cosmos/cosmos-sdk/x/staking/tags"
|
||||
"github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||
)
|
||||
|
||||
func NewHandler(k keeper.Keeper) sdk.Handler {
|
||||
return func(ctx sdk.Context, msg sdk.Msg) sdk.Result {
|
||||
// NOTE msg already has validate basic run
|
||||
ctx = ctx.WithEventManager(sdk.NewEventManager())
|
||||
|
||||
switch msg := msg.(type) {
|
||||
case types.MsgCreateValidator:
|
||||
return handleMsgCreateValidator(ctx, msg, k)
|
||||
@ -41,9 +41,7 @@ func NewHandler(k keeper.Keeper) sdk.Handler {
|
||||
}
|
||||
|
||||
// Called every block, update validator set
|
||||
func EndBlocker(ctx sdk.Context, k keeper.Keeper) ([]abci.ValidatorUpdate, sdk.Tags) {
|
||||
resTags := sdk.NewTags()
|
||||
|
||||
func EndBlocker(ctx sdk.Context, k keeper.Keeper) []abci.ValidatorUpdate {
|
||||
// Calculate validator set changes.
|
||||
//
|
||||
// NOTE: ApplyAndReturnValidatorSetUpdates has to come before
|
||||
@ -66,11 +64,13 @@ func EndBlocker(ctx sdk.Context, k keeper.Keeper) ([]abci.ValidatorUpdate, sdk.T
|
||||
continue
|
||||
}
|
||||
|
||||
resTags = resTags.AppendTags(sdk.NewTags(
|
||||
tags.Action, tags.ActionCompleteUnbonding,
|
||||
tags.Delegator, dvPair.DelegatorAddress.String(),
|
||||
tags.SrcValidator, dvPair.ValidatorAddress.String(),
|
||||
))
|
||||
ctx.EventManager().EmitEvent(
|
||||
sdk.NewEvent(
|
||||
types.EventTypeCompleteUnbonding,
|
||||
sdk.NewAttribute(types.AttributeKeyValidator, dvPair.ValidatorAddress.String()),
|
||||
sdk.NewAttribute(types.AttributeKeyDelegator, dvPair.DelegatorAddress.String()),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
// Remove all mature redelegations from the red queue.
|
||||
@ -82,16 +82,17 @@ func EndBlocker(ctx sdk.Context, k keeper.Keeper) ([]abci.ValidatorUpdate, sdk.T
|
||||
continue
|
||||
}
|
||||
|
||||
resTags = resTags.AppendTags(sdk.NewTags(
|
||||
tags.Action, tags.ActionCompleteRedelegation,
|
||||
tags.Category, tags.TxCategory,
|
||||
tags.Delegator, dvvTriplet.DelegatorAddress.String(),
|
||||
tags.SrcValidator, dvvTriplet.ValidatorSrcAddress.String(),
|
||||
tags.DstValidator, dvvTriplet.ValidatorDstAddress.String(),
|
||||
))
|
||||
ctx.EventManager().EmitEvent(
|
||||
sdk.NewEvent(
|
||||
types.EventTypeCompleteRedelegation,
|
||||
sdk.NewAttribute(types.AttributeKeyDelegator, dvvTriplet.DelegatorAddress.String()),
|
||||
sdk.NewAttribute(types.AttributeKeySrcValidator, dvvTriplet.ValidatorSrcAddress.String()),
|
||||
sdk.NewAttribute(types.AttributeKeyDstValidator, dvvTriplet.ValidatorDstAddress.String()),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
return validatorUpdates, resTags
|
||||
return validatorUpdates
|
||||
}
|
||||
|
||||
// These functions assume everything has been authenticated,
|
||||
@ -150,15 +151,20 @@ func handleMsgCreateValidator(ctx sdk.Context, msg types.MsgCreateValidator, k k
|
||||
return err.Result()
|
||||
}
|
||||
|
||||
resTags := sdk.NewTags(
|
||||
tags.Category, tags.TxCategory,
|
||||
tags.Sender, msg.DelegatorAddress.String(),
|
||||
tags.DstValidator, msg.ValidatorAddress.String(),
|
||||
)
|
||||
ctx.EventManager().EmitEvents(sdk.Events{
|
||||
sdk.NewEvent(
|
||||
types.EventTypeCreateValidator,
|
||||
sdk.NewAttribute(types.AttributeKeyValidator, msg.ValidatorAddress.String()),
|
||||
sdk.NewAttribute(types.AttributeKeyAmount, msg.Value.Amount.String()),
|
||||
),
|
||||
sdk.NewEvent(
|
||||
sdk.EventTypeMessage,
|
||||
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
|
||||
sdk.NewAttribute(sdk.AttributeKeySender, msg.DelegatorAddress.String()),
|
||||
),
|
||||
})
|
||||
|
||||
return sdk.Result{
|
||||
Tags: resTags,
|
||||
}
|
||||
return sdk.Result{Events: ctx.EventManager().Events()}
|
||||
}
|
||||
|
||||
func handleMsgEditValidator(ctx sdk.Context, msg types.MsgEditValidator, k keeper.Keeper) sdk.Result {
|
||||
@ -200,14 +206,20 @@ func handleMsgEditValidator(ctx sdk.Context, msg types.MsgEditValidator, k keepe
|
||||
|
||||
k.SetValidator(ctx, validator)
|
||||
|
||||
resTags := sdk.NewTags(
|
||||
tags.Category, tags.TxCategory,
|
||||
tags.Sender, msg.ValidatorAddress.String(),
|
||||
)
|
||||
ctx.EventManager().EmitEvents(sdk.Events{
|
||||
sdk.NewEvent(
|
||||
types.EventTypeEditValidator,
|
||||
sdk.NewAttribute(types.AttributeKeyCommissionRate, validator.Commission.String()),
|
||||
sdk.NewAttribute(types.AttributeKeyMinSelfDelegation, validator.MinSelfDelegation.String()),
|
||||
),
|
||||
sdk.NewEvent(
|
||||
sdk.EventTypeMessage,
|
||||
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
|
||||
sdk.NewAttribute(sdk.AttributeKeySender, msg.ValidatorAddress.String()),
|
||||
),
|
||||
})
|
||||
|
||||
return sdk.Result{
|
||||
Tags: resTags,
|
||||
}
|
||||
return sdk.Result{Events: ctx.EventManager().Events()}
|
||||
}
|
||||
|
||||
func handleMsgDelegate(ctx sdk.Context, msg types.MsgDelegate, k keeper.Keeper) sdk.Result {
|
||||
@ -225,15 +237,20 @@ func handleMsgDelegate(ctx sdk.Context, msg types.MsgDelegate, k keeper.Keeper)
|
||||
return err.Result()
|
||||
}
|
||||
|
||||
resTags := sdk.NewTags(
|
||||
tags.Category, tags.TxCategory,
|
||||
tags.Sender, msg.DelegatorAddress.String(),
|
||||
tags.DstValidator, msg.ValidatorAddress.String(),
|
||||
)
|
||||
ctx.EventManager().EmitEvents(sdk.Events{
|
||||
sdk.NewEvent(
|
||||
types.EventTypeDelegate,
|
||||
sdk.NewAttribute(types.AttributeKeyValidator, msg.ValidatorAddress.String()),
|
||||
sdk.NewAttribute(types.AttributeKeyAmount, msg.Amount.Amount.String()),
|
||||
),
|
||||
sdk.NewEvent(
|
||||
sdk.EventTypeMessage,
|
||||
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
|
||||
sdk.NewAttribute(sdk.AttributeKeySender, msg.DelegatorAddress.String()),
|
||||
),
|
||||
})
|
||||
|
||||
return sdk.Result{
|
||||
Tags: resTags,
|
||||
}
|
||||
return sdk.Result{Events: ctx.EventManager().Events()}
|
||||
}
|
||||
|
||||
func handleMsgUndelegate(ctx sdk.Context, msg types.MsgUndelegate, k keeper.Keeper) sdk.Result {
|
||||
@ -253,15 +270,22 @@ func handleMsgUndelegate(ctx sdk.Context, msg types.MsgUndelegate, k keeper.Keep
|
||||
return err.Result()
|
||||
}
|
||||
|
||||
finishTime := types.ModuleCdc.MustMarshalBinaryLengthPrefixed(completionTime)
|
||||
resTags := sdk.NewTags(
|
||||
tags.Category, tags.TxCategory,
|
||||
tags.Sender, msg.DelegatorAddress.String(),
|
||||
tags.SrcValidator, msg.ValidatorAddress.String(),
|
||||
tags.EndTime, completionTime.Format(time.RFC3339),
|
||||
)
|
||||
completionTimeBz := types.ModuleCdc.MustMarshalBinaryLengthPrefixed(completionTime)
|
||||
ctx.EventManager().EmitEvents(sdk.Events{
|
||||
sdk.NewEvent(
|
||||
types.EventTypeUnbond,
|
||||
sdk.NewAttribute(types.AttributeKeyValidator, msg.ValidatorAddress.String()),
|
||||
sdk.NewAttribute(types.AttributeKeyAmount, msg.Amount.Amount.String()),
|
||||
sdk.NewAttribute(types.AttributeKeyCompletionTime, completionTime.Format(time.RFC3339)),
|
||||
),
|
||||
sdk.NewEvent(
|
||||
sdk.EventTypeMessage,
|
||||
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
|
||||
sdk.NewAttribute(sdk.AttributeKeySender, msg.DelegatorAddress.String()),
|
||||
),
|
||||
})
|
||||
|
||||
return sdk.Result{Data: finishTime, Tags: resTags}
|
||||
return sdk.Result{Data: completionTimeBz, Events: ctx.EventManager().Events()}
|
||||
}
|
||||
|
||||
func handleMsgBeginRedelegate(ctx sdk.Context, msg types.MsgBeginRedelegate, k keeper.Keeper) sdk.Result {
|
||||
@ -283,14 +307,21 @@ func handleMsgBeginRedelegate(ctx sdk.Context, msg types.MsgBeginRedelegate, k k
|
||||
return err.Result()
|
||||
}
|
||||
|
||||
finishTime := types.ModuleCdc.MustMarshalBinaryLengthPrefixed(completionTime)
|
||||
resTags := sdk.NewTags(
|
||||
tags.Category, tags.TxCategory,
|
||||
tags.Sender, msg.DelegatorAddress.String(),
|
||||
tags.SrcValidator, msg.ValidatorSrcAddress.String(),
|
||||
tags.DstValidator, msg.ValidatorDstAddress.String(),
|
||||
tags.EndTime, completionTime.Format(time.RFC3339),
|
||||
)
|
||||
completionTimeBz := types.ModuleCdc.MustMarshalBinaryLengthPrefixed(completionTime)
|
||||
ctx.EventManager().EmitEvents(sdk.Events{
|
||||
sdk.NewEvent(
|
||||
types.EventTypeRedelegate,
|
||||
sdk.NewAttribute(types.AttributeKeySrcValidator, msg.ValidatorSrcAddress.String()),
|
||||
sdk.NewAttribute(types.AttributeKeyDstValidator, msg.ValidatorDstAddress.String()),
|
||||
sdk.NewAttribute(types.AttributeKeyAmount, msg.Amount.Amount.String()),
|
||||
sdk.NewAttribute(types.AttributeKeyCompletionTime, completionTime.Format(time.RFC3339)),
|
||||
),
|
||||
sdk.NewEvent(
|
||||
sdk.EventTypeMessage,
|
||||
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
|
||||
sdk.NewAttribute(sdk.AttributeKeySender, msg.DelegatorAddress.String()),
|
||||
),
|
||||
})
|
||||
|
||||
return sdk.Result{Data: finishTime, Tags: resTags}
|
||||
return sdk.Result{Data: completionTimeBz, Events: ctx.EventManager().Events()}
|
||||
}
|
||||
|
||||
@ -1277,7 +1277,7 @@ func TestInvalidMsg(t *testing.T) {
|
||||
k := keep.Keeper{}
|
||||
h := NewHandler(k)
|
||||
|
||||
res := h(sdk.Context{}, sdk.NewTestMsg())
|
||||
res := h(sdk.NewContext(nil, abci.Header{}, false, nil), sdk.NewTestMsg())
|
||||
require.False(t, res.IsOK())
|
||||
require.True(t, strings.Contains(res.Log, "unrecognized staking message type"))
|
||||
}
|
||||
|
||||
@ -469,7 +469,7 @@ func (k Keeper) Delegate(ctx sdk.Context, delAddr sdk.AccAddress, bondAmt sdk.In
|
||||
}
|
||||
|
||||
if subtractAccount {
|
||||
_, err := k.bankKeeper.DelegateCoins(ctx, delegation.DelegatorAddress, sdk.Coins{sdk.NewCoin(k.GetParams(ctx).BondDenom, bondAmt)})
|
||||
err := k.bankKeeper.DelegateCoins(ctx, delegation.DelegatorAddress, sdk.Coins{sdk.NewCoin(k.GetParams(ctx).BondDenom, bondAmt)})
|
||||
if err != nil {
|
||||
return sdk.Dec{}, err
|
||||
}
|
||||
@ -620,7 +620,7 @@ func (k Keeper) CompleteUnbonding(ctx sdk.Context, delAddr sdk.AccAddress,
|
||||
|
||||
// track undelegation only when remaining or truncated shares are non-zero
|
||||
if !entry.Balance.IsZero() {
|
||||
_, err := k.bankKeeper.UndelegateCoins(ctx, ubd.DelegatorAddress, sdk.Coins{sdk.NewCoin(k.GetParams(ctx).BondDenom, entry.Balance)})
|
||||
err := k.bankKeeper.UndelegateCoins(ctx, ubd.DelegatorAddress, sdk.Coins{sdk.NewCoin(k.GetParams(ctx).BondDenom, entry.Balance)})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -158,11 +158,9 @@ func (am AppModule) ExportGenesis(ctx sdk.Context) json.RawMessage {
|
||||
}
|
||||
|
||||
// module begin-block
|
||||
func (AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) sdk.Tags {
|
||||
return sdk.EmptyTags()
|
||||
}
|
||||
func (AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) {}
|
||||
|
||||
// module end-block
|
||||
func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) ([]abci.ValidatorUpdate, sdk.Tags) {
|
||||
func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate {
|
||||
return EndBlocker(ctx, am.keeper)
|
||||
}
|
||||
|
||||
@ -1,20 +0,0 @@
|
||||
package tags
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
// staking tags
|
||||
var (
|
||||
ActionCompleteUnbonding = "complete-unbonding"
|
||||
ActionCompleteRedelegation = "complete-redelegation"
|
||||
TxCategory = "staking"
|
||||
|
||||
Action = sdk.TagAction
|
||||
Category = sdk.TagCategory
|
||||
Sender = sdk.TagSender
|
||||
SrcValidator = sdk.TagSrcValidator
|
||||
DstValidator = sdk.TagDstValidator
|
||||
Delegator = sdk.TagDelegator
|
||||
EndTime = "end-time"
|
||||
)
|
||||
22
x/staking/types/events.go
Normal file
22
x/staking/types/events.go
Normal file
@ -0,0 +1,22 @@
|
||||
package types
|
||||
|
||||
// Staking module event types
|
||||
var (
|
||||
EventTypeCompleteUnbonding = "complete_unbonding"
|
||||
EventTypeCompleteRedelegation = "complete_redelegation"
|
||||
EventTypeCreateValidator = "create_validator"
|
||||
EventTypeEditValidator = "edit_validator"
|
||||
EventTypeDelegate = "delegate"
|
||||
EventTypeUnbond = "unbond"
|
||||
EventTypeRedelegate = "redelegate"
|
||||
|
||||
AttributeKeyValidator = "validator"
|
||||
AttributeKeyCommissionRate = "commission_rate"
|
||||
AttributeKeyMinSelfDelegation = "min_self_delegation"
|
||||
AttributeKeySrcValidator = "source_validator"
|
||||
AttributeKeyDstValidator = "destination_validator"
|
||||
AttributeKeyDelegator = "delegator"
|
||||
AttributeKeyAmount = "amount"
|
||||
AttributeKeyCompletionTime = "completion_time"
|
||||
AttributeValueCategory = ModuleName
|
||||
)
|
||||
@ -19,8 +19,8 @@ type FeeCollectionKeeper interface {
|
||||
|
||||
// expected bank keeper (noalias)
|
||||
type BankKeeper interface {
|
||||
DelegateCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) (sdk.Tags, sdk.Error)
|
||||
UndelegateCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) (sdk.Tags, sdk.Error)
|
||||
DelegateCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) sdk.Error
|
||||
UndelegateCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) sdk.Error
|
||||
}
|
||||
|
||||
// AccountKeeper expected Account keeper
|
||||
|
||||
Loading…
Reference in New Issue
Block a user