Merge remote-tracking branch 'origin/develop' into rigel/fee-distribution
This commit is contained in:
commit
436d2a0178
|
@ -109,6 +109,8 @@ IMPROVEMENTS
|
||||||
- [baseapp] Allow any alphanumeric character in route
|
- [baseapp] Allow any alphanumeric character in route
|
||||||
- [tools] Remove `rm -rf vendor/` from `make get_vendor_deps`
|
- [tools] Remove `rm -rf vendor/` from `make get_vendor_deps`
|
||||||
- [x/auth] Recover ErrorOutOfGas panic in order to set sdk.Result attributes correctly
|
- [x/auth] Recover ErrorOutOfGas panic in order to set sdk.Result attributes correctly
|
||||||
|
- [x/auth] \#2376 No longer runs any signature in a multi-msg, if any account/sequence number is wrong.
|
||||||
|
- [x/auth] \#2376 No longer charge gas for subtracting fees
|
||||||
- [x/bank] Unit tests are now table-driven
|
- [x/bank] Unit tests are now table-driven
|
||||||
- [tests] Add tests to example apps in docs
|
- [tests] Add tests to example apps in docs
|
||||||
- [tests] Fixes ansible scripts to work with AWS too
|
- [tests] Fixes ansible scripts to work with AWS too
|
||||||
|
|
|
@ -39,6 +39,7 @@ BREAKING CHANGES
|
||||||
* [x/stake] [#1013] TendermintUpdates now uses transient store
|
* [x/stake] [#1013] TendermintUpdates now uses transient store
|
||||||
* [x/gov] [#2195] Governance uses BFT Time
|
* [x/gov] [#2195] Governance uses BFT Time
|
||||||
* [x/gov] \#2256 Removed slashing for governance non-voting validators
|
* [x/gov] \#2256 Removed slashing for governance non-voting validators
|
||||||
|
* [simulation] \#2162 Added back correct supply invariants
|
||||||
|
|
||||||
* SDK
|
* SDK
|
||||||
* [core] [\#1807](https://github.com/cosmos/cosmos-sdk/issues/1807) Switch from use of rational to decimal
|
* [core] [\#1807](https://github.com/cosmos/cosmos-sdk/issues/1807) Switch from use of rational to decimal
|
||||||
|
@ -100,6 +101,7 @@ FEATURES
|
||||||
* [simulation] [\#1924](https://github.com/cosmos/cosmos-sdk/issues/1924) allow operations to specify future operations
|
* [simulation] [\#1924](https://github.com/cosmos/cosmos-sdk/issues/1924) allow operations to specify future operations
|
||||||
* [simulation] [\#1924](https://github.com/cosmos/cosmos-sdk/issues/1924) Add benchmarking capabilities, with makefile commands "test_sim_gaia_benchmark, test_sim_gaia_profile"
|
* [simulation] [\#1924](https://github.com/cosmos/cosmos-sdk/issues/1924) Add benchmarking capabilities, with makefile commands "test_sim_gaia_benchmark, test_sim_gaia_profile"
|
||||||
* [simulation] [\#2349](https://github.com/cosmos/cosmos-sdk/issues/2349) Add time-based future scheduled operations to simulator
|
* [simulation] [\#2349](https://github.com/cosmos/cosmos-sdk/issues/2349) Add time-based future scheduled operations to simulator
|
||||||
|
* [x/auth] \#2376 Remove FeePayer() from StdTx
|
||||||
* [x/stake] [\#1672](https://github.com/cosmos/cosmos-sdk/issues/1672) Implement
|
* [x/stake] [\#1672](https://github.com/cosmos/cosmos-sdk/issues/1672) Implement
|
||||||
basis for the validator commission model.
|
basis for the validator commission model.
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ func ExampleTxSendSize() {
|
||||||
Outputs: []bank.Output{bank.NewOutput(addr2, coins)},
|
Outputs: []bank.Output{bank.NewOutput(addr2, coins)},
|
||||||
}
|
}
|
||||||
sig, _ := priv1.Sign(msg1.GetSignBytes())
|
sig, _ := priv1.Sign(msg1.GetSignBytes())
|
||||||
sigs := []auth.StdSignature{auth.StdSignature{nil, sig, 0, 0}}
|
sigs := []auth.StdSignature{{nil, sig, 0, 0}}
|
||||||
tx := auth.NewStdTx([]sdk.Msg{msg1}, auth.NewStdFee(0, coins...), sigs, "")
|
tx := auth.NewStdTx([]sdk.Msg{msg1}, auth.NewStdFee(0, coins...), sigs, "")
|
||||||
fmt.Println(len(cdc.MustMarshalBinaryBare([]sdk.Msg{msg1})))
|
fmt.Println(len(cdc.MustMarshalBinaryBare([]sdk.Msg{msg1})))
|
||||||
fmt.Println(len(cdc.MustMarshalBinaryBare(tx)))
|
fmt.Println(len(cdc.MustMarshalBinaryBare(tx)))
|
||||||
|
|
|
@ -20,7 +20,8 @@ a private website repository has make targets consumed by a standard Jenkins tas
|
||||||
## README
|
## README
|
||||||
|
|
||||||
The [README.md](./README.md) is also the landing page for the documentation
|
The [README.md](./README.md) is also the landing page for the documentation
|
||||||
on the website.
|
on the website. During the Jenkins build, the current commit is added to the bottom
|
||||||
|
of the README.
|
||||||
|
|
||||||
## Config.js
|
## Config.js
|
||||||
|
|
||||||
|
|
|
@ -12,3 +12,7 @@ Cosmos can interoperate with multiple other applications and cryptocurrencies. B
|
||||||
|
|
||||||
See [this file](./DOCS_README.md) for details of the build process and
|
See [this file](./DOCS_README.md) for details of the build process and
|
||||||
considerations when making changes.
|
considerations when making changes.
|
||||||
|
|
||||||
|
## Version
|
||||||
|
|
||||||
|
This documentation is built from the following commit:
|
||||||
|
|
|
@ -133,7 +133,7 @@ Now that we have a native model for accounts, it's time to introduce the native
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// StdTx is a standard way to wrap a Msg with Fee and Signatures.
|
// StdTx is a standard way to wrap a Msg with Fee and Signatures.
|
||||||
// NOTE: the first signature is the FeePayer (Signatures must not be nil).
|
// NOTE: the first signature is the fee payer (Signatures must not be nil).
|
||||||
type StdTx struct {
|
type StdTx struct {
|
||||||
Msgs []sdk.Msg `json:"msg"`
|
Msgs []sdk.Msg `json:"msg"`
|
||||||
Fee StdFee `json:"fee"`
|
Fee StdFee `json:"fee"`
|
||||||
|
@ -259,8 +259,7 @@ the same message could be executed over and over again.
|
||||||
The PubKey is required for signature verification, but it is only required in
|
The PubKey is required for signature verification, but it is only required in
|
||||||
the StdSignature once. From that point on, it will be stored in the account.
|
the StdSignature once. From that point on, it will be stored in the account.
|
||||||
|
|
||||||
The fee is paid by the first address returned by `msg.GetSigners()` for the first `Msg`,
|
The fee is paid by the first address returned by `msg.GetSigners()` for the first `Msg`.
|
||||||
as provided by the `FeePayer(tx Tx) sdk.AccAddress` function.
|
|
||||||
|
|
||||||
## CoinKeeper
|
## CoinKeeper
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ func NewHandler(k Keeper) sdk.Handler {
|
||||||
case VoteMsg:
|
case VoteMsg:
|
||||||
return handleVoteMsg(ctx, k, msg)
|
return handleVoteMsg(ctx, k, msg)
|
||||||
default:
|
default:
|
||||||
errMsg := "Unrecognized gov Msg type: " + reflect.TypeOf(msg).Name()
|
errMsg := "Unrecognized gov Msg type: " + msg.Name()
|
||||||
return sdk.ErrUnknownRequest(errMsg).Result()
|
return sdk.ErrUnknownRequest(errMsg).Result()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ package cool
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
|
||||||
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
)
|
)
|
||||||
|
@ -26,7 +25,7 @@ func NewHandler(k Keeper) sdk.Handler {
|
||||||
case MsgQuiz:
|
case MsgQuiz:
|
||||||
return handleMsgQuiz(ctx, k, msg)
|
return handleMsgQuiz(ctx, k, msg)
|
||||||
default:
|
default:
|
||||||
errMsg := fmt.Sprintf("Unrecognized cool Msg type: %v", reflect.TypeOf(msg).Name())
|
errMsg := fmt.Sprintf("Unrecognized cool Msg type: %v", msg.Name())
|
||||||
return sdk.ErrUnknownRequest(errMsg).Result()
|
return sdk.ErrUnknownRequest(errMsg).Result()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
package pow
|
package pow
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"reflect"
|
|
||||||
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -12,7 +10,7 @@ func (pk Keeper) Handler(ctx sdk.Context, msg sdk.Msg) sdk.Result {
|
||||||
case MsgMine:
|
case MsgMine:
|
||||||
return handleMsgMine(ctx, pk, msg)
|
return handleMsgMine(ctx, pk, msg)
|
||||||
default:
|
default:
|
||||||
errMsg := "Unrecognized pow Msg type: " + reflect.TypeOf(msg).Name()
|
errMsg := "Unrecognized pow Msg type: " + msg.Name()
|
||||||
return sdk.ErrUnknownRequest(errMsg).Result()
|
return sdk.ErrUnknownRequest(errMsg).Result()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,8 +8,12 @@ import (
|
||||||
"github.com/tendermint/tendermint/crypto"
|
"github.com/tendermint/tendermint/crypto"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Account is a standard account using a sequence number for replay protection
|
// Account is an interface used to store coins at a given address within state.
|
||||||
// and a pubkey for authentication.
|
// It presumes a notion of sequence numbers for replay protection,
|
||||||
|
// a notion of account numbers for replay protection for previously pruned accounts,
|
||||||
|
// and a pubkey for authentication purposes.
|
||||||
|
//
|
||||||
|
// Many complex conditions can be used in the concrete struct which implements Account.
|
||||||
type Account interface {
|
type Account interface {
|
||||||
GetAddress() sdk.AccAddress
|
GetAddress() sdk.AccAddress
|
||||||
SetAddress(sdk.AccAddress) error // errors if already set.
|
SetAddress(sdk.AccAddress) error // errors if already set.
|
||||||
|
@ -35,9 +39,11 @@ type AccountDecoder func(accountBytes []byte) (Account, error)
|
||||||
|
|
||||||
var _ Account = (*BaseAccount)(nil)
|
var _ Account = (*BaseAccount)(nil)
|
||||||
|
|
||||||
// BaseAccount - base account structure.
|
// BaseAccount - a base account structure.
|
||||||
// Extend this by embedding this in your AppAccount.
|
// This can be extended by embedding within in your AppAccount.
|
||||||
// See the examples/basecoin/types/account.go for an example.
|
// There are examples of this in: examples/basecoin/types/account.go.
|
||||||
|
// However one doesn't have to use BaseAccount as long as your struct
|
||||||
|
// implements Account.
|
||||||
type BaseAccount struct {
|
type BaseAccount struct {
|
||||||
Address sdk.AccAddress `json:"address"`
|
Address sdk.AccAddress `json:"address"`
|
||||||
Coins sdk.Coins `json:"coins"`
|
Coins sdk.Coins `json:"coins"`
|
||||||
|
@ -118,7 +124,7 @@ func (acc *BaseAccount) SetSequence(seq int64) error {
|
||||||
//----------------------------------------
|
//----------------------------------------
|
||||||
// Wire
|
// Wire
|
||||||
|
|
||||||
// Most users shouldn't use this, but this comes handy for tests.
|
// Most users shouldn't use this, but this comes in handy for tests.
|
||||||
func RegisterBaseAccount(cdc *codec.Codec) {
|
func RegisterBaseAccount(cdc *codec.Codec) {
|
||||||
cdc.RegisterInterface((*Account)(nil), nil)
|
cdc.RegisterInterface((*Account)(nil), nil)
|
||||||
cdc.RegisterConcrete(&BaseAccount{}, "cosmos-sdk/BaseAccount", nil)
|
cdc.RegisterConcrete(&BaseAccount{}, "cosmos-sdk/BaseAccount", nil)
|
||||||
|
|
199
x/auth/ante.go
199
x/auth/ante.go
|
@ -12,19 +12,18 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
deductFeesCost sdk.Gas = 10
|
memoCostPerByte sdk.Gas = 1
|
||||||
memoCostPerByte sdk.Gas = 1
|
ed25519VerifyCost = 59
|
||||||
ed25519VerifyCost = 59
|
secp256k1VerifyCost = 100
|
||||||
secp256k1VerifyCost = 100
|
maxMemoCharacters = 100
|
||||||
maxMemoCharacters = 100
|
// how much gas = 1 atom
|
||||||
feeDeductionGasFactor = 0.001
|
gasPerUnitCost = 1000
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewAnteHandler returns an AnteHandler that checks
|
// NewAnteHandler returns an AnteHandler that checks
|
||||||
// and increments sequence numbers, checks signatures & account numbers,
|
// and increments sequence numbers, checks signatures & account numbers,
|
||||||
// and deducts fees from the first signer.
|
// and deducts fees from the first signer.
|
||||||
func NewAnteHandler(am AccountMapper, fck FeeCollectionKeeper) sdk.AnteHandler {
|
func NewAnteHandler(am AccountMapper, fck FeeCollectionKeeper) sdk.AnteHandler {
|
||||||
|
|
||||||
return func(
|
return func(
|
||||||
ctx sdk.Context, tx sdk.Tx, simulate bool,
|
ctx sdk.Context, tx sdk.Tx, simulate bool,
|
||||||
) (newCtx sdk.Context, res sdk.Result, abort bool) {
|
) (newCtx sdk.Context, res sdk.Result, abort bool) {
|
||||||
|
@ -35,13 +34,17 @@ func NewAnteHandler(am AccountMapper, fck FeeCollectionKeeper) sdk.AnteHandler {
|
||||||
return ctx, sdk.ErrInternal("tx must be StdTx").Result(), true
|
return ctx, sdk.ErrInternal("tx must be StdTx").Result(), true
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the gas meter
|
// Ensure that the provided fees meet a minimum threshold for the validator, if this is a CheckTx.
|
||||||
if simulate {
|
// This is only for local mempool purposes, and thus is only ran on check tx.
|
||||||
newCtx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter())
|
if ctx.IsCheckTx() && !simulate {
|
||||||
} else {
|
res := ensureSufficientMempoolFees(ctx, stdTx)
|
||||||
newCtx = ctx.WithGasMeter(sdk.NewGasMeter(stdTx.Fee.Gas))
|
if !res.IsOK() {
|
||||||
|
return newCtx, res, true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
newCtx = setGasMeter(simulate, ctx, stdTx)
|
||||||
|
|
||||||
// AnteHandlers must have their own defer/recover in order
|
// AnteHandlers must have their own defer/recover in order
|
||||||
// for the BaseApp to know how much gas was used!
|
// for the BaseApp to know how much gas was used!
|
||||||
// This is because the GasMeter is created in the AnteHandler,
|
// This is because the GasMeter is created in the AnteHandler,
|
||||||
|
@ -65,64 +68,49 @@ func NewAnteHandler(am AccountMapper, fck FeeCollectionKeeper) sdk.AnteHandler {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return newCtx, err.Result(), true
|
return newCtx, err.Result(), true
|
||||||
}
|
}
|
||||||
|
|
||||||
sigs := stdTx.GetSignatures() // When simulating, this would just be a 0-length slice.
|
|
||||||
signerAddrs := stdTx.GetSigners()
|
|
||||||
msgs := tx.GetMsgs()
|
|
||||||
|
|
||||||
// charge gas for the memo
|
// charge gas for the memo
|
||||||
newCtx.GasMeter().ConsumeGas(memoCostPerByte*sdk.Gas(len(stdTx.GetMemo())), "memo")
|
newCtx.GasMeter().ConsumeGas(memoCostPerByte*sdk.Gas(len(stdTx.GetMemo())), "memo")
|
||||||
|
|
||||||
// Get the sign bytes (requires all account & sequence numbers and the fee)
|
// stdSigs contains the sequence number, account number, and signatures
|
||||||
sequences := make([]int64, len(sigs))
|
stdSigs := stdTx.GetSignatures() // When simulating, this would just be a 0-length slice.
|
||||||
accNums := make([]int64, len(sigs))
|
signerAddrs := stdTx.GetSigners()
|
||||||
for i := 0; i < len(sigs); i++ {
|
|
||||||
sequences[i] = sigs[i].Sequence
|
// create the list of all sign bytes
|
||||||
accNums[i] = sigs[i].AccountNumber
|
signBytesList := getSignBytesList(newCtx.ChainID(), stdTx, stdSigs)
|
||||||
|
signerAccs, res := getSignerAccs(newCtx, am, signerAddrs)
|
||||||
|
if !res.IsOK() {
|
||||||
|
return newCtx, res, true
|
||||||
|
}
|
||||||
|
res = validateAccNumAndSequence(signerAccs, stdSigs)
|
||||||
|
if !res.IsOK() {
|
||||||
|
return newCtx, res, true
|
||||||
}
|
}
|
||||||
fee := stdTx.Fee
|
|
||||||
|
|
||||||
// Check sig and nonce and collect signer accounts.
|
// first sig pays the fees
|
||||||
var signerAccs = make([]Account, len(signerAddrs))
|
if !stdTx.Fee.Amount.IsZero() {
|
||||||
for i := 0; i < len(sigs); i++ {
|
// signerAccs[0] is the fee payer
|
||||||
signerAddr, sig := signerAddrs[i], sigs[i]
|
signerAccs[0], res = deductFees(signerAccs[0], stdTx.Fee)
|
||||||
|
if !res.IsOK() {
|
||||||
|
return newCtx, res, true
|
||||||
|
}
|
||||||
|
fck.addCollectedFees(newCtx, stdTx.Fee.Amount)
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < len(stdSigs); i++ {
|
||||||
// check signature, return account with incremented nonce
|
// check signature, return account with incremented nonce
|
||||||
signBytes := StdSignBytes(newCtx.ChainID(), accNums[i], sequences[i], fee, msgs, stdTx.GetMemo())
|
signerAccs[i], res = processSig(newCtx, signerAccs[i], stdSigs[i], signBytesList[i], simulate)
|
||||||
signerAcc, res := processSig(newCtx, am, signerAddr, sig, signBytes, simulate)
|
|
||||||
if !res.IsOK() {
|
if !res.IsOK() {
|
||||||
return newCtx, res, true
|
return newCtx, res, true
|
||||||
}
|
}
|
||||||
|
|
||||||
requiredFees := adjustFeesByGas(ctx.MinimumFees(), fee.Gas)
|
|
||||||
// fees must be greater than the minimum set by the validator adjusted by gas
|
|
||||||
if ctx.IsCheckTx() && !simulate && !ctx.MinimumFees().IsZero() && fee.Amount.IsLT(requiredFees) {
|
|
||||||
// validators reject any tx from the mempool with less than the minimum fee per gas * gas factor
|
|
||||||
return newCtx, sdk.ErrInsufficientFee(fmt.Sprintf(
|
|
||||||
"insufficient fee, got: %q required: %q", fee.Amount, requiredFees)).Result(), true
|
|
||||||
}
|
|
||||||
|
|
||||||
// first sig pays the fees
|
|
||||||
// Can this function be moved outside of the loop?
|
|
||||||
if i == 0 && !fee.Amount.IsZero() {
|
|
||||||
newCtx.GasMeter().ConsumeGas(deductFeesCost, "deductFees")
|
|
||||||
signerAcc, res = deductFees(signerAcc, fee)
|
|
||||||
if !res.IsOK() {
|
|
||||||
return newCtx, res, true
|
|
||||||
}
|
|
||||||
fck.addCollectedFees(newCtx, fee.Amount)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save the account.
|
// Save the account.
|
||||||
am.SetAccount(newCtx, signerAcc)
|
am.SetAccount(newCtx, signerAccs[i])
|
||||||
signerAccs[i] = signerAcc
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// cache the signer accounts in the context
|
// cache the signer accounts in the context
|
||||||
newCtx = WithSigners(newCtx, signerAccs)
|
newCtx = WithSigners(newCtx, signerAccs)
|
||||||
|
|
||||||
// TODO: tx tags (?)
|
// TODO: tx tags (?)
|
||||||
|
|
||||||
return newCtx, sdk.Result{GasWanted: stdTx.Fee.Gas}, false // continue...
|
return newCtx, sdk.Result{GasWanted: stdTx.Fee.Gas}, false // continue...
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -150,42 +138,45 @@ func validateBasic(tx StdTx) (err sdk.Error) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getSignerAccs(ctx sdk.Context, am AccountMapper, addrs []sdk.AccAddress) (accs []Account, res sdk.Result) {
|
||||||
|
accs = make([]Account, len(addrs))
|
||||||
|
for i := 0; i < len(accs); i++ {
|
||||||
|
accs[i] = am.GetAccount(ctx, addrs[i])
|
||||||
|
if accs[i] == nil {
|
||||||
|
return nil, sdk.ErrUnknownAddress(addrs[i].String()).Result()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateAccNumAndSequence(accs []Account, sigs []StdSignature) sdk.Result {
|
||||||
|
for i := 0; i < len(accs); i++ {
|
||||||
|
accnum := accs[i].GetAccountNumber()
|
||||||
|
seq := accs[i].GetSequence()
|
||||||
|
// Check account number.
|
||||||
|
if accnum != sigs[i].AccountNumber {
|
||||||
|
return sdk.ErrInvalidSequence(
|
||||||
|
fmt.Sprintf("Invalid account number. Got %d, expected %d", sigs[i].AccountNumber, accnum)).Result()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check sequence number.
|
||||||
|
if seq != sigs[i].Sequence {
|
||||||
|
return sdk.ErrInvalidSequence(
|
||||||
|
fmt.Sprintf("Invalid sequence. Got %d, expected %d", sigs[i].Sequence, seq)).Result()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sdk.Result{}
|
||||||
|
}
|
||||||
|
|
||||||
// verify the signature and increment the sequence.
|
// verify the signature and increment the sequence.
|
||||||
// if the account doesn't have a pubkey, set it.
|
// if the account doesn't have a pubkey, set it.
|
||||||
func processSig(
|
func processSig(ctx sdk.Context,
|
||||||
ctx sdk.Context, am AccountMapper,
|
acc Account, sig StdSignature, signBytes []byte, simulate bool) (updatedAcc Account, res sdk.Result) {
|
||||||
addr sdk.AccAddress, sig StdSignature, signBytes []byte, simulate bool) (
|
|
||||||
acc Account, res sdk.Result) {
|
|
||||||
// Get the account.
|
|
||||||
acc = am.GetAccount(ctx, addr)
|
|
||||||
if acc == nil {
|
|
||||||
return nil, sdk.ErrUnknownAddress(addr.String()).Result()
|
|
||||||
}
|
|
||||||
|
|
||||||
accnum := acc.GetAccountNumber()
|
|
||||||
seq := acc.GetSequence()
|
|
||||||
|
|
||||||
// Check account number.
|
|
||||||
if accnum != sig.AccountNumber {
|
|
||||||
return nil, sdk.ErrInvalidSequence(
|
|
||||||
fmt.Sprintf("Invalid account number. Got %d, expected %d", sig.AccountNumber, accnum)).Result()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check sequence number.
|
|
||||||
if seq != sig.Sequence {
|
|
||||||
return nil, sdk.ErrInvalidSequence(
|
|
||||||
fmt.Sprintf("Invalid sequence. Got %d, expected %d", sig.Sequence, seq)).Result()
|
|
||||||
}
|
|
||||||
err := acc.SetSequence(seq + 1)
|
|
||||||
if err != nil {
|
|
||||||
// Handle w/ #870
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
pubKey, res := processPubKey(acc, sig, simulate)
|
pubKey, res := processPubKey(acc, sig, simulate)
|
||||||
if !res.IsOK() {
|
if !res.IsOK() {
|
||||||
return nil, res
|
return nil, res
|
||||||
}
|
}
|
||||||
err = acc.SetPubKey(pubKey)
|
err := acc.SetPubKey(pubKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, sdk.ErrInternal("setting PubKey on signer's account").Result()
|
return nil, sdk.ErrInternal("setting PubKey on signer's account").Result()
|
||||||
}
|
}
|
||||||
|
@ -195,7 +186,14 @@ func processSig(
|
||||||
return nil, sdk.ErrUnauthorized("signature verification failed").Result()
|
return nil, sdk.ErrUnauthorized("signature verification failed").Result()
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
// increment the sequence number
|
||||||
|
err = acc.SetSequence(acc.GetSequence() + 1)
|
||||||
|
if err != nil {
|
||||||
|
// Handle w/ #870
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return acc, res
|
||||||
}
|
}
|
||||||
|
|
||||||
var dummySecp256k1Pubkey secp256k1.PubKeySecp256k1
|
var dummySecp256k1Pubkey secp256k1.PubKeySecp256k1
|
||||||
|
@ -244,8 +242,9 @@ func consumeSignatureVerificationGas(meter sdk.GasMeter, pubkey crypto.PubKey) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func adjustFeesByGas(fees sdk.Coins, gas int64) sdk.Coins {
|
func adjustFeesByGas(fees sdk.Coins, gas int64) sdk.Coins {
|
||||||
gasCost := int64(float64(gas) * feeDeductionGasFactor)
|
gasCost := gas / gasPerUnitCost
|
||||||
gasFees := make(sdk.Coins, len(fees))
|
gasFees := make(sdk.Coins, len(fees))
|
||||||
|
// TODO: Make this not price all coins in the same way
|
||||||
for i := 0; i < len(fees); i++ {
|
for i := 0; i < len(fees); i++ {
|
||||||
gasFees[i] = sdk.NewInt64Coin(fees[i].Denom, gasCost)
|
gasFees[i] = sdk.NewInt64Coin(fees[i].Denom, gasCost)
|
||||||
}
|
}
|
||||||
|
@ -271,3 +270,35 @@ func deductFees(acc Account, fee StdFee) (Account, sdk.Result) {
|
||||||
}
|
}
|
||||||
return acc, sdk.Result{}
|
return acc, sdk.Result{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ensureSufficientMempoolFees(ctx sdk.Context, stdTx StdTx) sdk.Result {
|
||||||
|
// currently we use a very primitive gas pricing model with a constant gasPrice.
|
||||||
|
// adjustFeesByGas handles calculating the amount of fees required based on the provided gas.
|
||||||
|
// TODO: Make the gasPrice not a constant, and account for tx size.
|
||||||
|
requiredFees := adjustFeesByGas(ctx.MinimumFees(), stdTx.Fee.Gas)
|
||||||
|
|
||||||
|
if !ctx.MinimumFees().IsZero() && stdTx.Fee.Amount.IsLT(requiredFees) {
|
||||||
|
// validators reject any tx from the mempool with less than the minimum fee per gas * gas factor
|
||||||
|
return sdk.ErrInsufficientFee(fmt.Sprintf(
|
||||||
|
"insufficient fee, got: %q required: %q", stdTx.Fee.Amount, requiredFees)).Result()
|
||||||
|
}
|
||||||
|
return sdk.Result{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func setGasMeter(simulate bool, ctx sdk.Context, stdTx StdTx) sdk.Context {
|
||||||
|
// set the gas meter
|
||||||
|
if simulate {
|
||||||
|
return ctx.WithGasMeter(sdk.NewInfiniteGasMeter())
|
||||||
|
}
|
||||||
|
return ctx.WithGasMeter(sdk.NewGasMeter(stdTx.Fee.Gas))
|
||||||
|
}
|
||||||
|
|
||||||
|
func getSignBytesList(chainID string, stdTx StdTx, stdSigs []StdSignature) (signatureBytesList [][]byte) {
|
||||||
|
signatureBytesList = make([][]byte, len(stdSigs))
|
||||||
|
for i := 0; i < len(stdSigs); i++ {
|
||||||
|
signatureBytesList[i] = StdSignBytes(chainID,
|
||||||
|
stdSigs[i].AccountNumber, stdSigs[i].Sequence,
|
||||||
|
stdTx.Fee, stdTx.Msgs, stdTx.Memo)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ import (
|
||||||
var _ sdk.Tx = (*StdTx)(nil)
|
var _ sdk.Tx = (*StdTx)(nil)
|
||||||
|
|
||||||
// StdTx is a standard way to wrap a Msg with Fee and Signatures.
|
// StdTx is a standard way to wrap a Msg with Fee and Signatures.
|
||||||
// NOTE: the first signature is the FeePayer (Signatures must not be nil).
|
// NOTE: the first signature is the fee payer (Signatures must not be nil).
|
||||||
type StdTx struct {
|
type StdTx struct {
|
||||||
Msgs []sdk.Msg `json:"msg"`
|
Msgs []sdk.Msg `json:"msg"`
|
||||||
Fee StdFee `json:"fee"`
|
Fee StdFee `json:"fee"`
|
||||||
|
@ -63,13 +63,6 @@ func (tx StdTx) GetMemo() string { return tx.Memo }
|
||||||
// .Empty().
|
// .Empty().
|
||||||
func (tx StdTx) GetSignatures() []StdSignature { return tx.Signatures }
|
func (tx StdTx) GetSignatures() []StdSignature { return tx.Signatures }
|
||||||
|
|
||||||
// FeePayer returns the address responsible for paying the fees
|
|
||||||
// for the transactions. It's the first address returned by msg.GetSigners().
|
|
||||||
// If GetSigners() is empty, this panics.
|
|
||||||
func FeePayer(tx sdk.Tx) sdk.AccAddress {
|
|
||||||
return tx.GetMsgs()[0].GetSigners()[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
//__________________________________________________________
|
//__________________________________________________________
|
||||||
|
|
||||||
// StdFee includes the amount of coins paid in fees and the maximum
|
// StdFee includes the amount of coins paid in fees and the maximum
|
||||||
|
|
|
@ -23,7 +23,7 @@ func TestStdTx(t *testing.T) {
|
||||||
require.Equal(t, msgs, tx.GetMsgs())
|
require.Equal(t, msgs, tx.GetMsgs())
|
||||||
require.Equal(t, sigs, tx.GetSignatures())
|
require.Equal(t, sigs, tx.GetSignatures())
|
||||||
|
|
||||||
feePayer := FeePayer(tx)
|
feePayer := tx.GetSigners()[0]
|
||||||
require.Equal(t, addr, feePayer)
|
require.Equal(t, addr, feePayer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
package bank
|
package bank
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"reflect"
|
|
||||||
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -15,7 +13,7 @@ func NewHandler(k Keeper) sdk.Handler {
|
||||||
case MsgIssue:
|
case MsgIssue:
|
||||||
return handleMsgIssue(ctx, k, msg)
|
return handleMsgIssue(ctx, k, msg)
|
||||||
default:
|
default:
|
||||||
errMsg := "Unrecognized bank Msg type: " + reflect.TypeOf(msg).Name()
|
errMsg := "Unrecognized bank Msg type: %s" + msg.Name()
|
||||||
return sdk.ErrUnknownRequest(errMsg).Result()
|
return sdk.ErrUnknownRequest(errMsg).Result()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
package ibc
|
package ibc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"reflect"
|
|
||||||
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
"github.com/cosmos/cosmos-sdk/x/bank"
|
"github.com/cosmos/cosmos-sdk/x/bank"
|
||||||
)
|
)
|
||||||
|
@ -15,7 +13,7 @@ func NewHandler(ibcm Mapper, ck bank.Keeper) sdk.Handler {
|
||||||
case IBCReceiveMsg:
|
case IBCReceiveMsg:
|
||||||
return handleIBCReceiveMsg(ctx, ibcm, ck, msg)
|
return handleIBCReceiveMsg(ctx, ibcm, ck, msg)
|
||||||
default:
|
default:
|
||||||
errMsg := "Unrecognized IBC Msg type: " + reflect.TypeOf(msg).Name()
|
errMsg := "Unrecognized IBC Msg type: " + msg.Name()
|
||||||
return sdk.ErrUnknownRequest(errMsg).Result()
|
return sdk.ErrUnknownRequest(errMsg).Result()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ func AllInvariants(ck bank.Keeper, k stake.Keeper, am auth.AccountMapper) simula
|
||||||
func SupplyInvariants(ck bank.Keeper, k stake.Keeper, am auth.AccountMapper) simulation.Invariant {
|
func SupplyInvariants(ck bank.Keeper, k stake.Keeper, am auth.AccountMapper) simulation.Invariant {
|
||||||
return func(app *baseapp.BaseApp) error {
|
return func(app *baseapp.BaseApp) error {
|
||||||
ctx := app.NewContext(false, abci.Header{})
|
ctx := app.NewContext(false, abci.Header{})
|
||||||
//pool := k.GetPool(ctx)
|
pool := k.GetPool(ctx)
|
||||||
|
|
||||||
loose := sdk.ZeroInt()
|
loose := sdk.ZeroInt()
|
||||||
bonded := sdk.ZeroDec()
|
bonded := sdk.ZeroDec()
|
||||||
|
@ -59,14 +59,14 @@ func SupplyInvariants(ck bank.Keeper, k stake.Keeper, am auth.AccountMapper) sim
|
||||||
})
|
})
|
||||||
|
|
||||||
// Loose tokens should equal coin supply plus unbonding delegations plus tokens on unbonded validators
|
// Loose tokens should equal coin supply plus unbonding delegations plus tokens on unbonded validators
|
||||||
// XXX TODO https://github.com/cosmos/cosmos-sdk/issues/2063#issuecomment-413720872
|
if pool.LooseTokens.RoundInt64() != loose.Int64() {
|
||||||
// require.True(t, pool.LooseTokens.RoundInt64() == loose.Int64(), "expected loose tokens to equal total steak held by accounts - pool.LooseTokens: %v, sum of account tokens: %v\nlog: %s",
|
return fmt.Errorf("expected loose tokens to equal total steak held by accounts - pool.LooseTokens: %v, sum of account tokens: %v", pool.LooseTokens.RoundInt64(), loose.Int64())
|
||||||
// pool.LooseTokens.RoundInt64(), loose.Int64(), log)
|
}
|
||||||
|
|
||||||
// Bonded tokens should equal sum of tokens with bonded validators
|
// Bonded tokens should equal sum of tokens with bonded validators
|
||||||
// XXX TODO https://github.com/cosmos/cosmos-sdk/issues/2063#issuecomment-413720872
|
if pool.BondedTokens.RoundInt64() != bonded.RoundInt64() {
|
||||||
// require.True(t, pool.BondedTokens.RoundInt64() == bonded.RoundInt64(), "expected bonded tokens to equal total steak held by bonded validators - pool.BondedTokens: %v, sum of bonded validator tokens: %v\nlog: %s",
|
return fmt.Errorf("expected bonded tokens to equal total steak held by bonded validators - pool.BondedTokens: %v, sum of bonded validator tokens: %v", pool.BondedTokens.RoundInt64(), bonded.RoundInt64())
|
||||||
// pool.BondedTokens.RoundInt64(), bonded.RoundInt64(), log)
|
}
|
||||||
|
|
||||||
// TODO Inflation check on total supply
|
// TODO Inflation check on total supply
|
||||||
return nil
|
return nil
|
||||||
|
|
Loading…
Reference in New Issue