additions

This commit is contained in:
Federico Kunze 2021-04-18 17:54:18 +02:00
parent 5a3d514ba0
commit 614e62fb7e
No known key found for this signature in database
GPG Key ID: 655F93A970080A30
138 changed files with 11348 additions and 2906 deletions

View File

@ -61,25 +61,3 @@ func ValidateChainID(baseCmd *cobra.Command) *cobra.Command {
baseCmd.RunE = validateFn baseCmd.RunE = validateFn
return baseCmd return baseCmd
} }
// GenerateChainID wraps a cobra command with a RunE function with base 10 integer chain-id random generation
// when a chain-id is not provided.
func GenerateChainID(baseCmd *cobra.Command) *cobra.Command {
// Copy base run command to be used after chain verification
baseRunE := baseCmd.RunE
// Function to replace command's RunE function
generateFn := func(cmd *cobra.Command, args []string) error {
chainID, _ := cmd.Flags().GetString(flags.FlagChainID)
if chainID == "" {
if err := cmd.Flags().Set(flags.FlagChainID, ethermint.GenerateRandomChainID()); err != nil {
return fmt.Errorf("could not set random chain-id: %v", err)
}
}
return baseRunE(cmd, args)
}
baseCmd.RunE = generateFn
return baseCmd
}

View File

@ -5,17 +5,15 @@ import (
"fmt" "fmt"
"strings" "strings"
"github.com/spf13/cobra"
"github.com/ethereum/go-ethereum/common/hexutil"
ethcrypto "github.com/ethereum/go-ethereum/crypto"
"github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/client/input" "github.com/cosmos/cosmos-sdk/client/input"
"github.com/cosmos/cosmos-sdk/crypto" "github.com/cosmos/cosmos-sdk/crypto"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/ethereum/go-ethereum/common/hexutil"
ethcrypto "github.com/ethereum/go-ethereum/crypto"
"github.com/spf13/cobra"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
"github.com/cosmos/ethermint/crypto/ethsecp256k1" "github.com/cosmos/ethermint/crypto/ethsecp256k1"
"github.com/cosmos/ethermint/crypto/hd" "github.com/cosmos/ethermint/crypto/hd"
) )
@ -77,13 +75,13 @@ func UnsafeExportEthKeyCommand() *cobra.Command {
} }
// Converts key to Ethermint secp256 implementation // Converts key to Ethermint secp256 implementation
ethermintPrivKey, ok := privKey.(*ethsecp256k1.PrivKey) ethPrivKey, ok := privKey.(*ethsecp256k1.PrivKey)
if !ok { if !ok {
return fmt.Errorf("invalid private key type %T, expected %T", privKey, &ethsecp256k1.PrivKey{}) return fmt.Errorf("invalid private key type %T, expected %T", privKey, &ethsecp256k1.PrivKey{})
} }
// Formats key for output // Formats key for output
privB := ethcrypto.FromECDSA(ethermintPrivKey.ToECDSA()) privB := ethcrypto.FromECDSA(ethPrivKey.ToECDSA())
keyS := strings.ToUpper(hexutil.Encode(privB)[2:]) keyS := strings.ToUpper(hexutil.Encode(privB)[2:])
fmt.Println(keyS) fmt.Println(keyS)

58
client/import.go Normal file
View File

@ -0,0 +1,58 @@
package client
import (
"bufio"
"github.com/spf13/cobra"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/client/input"
"github.com/cosmos/cosmos-sdk/crypto"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/ethermint/crypto/ethsecp256k1"
"github.com/ethereum/go-ethereum/common"
"github.com/cosmos/ethermint/crypto/hd"
)
// UnsafeImportKeyCommand imports private keys from a keyfile.
func UnsafeImportKeyCommand() *cobra.Command {
return &cobra.Command{
Use: "unsafe-import-eth-key <name> <pk>",
Short: "**UNSAFE** Import Ethereum private keys into the local keybase",
Long: "**UNSAFE** Import a hex-encoded Ethereum private key into the local keybase.",
Args: cobra.ExactArgs(2),
RunE: runImportCmd,
}
}
func runImportCmd(cmd *cobra.Command, args []string) error {
inBuf := bufio.NewReader(cmd.InOrStdin())
keyringBackend, _ := cmd.Flags().GetString(flags.FlagKeyringBackend)
rootDir, _ := cmd.Flags().GetString(flags.FlagHome)
kb, err := keyring.New(
sdk.KeyringServiceName(),
keyringBackend,
rootDir,
inBuf,
hd.EthSecp256k1Option(),
)
if err != nil {
return err
}
passphrase, err := input.GetPassword("Enter passphrase to encrypt your key:", inBuf)
if err != nil {
return err
}
privKey := &ethsecp256k1.PrivKey{
Key: common.FromHex(args[1]),
}
armor := crypto.EncryptArmorPrivKey(privKey, passphrase, "eth_secp256k1")
return kb.ImportPrivKey(args[0], armor, passphrase)
}

109
client/keys.go Normal file
View File

@ -0,0 +1,109 @@
package client
import (
"bufio"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/client/keys"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/spf13/cobra"
"github.com/tendermint/tendermint/libs/cli"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
"github.com/cosmos/ethermint/crypto/hd"
)
const (
flagDryRun = "dry-run"
)
// KeyCommands registers a sub-tree of commands to interact with
// local private key storage.
func KeyCommands(defaultNodeHome string) *cobra.Command {
cmd := &cobra.Command{
Use: "keys",
Short: "Manage your application's keys",
Long: `Keyring management commands. These keys may be in any format supported by the
Tendermint crypto library and can be used by light-clients, full nodes, or any other application
that needs to sign with a private key.
The keyring supports the following backends:
os Uses the operating system's default credentials store.
file Uses encrypted file-based keystore within the app's configuration directory.
This keyring will request a password each time it is accessed, which may occur
multiple times in a single command resulting in repeated password prompts.
kwallet Uses KDE Wallet Manager as a credentials management application.
pass Uses the pass command line utility to store and retrieve keys.
test Stores keys insecurely to disk. It does not prompt for a password to be unlocked
and it should be use only for testing purposes.
kwallet and pass backends depend on external tools. Refer to their respective documentation for more
information:
KWallet https://github.com/KDE/kwallet
pass https://www.passwordstore.org/
The pass backend requires GnuPG: https://gnupg.org/
`,
}
// support adding Ethereum supported keys
addCmd := keys.AddKeyCommand()
// update the default signing algorithm value to "eth_secp256k1"
algoFlag := addCmd.Flag("algo")
algoFlag.DefValue = string(hd.EthSecp256k1Type)
err := algoFlag.Value.Set(string(hd.EthSecp256k1Type))
if err != nil {
panic(err)
}
addCmd.RunE = runAddCmd
cmd.AddCommand(
keys.MnemonicKeyCommand(),
addCmd,
keys.ExportKeyCommand(),
keys.ImportKeyCommand(),
keys.ListKeysCmd(),
keys.ShowKeysCmd(),
flags.LineBreak,
keys.DeleteKeyCommand(),
keys.ParseKeyStringCommand(),
keys.MigrateCommand(),
flags.LineBreak,
UnsafeExportEthKeyCommand(),
UnsafeImportKeyCommand(),
)
cmd.PersistentFlags().String(flags.FlagHome, defaultNodeHome, "The application home directory")
cmd.PersistentFlags().String(flags.FlagKeyringDir, "", "The client Keyring directory; if omitted, the default 'home' directory will be used")
cmd.PersistentFlags().String(flags.FlagKeyringBackend, keyring.BackendFile, "Select keyring's backend (os|file|test)")
cmd.PersistentFlags().String(cli.OutputFlag, "text", "Output format (text|json)")
return cmd
}
func runAddCmd(cmd *cobra.Command, args []string) error {
buf := bufio.NewReader(cmd.InOrStdin())
clientCtx := client.GetClientContextFromCmd(cmd)
var (
kr keyring.Keyring
err error
)
dryRun, _ := cmd.Flags().GetBool(flags.FlagDryRun)
if dryRun {
kr, err = keyring.New(sdk.KeyringServiceName(), keyring.BackendMemory, clientCtx.KeyringDir, buf, hd.EthSecp256k1Option())
} else {
backend, _ := cmd.Flags().GetString(flags.FlagKeyringBackend)
kr, err = keyring.New(sdk.KeyringServiceName(), backend, clientCtx.KeyringDir, buf, hd.EthSecp256k1Option())
}
if err != nil {
return err
}
return keys.RunAddCmd(cmd, args, kr, buf)
}

View File

@ -4,13 +4,20 @@ package client
import ( import (
"bufio" "bufio"
"bytes"
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"io/ioutil"
"log"
"net" "net"
"os" "os"
"path/filepath" "path/filepath"
"strings"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
ethcrypto "github.com/ethereum/go-ethereum/crypto"
"github.com/spf13/cobra" "github.com/spf13/cobra"
tmconfig "github.com/tendermint/tendermint/config" tmconfig "github.com/tendermint/tendermint/config"
@ -22,8 +29,6 @@ import (
"github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/client/tx" "github.com/cosmos/cosmos-sdk/client/tx"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
"github.com/cosmos/cosmos-sdk/server" "github.com/cosmos/cosmos-sdk/server"
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module" "github.com/cosmos/cosmos-sdk/types/module"
@ -36,12 +41,14 @@ import (
mintypes "github.com/cosmos/cosmos-sdk/x/mint/types" mintypes "github.com/cosmos/cosmos-sdk/x/mint/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
ethcrypto "github.com/ethereum/go-ethereum/crypto" "github.com/cosmos/cosmos-sdk/crypto/keyring"
"github.com/cosmos/ethermint/crypto/hd" "github.com/cosmos/ethermint/crypto/hd"
srvconfig "github.com/cosmos/ethermint/server/config" chaintypes "github.com/cosmos/ethermint/types"
ethermint "github.com/cosmos/ethermint/types"
evmtypes "github.com/cosmos/ethermint/x/evm/types" evmtypes "github.com/cosmos/ethermint/x/evm/types"
"github.com/cosmos/ethermint/cmd/injectived/config"
"github.com/cosmos/ethermint/crypto/ethsecp256k1"
"github.com/ethereum/go-ethereum/common"
) )
var ( var (
@ -67,7 +74,7 @@ necessary files (private validator, genesis, config, etc.).
Note, strict routability for addresses is turned off in the config file.`, Note, strict routability for addresses is turned off in the config file.`,
Example: "ethermintd testnet --v 4 --keyring-backend test --output-dir ./output --ip-addresses 192.168.10.2", Example: "injectived testnet --v 4 --keyring-backend test --output-dir ./output --ip-addresses 192.168.10.2",
RunE: func(cmd *cobra.Command, _ []string) error { RunE: func(cmd *cobra.Command, _ []string) error {
clientCtx := client.GetClientContextFromCmd(cmd) clientCtx := client.GetClientContextFromCmd(cmd)
@ -99,13 +106,13 @@ Note, strict routability for addresses is turned off in the config file.`,
cmd.Flags().Int(flagNumValidators, 4, "Number of validators to initialize the testnet with") cmd.Flags().Int(flagNumValidators, 4, "Number of validators to initialize the testnet with")
cmd.Flags().StringP(flagOutputDir, "o", "./mytestnet", "Directory to store initialization data for the testnet") cmd.Flags().StringP(flagOutputDir, "o", "./mytestnet", "Directory to store initialization data for the testnet")
cmd.Flags().String(flagNodeDirPrefix, "node", "Prefix the directory name for each node with (node results in node0, node1, ...)") cmd.Flags().String(flagNodeDirPrefix, "node", "Prefix the directory name for each node with (node results in node0, node1, ...)")
cmd.Flags().String(flagNodeDaemonHome, "simd", "Home directory of the node's daemon configuration") cmd.Flags().String(flagNodeDaemonHome, "injectived", "Home directory of the node's daemon configuration")
cmd.Flags().StringSlice(flagIPAddrs, []string{"192.168.0.1"}, "List of IP addresses to use (i.e. `192.168.0.1,172.168.0.1` results in persistent peers list ID0@192.168.0.1:46656, ID1@172.168.0.1)") cmd.Flags().StringSlice(flagIPAddrs, []string{"192.168.0.1"}, "List of IP addresses to use (i.e. `192.168.0.1,172.168.0.1` results in persistent peers list ID0@192.168.0.1:46656, ID1@172.168.0.1)")
cmd.Flags().String(flags.FlagChainID, "", "genesis file chain-id, if left blank will be randomly created") cmd.Flags().String(flags.FlagChainID, "", "genesis file chain-id, if left blank will be randomly created")
cmd.Flags().String(server.FlagMinGasPrices, fmt.Sprintf("0.000006%s", ethermint.AttoPhoton), "Minimum gas prices to accept for transactions; All fees in a tx must meet this minimum (e.g. 0.01aphoton,0.001stake)") cmd.Flags().String(server.FlagMinGasPrices, "", "Minimum gas prices to accept for transactions; All fees in a tx must meet this minimum (e.g. 0.01inj,0.001stake)")
cmd.Flags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, "Select keyring's backend (os|file|test)") cmd.Flags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, "Select keyring's backend (os|file|test)")
cmd.Flags().String(flags.FlagKeyAlgorithm, string(hd.EthSecp256k1Type), "Key signing algorithm to generate keys for") cmd.Flags().String(flags.FlagKeyAlgorithm, string(hd.EthSecp256k1Type), "Key signing algorithm to generate keys for")
cmd.Flags().String(flagCoinDenom, ethermint.AttoPhoton, "Coin denomination used for staking, governance, mint, crisis and evm parameters") cmd.Flags().String(flagCoinDenom, chaintypes.InjectiveCoin, "Coin denomination used for staking, governance, mint, crisis and evm parameters")
return cmd return cmd
} }
@ -129,10 +136,10 @@ func InitTestnet(
) error { ) error {
if chainID == "" { if chainID == "" {
chainID = fmt.Sprintf("ethermint-%d", tmrand.Int63n(9999999999999)+1) chainID = fmt.Sprintf("injective-%d", tmrand.Int63n(9999999999999)+1)
} }
if !ethermint.IsValidChainID(chainID) { if !chaintypes.IsValidChainID(chainID) {
return fmt.Errorf("invalid chain-id: %s", chainID) return fmt.Errorf("invalid chain-id: %s", chainID)
} }
@ -147,7 +154,7 @@ func InitTestnet(
nodeIDs := make([]string, numValidators) nodeIDs := make([]string, numValidators)
valPubKeys := make([]cryptotypes.PubKey, numValidators) valPubKeys := make([]cryptotypes.PubKey, numValidators)
appConfig := srvconfig.DefaultConfig() appConfig := config.DefaultConfig()
appConfig.MinGasPrices = minGasPrices appConfig.MinGasPrices = minGasPrices
appConfig.API.Enable = true appConfig.API.Enable = true
appConfig.Telemetry.Enabled = true appConfig.Telemetry.Enabled = true
@ -243,7 +250,7 @@ func InitTestnet(
) )
genBalances = append(genBalances, banktypes.Balance{Address: addr.String(), Coins: coins}) genBalances = append(genBalances, banktypes.Balance{Address: addr.String(), Coins: coins})
genAccounts = append(genAccounts, &ethermint.EthAccount{ genAccounts = append(genAccounts, &chaintypes.EthAccount{
BaseAccount: authtypes.NewBaseAccount(addr, nil, 0, 0), BaseAccount: authtypes.NewBaseAccount(addr, nil, 0, 0),
CodeHash: ethcrypto.Keccak256(nil), CodeHash: ethcrypto.Keccak256(nil),
}) })
@ -289,7 +296,10 @@ func InitTestnet(
return err return err
} }
srvconfig.WriteConfigFile(filepath.Join(nodeDir, "config/app.toml"), appConfig) config.WriteConfigFile(filepath.Join(nodeDir, "config/app.toml"), appConfig)
ethPrivKey, err := keyring.NewUnsafe(kb).UnsafeExportPrivKeyHex(nodeDirName)
initPeggo(outputDir, nodeDirName, []byte(strings.ToUpper(ethPrivKey)))
} }
if err := initGenFiles(clientCtx, mbm, chainID, coinDenom, genAccounts, genBalances, genFiles, numValidators); err != nil { if err := initGenFiles(clientCtx, mbm, chainID, coinDenom, genAccounts, genBalances, genFiles, numValidators); err != nil {
@ -308,6 +318,32 @@ func InitTestnet(
return nil return nil
} }
func initPeggo(outputDir string, nodeDirName string, privKey []byte) {
peggoDir := filepath.Join(outputDir, nodeDirName, "peggo")
if envdata, _ := ioutil.ReadFile("./templates/peggo_config.template"); len(envdata) > 0 {
s := bufio.NewScanner(bytes.NewReader(envdata))
for s.Scan() {
parts := strings.Split(s.Text(), "=")
if len(parts) != 2 {
continue
} else {
content := []byte(s.Text())
if parts[0] == "PEGGY_COSMOS_PRIVKEY" {
content = append([]byte(parts[0]+"="), privKey...)
} else if parts[0] == "PEGGY_ETH_PRIVATE_KEY" {
newPrivkey, _ := ethsecp256k1.GenerateKey()
privKeyStr := common.Bytes2Hex(newPrivkey.GetKey())
privKeyBytes := []byte(strings.ToUpper(privKeyStr))
content = append([]byte(parts[0]+"="), privKeyBytes...)
}
if err := appendToFile(fmt.Sprintf("config.env"), peggoDir, content); err != nil {
fmt.Println("Error writing peggo config", "error", err)
}
}
}
}
}
func initGenFiles( func initGenFiles(
clientCtx client.Context, clientCtx client.Context,
mbm module.BasicManager, mbm module.BasicManager,
@ -476,3 +512,42 @@ func writeFile(name string, dir string, contents []byte) error {
return nil return nil
} }
func appendToFile(name string, dir string, contents []byte) error {
writePath := filepath.Join(dir)
file := filepath.Join(writePath, name)
err := tmos.EnsureDir(writePath, 0755)
if err != nil {
return err
}
if _, err = os.Stat(file); err == nil {
err = os.Chmod(file, 0777)
if err != nil {
fmt.Println(err)
return err
}
}
f, err := os.OpenFile(file, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
log.Println(err)
return err
}
defer f.Close()
_, err = f.Write(contents)
if err != nil {
log.Println(err)
return err
}
f.Write([]byte("\n"))
if err != nil {
log.Println(err)
return err
}
return nil
}

View File

@ -9,4 +9,4 @@ for D in ../x/*; do
fi fi
done done
cat ../x/README.md | sed 's/\.\/x/\/modules/g' | sed 's/spec\/README.md//g' cat ../x/README.md | sed 's/\.\/x/\/x/g' | sed 's/spec\/README.md//g'

View File

@ -171,3 +171,79 @@ message Log {
// through a filter query. // through a filter query.
bool removed = 9; bool removed = 9;
} }
// TxReceipt defines the receipt type stored in KV for each EVM transaction.
message TxReceipt {
option (gogoproto.goproto_getters) = false;
bytes hash = 1;
bytes from = 2;
TxData data = 3;
TxResult result = 4;
uint64 index = 5;
uint64 blockHeight = 6;
bytes blockHash = 7;
}
// TxResult stores results of Tx execution.
message TxResult {
option (gogoproto.goproto_getters) = false;
// contract_address contains the ethereum address of the created contract (if
// any). If the state transition is an evm.Call, the contract address will be
// empty.
string contract_address = 1
[ (gogoproto.moretags) = "yaml:\"contract_address\"" ];
// bloom represents the bloom filter bytes
bytes bloom = 2;
// tx_logs contains the transaction hash and the proto-compatible ethereum
// logs.
TransactionLogs tx_logs = 3 [
(gogoproto.moretags) = "yaml:\"tx_logs\"",
(gogoproto.nullable) = false
];
// ret defines the bytes from the execution.
bytes ret = 4;
// reverted flag is set to true when the call has been reverted
bool reverted = 5;
// gas_used notes the amount of gas consumed while execution
uint64 gas_used = 6;
}
// TxData implements the Ethereum transaction data structure. It is used
// solely as intended in Ethereum abiding by the protocol.
message TxData {
option (gogoproto.goproto_getters) = false;
// nonce corresponds to the account nonce (transaction sequence).
uint64 nonce = 1 [(gogoproto.customname) = "AccountNonce"];
// price defines the unsigned integer value of the gas price in bytes.
bytes price = 2 [
(gogoproto.jsontag) = "gasPrice"
];
// gas defines the gas limit defined for the transaction.
uint64 gas = 3 [(gogoproto.customname) = "GasLimit"];
bytes to = 4 [
(gogoproto.customname) = "Recipient"
];
// value defines the unsigned integer value of the transaction amount.
bytes value = 5 [
(gogoproto.customname) = "Amount"
];
// input defines the data payload bytes of the transaction.
bytes input = 6 [(gogoproto.customname) = "Payload"];
// v defines the signature value
bytes v = 7;
// r defines the signature value
bytes r = 8;
// s define the signature value
bytes s = 9;
// hash defines the tx data hash, which is only used when marshaling to JSON.
string hash = 10 [ (gogoproto.moretags) = "rlp:\"-\"" ];
}
message BytesList {
option (gogoproto.goproto_getters) = false;
repeated bytes bytes = 1;
}

View File

@ -14,6 +14,11 @@ service Query {
option (google.api.http).get = "/ethermint/evm/v1alpha1/account/{address}"; option (google.api.http).get = "/ethermint/evm/v1alpha1/account/{address}";
} }
// Account queries an Ethereum account's Cosmos Address.
rpc CosmosAccount(QueryCosmosAccountRequest) returns (QueryCosmosAccountResponse) {
option (google.api.http).get = "/ethermint/evm/v1alpha1/cosmos_account/{address}";
}
// Balance queries the balance of a the EVM denomination for a single // Balance queries the balance of a the EVM denomination for a single
// EthAccount. // EthAccount.
rpc Balance(QueryBalanceRequest) returns (QueryBalanceResponse) { rpc Balance(QueryBalanceRequest) returns (QueryBalanceResponse) {
@ -36,6 +41,21 @@ service Query {
option (google.api.http).get = "/ethermint/evm/v1alpha1/tx_logs/{hash}"; option (google.api.http).get = "/ethermint/evm/v1alpha1/tx_logs/{hash}";
} }
// TxReceipt queries a receipt by a transaction hash.
rpc TxReceipt(QueryTxReceiptRequest) returns (QueryTxReceiptResponse) {
option (google.api.http).get = "/ethermint/evm/v1alpha1/tx_receipt/{hash}";
}
// TxReceiptsByBlockHeight queries tx receipts by a block height.
rpc TxReceiptsByBlockHeight(QueryTxReceiptsByBlockHeightRequest) returns (QueryTxReceiptsByBlockHeightResponse) {
option (google.api.http).get = "/ethermint/evm/v1alpha1/tx_receipts_block/{height}";
}
// TxReceiptsByBlockHash queries tx receipts by a block hash.
rpc TxReceiptsByBlockHash(QueryTxReceiptsByBlockHashRequest) returns (QueryTxReceiptsByBlockHashResponse) {
option (google.api.http).get = "/ethermint/evm/v1alpha1/tx_receipts_block_hash/{hash}";
}
// BlockLogs queries all the ethereum logs for a given block hash. // BlockLogs queries all the ethereum logs for a given block hash.
rpc BlockLogs(QueryBlockLogsRequest) returns (QueryBlockLogsResponse) { rpc BlockLogs(QueryBlockLogsRequest) returns (QueryBlockLogsResponse) {
option (google.api.http).get = "/ethermint/evm/v1alpha1/block_logs/{hash}"; option (google.api.http).get = "/ethermint/evm/v1alpha1/block_logs/{hash}";
@ -50,6 +70,11 @@ service Query {
rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { rpc Params(QueryParamsRequest) returns (QueryParamsResponse) {
option (google.api.http).get = "/ethermint/evm/v1alpha1/params"; option (google.api.http).get = "/ethermint/evm/v1alpha1/params";
} }
// StaticCall queries the static call value of x/evm module.
rpc StaticCall(QueryStaticCallRequest) returns (QueryStaticCallResponse) {
option (google.api.http).get = "/ethermint/evm/v1alpha1/static_call";
}
} }
// QueryAccountRequest is the request type for the Query/Account RPC method. // QueryAccountRequest is the request type for the Query/Account RPC method.
@ -71,6 +96,25 @@ message QueryAccountResponse {
uint64 nonce = 3; uint64 nonce = 3;
} }
// QueryCosmosAccountRequest is the request type for the Query/CosmosAccount RPC method.
message QueryCosmosAccountRequest {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
// address is the ethereum hex address to query the account for.
string address = 1;
}
// QueryCosmosAccountResponse is the response type for the Query/CosmosAccount RPC method.
message QueryCosmosAccountResponse {
// cosmos_address is the cosmos address of the account.
string cosmos_address = 1;
// sequence is the account's sequence number.
uint64 sequence = 2;
// account_number is the account numbert
uint64 account_number = 3;
}
// QueryBalanceRequest is the request type for the Query/Balance RPC method. // QueryBalanceRequest is the request type for the Query/Balance RPC method.
message QueryBalanceRequest { message QueryBalanceRequest {
option (gogoproto.equal) = false; option (gogoproto.equal) = false;
@ -136,6 +180,51 @@ message QueryTxLogsResponse {
repeated Log logs = 1; repeated Log logs = 1;
} }
// QueryTxReceiptRequest is the request type for the Query/TxReceipt RPC method.
message QueryTxReceiptRequest {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
// hash is the ethereum transaction hex hash to query the receipt for.
string hash = 1;
}
// QueryTxReceiptResponse is the response type for the Query/TxReceipt RPC method.
message QueryTxReceiptResponse {
// receipt represents the ethereum receipt for the given transaction.
TxReceipt receipt = 1;
}
// QueryTxReceiptsByBlockHeightRequest is the request type for the Query/TxReceiptsByBlockHeight RPC method.
message QueryTxReceiptsByBlockHeightRequest {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
// height is the block height to query tx receipts for
int64 height = 1;
}
// QueryTxReceiptsByBlockHeightResponse is the response type for the Query/TxReceiptsByBlockHeight RPC method.
message QueryTxReceiptsByBlockHeightResponse {
// tx receipts list for the block
repeated TxReceipt receipts = 1;
}
// QueryTxReceiptsByBlockHashRequest is the request type for the Query/TxReceiptsByBlockHash RPC method.
message QueryTxReceiptsByBlockHashRequest {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
// hash is the ethereum transaction hex hash to query the receipt for.
string hash = 1;
}
// QueryTxReceiptsByBlockHashResponse is the response type for the Query/TxReceiptsByBlockHash RPC method.
message QueryTxReceiptsByBlockHashResponse {
// tx receipts list for the block
repeated TxReceipt receipts = 1;
}
// QueryBlockLogsRequest is the request type for the Query/BlockLogs RPC method. // QueryBlockLogsRequest is the request type for the Query/BlockLogs RPC method.
message QueryBlockLogsRequest { message QueryBlockLogsRequest {
option (gogoproto.equal) = false; option (gogoproto.equal) = false;
@ -153,7 +242,7 @@ message QueryBlockLogsResponse {
// QueryBlockBloomRequest is the request type for the Query/BlockBloom RPC // QueryBlockBloomRequest is the request type for the Query/BlockBloom RPC
// method. // method.
message QueryBlockBloomRequest {} message QueryBlockBloomRequest { int64 height = 1; }
// QueryBlockBloomResponse is the response type for the Query/BlockBloom RPC // QueryBlockBloomResponse is the response type for the Query/BlockBloom RPC
// method. // method.
@ -170,3 +259,16 @@ message QueryParamsResponse {
// params define the evm module parameters. // params define the evm module parameters.
Params params = 1 [ (gogoproto.nullable) = false ]; Params params = 1 [ (gogoproto.nullable) = false ];
} }
// QueryStaticCallRequest defines static call request
message QueryStaticCallRequest {
// address is the ethereum contract hex address to for static call.
string address = 1;
// static call input generated from abi
bytes input = 2;
}
// // QueryStaticCallRequest defines static call response
message QueryStaticCallResponse {
bytes data = 1;
}

View File

@ -22,6 +22,14 @@ message MsgEthereumTx {
SigCache from = 3 [ (gogoproto.jsontag) = "-" ]; SigCache from = 3 [ (gogoproto.jsontag) = "-" ];
} }
message ExtensionOptionsEthereumTx {
option (gogoproto.goproto_getters) = false;
}
message ExtensionOptionsWeb3Tx {
option (gogoproto.goproto_getters) = false;
}
// MsgEthereumTxResponse defines the Msg/EthereumTx response type. // MsgEthereumTxResponse defines the Msg/EthereumTx response type.
message MsgEthereumTxResponse { message MsgEthereumTxResponse {
option (gogoproto.goproto_getters) = false; option (gogoproto.goproto_getters) = false;
@ -40,52 +48,8 @@ message MsgEthereumTxResponse {
]; ];
// ret defines the bytes from the execution. // ret defines the bytes from the execution.
bytes ret = 4; bytes ret = 4;
} // reverted flag is set to true when the call has been reverted
bool reverted = 5;
// TxData implements the Ethereum transaction data structure. It is used
// solely as intended in Ethereum abiding by the protocol.
message TxData {
option (gogoproto.goproto_getters) = false;
// nonce corresponds to the account nonce (transaction sequence).
uint64 nonce = 1 [(gogoproto.customname) = "AccountNonce"];
// price defines the unsigned integer value of the gas price in bytes.
string price = 2 [
(gogoproto.jsontag) = "gasPrice",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false
];
// gas defines the gas limit defined for the transaction.
uint64 gas = 3 [(gogoproto.customname) = "GasLimit"];
Recipient to = 4 [
(gogoproto.customname) = "Recipient",
(gogoproto.moretags) = "rlp:\"nil\""
];
// value defines the unsigned integer value of the transaction amount.
string value = 5 [
(gogoproto.customname) = "Amount",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false
];
// input defines the data payload bytes of the transaction.
bytes input = 6 [(gogoproto.customname) = "Payload"];
// v defines the signature value
bytes v = 7;
// r defines the signature value
bytes r = 8;
// s define the signature value
bytes s = 9;
// hash defines the tx data hash, which is only used when marshaling to JSON.
string hash = 10 [ (gogoproto.moretags) = "rlp:\"-\"" ];
}
// Recipient defines a protobuf-compatible wrapper for an Ethereum address
// pointer. It is required for RLP encoding.
message Recipient {
option (gogoproto.goproto_getters) = false;
// address defines the hex-formated ethereum address of the recipient
string address = 1;
} }
// SigCache is used to cache the derived sender and contains the signer used // SigCache is used to cache the derived sender and contains the signer used
@ -94,7 +58,7 @@ message SigCache {
option (gogoproto.goproto_getters) = false; option (gogoproto.goproto_getters) = false;
EIP155Signer signer = 1; EIP155Signer signer = 1;
string address = 2; bytes address = 2;
} }
// EIP155Transaction implements Signer using the EIP155 rules. // EIP155Transaction implements Signer using the EIP155 rules.

View File

@ -18,12 +18,9 @@ message BaseAccount {
option (cosmos_proto.implements_interface) = "AccountI"; option (cosmos_proto.implements_interface) = "AccountI";
string address = 1; string address = 1;
google.protobuf.Any pub_key = 2 [ google.protobuf.Any pub_key = 2
(gogoproto.jsontag) = "public_key,omitempty", [(gogoproto.jsontag) = "public_key,omitempty", (gogoproto.moretags) = "yaml:\"public_key\""];
(gogoproto.moretags) = "yaml:\"public_key\"" uint64 account_number = 3 [(gogoproto.moretags) = "yaml:\"account_number\""];
];
uint64 account_number = 3
[ (gogoproto.moretags) = "yaml:\"account_number\"" ];
uint64 sequence = 4; uint64 sequence = 4;
} }
@ -33,10 +30,7 @@ message ModuleAccount {
option (gogoproto.goproto_stringer) = false; option (gogoproto.goproto_stringer) = false;
option (cosmos_proto.implements_interface) = "ModuleAccountI"; option (cosmos_proto.implements_interface) = "ModuleAccountI";
BaseAccount base_account = 1 [ BaseAccount base_account = 1 [(gogoproto.embed) = true, (gogoproto.moretags) = "yaml:\"base_account\""];
(gogoproto.embed) = true,
(gogoproto.moretags) = "yaml:\"base_account\""
];
string name = 2; string name = 2;
repeated string permissions = 3; repeated string permissions = 3;
} }
@ -46,17 +40,11 @@ message Params {
option (gogoproto.equal) = true; option (gogoproto.equal) = true;
option (gogoproto.goproto_stringer) = false; option (gogoproto.goproto_stringer) = false;
uint64 max_memo_characters = 1 uint64 max_memo_characters = 1 [(gogoproto.moretags) = "yaml:\"max_memo_characters\""];
[ (gogoproto.moretags) = "yaml:\"max_memo_characters\"" ];
uint64 tx_sig_limit = 2 [(gogoproto.moretags) = "yaml:\"tx_sig_limit\""]; uint64 tx_sig_limit = 2 [(gogoproto.moretags) = "yaml:\"tx_sig_limit\""];
uint64 tx_size_cost_per_byte = 3 uint64 tx_size_cost_per_byte = 3 [(gogoproto.moretags) = "yaml:\"tx_size_cost_per_byte\""];
[ (gogoproto.moretags) = "yaml:\"tx_size_cost_per_byte\"" ]; uint64 sig_verify_cost_ed25519 = 4
uint64 sig_verify_cost_ed25519 = 4 [ [(gogoproto.customname) = "SigVerifyCostED25519", (gogoproto.moretags) = "yaml:\"sig_verify_cost_ed25519\""];
(gogoproto.customname) = "SigVerifyCostED25519", uint64 sig_verify_cost_secp256k1 = 5
(gogoproto.moretags) = "yaml:\"sig_verify_cost_ed25519\"" [(gogoproto.customname) = "SigVerifyCostSecp256k1", (gogoproto.moretags) = "yaml:\"sig_verify_cost_secp256k1\""];
];
uint64 sig_verify_cost_secp256k1 = 5 [
(gogoproto.customname) = "SigVerifyCostSecp256k1",
(gogoproto.moretags) = "yaml:\"sig_verify_cost_secp256k1\""
];
} }

View File

@ -34,8 +34,7 @@ message QueryAccountRequest {
// QueryAccountResponse is the response type for the Query/Account RPC method. // QueryAccountResponse is the response type for the Query/Account RPC method.
message QueryAccountResponse { message QueryAccountResponse {
// account defines the account of the corresponding address. // account defines the account of the corresponding address.
google.protobuf.Any account = 1 google.protobuf.Any account = 1 [(cosmos_proto.accepts_interface) = "AccountI"];
[ (cosmos_proto.accepts_interface) = "AccountI" ];
} }
// QueryParamsRequest is the request type for the Query/Params RPC method. // QueryParamsRequest is the request type for the Query/Params RPC method.

View File

@ -0,0 +1,37 @@
syntax = "proto3";
package cosmos.authz.v1beta1;
import "cosmos/base/v1beta1/coin.proto";
import "cosmos_proto/cosmos.proto";
import "google/protobuf/timestamp.proto";
import "gogoproto/gogo.proto";
import "google/protobuf/any.proto";
option go_package = "github.com/cosmos/cosmos-sdk/x/authz/types";
// SendAuthorization allows the grantee to spend up to spend_limit coins from
// the granter's account.
message SendAuthorization {
option (cosmos_proto.implements_interface) = "Authorization";
repeated cosmos.base.v1beta1.Coin spend_limit = 1
[(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"];
}
// GenericAuthorization gives the grantee unrestricted permissions to execute
// the provided method on behalf of the granter's account.
message GenericAuthorization {
option (cosmos_proto.implements_interface) = "Authorization";
// method name to grant unrestricted permissions to execute
// Note: MethodName() is already a method on `GenericAuthorization` type,
// we need some custom naming here so using `MessageName`
string method_name = 1 [(gogoproto.customname) = "MessageName"];
}
// AuthorizationGrant gives permissions to execute
// the provide method with expiration time.
message AuthorizationGrant {
google.protobuf.Any authorization = 1 [(cosmos_proto.accepts_interface) = "Authorization"];
google.protobuf.Timestamp expiration = 2 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false];
}

View File

@ -0,0 +1,24 @@
syntax = "proto3";
package cosmos.authz.v1beta1;
import "google/protobuf/timestamp.proto";
import "google/protobuf/any.proto";
import "gogoproto/gogo.proto";
import "cosmos_proto/cosmos.proto";
import "cosmos/authz/v1beta1/tx.proto";
option go_package = "github.com/cosmos/cosmos-sdk/x/authz/types";
// GenesisState defines the authz module's genesis state.
message GenesisState {
repeated GrantAuthorization authorization = 1 [(gogoproto.nullable) = false];
}
// GrantAuthorization defines the GenesisState/GrantAuthorization type.
message GrantAuthorization {
string granter = 1;
string grantee = 2;
google.protobuf.Any authorization = 3 [(cosmos_proto.accepts_interface) = "Authorization"];
google.protobuf.Timestamp expiration = 4 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
}

View File

@ -0,0 +1,51 @@
syntax = "proto3";
package cosmos.authz.v1beta1;
import "google/api/annotations.proto";
import "cosmos/base/query/v1beta1/pagination.proto";
import "cosmos/authz/v1beta1/authz.proto";
option go_package = "github.com/cosmos/cosmos-sdk/x/authz/types";
// Query defines the gRPC querier service.
service Query {
// Returns any `Authorization` (or `nil`), with the expiration time, granted to the grantee by the granter for the
// provided msg type.
rpc Authorization(QueryAuthorizationRequest) returns (QueryAuthorizationResponse) {
option (google.api.http).get = "/cosmos/authz/v1beta1/granters/{granter}/grantees/{grantee}/grant";
}
// Returns list of `Authorization`, granted to the grantee by the granter.
rpc Authorizations(QueryAuthorizationsRequest) returns (QueryAuthorizationsResponse) {
option (google.api.http).get = "/cosmos/authz/v1beta1/granters/{granter}/grantees/{grantee}/grants";
}
}
// QueryAuthorizationRequest is the request type for the Query/Authorization RPC method.
message QueryAuthorizationRequest {
string granter = 1;
string grantee = 2;
string method_name = 3;
}
// QueryAuthorizationResponse is the response type for the Query/Authorization RPC method.
message QueryAuthorizationResponse {
// authorization is a authorization granted for grantee by granter.
cosmos.authz.v1beta1.AuthorizationGrant authorization = 1;
}
// QueryAuthorizationsRequest is the request type for the Query/Authorizations RPC method.
message QueryAuthorizationsRequest {
string granter = 1;
string grantee = 2;
// pagination defines an pagination for the request.
cosmos.base.query.v1beta1.PageRequest pagination = 3;
}
// QueryAuthorizationsResponse is the response type for the Query/Authorizations RPC method.
message QueryAuthorizationsResponse {
// authorizations is a list of grants granted for grantee by granter.
repeated cosmos.authz.v1beta1.AuthorizationGrant authorizations = 1;
// pagination defines an pagination for the response.
cosmos.base.query.v1beta1.PageResponse pagination = 2;
}

View File

@ -0,0 +1,62 @@
syntax = "proto3";
package cosmos.authz.v1beta1;
import "cosmos_proto/cosmos.proto";
import "gogoproto/gogo.proto";
import "google/protobuf/timestamp.proto";
import "google/protobuf/any.proto";
import "cosmos/base/abci/v1beta1/abci.proto";
option go_package = "github.com/cosmos/cosmos-sdk/x/authz/types";
// Msg defines the authz Msg service.
service Msg {
// GrantAuthorization grants the provided authorization to the grantee on the granter's
// account with the provided expiration time.
rpc GrantAuthorization(MsgGrantAuthorizationRequest) returns (MsgGrantAuthorizationResponse);
// ExecAuthorized attempts to execute the provided messages using
// authorizations granted to the grantee. Each message should have only
// one signer corresponding to the granter of the authorization.
rpc ExecAuthorized(MsgExecAuthorizedRequest) returns (MsgExecAuthorizedResponse);
// RevokeAuthorization revokes any authorization corresponding to the provided method name on the
// granter's account that has been granted to the grantee.
rpc RevokeAuthorization(MsgRevokeAuthorizationRequest) returns (MsgRevokeAuthorizationResponse);
}
// MsgGrantAuthorizationRequest grants the provided authorization to the grantee on the granter's
// account with the provided expiration time.
message MsgGrantAuthorizationRequest {
string granter = 1;
string grantee = 2;
google.protobuf.Any authorization = 3 [(cosmos_proto.accepts_interface) = "Authorization"];
google.protobuf.Timestamp expiration = 4 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
}
// MsgExecAuthorizedResponse defines the Msg/MsgExecAuthorizedResponse response type.
message MsgExecAuthorizedResponse {
cosmos.base.abci.v1beta1.Result result = 1;
}
// MsgExecAuthorizedRequest attempts to execute the provided messages using
// authorizations granted to the grantee. Each message should have only
// one signer corresponding to the granter of the authorization.
message MsgExecAuthorizedRequest {
string grantee = 1;
repeated google.protobuf.Any msgs = 2;
}
// MsgGrantAuthorizationResponse defines the Msg/MsgGrantAuthorization response type.
message MsgGrantAuthorizationResponse {}
// MsgRevokeAuthorizationRequest revokes any authorization with the provided sdk.Msg type on the
// granter's account with that has been granted to the grantee.
message MsgRevokeAuthorizationRequest {
string granter = 1;
string grantee = 2;
string method_name = 3;
}
// MsgRevokeAuthorizationResponse defines the Msg/MsgRevokeAuthorizationResponse response type.
message MsgRevokeAuthorizationResponse {}

View File

@ -10,10 +10,8 @@ option go_package = "github.com/cosmos/cosmos-sdk/x/bank/types";
// Params defines the parameters for the bank module. // Params defines the parameters for the bank module.
message Params { message Params {
option (gogoproto.goproto_stringer) = false; option (gogoproto.goproto_stringer) = false;
repeated SendEnabled send_enabled = 1 repeated SendEnabled send_enabled = 1 [(gogoproto.moretags) = "yaml:\"send_enabled,omitempty\""];
[ (gogoproto.moretags) = "yaml:\"send_enabled,omitempty\"" ]; bool default_send_enabled = 2 [(gogoproto.moretags) = "yaml:\"default_send_enabled,omitempty\""];
bool default_send_enabled = 2
[ (gogoproto.moretags) = "yaml:\"default_send_enabled,omitempty\"" ];
} }
// SendEnabled maps coin denom to a send_enabled status (whether a denom is // SendEnabled maps coin denom to a send_enabled status (whether a denom is
@ -31,10 +29,8 @@ message Input {
option (gogoproto.goproto_getters) = false; option (gogoproto.goproto_getters) = false;
string address = 1; string address = 1;
repeated cosmos.base.v1beta1.Coin coins = 2 [ repeated cosmos.base.v1beta1.Coin coins = 2
(gogoproto.nullable) = false, [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"];
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"
];
} }
// Output models transaction outputs. // Output models transaction outputs.
@ -43,10 +39,8 @@ message Output {
option (gogoproto.goproto_getters) = false; option (gogoproto.goproto_getters) = false;
string address = 1; string address = 1;
repeated cosmos.base.v1beta1.Coin coins = 2 [ repeated cosmos.base.v1beta1.Coin coins = 2
(gogoproto.nullable) = false, [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"];
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"
];
} }
// Supply represents a struct that passively keeps track of the total supply // Supply represents a struct that passively keeps track of the total supply
@ -56,13 +50,10 @@ message Supply {
option (gogoproto.goproto_getters) = false; option (gogoproto.goproto_getters) = false;
option (gogoproto.goproto_stringer) = false; option (gogoproto.goproto_stringer) = false;
option (cosmos_proto.implements_interface) = option (cosmos_proto.implements_interface) = "*github.com/cosmos/cosmos-sdk/x/bank/exported.SupplyI";
"*github.com/cosmos/cosmos-sdk/x/bank/exported.SupplyI";
repeated cosmos.base.v1beta1.Coin total = 1 [ repeated cosmos.base.v1beta1.Coin total = 1
(gogoproto.nullable) = false, [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"];
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"
];
} }
// DenomUnit represents a struct that describes a given // DenomUnit represents a struct that describes a given

View File

@ -16,16 +16,11 @@ message GenesisState {
repeated Balance balances = 2 [(gogoproto.nullable) = false]; repeated Balance balances = 2 [(gogoproto.nullable) = false];
// supply represents the total supply. // supply represents the total supply.
repeated cosmos.base.v1beta1.Coin supply = 3 [ repeated cosmos.base.v1beta1.Coin supply = 3
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", [(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", (gogoproto.nullable) = false];
(gogoproto.nullable) = false
];
// denom_metadata defines the metadata of the differents coins. // denom_metadata defines the metadata of the differents coins.
repeated Metadata denom_metadata = 4 [ repeated Metadata denom_metadata = 4 [(gogoproto.moretags) = "yaml:\"denom_metadata\"", (gogoproto.nullable) = false];
(gogoproto.moretags) = "yaml:\"denom_metadata\"",
(gogoproto.nullable) = false
];
} }
// Balance defines an account address and balance pair used in the bank module's // Balance defines an account address and balance pair used in the bank module's
@ -38,8 +33,6 @@ message Balance {
string address = 1; string address = 1;
// coins defines the different coins this balance holds. // coins defines the different coins this balance holds.
repeated cosmos.base.v1beta1.Coin coins = 2 [ repeated cosmos.base.v1beta1.Coin coins = 2
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", [(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", (gogoproto.nullable) = false];
(gogoproto.nullable) = false
];
} }

View File

@ -13,8 +13,7 @@ option go_package = "github.com/cosmos/cosmos-sdk/x/bank/types";
service Query { service Query {
// Balance queries the balance of a single coin for a single account. // Balance queries the balance of a single coin for a single account.
rpc Balance(QueryBalanceRequest) returns (QueryBalanceResponse) { rpc Balance(QueryBalanceRequest) returns (QueryBalanceResponse) {
option (google.api.http).get = option (google.api.http).get = "/cosmos/bank/v1beta1/balances/{address}/{denom}";
"/cosmos/bank/v1beta1/balances/{address}/{denom}";
} }
// AllBalances queries the balance of all coins for a single account. // AllBalances queries the balance of all coins for a single account.
@ -36,6 +35,16 @@ service Query {
rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { rpc Params(QueryParamsRequest) returns (QueryParamsResponse) {
option (google.api.http).get = "/cosmos/bank/v1beta1/params"; option (google.api.http).get = "/cosmos/bank/v1beta1/params";
} }
// DenomsMetadata queries the client metadata of a given coin denomination.
rpc DenomMetadata(QueryDenomMetadataRequest) returns (QueryDenomMetadataResponse) {
option (google.api.http).get = "/cosmos/bank/v1beta1/denoms_metadata/{denom}";
}
// DenomsMetadata queries the client metadata for all registered coin denominations.
rpc DenomsMetadata(QueryDenomsMetadataRequest) returns (QueryDenomsMetadataResponse) {
option (google.api.http).get = "/cosmos/bank/v1beta1/denoms_metadata";
}
} }
// QueryBalanceRequest is the request type for the Query/Balance RPC method. // QueryBalanceRequest is the request type for the Query/Balance RPC method.
@ -72,10 +81,8 @@ message QueryAllBalancesRequest {
// method. // method.
message QueryAllBalancesResponse { message QueryAllBalancesResponse {
// balances is the balances of all the coins. // balances is the balances of all the coins.
repeated cosmos.base.v1beta1.Coin balances = 1 [ repeated cosmos.base.v1beta1.Coin balances = 1
(gogoproto.nullable) = false, [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"];
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"
];
// pagination defines the pagination in the response. // pagination defines the pagination in the response.
cosmos.base.query.v1beta1.PageResponse pagination = 2; cosmos.base.query.v1beta1.PageResponse pagination = 2;
@ -89,10 +96,8 @@ message QueryTotalSupplyRequest {}
// method // method
message QueryTotalSupplyResponse { message QueryTotalSupplyResponse {
// supply is the supply of the coins // supply is the supply of the coins
repeated cosmos.base.v1beta1.Coin supply = 1 [ repeated cosmos.base.v1beta1.Coin supply = 1
(gogoproto.nullable) = false, [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"];
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"
];
} }
// QuerySupplyOfRequest is the request type for the Query/SupplyOf RPC method. // QuerySupplyOfRequest is the request type for the Query/SupplyOf RPC method.
@ -114,3 +119,32 @@ message QueryParamsRequest {}
message QueryParamsResponse { message QueryParamsResponse {
Params params = 1 [(gogoproto.nullable) = false]; Params params = 1 [(gogoproto.nullable) = false];
} }
// QueryDenomsMetadataRequest is the request type for the Query/DenomsMetadata RPC method.
message QueryDenomsMetadataRequest {
// pagination defines an optional pagination for the request.
cosmos.base.query.v1beta1.PageRequest pagination = 1;
}
// QueryDenomsMetadataResponse is the response type for the Query/DenomsMetadata RPC
// method.
message QueryDenomsMetadataResponse {
// metadata provides the client information for all the registered tokens.
repeated Metadata metadatas = 1 [(gogoproto.nullable) = false];
// pagination defines the pagination in the response.
cosmos.base.query.v1beta1.PageResponse pagination = 2;
}
// QueryDenomMetadataRequest is the request type for the Query/DenomMetadata RPC method.
message QueryDenomMetadataRequest {
// denom is the coin denom to query the metadata for.
string denom = 1;
}
// QueryDenomMetadataResponse is the response type for the Query/DenomMetadata RPC
// method.
message QueryDenomMetadataResponse {
// metadata describes and provides all the client information for the requested token.
Metadata metadata = 1 [(gogoproto.nullable) = false];
}

View File

@ -7,6 +7,15 @@ import "cosmos/bank/v1beta1/bank.proto";
option go_package = "github.com/cosmos/cosmos-sdk/x/bank/types"; option go_package = "github.com/cosmos/cosmos-sdk/x/bank/types";
// Msg defines the bank Msg service.
service Msg {
// Send defines a method for sending coins from one account to another account.
rpc Send(MsgSend) returns (MsgSendResponse);
// MultiSend defines a method for sending coins from some accounts to other accounts.
rpc MultiSend(MsgMultiSend) returns (MsgMultiSendResponse);
}
// MsgSend represents a message to send coins from one account to another. // MsgSend represents a message to send coins from one account to another.
message MsgSend { message MsgSend {
option (gogoproto.equal) = false; option (gogoproto.equal) = false;
@ -14,12 +23,13 @@ message MsgSend {
string from_address = 1 [(gogoproto.moretags) = "yaml:\"from_address\""]; string from_address = 1 [(gogoproto.moretags) = "yaml:\"from_address\""];
string to_address = 2 [(gogoproto.moretags) = "yaml:\"to_address\""]; string to_address = 2 [(gogoproto.moretags) = "yaml:\"to_address\""];
repeated cosmos.base.v1beta1.Coin amount = 3 [ repeated cosmos.base.v1beta1.Coin amount = 3
(gogoproto.nullable) = false, [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"];
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"
];
} }
// MsgSendResponse defines the Msg/Send response type.
message MsgSendResponse {}
// MsgMultiSend represents an arbitrary multi-in, multi-out send message. // MsgMultiSend represents an arbitrary multi-in, multi-out send message.
message MsgMultiSend { message MsgMultiSend {
option (gogoproto.equal) = false; option (gogoproto.equal) = false;
@ -27,3 +37,6 @@ message MsgMultiSend {
repeated Input inputs = 1 [(gogoproto.nullable) = false]; repeated Input inputs = 1 [(gogoproto.nullable) = false];
repeated Output outputs = 2 [(gogoproto.nullable) = false]; repeated Output outputs = 2 [(gogoproto.nullable) = false];
} }
// MsgMultiSendResponse defines the Msg/MultiSend response type.
message MsgMultiSendResponse {}

View File

@ -26,10 +26,7 @@ message TxResponse {
// non-deterministic. // non-deterministic.
string raw_log = 6; string raw_log = 6;
// The output of the application's logger (typed). May be non-deterministic. // The output of the application's logger (typed). May be non-deterministic.
repeated ABCIMessageLog logs = 7 [ repeated ABCIMessageLog logs = 7 [(gogoproto.castrepeated) = "ABCIMessageLogs", (gogoproto.nullable) = false];
(gogoproto.castrepeated) = "ABCIMessageLogs",
(gogoproto.nullable) = false
];
// Additional information. May be non-deterministic. // Additional information. May be non-deterministic.
string info = 8; string info = 8;
// Amount of gas requested for transaction. // Amount of gas requested for transaction.
@ -53,10 +50,7 @@ message ABCIMessageLog {
// Events contains a slice of Event objects that were emitted during some // Events contains a slice of Event objects that were emitted during some
// execution. // execution.
repeated StringEvent events = 3 [ repeated StringEvent events = 3 [(gogoproto.castrepeated) = "StringEvents", (gogoproto.nullable) = false];
(gogoproto.castrepeated) = "StringEvents",
(gogoproto.nullable) = false
];
} }
// StringEvent defines en Event object wrapper where all the attributes // StringEvent defines en Event object wrapper where all the attributes
@ -103,8 +97,7 @@ message Result {
// SimulationResponse defines the response generated when a transaction is // SimulationResponse defines the response generated when a transaction is
// successfully simulated. // successfully simulated.
message SimulationResponse { message SimulationResponse {
GasInfo gas_info = 1 GasInfo gas_info = 1 [(gogoproto.embed) = true, (gogoproto.nullable) = false];
[ (gogoproto.embed) = true, (gogoproto.nullable) = false ];
Result result = 2; Result result = 2;
} }
@ -130,22 +123,13 @@ message SearchTxsResult {
option (gogoproto.stringer) = true; option (gogoproto.stringer) = true;
// Count of all txs // Count of all txs
uint64 total_count = 1 [ uint64 total_count = 1 [(gogoproto.moretags) = "yaml:\"total_count\"", (gogoproto.jsontag) = "total_count"];
(gogoproto.moretags) = "yaml:\"total_count\"",
(gogoproto.jsontag) = "total_count"
];
// Count of txs in current page // Count of txs in current page
uint64 count = 2; uint64 count = 2;
// Index of current page, start from 1 // Index of current page, start from 1
uint64 page_number = 3 [ uint64 page_number = 3 [(gogoproto.moretags) = "yaml:\"page_number\"", (gogoproto.jsontag) = "page_number"];
(gogoproto.moretags) = "yaml:\"page_number\"",
(gogoproto.jsontag) = "page_number"
];
// Count of total pages // Count of total pages
uint64 page_total = 4 [ uint64 page_total = 4 [(gogoproto.moretags) = "yaml:\"page_total\"", (gogoproto.jsontag) = "page_total"];
(gogoproto.moretags) = "yaml:\"page_total\"",
(gogoproto.jsontag) = "page_total"
];
// Max count txs per page // Max count txs per page
uint64 limit = 5; uint64 limit = 5;
// List of txs in current page // List of txs in current page

View File

@ -6,7 +6,9 @@ import "gogoproto/gogo.proto";
option go_package = "github.com/cosmos/cosmos-sdk/types/kv"; option go_package = "github.com/cosmos/cosmos-sdk/types/kv";
// Pairs defines a repeated slice of Pair objects. // Pairs defines a repeated slice of Pair objects.
message Pairs { repeated Pair pairs = 1 [ (gogoproto.nullable) = false ]; } message Pairs {
repeated Pair pairs = 1 [(gogoproto.nullable) = false];
}
// Pair defines a key/value bytes tuple. // Pair defines a key/value bytes tuple.
message Pair { message Pair {

View File

@ -9,15 +9,13 @@ option go_package = "github.com/cosmos/cosmos-sdk/client/grpc/reflection";
service ReflectionService { service ReflectionService {
// ListAllInterfaces lists all the interfaces registered in the interface // ListAllInterfaces lists all the interfaces registered in the interface
// registry. // registry.
rpc ListAllInterfaces(ListAllInterfacesRequest) rpc ListAllInterfaces(ListAllInterfacesRequest) returns (ListAllInterfacesResponse) {
returns (ListAllInterfacesResponse) {
option (google.api.http).get = "/cosmos/base/reflection/v1beta1/interfaces"; option (google.api.http).get = "/cosmos/base/reflection/v1beta1/interfaces";
}; };
// ListImplementations list all the concrete types that implement a given // ListImplementations list all the concrete types that implement a given
// interface. // interface.
rpc ListImplementations(ListImplementationsRequest) rpc ListImplementations(ListImplementationsRequest) returns (ListImplementationsResponse) {
returns (ListImplementationsResponse) {
option (google.api.http).get = "/cosmos/base/reflection/v1beta1/interfaces/" option (google.api.http).get = "/cosmos/base/reflection/v1beta1/interfaces/"
"{interface_name}/implementations"; "{interface_name}/implementations";
}; };

View File

@ -1,33 +0,0 @@
syntax = "proto3";
package cosmos.base.simulate.v1beta1;
import "google/api/annotations.proto";
import "cosmos/base/abci/v1beta1/abci.proto";
import "cosmos/tx/v1beta1/tx.proto";
option go_package = "github.com/cosmos/cosmos-sdk/client/grpc/simulate";
// SimulateService defines a gRPC service for simulating transactions.
// It may also support querying and broadcasting in the future.
service SimulateService {
// Simulate simulates executing a transaction for estimating gas usage.
rpc Simulate(SimulateRequest) returns (SimulateResponse) {
option (google.api.http).post = "/cosmos/base/simulate/v1beta1/simulate";
}
}
// SimulateRequest is the request type for the SimulateServiceService.Simulate
// RPC method.
message SimulateRequest {
// tx is the transaction to simulate.
cosmos.tx.v1beta1.Tx tx = 1;
}
// SimulateResponse is the response type for the
// SimulateServiceService.SimulateRPC method.
message SimulateResponse {
// gas_info is the information about gas used in the simulation.
cosmos.base.abci.v1beta1.GasInfo gas_info = 1;
// result is the result of the simulation.
cosmos.base.abci.v1beta1.Result result = 2;
}

View File

@ -15,7 +15,9 @@ message SnapshotItem {
} }
// SnapshotStoreItem contains metadata about a snapshotted store. // SnapshotStoreItem contains metadata about a snapshotted store.
message SnapshotStoreItem { string name = 1; } message SnapshotStoreItem {
string name = 1;
}
// SnapshotIAVLItem is an exported IAVL node. // SnapshotIAVLItem is an exported IAVL node.
message SnapshotIAVLItem { message SnapshotIAVLItem {

View File

@ -0,0 +1,135 @@
syntax = "proto3";
package cosmos.base.tendermint.v1beta1;
import "google/protobuf/any.proto";
import "google/api/annotations.proto";
import "tendermint/p2p/types.proto";
import "tendermint/types/block.proto";
import "tendermint/types/types.proto";
import "cosmos/base/query/v1beta1/pagination.proto";
option go_package = "github.com/cosmos/cosmos-sdk/client/grpc/tmservice";
// Service defines the gRPC querier service for tendermint queries.
service Service {
// GetNodeInfo queries the current node info.
rpc GetNodeInfo(GetNodeInfoRequest) returns (GetNodeInfoResponse) {
option (google.api.http).get = "/cosmos/base/tendermint/v1beta1/node_info";
}
// GetSyncing queries node syncing.
rpc GetSyncing(GetSyncingRequest) returns (GetSyncingResponse) {
option (google.api.http).get = "/cosmos/base/tendermint/v1beta1/syncing";
}
// GetLatestBlock returns the latest block.
rpc GetLatestBlock(GetLatestBlockRequest) returns (GetLatestBlockResponse) {
option (google.api.http).get = "/cosmos/base/tendermint/v1beta1/blocks/latest";
}
// GetBlockByHeight queries block for given height.
rpc GetBlockByHeight(GetBlockByHeightRequest) returns (GetBlockByHeightResponse) {
option (google.api.http).get = "/cosmos/base/tendermint/v1beta1/blocks/{height}";
}
// GetLatestValidatorSet queries latest validator-set.
rpc GetLatestValidatorSet(GetLatestValidatorSetRequest) returns (GetLatestValidatorSetResponse) {
option (google.api.http).get = "/cosmos/base/tendermint/v1beta1/validatorsets/latest";
}
// GetValidatorSetByHeight queries validator-set at a given height.
rpc GetValidatorSetByHeight(GetValidatorSetByHeightRequest) returns (GetValidatorSetByHeightResponse) {
option (google.api.http).get = "/cosmos/base/tendermint/v1beta1/validatorsets/{height}";
}
}
// GetValidatorSetByHeightRequest is the request type for the Query/GetValidatorSetByHeight RPC method.
message GetValidatorSetByHeightRequest {
int64 height = 1;
// pagination defines an pagination for the request.
cosmos.base.query.v1beta1.PageRequest pagination = 2;
}
// GetValidatorSetByHeightResponse is the response type for the Query/GetValidatorSetByHeight RPC method.
message GetValidatorSetByHeightResponse {
int64 block_height = 1;
repeated Validator validators = 2;
// pagination defines an pagination for the response.
cosmos.base.query.v1beta1.PageResponse pagination = 3;
}
// GetLatestValidatorSetRequest is the request type for the Query/GetValidatorSetByHeight RPC method.
message GetLatestValidatorSetRequest {
// pagination defines an pagination for the request.
cosmos.base.query.v1beta1.PageRequest pagination = 1;
}
// GetLatestValidatorSetResponse is the response type for the Query/GetValidatorSetByHeight RPC method.
message GetLatestValidatorSetResponse {
int64 block_height = 1;
repeated Validator validators = 2;
// pagination defines an pagination for the response.
cosmos.base.query.v1beta1.PageResponse pagination = 3;
}
// Validator is the type for the validator-set.
message Validator {
string address = 1;
google.protobuf.Any pub_key = 2;
int64 voting_power = 3;
int64 proposer_priority = 4;
}
// GetBlockByHeightRequest is the request type for the Query/GetBlockByHeight RPC method.
message GetBlockByHeightRequest {
int64 height = 1;
}
// GetBlockByHeightResponse is the response type for the Query/GetBlockByHeight RPC method.
message GetBlockByHeightResponse {
.tendermint.types.BlockID block_id = 1;
.tendermint.types.Block block = 2;
}
// GetLatestBlockRequest is the request type for the Query/GetLatestBlock RPC method.
message GetLatestBlockRequest {}
// GetLatestBlockResponse is the response type for the Query/GetLatestBlock RPC method.
message GetLatestBlockResponse {
.tendermint.types.BlockID block_id = 1;
.tendermint.types.Block block = 2;
}
// GetSyncingRequest is the request type for the Query/GetSyncing RPC method.
message GetSyncingRequest {}
// GetSyncingResponse is the response type for the Query/GetSyncing RPC method.
message GetSyncingResponse {
bool syncing = 1;
}
// GetNodeInfoRequest is the request type for the Query/GetNodeInfo RPC method.
message GetNodeInfoRequest {}
// GetNodeInfoResponse is the request type for the Query/GetNodeInfo RPC method.
message GetNodeInfoResponse {
.tendermint.p2p.DefaultNodeInfo default_node_info = 1;
VersionInfo application_version = 2;
}
// VersionInfo is the type for the GetNodeInfoResponse message.
message VersionInfo {
string name = 1;
string app_name = 2;
string version = 3;
string git_commit = 4;
string build_tags = 5;
string go_version = 6;
repeated Module build_deps = 7;
}
// Module is the type for VersionInfo
message Module {
// module path
string path = 1;
// module version
string version = 2;
// checksum
string sum = 3;
}

View File

@ -15,8 +15,7 @@ message Coin {
option (gogoproto.equal) = true; option (gogoproto.equal) = true;
string denom = 1; string denom = 1;
string amount = 2 string amount = 2 [(gogoproto.customtype) = "Int", (gogoproto.nullable) = false];
[ (gogoproto.customtype) = "Int", (gogoproto.nullable) = false ];
} }
// DecCoin defines a token with a denomination and a decimal amount. // DecCoin defines a token with a denomination and a decimal amount.
@ -27,18 +26,15 @@ message DecCoin {
option (gogoproto.equal) = true; option (gogoproto.equal) = true;
string denom = 1; string denom = 1;
string amount = 2 string amount = 2 [(gogoproto.customtype) = "Dec", (gogoproto.nullable) = false];
[ (gogoproto.customtype) = "Dec", (gogoproto.nullable) = false ];
} }
// IntProto defines a Protobuf wrapper around an Int object. // IntProto defines a Protobuf wrapper around an Int object.
message IntProto { message IntProto {
string int = 1 string int = 1 [(gogoproto.customtype) = "Int", (gogoproto.nullable) = false];
[ (gogoproto.customtype) = "Int", (gogoproto.nullable) = false ];
} }
// DecProto defines a Protobuf wrapper around a Dec object. // DecProto defines a Protobuf wrapper around a Dec object.
message DecProto { message DecProto {
string dec = 1 string dec = 1 [(gogoproto.customtype) = "Dec", (gogoproto.nullable) = false];
[ (gogoproto.customtype) = "Dec", (gogoproto.nullable) = false ];
} }

View File

@ -0,0 +1,30 @@
syntax = "proto3";
package cosmos.capability.v1beta1;
option go_package = "github.com/cosmos/cosmos-sdk/x/capability/types";
import "gogoproto/gogo.proto";
// Capability defines an implementation of an object capability. The index
// provided to a Capability must be globally unique.
message Capability {
option (gogoproto.goproto_stringer) = false;
uint64 index = 1 [(gogoproto.moretags) = "yaml:\"index\""];
}
// Owner defines a single capability owner. An owner is defined by the name of
// capability and the module name.
message Owner {
option (gogoproto.goproto_stringer) = false;
option (gogoproto.goproto_getters) = false;
string module = 1 [(gogoproto.moretags) = "yaml:\"module\""];
string name = 2 [(gogoproto.moretags) = "yaml:\"name\""];
}
// CapabilityOwners defines a set of owners of a single Capability. The set of
// owners must be unique.
message CapabilityOwners {
repeated Owner owners = 1 [(gogoproto.nullable) = false];
}

View File

@ -0,0 +1,26 @@
syntax = "proto3";
package cosmos.capability.v1beta1;
import "gogoproto/gogo.proto";
import "cosmos/capability/v1beta1/capability.proto";
option go_package = "github.com/cosmos/cosmos-sdk/x/capability/types";
// GenesisOwners defines the capability owners with their corresponding index.
message GenesisOwners {
// index is the index of the capability owner.
uint64 index = 1;
// index_owners are the owners at the given index.
CapabilityOwners index_owners = 2 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"index_owners\""];
}
// GenesisState defines the capability module's genesis state.
message GenesisState {
// index is the capability global index.
uint64 index = 1;
// owners represents a map from index to owners of the capability index
// index key is string to allow amino marshalling.
repeated GenesisOwners owners = 2 [(gogoproto.nullable) = false];
}

View File

@ -0,0 +1,15 @@
syntax = "proto3";
package cosmos.crisis.v1beta1;
option go_package = "github.com/cosmos/cosmos-sdk/x/crisis/types";
import "gogoproto/gogo.proto";
import "cosmos/base/v1beta1/coin.proto";
// GenesisState defines the crisis module's genesis state.
message GenesisState {
// constant_fee is the fee used to verify the invariant in the crisis
// module.
cosmos.base.v1beta1.Coin constant_fee = 3
[(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"constant_fee\""];
}

View File

@ -0,0 +1,25 @@
syntax = "proto3";
package cosmos.crisis.v1beta1;
option go_package = "github.com/cosmos/cosmos-sdk/x/crisis/types";
import "gogoproto/gogo.proto";
// Msg defines the bank Msg service.
service Msg {
// VerifyInvariant defines a method to verify a particular invariance.
rpc VerifyInvariant(MsgVerifyInvariant) returns (MsgVerifyInvariantResponse);
}
// MsgVerifyInvariant represents a message to verify a particular invariance.
message MsgVerifyInvariant {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
string sender = 1;
string invariant_module_name = 2 [(gogoproto.moretags) = "yaml:\"invariant_module_name\""];
string invariant_route = 3 [(gogoproto.moretags) = "yaml:\"invariant_route\""];
}
// MsgVerifyInvariantResponse defines the Msg/VerifyInvariant response type.
message MsgVerifyInvariantResponse {}

View File

@ -6,15 +6,17 @@ import "gogoproto/gogo.proto";
option go_package = "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"; option go_package = "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519";
// PubKey defines a ed25519 public key // PubKey defines a ed25519 public key
// Key is the compressed form of the pubkey. The first byte depends is a 0x02 // Key is the compressed form of the pubkey. The first byte depends is a 0x02 byte
// byte if the y-coordinate is the lexicographically largest of the two // if the y-coordinate is the lexicographically largest of the two associated with
// associated with the x-coordinate. Otherwise the first byte is a 0x03. This // the x-coordinate. Otherwise the first byte is a 0x03.
// prefix is followed with the x-coordinate. // This prefix is followed with the x-coordinate.
message PubKey { message PubKey {
option (gogoproto.goproto_stringer) = false; option (gogoproto.goproto_stringer) = false;
bytes key = 1; bytes key = 1 [(gogoproto.casttype) = "crypto/ed25519.PublicKey"];
} }
// PrivKey defines a ed25519 private key. // PrivKey defines a ed25519 private key.
message PrivKey { bytes key = 1; } message PrivKey {
bytes key = 1 [(gogoproto.casttype) = "crypto/ed25519.PrivateKey"];
}

View File

@ -13,8 +13,6 @@ message LegacyAminoPubKey {
option (gogoproto.goproto_getters) = false; option (gogoproto.goproto_getters) = false;
uint32 threshold = 1 [(gogoproto.moretags) = "yaml:\"threshold\""]; uint32 threshold = 1 [(gogoproto.moretags) = "yaml:\"threshold\""];
repeated google.protobuf.Any public_keys = 2 [ repeated google.protobuf.Any public_keys = 2
(gogoproto.customname) = "PubKeys", [(gogoproto.customname) = "PubKeys", (gogoproto.moretags) = "yaml:\"pubkeys\""];
(gogoproto.moretags) = "yaml:\"pubkeys\""
];
} }

View File

@ -6,10 +6,10 @@ import "gogoproto/gogo.proto";
option go_package = "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"; option go_package = "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1";
// PubKey defines a secp256k1 public key // PubKey defines a secp256k1 public key
// Key is the compressed form of the pubkey. The first byte depends is a 0x02 // Key is the compressed form of the pubkey. The first byte depends is a 0x02 byte
// byte if the y-coordinate is the lexicographically largest of the two // if the y-coordinate is the lexicographically largest of the two associated with
// associated with the x-coordinate. Otherwise the first byte is a 0x03. This // the x-coordinate. Otherwise the first byte is a 0x03.
// prefix is followed with the x-coordinate. // This prefix is followed with the x-coordinate.
message PubKey { message PubKey {
option (gogoproto.goproto_stringer) = false; option (gogoproto.goproto_stringer) = false;
@ -17,4 +17,6 @@ message PubKey {
} }
// PrivKey defines a secp256k1 private key. // PrivKey defines a secp256k1 private key.
message PrivKey { bytes key = 1; } message PrivKey {
bytes key = 1;
}

View File

@ -0,0 +1,157 @@
syntax = "proto3";
package cosmos.distribution.v1beta1;
option go_package = "github.com/cosmos/cosmos-sdk/x/distribution/types";
option (gogoproto.equal_all) = true;
import "gogoproto/gogo.proto";
import "cosmos/base/v1beta1/coin.proto";
// Params defines the set of params for the distribution module.
message Params {
option (gogoproto.goproto_stringer) = false;
string community_tax = 1 [
(gogoproto.moretags) = "yaml:\"community_tax\"",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
string base_proposer_reward = 2 [
(gogoproto.moretags) = "yaml:\"base_proposer_reward\"",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
string bonus_proposer_reward = 3 [
(gogoproto.moretags) = "yaml:\"bonus_proposer_reward\"",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
bool withdraw_addr_enabled = 4 [(gogoproto.moretags) = "yaml:\"withdraw_addr_enabled\""];
}
// ValidatorHistoricalRewards represents historical rewards for a validator.
// Height is implicit within the store key.
// Cumulative reward ratio is the sum from the zeroeth period
// until this period of rewards / tokens, per the spec.
// The reference count indicates the number of objects
// which might need to reference this historical entry at any point.
// ReferenceCount =
// number of outstanding delegations which ended the associated period (and
// might need to read that record)
// + number of slashes which ended the associated period (and might need to
// read that record)
// + one per validator for the zeroeth period, set on initialization
message ValidatorHistoricalRewards {
repeated cosmos.base.v1beta1.DecCoin cumulative_reward_ratio = 1 [
(gogoproto.moretags) = "yaml:\"cumulative_reward_ratio\"",
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins",
(gogoproto.nullable) = false
];
uint32 reference_count = 2 [(gogoproto.moretags) = "yaml:\"reference_count\""];
}
// ValidatorCurrentRewards represents current rewards and current
// period for a validator kept as a running counter and incremented
// each block as long as the validator's tokens remain constant.
message ValidatorCurrentRewards {
repeated cosmos.base.v1beta1.DecCoin rewards = 1
[(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins", (gogoproto.nullable) = false];
uint64 period = 2;
}
// ValidatorAccumulatedCommission represents accumulated commission
// for a validator kept as a running counter, can be withdrawn at any time.
message ValidatorAccumulatedCommission {
repeated cosmos.base.v1beta1.DecCoin commission = 1
[(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins", (gogoproto.nullable) = false];
}
// ValidatorOutstandingRewards represents outstanding (un-withdrawn) rewards
// for a validator inexpensive to track, allows simple sanity checks.
message ValidatorOutstandingRewards {
repeated cosmos.base.v1beta1.DecCoin rewards = 1 [
(gogoproto.moretags) = "yaml:\"rewards\"",
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins",
(gogoproto.nullable) = false
];
}
// ValidatorSlashEvent represents a validator slash event.
// Height is implicit within the store key.
// This is needed to calculate appropriate amount of staking tokens
// for delegations which are withdrawn after a slash has occurred.
message ValidatorSlashEvent {
uint64 validator_period = 1 [(gogoproto.moretags) = "yaml:\"validator_period\""];
string fraction = 2 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false];
}
// ValidatorSlashEvents is a collection of ValidatorSlashEvent messages.
message ValidatorSlashEvents {
option (gogoproto.goproto_stringer) = false;
repeated ValidatorSlashEvent validator_slash_events = 1
[(gogoproto.moretags) = "yaml:\"validator_slash_events\"", (gogoproto.nullable) = false];
}
// FeePool is the global fee pool for distribution.
message FeePool {
repeated cosmos.base.v1beta1.DecCoin community_pool = 1 [
(gogoproto.nullable) = false,
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins",
(gogoproto.moretags) = "yaml:\"community_pool\""
];
}
// CommunityPoolSpendProposal details a proposal for use of community funds,
// together with how many coins are proposed to be spent, and to which
// recipient account.
message CommunityPoolSpendProposal {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
option (gogoproto.goproto_stringer) = false;
string title = 1;
string description = 2;
string recipient = 3;
repeated cosmos.base.v1beta1.Coin amount = 4
[(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"];
}
// DelegatorStartingInfo represents the starting info for a delegator reward
// period. It tracks the previous validator period, the delegation's amount of
// staking token, and the creation height (to check later on if any slashes have
// occurred). NOTE: Even though validators are slashed to whole staking tokens,
// the delegators within the validator may be left with less than a full token,
// thus sdk.Dec is used.
message DelegatorStartingInfo {
uint64 previous_period = 1 [(gogoproto.moretags) = "yaml:\"previous_period\""];
string stake = 2 [
(gogoproto.moretags) = "yaml:\"stake\"",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
uint64 height = 3 [(gogoproto.moretags) = "yaml:\"creation_height\"", (gogoproto.jsontag) = "creation_height"];
}
// DelegationDelegatorReward represents the properties
// of a delegator's delegation reward.
message DelegationDelegatorReward {
option (gogoproto.goproto_getters) = false;
option (gogoproto.goproto_stringer) = true;
string validator_address = 1 [(gogoproto.moretags) = "yaml:\"validator_address\""];
repeated cosmos.base.v1beta1.DecCoin reward = 2
[(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins", (gogoproto.nullable) = false];
}
// CommunityPoolSpendProposalWithDeposit defines a CommunityPoolSpendProposal
// with a deposit
message CommunityPoolSpendProposalWithDeposit {
option (gogoproto.goproto_getters) = false;
option (gogoproto.goproto_stringer) = true;
string title = 1 [(gogoproto.moretags) = "yaml:\"title\""];
string description = 2 [(gogoproto.moretags) = "yaml:\"description\""];
string recipient = 3 [(gogoproto.moretags) = "yaml:\"recipient\""];
string amount = 4 [(gogoproto.moretags) = "yaml:\"amount\""];
string deposit = 5 [(gogoproto.moretags) = "yaml:\"deposit\""];
}

View File

@ -0,0 +1,155 @@
syntax = "proto3";
package cosmos.distribution.v1beta1;
option go_package = "github.com/cosmos/cosmos-sdk/x/distribution/types";
option (gogoproto.equal_all) = true;
import "gogoproto/gogo.proto";
import "cosmos/base/v1beta1/coin.proto";
import "cosmos/distribution/v1beta1/distribution.proto";
// DelegatorWithdrawInfo is the address for where distributions rewards are
// withdrawn to by default this struct is only used at genesis to feed in
// default withdraw addresses.
message DelegatorWithdrawInfo {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
// delegator_address is the address of the delegator.
string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""];
// withdraw_address is the address to withdraw the delegation rewards to.
string withdraw_address = 2 [(gogoproto.moretags) = "yaml:\"withdraw_address\""];
}
// ValidatorOutstandingRewardsRecord is used for import/export via genesis json.
message ValidatorOutstandingRewardsRecord {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
// validator_address is the address of the validator.
string validator_address = 1 [(gogoproto.moretags) = "yaml:\"validator_address\""];
// outstanding_rewards represents the oustanding rewards of a validator.
repeated cosmos.base.v1beta1.DecCoin outstanding_rewards = 2 [
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins",
(gogoproto.nullable) = false,
(gogoproto.moretags) = "yaml:\"outstanding_rewards\""
];
}
// ValidatorAccumulatedCommissionRecord is used for import / export via genesis
// json.
message ValidatorAccumulatedCommissionRecord {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
// validator_address is the address of the validator.
string validator_address = 1 [(gogoproto.moretags) = "yaml:\"validator_address\""];
// accumulated is the accumulated commission of a validator.
ValidatorAccumulatedCommission accumulated = 2
[(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"accumulated\""];
}
// ValidatorHistoricalRewardsRecord is used for import / export via genesis
// json.
message ValidatorHistoricalRewardsRecord {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
// validator_address is the address of the validator.
string validator_address = 1 [(gogoproto.moretags) = "yaml:\"validator_address\""];
// period defines the period the historical rewards apply to.
uint64 period = 2;
// rewards defines the historical rewards of a validator.
ValidatorHistoricalRewards rewards = 3 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"rewards\""];
}
// ValidatorCurrentRewardsRecord is used for import / export via genesis json.
message ValidatorCurrentRewardsRecord {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
// validator_address is the address of the validator.
string validator_address = 1 [(gogoproto.moretags) = "yaml:\"validator_address\""];
// rewards defines the current rewards of a validator.
ValidatorCurrentRewards rewards = 2 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"rewards\""];
}
// DelegatorStartingInfoRecord used for import / export via genesis json.
message DelegatorStartingInfoRecord {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
// delegator_address is the address of the delegator.
string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""];
// validator_address is the address of the validator.
string validator_address = 2 [(gogoproto.moretags) = "yaml:\"validator_address\""];
// starting_info defines the starting info of a delegator.
DelegatorStartingInfo starting_info = 3
[(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"starting_info\""];
}
// ValidatorSlashEventRecord is used for import / export via genesis json.
message ValidatorSlashEventRecord {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
// validator_address is the address of the validator.
string validator_address = 1 [(gogoproto.moretags) = "yaml:\"validator_address\""];
// height defines the block height at which the slash event occured.
uint64 height = 2;
// period is the period of the slash event.
uint64 period = 3;
// validator_slash_event describes the slash event.
ValidatorSlashEvent validator_slash_event = 4 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"event\""];
}
// GenesisState defines the distribution module's genesis state.
message GenesisState {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
// params defines all the paramaters of the module.
Params params = 1 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"params\""];
// fee_pool defines the fee pool at genesis.
FeePool fee_pool = 2 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"fee_pool\""];
// fee_pool defines the delegator withdraw infos at genesis.
repeated DelegatorWithdrawInfo delegator_withdraw_infos = 3
[(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"delegator_withdraw_infos\""];
// fee_pool defines the previous proposer at genesis.
string previous_proposer = 4 [(gogoproto.moretags) = "yaml:\"previous_proposer\""];
// fee_pool defines the outstanding rewards of all validators at genesis.
repeated ValidatorOutstandingRewardsRecord outstanding_rewards = 5
[(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"outstanding_rewards\""];
// fee_pool defines the accumulated commisions of all validators at genesis.
repeated ValidatorAccumulatedCommissionRecord validator_accumulated_commissions = 6
[(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"validator_accumulated_commissions\""];
// fee_pool defines the historical rewards of all validators at genesis.
repeated ValidatorHistoricalRewardsRecord validator_historical_rewards = 7
[(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"validator_historical_rewards\""];
// fee_pool defines the current rewards of all validators at genesis.
repeated ValidatorCurrentRewardsRecord validator_current_rewards = 8
[(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"validator_current_rewards\""];
// fee_pool defines the delegator starting infos at genesis.
repeated DelegatorStartingInfoRecord delegator_starting_infos = 9
[(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"delegator_starting_infos\""];
// fee_pool defines the validator slash events at genesis.
repeated ValidatorSlashEventRecord validator_slash_events = 10
[(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"validator_slash_events\""];
}

View File

@ -0,0 +1,218 @@
syntax = "proto3";
package cosmos.distribution.v1beta1;
import "cosmos/base/query/v1beta1/pagination.proto";
import "gogoproto/gogo.proto";
import "google/api/annotations.proto";
import "cosmos/base/v1beta1/coin.proto";
import "cosmos/distribution/v1beta1/distribution.proto";
option go_package = "github.com/cosmos/cosmos-sdk/x/distribution/types";
// Query defines the gRPC querier service for distribution module.
service Query {
// Params queries params of the distribution module.
rpc Params(QueryParamsRequest) returns (QueryParamsResponse) {
option (google.api.http).get = "/cosmos/distribution/v1beta1/params";
}
// ValidatorOutstandingRewards queries rewards of a validator address.
rpc ValidatorOutstandingRewards(QueryValidatorOutstandingRewardsRequest)
returns (QueryValidatorOutstandingRewardsResponse) {
option (google.api.http).get = "/cosmos/distribution/v1beta1/validators/"
"{validator_address}/outstanding_rewards";
}
// ValidatorCommission queries accumulated commission for a validator.
rpc ValidatorCommission(QueryValidatorCommissionRequest) returns (QueryValidatorCommissionResponse) {
option (google.api.http).get = "/cosmos/distribution/v1beta1/validators/"
"{validator_address}/commission";
}
// ValidatorSlashes queries slash events of a validator.
rpc ValidatorSlashes(QueryValidatorSlashesRequest) returns (QueryValidatorSlashesResponse) {
option (google.api.http).get = "/cosmos/distribution/v1beta1/validators/{validator_address}/slashes";
}
// DelegationRewards queries the total rewards accrued by a delegation.
rpc DelegationRewards(QueryDelegationRewardsRequest) returns (QueryDelegationRewardsResponse) {
option (google.api.http).get = "/cosmos/distribution/v1beta1/delegators/{delegator_address}/rewards/"
"{validator_address}";
}
// DelegationTotalRewards queries the total rewards accrued by a each
// validator.
rpc DelegationTotalRewards(QueryDelegationTotalRewardsRequest) returns (QueryDelegationTotalRewardsResponse) {
option (google.api.http).get = "/cosmos/distribution/v1beta1/delegators/{delegator_address}/rewards";
}
// DelegatorValidators queries the validators of a delegator.
rpc DelegatorValidators(QueryDelegatorValidatorsRequest) returns (QueryDelegatorValidatorsResponse) {
option (google.api.http).get = "/cosmos/distribution/v1beta1/delegators/"
"{delegator_address}/validators";
}
// DelegatorWithdrawAddress queries withdraw address of a delegator.
rpc DelegatorWithdrawAddress(QueryDelegatorWithdrawAddressRequest) returns (QueryDelegatorWithdrawAddressResponse) {
option (google.api.http).get = "/cosmos/distribution/v1beta1/delegators/"
"{delegator_address}/withdraw_address";
}
// CommunityPool queries the community pool coins.
rpc CommunityPool(QueryCommunityPoolRequest) returns (QueryCommunityPoolResponse) {
option (google.api.http).get = "/cosmos/distribution/v1beta1/community_pool";
}
}
// QueryParamsRequest is the request type for the Query/Params RPC method.
message QueryParamsRequest {}
// QueryParamsResponse is the response type for the Query/Params RPC method.
message QueryParamsResponse {
// params defines the parameters of the module.
Params params = 1 [(gogoproto.nullable) = false];
}
// QueryValidatorOutstandingRewardsRequest is the request type for the
// Query/ValidatorOutstandingRewards RPC method.
message QueryValidatorOutstandingRewardsRequest {
// validator_address defines the validator address to query for.
string validator_address = 1;
}
// QueryValidatorOutstandingRewardsResponse is the response type for the
// Query/ValidatorOutstandingRewards RPC method.
message QueryValidatorOutstandingRewardsResponse {
ValidatorOutstandingRewards rewards = 1 [(gogoproto.nullable) = false];
}
// QueryValidatorCommissionRequest is the request type for the
// Query/ValidatorCommission RPC method
message QueryValidatorCommissionRequest {
// validator_address defines the validator address to query for.
string validator_address = 1;
}
// QueryValidatorCommissionResponse is the response type for the
// Query/ValidatorCommission RPC method
message QueryValidatorCommissionResponse {
// commission defines the commision the validator received.
ValidatorAccumulatedCommission commission = 1 [(gogoproto.nullable) = false];
}
// QueryValidatorSlashesRequest is the request type for the
// Query/ValidatorSlashes RPC method
message QueryValidatorSlashesRequest {
option (gogoproto.goproto_getters) = false;
option (gogoproto.goproto_stringer) = true;
// validator_address defines the validator address to query for.
string validator_address = 1;
// starting_height defines the optional starting height to query the slashes.
uint64 starting_height = 2;
// starting_height defines the optional ending height to query the slashes.
uint64 ending_height = 3;
// pagination defines an optional pagination for the request.
cosmos.base.query.v1beta1.PageRequest pagination = 4;
}
// QueryValidatorSlashesResponse is the response type for the
// Query/ValidatorSlashes RPC method.
message QueryValidatorSlashesResponse {
// slashes defines the slashes the validator received.
repeated ValidatorSlashEvent slashes = 1 [(gogoproto.nullable) = false];
// pagination defines the pagination in the response.
cosmos.base.query.v1beta1.PageResponse pagination = 2;
}
// QueryDelegationRewardsRequest is the request type for the
// Query/DelegationRewards RPC method.
message QueryDelegationRewardsRequest {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
// delegator_address defines the delegator address to query for.
string delegator_address = 1;
// validator_address defines the validator address to query for.
string validator_address = 2;
}
// QueryDelegationRewardsResponse is the response type for the
// Query/DelegationRewards RPC method.
message QueryDelegationRewardsResponse {
// rewards defines the rewards accrued by a delegation.
repeated cosmos.base.v1beta1.DecCoin rewards = 1
[(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins"];
}
// QueryDelegationTotalRewardsRequest is the request type for the
// Query/DelegationTotalRewards RPC method.
message QueryDelegationTotalRewardsRequest {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
// delegator_address defines the delegator address to query for.
string delegator_address = 1;
}
// QueryDelegationTotalRewardsResponse is the response type for the
// Query/DelegationTotalRewards RPC method.
message QueryDelegationTotalRewardsResponse {
// rewards defines all the rewards accrued by a delegator.
repeated DelegationDelegatorReward rewards = 1 [(gogoproto.nullable) = false];
// total defines the sum of all the rewards.
repeated cosmos.base.v1beta1.DecCoin total = 2
[(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins"];
}
// QueryDelegatorValidatorsRequest is the request type for the
// Query/DelegatorValidators RPC method.
message QueryDelegatorValidatorsRequest {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
// delegator_address defines the delegator address to query for.
string delegator_address = 1;
}
// QueryDelegatorValidatorsResponse is the response type for the
// Query/DelegatorValidators RPC method.
message QueryDelegatorValidatorsResponse {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
// validators defines the validators a delegator is delegating for.
repeated string validators = 1;
}
// QueryDelegatorWithdrawAddressRequest is the request type for the
// Query/DelegatorWithdrawAddress RPC method.
message QueryDelegatorWithdrawAddressRequest {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
// delegator_address defines the delegator address to query for.
string delegator_address = 1;
}
// QueryDelegatorWithdrawAddressResponse is the response type for the
// Query/DelegatorWithdrawAddress RPC method.
message QueryDelegatorWithdrawAddressResponse {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
// withdraw_address defines the delegator address to query for.
string withdraw_address = 1;
}
// QueryCommunityPoolRequest is the request type for the Query/CommunityPool RPC
// method.
message QueryCommunityPoolRequest {}
// QueryCommunityPoolResponse is the response type for the Query/CommunityPool
// RPC method.
message QueryCommunityPoolResponse {
// pool defines community pool's coins.
repeated cosmos.base.v1beta1.DecCoin pool = 1
[(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins", (gogoproto.nullable) = false];
}

View File

@ -0,0 +1,79 @@
syntax = "proto3";
package cosmos.distribution.v1beta1;
option go_package = "github.com/cosmos/cosmos-sdk/x/distribution/types";
option (gogoproto.equal_all) = true;
import "gogoproto/gogo.proto";
import "cosmos/base/v1beta1/coin.proto";
// Msg defines the distribution Msg service.
service Msg {
// SetWithdrawAddress defines a method to change the withdraw address
// for a delegator (or validator self-delegation).
rpc SetWithdrawAddress(MsgSetWithdrawAddress) returns (MsgSetWithdrawAddressResponse);
// WithdrawDelegatorReward defines a method to withdraw rewards of delegator
// from a single validator.
rpc WithdrawDelegatorReward(MsgWithdrawDelegatorReward) returns (MsgWithdrawDelegatorRewardResponse);
// WithdrawValidatorCommission defines a method to withdraw the
// full commission to the validator address.
rpc WithdrawValidatorCommission(MsgWithdrawValidatorCommission) returns (MsgWithdrawValidatorCommissionResponse);
// FundCommunityPool defines a method to allow an account to directly
// fund the community pool.
rpc FundCommunityPool(MsgFundCommunityPool) returns (MsgFundCommunityPoolResponse);
}
// MsgSetWithdrawAddress sets the withdraw address for
// a delegator (or validator self-delegation).
message MsgSetWithdrawAddress {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""];
string withdraw_address = 2 [(gogoproto.moretags) = "yaml:\"withdraw_address\""];
}
// MsgSetWithdrawAddressResponse defines the Msg/SetWithdrawAddress response type.
message MsgSetWithdrawAddressResponse {}
// MsgWithdrawDelegatorReward represents delegation withdrawal to a delegator
// from a single validator.
message MsgWithdrawDelegatorReward {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""];
string validator_address = 2 [(gogoproto.moretags) = "yaml:\"validator_address\""];
}
// MsgWithdrawDelegatorRewardResponse defines the Msg/WithdrawDelegatorReward response type.
message MsgWithdrawDelegatorRewardResponse {}
// MsgWithdrawValidatorCommission withdraws the full commission to the validator
// address.
message MsgWithdrawValidatorCommission {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
string validator_address = 1 [(gogoproto.moretags) = "yaml:\"validator_address\""];
}
// MsgWithdrawValidatorCommissionResponse defines the Msg/WithdrawValidatorCommission response type.
message MsgWithdrawValidatorCommissionResponse {}
// MsgFundCommunityPool allows an account to directly
// fund the community pool.
message MsgFundCommunityPool {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
repeated cosmos.base.v1beta1.Coin amount = 1
[(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"];
string depositor = 2;
}
// MsgFundCommunityPoolResponse defines the Msg/FundCommunityPool response type.
message MsgFundCommunityPoolResponse {}

View File

@ -0,0 +1,21 @@
syntax = "proto3";
package cosmos.evidence.v1beta1;
option go_package = "github.com/cosmos/cosmos-sdk/x/evidence/types";
option (gogoproto.equal_all) = true;
import "gogoproto/gogo.proto";
import "google/protobuf/timestamp.proto";
// Equivocation implements the Evidence interface and defines evidence of double
// signing misbehavior.
message Equivocation {
option (gogoproto.goproto_stringer) = false;
option (gogoproto.goproto_getters) = false;
option (gogoproto.equal) = false;
int64 height = 1;
google.protobuf.Timestamp time = 2 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
int64 power = 3;
string consensus_address = 4 [(gogoproto.moretags) = "yaml:\"consensus_address\""];
}

View File

@ -0,0 +1,12 @@
syntax = "proto3";
package cosmos.evidence.v1beta1;
option go_package = "github.com/cosmos/cosmos-sdk/x/evidence/types";
import "google/protobuf/any.proto";
// GenesisState defines the evidence module's genesis state.
message GenesisState {
// evidence defines all the evidence at genesis.
repeated google.protobuf.Any evidence = 1;
}

View File

@ -0,0 +1,51 @@
syntax = "proto3";
package cosmos.evidence.v1beta1;
import "cosmos/base/query/v1beta1/pagination.proto";
import "gogoproto/gogo.proto";
import "google/protobuf/any.proto";
import "google/api/annotations.proto";
option go_package = "github.com/cosmos/cosmos-sdk/x/evidence/types";
// Query defines the gRPC querier service.
service Query {
// Evidence queries evidence based on evidence hash.
rpc Evidence(QueryEvidenceRequest) returns (QueryEvidenceResponse) {
option (google.api.http).get = "/cosmos/evidence/v1beta1/evidence/{evidence_hash}";
}
// AllEvidence queries all evidence.
rpc AllEvidence(QueryAllEvidenceRequest) returns (QueryAllEvidenceResponse) {
option (google.api.http).get = "/cosmos/evidence/v1beta1/evidence";
}
}
// QueryEvidenceRequest is the request type for the Query/Evidence RPC method.
message QueryEvidenceRequest {
// evidence_hash defines the hash of the requested evidence.
bytes evidence_hash = 1 [(gogoproto.casttype) = "github.com/tendermint/tendermint/libs/bytes.HexBytes"];
}
// QueryEvidenceResponse is the response type for the Query/Evidence RPC method.
message QueryEvidenceResponse {
// evidence returns the requested evidence.
google.protobuf.Any evidence = 1;
}
// QueryEvidenceRequest is the request type for the Query/AllEvidence RPC
// method.
message QueryAllEvidenceRequest {
// pagination defines an optional pagination for the request.
cosmos.base.query.v1beta1.PageRequest pagination = 1;
}
// QueryAllEvidenceResponse is the response type for the Query/AllEvidence RPC
// method.
message QueryAllEvidenceResponse {
// evidence returns all evidences.
repeated google.protobuf.Any evidence = 1;
// pagination defines the pagination in the response.
cosmos.base.query.v1beta1.PageResponse pagination = 2;
}

View File

@ -0,0 +1,32 @@
syntax = "proto3";
package cosmos.evidence.v1beta1;
option go_package = "github.com/cosmos/cosmos-sdk/x/evidence/types";
option (gogoproto.equal_all) = true;
import "gogoproto/gogo.proto";
import "google/protobuf/any.proto";
import "cosmos_proto/cosmos.proto";
// Msg defines the evidence Msg service.
service Msg {
// SubmitEvidence submits an arbitrary Evidence of misbehavior such as equivocation or
// counterfactual signing.
rpc SubmitEvidence(MsgSubmitEvidence) returns (MsgSubmitEvidenceResponse);
}
// MsgSubmitEvidence represents a message that supports submitting arbitrary
// Evidence of misbehavior such as equivocation or counterfactual signing.
message MsgSubmitEvidence {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
string submitter = 1;
google.protobuf.Any evidence = 2 [(cosmos_proto.accepts_interface) = "Evidence"];
}
// MsgSubmitEvidenceResponse defines the Msg/SubmitEvidence response type.
message MsgSubmitEvidenceResponse {
// hash defines the hash of the evidence.
bytes hash = 4;
}

View File

@ -0,0 +1,81 @@
syntax = "proto3";
package cosmos.feegrant.v1beta1;
import "gogoproto/gogo.proto";
import "google/protobuf/any.proto";
import "cosmos_proto/cosmos.proto";
import "cosmos/base/v1beta1/coin.proto";
import "google/protobuf/timestamp.proto";
import "google/protobuf/duration.proto";
option go_package = "github.com/cosmos/cosmos-sdk/x/feegrant/types";
// BasicFeeAllowance implements FeeAllowance with a one-time grant of tokens
// that optionally expires. The delegatee can use up to SpendLimit to cover fees.
message BasicFeeAllowance {
option (cosmos_proto.implements_interface) = "FeeAllowanceI";
// spend_limit specifies the maximum amount of tokens that can be spent
// by this allowance and will be updated as tokens are spent. If it is
// empty, there is no spend limit and any amount of coins can be spent.
repeated cosmos.base.v1beta1.Coin spend_limit = 1
[(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"];
// expiration specifies an optional time when this allowance expires
ExpiresAt expiration = 2 [(gogoproto.nullable) = false];
}
// PeriodicFeeAllowance extends FeeAllowance to allow for both a maximum cap,
// as well as a limit per time period.
message PeriodicFeeAllowance {
option (cosmos_proto.implements_interface) = "FeeAllowanceI";
// basic specifies a struct of `BasicFeeAllowance`
BasicFeeAllowance basic = 1 [(gogoproto.nullable) = false];
// period specifies the time duration in which period_spend_limit coins can
// be spent before that allowance is reset
Duration period = 2 [(gogoproto.nullable) = false];
// period_spend_limit specifies the maximum number of coins that can be spent
// in the period
repeated cosmos.base.v1beta1.Coin period_spend_limit = 3
[(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"];
// period_can_spend is the number of coins left to be spent before the period_reset time
repeated cosmos.base.v1beta1.Coin period_can_spend = 4
[(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"];
// period_reset is the time at which this period resets and a new one begins,
// it is calculated from the start time of the first transaction after the
// last period ended
ExpiresAt period_reset = 5 [(gogoproto.nullable) = false];
}
// Duration is a span of a clock time or number of blocks.
// This is designed to be added to an ExpiresAt struct.
message Duration {
// sum is the oneof that represents either duration or block
oneof sum {
google.protobuf.Duration duration = 1 [(gogoproto.stdduration) = true];
uint64 blocks = 2;
}
}
// ExpiresAt is a point in time where something expires.
// It may be *either* block time or block height
message ExpiresAt {
// sum is the oneof that represents either time or height
oneof sum {
google.protobuf.Timestamp time = 1 [(gogoproto.stdtime) = true];
int64 height = 2;
}
}
// FeeAllowanceGrant is stored in the KVStore to record a grant with full context
message FeeAllowanceGrant {
string granter = 1;
string grantee = 2;
google.protobuf.Any allowance = 3 [(cosmos_proto.accepts_interface) = "FeeAllowanceI"];
}

View File

@ -0,0 +1,12 @@
syntax = "proto3";
package cosmos.feegrant.v1beta1;
import "gogoproto/gogo.proto";
import "cosmos/feegrant/v1beta1/feegrant.proto";
option go_package = "github.com/cosmos/cosmos-sdk/x/feegrant/types";
// GenesisState contains a set of fee allowances, persisted from the store
message GenesisState {
repeated FeeAllowanceGrant fee_allowances = 1 [(gogoproto.nullable) = false];
}

View File

@ -0,0 +1,51 @@
syntax = "proto3";
package cosmos.feegrant.v1beta1;
import "cosmos/feegrant/v1beta1/feegrant.proto";
import "cosmos/base/query/v1beta1/pagination.proto";
import "google/api/annotations.proto";
option go_package = "github.com/cosmos/cosmos-sdk/x/feegrant/types";
// Query defines the gRPC querier service.
service Query {
// FeeAllowance returns fee granted to the grantee by the granter.
rpc FeeAllowance(QueryFeeAllowanceRequest) returns (QueryFeeAllowanceResponse) {
option (google.api.http).get = "/cosmos/feegrant/v1beta1/fee_allowance/{granter}/{grantee}";
}
// FeeAllowances returns all the grants for address.
rpc FeeAllowances(QueryFeeAllowancesRequest) returns (QueryFeeAllowancesResponse) {
option (google.api.http).get = "/cosmos/feegrant/v1beta1/fee_allowances/{grantee}";
}
}
// QueryFeeAllowanceRequest is the request type for the Query/FeeAllowance RPC method.
message QueryFeeAllowanceRequest {
string granter = 1;
string grantee = 2;
}
// QueryFeeAllowanceResponse is the response type for the Query/FeeAllowance RPC method.
message QueryFeeAllowanceResponse {
// fee_allowance is a fee_allowance granted for grantee by granter.
cosmos.feegrant.v1beta1.FeeAllowanceGrant fee_allowance = 1;
}
// QueryFeeAllowancesRequest is the request type for the Query/FeeAllowances RPC method.
message QueryFeeAllowancesRequest {
string grantee = 1;
// pagination defines an pagination for the request.
cosmos.base.query.v1beta1.PageRequest pagination = 2;
}
// QueryFeeAllowancesResponse is the response type for the Query/FeeAllowances RPC method.
message QueryFeeAllowancesResponse {
// fee_allowances are fee_allowance's granted for grantee by granter.
repeated cosmos.feegrant.v1beta1.FeeAllowanceGrant fee_allowances = 1;
// pagination defines an pagination for the response.
cosmos.base.query.v1beta1.PageResponse pagination = 2;
}

View File

@ -0,0 +1,40 @@
syntax = "proto3";
package cosmos.feegrant.v1beta1;
import "gogoproto/gogo.proto";
import "google/protobuf/any.proto";
import "cosmos_proto/cosmos.proto";
option go_package = "github.com/cosmos/cosmos-sdk/x/feegrant/types";
// Msg defines the feegrant msg service.
service Msg {
// GrantFeeAllowance grants fee allowance to the grantee on the granter's
// account with the provided expiration time.
rpc GrantFeeAllowance(MsgGrantFeeAllowance) returns (MsgGrantFeeAllowanceResponse);
// RevokeFeeAllowance revokes any fee allowance of granter's account that
// has been granted to the grantee.
rpc RevokeFeeAllowance(MsgRevokeFeeAllowance) returns (MsgRevokeFeeAllowanceResponse);
}
// MsgGrantFeeAllowance adds permission for Grantee to spend up to Allowance
// of fees from the account of Granter.
message MsgGrantFeeAllowance {
string granter = 1;
string grantee = 2;
google.protobuf.Any allowance = 3 [(cosmos_proto.accepts_interface) = "FeeAllowanceI"];
}
// MsgGrantFeeAllowanceResponse defines the Msg/GrantFeeAllowanceResponse response type.
message MsgGrantFeeAllowanceResponse {}
// MsgRevokeFeeAllowance removes any existing FeeAllowance from Granter to Grantee.
message MsgRevokeFeeAllowance {
string granter = 1;
string grantee = 2;
}
// MsgRevokeFeeAllowanceResponse defines the Msg/RevokeFeeAllowanceResponse response type.
message MsgRevokeFeeAllowanceResponse {}

View File

@ -0,0 +1,26 @@
syntax = "proto3";
package cosmos.gov.v1beta1;
import "gogoproto/gogo.proto";
import "cosmos/gov/v1beta1/gov.proto";
option go_package = "github.com/cosmos/cosmos-sdk/x/gov/types";
// GenesisState defines the gov module's genesis state.
message GenesisState {
// starting_proposal_id is the ID of the starting proposal.
uint64 starting_proposal_id = 1 [(gogoproto.moretags) = "yaml:\"starting_proposal_id\""];
// deposits defines all the deposits present at genesis.
repeated Deposit deposits = 2 [(gogoproto.castrepeated) = "Deposits", (gogoproto.nullable) = false];
// votes defines all the votes present at genesis.
repeated Vote votes = 3 [(gogoproto.castrepeated) = "Votes", (gogoproto.nullable) = false];
// proposals defines all the proposals present at genesis.
repeated Proposal proposals = 4 [(gogoproto.castrepeated) = "Proposals", (gogoproto.nullable) = false];
// params defines all the paramaters of related to deposit.
DepositParams deposit_params = 5 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"deposit_params\""];
// params defines all the paramaters of related to voting.
VotingParams voting_params = 6 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"voting_params\""];
// params defines all the paramaters of related to tally.
TallyParams tally_params = 7 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"tally_params\""];
}

View File

@ -0,0 +1,183 @@
syntax = "proto3";
package cosmos.gov.v1beta1;
import "cosmos/base/v1beta1/coin.proto";
import "gogoproto/gogo.proto";
import "cosmos_proto/cosmos.proto";
import "google/protobuf/timestamp.proto";
import "google/protobuf/any.proto";
import "google/protobuf/duration.proto";
option go_package = "github.com/cosmos/cosmos-sdk/x/gov/types";
option (gogoproto.goproto_stringer_all) = false;
option (gogoproto.stringer_all) = false;
option (gogoproto.goproto_getters_all) = false;
// VoteOption enumerates the valid vote options for a given governance proposal.
enum VoteOption {
option (gogoproto.goproto_enum_prefix) = false;
// VOTE_OPTION_UNSPECIFIED defines a no-op vote option.
VOTE_OPTION_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "OptionEmpty"];
// VOTE_OPTION_YES defines a yes vote option.
VOTE_OPTION_YES = 1 [(gogoproto.enumvalue_customname) = "OptionYes"];
// VOTE_OPTION_ABSTAIN defines an abstain vote option.
VOTE_OPTION_ABSTAIN = 2 [(gogoproto.enumvalue_customname) = "OptionAbstain"];
// VOTE_OPTION_NO defines a no vote option.
VOTE_OPTION_NO = 3 [(gogoproto.enumvalue_customname) = "OptionNo"];
// VOTE_OPTION_NO_WITH_VETO defines a no with veto vote option.
VOTE_OPTION_NO_WITH_VETO = 4 [(gogoproto.enumvalue_customname) = "OptionNoWithVeto"];
}
// TextProposal defines a standard text proposal whose changes need to be
// manually updated in case of approval.
message TextProposal {
option (cosmos_proto.implements_interface) = "Content";
option (gogoproto.equal) = true;
string title = 1;
string description = 2;
}
// Deposit defines an amount deposited by an account address to an active
// proposal.
message Deposit {
option (gogoproto.goproto_getters) = false;
option (gogoproto.equal) = false;
uint64 proposal_id = 1 [(gogoproto.moretags) = "yaml:\"proposal_id\""];
string depositor = 2;
repeated cosmos.base.v1beta1.Coin amount = 3
[(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"];
}
// Proposal defines the core field members of a governance proposal.
message Proposal {
option (gogoproto.equal) = true;
uint64 proposal_id = 1 [(gogoproto.jsontag) = "id", (gogoproto.moretags) = "yaml:\"id\""];
google.protobuf.Any content = 2 [(cosmos_proto.accepts_interface) = "Content"];
ProposalStatus status = 3 [(gogoproto.moretags) = "yaml:\"proposal_status\""];
TallyResult final_tally_result = 4
[(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"final_tally_result\""];
google.protobuf.Timestamp submit_time = 5
[(gogoproto.stdtime) = true, (gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"submit_time\""];
google.protobuf.Timestamp deposit_end_time = 6
[(gogoproto.stdtime) = true, (gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"deposit_end_time\""];
repeated cosmos.base.v1beta1.Coin total_deposit = 7 [
(gogoproto.nullable) = false,
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins",
(gogoproto.moretags) = "yaml:\"total_deposit\""
];
google.protobuf.Timestamp voting_start_time = 8
[(gogoproto.stdtime) = true, (gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"voting_start_time\""];
google.protobuf.Timestamp voting_end_time = 9
[(gogoproto.stdtime) = true, (gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"voting_end_time\""];
}
// ProposalStatus enumerates the valid statuses of a proposal.
enum ProposalStatus {
option (gogoproto.goproto_enum_prefix) = false;
// PROPOSAL_STATUS_UNSPECIFIED defines the default propopsal status.
PROPOSAL_STATUS_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "StatusNil"];
// PROPOSAL_STATUS_DEPOSIT_PERIOD defines a proposal status during the deposit
// period.
PROPOSAL_STATUS_DEPOSIT_PERIOD = 1 [(gogoproto.enumvalue_customname) = "StatusDepositPeriod"];
// PROPOSAL_STATUS_VOTING_PERIOD defines a proposal status during the voting
// period.
PROPOSAL_STATUS_VOTING_PERIOD = 2 [(gogoproto.enumvalue_customname) = "StatusVotingPeriod"];
// PROPOSAL_STATUS_PASSED defines a proposal status of a proposal that has
// passed.
PROPOSAL_STATUS_PASSED = 3 [(gogoproto.enumvalue_customname) = "StatusPassed"];
// PROPOSAL_STATUS_REJECTED defines a proposal status of a proposal that has
// been rejected.
PROPOSAL_STATUS_REJECTED = 4 [(gogoproto.enumvalue_customname) = "StatusRejected"];
// PROPOSAL_STATUS_FAILED defines a proposal status of a proposal that has
// failed.
PROPOSAL_STATUS_FAILED = 5 [(gogoproto.enumvalue_customname) = "StatusFailed"];
}
// TallyResult defines a standard tally for a governance proposal.
message TallyResult {
option (gogoproto.equal) = true;
string yes = 1 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", (gogoproto.nullable) = false];
string abstain = 2 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", (gogoproto.nullable) = false];
string no = 3 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", (gogoproto.nullable) = false];
string no_with_veto = 4 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false,
(gogoproto.moretags) = "yaml:\"no_with_veto\""
];
}
// Vote defines a vote on a governance proposal.
// A Vote consists of a proposal ID, the voter, and the vote option.
message Vote {
option (gogoproto.goproto_stringer) = false;
option (gogoproto.equal) = false;
uint64 proposal_id = 1 [(gogoproto.moretags) = "yaml:\"proposal_id\""];
string voter = 2;
VoteOption option = 3;
}
// DepositParams defines the params for deposits on governance proposals.
message DepositParams {
// Minimum deposit for a proposal to enter voting period.
repeated cosmos.base.v1beta1.Coin min_deposit = 1 [
(gogoproto.nullable) = false,
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins",
(gogoproto.moretags) = "yaml:\"min_deposit\"",
(gogoproto.jsontag) = "min_deposit,omitempty"
];
// Maximum period for Atom holders to deposit on a proposal. Initial value: 2
// months.
google.protobuf.Duration max_deposit_period = 2 [
(gogoproto.nullable) = false,
(gogoproto.stdduration) = true,
(gogoproto.jsontag) = "max_deposit_period,omitempty",
(gogoproto.moretags) = "yaml:\"max_deposit_period\""
];
}
// VotingParams defines the params for voting on governance proposals.
message VotingParams {
// Length of the voting period.
google.protobuf.Duration voting_period = 1 [
(gogoproto.nullable) = false,
(gogoproto.stdduration) = true,
(gogoproto.jsontag) = "voting_period,omitempty",
(gogoproto.moretags) = "yaml:\"voting_period\""
];
}
// TallyParams defines the params for tallying votes on governance proposals.
message TallyParams {
// Minimum percentage of total stake needed to vote for a result to be
// considered valid.
bytes quorum = 1 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false,
(gogoproto.jsontag) = "quorum,omitempty"
];
// Minimum proportion of Yes votes for proposal to pass. Default value: 0.5.
bytes threshold = 2 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false,
(gogoproto.jsontag) = "threshold,omitempty"
];
// Minimum value of Veto votes to Total votes ratio for proposal to be
// vetoed. Default value: 1/3.
bytes veto_threshold = 3 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false,
(gogoproto.jsontag) = "veto_threshold,omitempty",
(gogoproto.moretags) = "yaml:\"veto_threshold\""
];
}

View File

@ -0,0 +1,190 @@
syntax = "proto3";
package cosmos.gov.v1beta1;
import "cosmos/base/query/v1beta1/pagination.proto";
import "gogoproto/gogo.proto";
import "google/api/annotations.proto";
import "cosmos/gov/v1beta1/gov.proto";
option go_package = "github.com/cosmos/cosmos-sdk/x/gov/types";
// Query defines the gRPC querier service for gov module
service Query {
// Proposal queries proposal details based on ProposalID.
rpc Proposal(QueryProposalRequest) returns (QueryProposalResponse) {
option (google.api.http).get = "/cosmos/gov/v1beta1/proposals/{proposal_id}";
}
// Proposals queries all proposals based on given status.
rpc Proposals(QueryProposalsRequest) returns (QueryProposalsResponse) {
option (google.api.http).get = "/cosmos/gov/v1beta1/proposals";
}
// Vote queries voted information based on proposalID, voterAddr.
rpc Vote(QueryVoteRequest) returns (QueryVoteResponse) {
option (google.api.http).get = "/cosmos/gov/v1beta1/proposals/{proposal_id}/votes/{voter}";
}
// Votes queries votes of a given proposal.
rpc Votes(QueryVotesRequest) returns (QueryVotesResponse) {
option (google.api.http).get = "/cosmos/gov/v1beta1/proposals/{proposal_id}/votes";
}
// Params queries all parameters of the gov module.
rpc Params(QueryParamsRequest) returns (QueryParamsResponse) {
option (google.api.http).get = "/cosmos/gov/v1beta1/params/{params_type}";
}
// Deposit queries single deposit information based proposalID, depositAddr.
rpc Deposit(QueryDepositRequest) returns (QueryDepositResponse) {
option (google.api.http).get = "/cosmos/gov/v1beta1/proposals/{proposal_id}/deposits/{depositor}";
}
// Deposits queries all deposits of a single proposal.
rpc Deposits(QueryDepositsRequest) returns (QueryDepositsResponse) {
option (google.api.http).get = "/cosmos/gov/v1beta1/proposals/{proposal_id}/deposits";
}
// TallyResult queries the tally of a proposal vote.
rpc TallyResult(QueryTallyResultRequest) returns (QueryTallyResultResponse) {
option (google.api.http).get = "/cosmos/gov/v1beta1/proposals/{proposal_id}/tally";
}
}
// QueryProposalRequest is the request type for the Query/Proposal RPC method.
message QueryProposalRequest {
// proposal_id defines the unique id of the proposal.
uint64 proposal_id = 1;
}
// QueryProposalResponse is the response type for the Query/Proposal RPC method.
message QueryProposalResponse {
Proposal proposal = 1 [(gogoproto.nullable) = false];
}
// QueryProposalsRequest is the request type for the Query/Proposals RPC method.
message QueryProposalsRequest {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
// proposal_status defines the status of the proposals.
ProposalStatus proposal_status = 1;
// voter defines the voter address for the proposals.
string voter = 2;
// depositor defines the deposit addresses from the proposals.
string depositor = 3;
// pagination defines an optional pagination for the request.
cosmos.base.query.v1beta1.PageRequest pagination = 4;
}
// QueryProposalsResponse is the response type for the Query/Proposals RPC
// method.
message QueryProposalsResponse {
repeated Proposal proposals = 1 [(gogoproto.nullable) = false];
// pagination defines the pagination in the response.
cosmos.base.query.v1beta1.PageResponse pagination = 2;
}
// QueryVoteRequest is the request type for the Query/Vote RPC method.
message QueryVoteRequest {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
// proposal_id defines the unique id of the proposal.
uint64 proposal_id = 1;
// voter defines the oter address for the proposals.
string voter = 2;
}
// QueryVoteResponse is the response type for the Query/Vote RPC method.
message QueryVoteResponse {
// vote defined the queried vote.
Vote vote = 1 [(gogoproto.nullable) = false];
}
// QueryVotesRequest is the request type for the Query/Votes RPC method.
message QueryVotesRequest {
// proposal_id defines the unique id of the proposal.
uint64 proposal_id = 1;
// pagination defines an optional pagination for the request.
cosmos.base.query.v1beta1.PageRequest pagination = 2;
}
// QueryVotesResponse is the response type for the Query/Votes RPC method.
message QueryVotesResponse {
// votes defined the queried votes.
repeated Vote votes = 1 [(gogoproto.nullable) = false];
// pagination defines the pagination in the response.
cosmos.base.query.v1beta1.PageResponse pagination = 2;
}
// QueryParamsRequest is the request type for the Query/Params RPC method.
message QueryParamsRequest {
// params_type defines which parameters to query for, can be one of "voting",
// "tallying" or "deposit".
string params_type = 1;
}
// QueryParamsResponse is the response type for the Query/Params RPC method.
message QueryParamsResponse {
// voting_params defines the parameters related to voting.
VotingParams voting_params = 1 [(gogoproto.nullable) = false];
// deposit_params defines the parameters related to deposit.
DepositParams deposit_params = 2 [(gogoproto.nullable) = false];
// tally_params defines the parameters related to tally.
TallyParams tally_params = 3 [(gogoproto.nullable) = false];
}
// QueryDepositRequest is the request type for the Query/Deposit RPC method.
message QueryDepositRequest {
option (gogoproto.goproto_getters) = false;
option (gogoproto.equal) = false;
// proposal_id defines the unique id of the proposal.
uint64 proposal_id = 1;
// depositor defines the deposit addresses from the proposals.
string depositor = 2;
}
// QueryDepositResponse is the response type for the Query/Deposit RPC method.
message QueryDepositResponse {
// deposit defines the requested deposit.
Deposit deposit = 1 [(gogoproto.nullable) = false];
}
// QueryDepositsRequest is the request type for the Query/Deposits RPC method.
message QueryDepositsRequest {
// proposal_id defines the unique id of the proposal.
uint64 proposal_id = 1;
// pagination defines an optional pagination for the request.
cosmos.base.query.v1beta1.PageRequest pagination = 2;
}
// QueryDepositsResponse is the response type for the Query/Deposits RPC method.
message QueryDepositsResponse {
repeated Deposit deposits = 1 [(gogoproto.nullable) = false];
// pagination defines the pagination in the response.
cosmos.base.query.v1beta1.PageResponse pagination = 2;
}
// QueryTallyResultRequest is the request type for the Query/Tally RPC method.
message QueryTallyResultRequest {
// proposal_id defines the unique id of the proposal.
uint64 proposal_id = 1;
}
// QueryTallyResultResponse is the response type for the Query/Tally RPC method.
message QueryTallyResultResponse {
// tally defines the requested tally.
TallyResult tally = 1 [(gogoproto.nullable) = false];
}

View File

@ -0,0 +1,75 @@
syntax = "proto3";
package cosmos.gov.v1beta1;
import "cosmos/base/v1beta1/coin.proto";
import "cosmos/gov/v1beta1/gov.proto";
import "cosmos_proto/cosmos.proto";
import "gogoproto/gogo.proto";
import "google/protobuf/any.proto";
option go_package = "github.com/cosmos/cosmos-sdk/x/gov/types";
// Msg defines the bank Msg service.
service Msg {
// SubmitProposal defines a method to create new proposal given a content.
rpc SubmitProposal(MsgSubmitProposal) returns (MsgSubmitProposalResponse);
// Vote defines a method to add a vote on a specific proposal.
rpc Vote(MsgVote) returns (MsgVoteResponse);
// Deposit defines a method to add deposit on a specific proposal.
rpc Deposit(MsgDeposit) returns (MsgDepositResponse);
}
// MsgSubmitProposal defines an sdk.Msg type that supports submitting arbitrary
// proposal Content.
message MsgSubmitProposal {
option (gogoproto.equal) = false;
option (gogoproto.goproto_stringer) = false;
option (gogoproto.stringer) = false;
option (gogoproto.goproto_getters) = false;
google.protobuf.Any content = 1 [(cosmos_proto.accepts_interface) = "Content"];
repeated cosmos.base.v1beta1.Coin initial_deposit = 2 [
(gogoproto.nullable) = false,
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins",
(gogoproto.moretags) = "yaml:\"initial_deposit\""
];
string proposer = 3;
}
// MsgSubmitProposalResponse defines the Msg/SubmitProposal response type.
message MsgSubmitProposalResponse {
uint64 proposal_id = 1 [(gogoproto.jsontag) = "proposal_id", (gogoproto.moretags) = "yaml:\"proposal_id\""];
}
// MsgVote defines a message to cast a vote.
message MsgVote {
option (gogoproto.equal) = false;
option (gogoproto.goproto_stringer) = false;
option (gogoproto.stringer) = false;
option (gogoproto.goproto_getters) = false;
uint64 proposal_id = 1 [(gogoproto.jsontag) = "proposal_id", (gogoproto.moretags) = "yaml:\"proposal_id\""];
string voter = 2;
VoteOption option = 3;
}
// MsgVoteResponse defines the Msg/Vote response type.
message MsgVoteResponse {}
// MsgDeposit defines a message to submit a deposit to an existing proposal.
message MsgDeposit {
option (gogoproto.equal) = false;
option (gogoproto.goproto_stringer) = false;
option (gogoproto.stringer) = false;
option (gogoproto.goproto_getters) = false;
uint64 proposal_id = 1 [(gogoproto.jsontag) = "proposal_id", (gogoproto.moretags) = "yaml:\"proposal_id\""];
string depositor = 2;
repeated cosmos.base.v1beta1.Coin amount = 3
[(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"];
}
// MsgDepositResponse defines the Msg/Deposit response type.
message MsgDepositResponse {}

View File

@ -0,0 +1,16 @@
syntax = "proto3";
package cosmos.mint.v1beta1;
import "gogoproto/gogo.proto";
import "cosmos/mint/v1beta1/mint.proto";
option go_package = "github.com/cosmos/cosmos-sdk/x/mint/types";
// GenesisState defines the mint module's genesis state.
message GenesisState {
// minter is a space for holding current inflation information.
Minter minter = 1 [(gogoproto.nullable) = false];
// params defines all the paramaters of the module.
Params params = 2 [(gogoproto.nullable) = false];
}

View File

@ -0,0 +1,53 @@
syntax = "proto3";
package cosmos.mint.v1beta1;
option go_package = "github.com/cosmos/cosmos-sdk/x/mint/types";
import "gogoproto/gogo.proto";
// Minter represents the minting state.
message Minter {
// current annual inflation rate
string inflation = 1
[(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false];
// current annual expected provisions
string annual_provisions = 2 [
(gogoproto.moretags) = "yaml:\"annual_provisions\"",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
}
// Params holds parameters for the mint module.
message Params {
option (gogoproto.goproto_stringer) = false;
// type of coin to mint
string mint_denom = 1;
// maximum annual change in inflation rate
string inflation_rate_change = 2 [
(gogoproto.moretags) = "yaml:\"inflation_rate_change\"",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
// maximum inflation rate
string inflation_max = 3 [
(gogoproto.moretags) = "yaml:\"inflation_max\"",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
// minimum inflation rate
string inflation_min = 4 [
(gogoproto.moretags) = "yaml:\"inflation_min\"",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
// goal of percent bonded atoms
string goal_bonded = 5 [
(gogoproto.moretags) = "yaml:\"goal_bonded\"",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
// expected blocks per year
uint64 blocks_per_year = 6 [(gogoproto.moretags) = "yaml:\"blocks_per_year\""];
}

View File

@ -0,0 +1,57 @@
syntax = "proto3";
package cosmos.mint.v1beta1;
import "gogoproto/gogo.proto";
import "google/api/annotations.proto";
import "cosmos/mint/v1beta1/mint.proto";
option go_package = "github.com/cosmos/cosmos-sdk/x/mint/types";
// Query provides defines the gRPC querier service.
service Query {
// Params returns the total set of minting parameters.
rpc Params(QueryParamsRequest) returns (QueryParamsResponse) {
option (google.api.http).get = "/cosmos/mint/v1beta1/params";
}
// Inflation returns the current minting inflation value.
rpc Inflation(QueryInflationRequest) returns (QueryInflationResponse) {
option (google.api.http).get = "/cosmos/mint/v1beta1/inflation";
}
// AnnualProvisions current minting annual provisions value.
rpc AnnualProvisions(QueryAnnualProvisionsRequest) returns (QueryAnnualProvisionsResponse) {
option (google.api.http).get = "/cosmos/mint/v1beta1/annual_provisions";
}
}
// QueryParamsRequest is the request type for the Query/Params RPC method.
message QueryParamsRequest {}
// QueryParamsResponse is the response type for the Query/Params RPC method.
message QueryParamsResponse {
// params defines the parameters of the module.
Params params = 1 [(gogoproto.nullable) = false];
}
// QueryInflationRequest is the request type for the Query/Inflation RPC method.
message QueryInflationRequest {}
// QueryInflationResponse is the response type for the Query/Inflation RPC
// method.
message QueryInflationResponse {
// inflation is the current minting inflation value.
bytes inflation = 1 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false];
}
// QueryAnnualProvisionsRequest is the request type for the
// Query/AnnualProvisions RPC method.
message QueryAnnualProvisionsRequest {}
// QueryAnnualProvisionsResponse is the response type for the
// Query/AnnualProvisions RPC method.
message QueryAnnualProvisionsResponse {
// annual_provisions is the current minting annual provisions value.
bytes annual_provisions = 1
[(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false];
}

View File

@ -0,0 +1,27 @@
syntax = "proto3";
package cosmos.params.v1beta1;
option go_package = "github.com/cosmos/cosmos-sdk/x/params/types/proposal";
option (gogoproto.equal_all) = true;
import "gogoproto/gogo.proto";
// ParameterChangeProposal defines a proposal to change one or more parameters.
message ParameterChangeProposal {
option (gogoproto.goproto_getters) = false;
option (gogoproto.goproto_stringer) = false;
string title = 1;
string description = 2;
repeated ParamChange changes = 3 [(gogoproto.nullable) = false];
}
// ParamChange defines an individual parameter change, for use in
// ParameterChangeProposal.
message ParamChange {
option (gogoproto.goproto_stringer) = false;
string subspace = 1;
string key = 2;
string value = 3;
}

View File

@ -0,0 +1,32 @@
syntax = "proto3";
package cosmos.params.v1beta1;
import "gogoproto/gogo.proto";
import "google/api/annotations.proto";
import "cosmos/params/v1beta1/params.proto";
option go_package = "github.com/cosmos/cosmos-sdk/x/params/types/proposal";
// Query defines the gRPC querier service.
service Query {
// Params queries a specific parameter of a module, given its subspace and
// key.
rpc Params(QueryParamsRequest) returns (QueryParamsResponse) {
option (google.api.http).get = "/cosmos/params/v1beta1/params";
}
}
// QueryParamsRequest is request type for the Query/Params RPC method.
message QueryParamsRequest {
// subspace defines the module to query the parameter for.
string subspace = 1;
// key defines the key of the parameter in the subspace.
string key = 2;
}
// QueryParamsResponse is response type for the Query/Params RPC method.
message QueryParamsResponse {
// param defines the queried parameter.
ParamChange param = 1 [(gogoproto.nullable) = false];
}

View File

@ -0,0 +1,50 @@
syntax = "proto3";
package cosmos.slashing.v1beta1;
option go_package = "github.com/cosmos/cosmos-sdk/x/slashing/types";
import "gogoproto/gogo.proto";
import "cosmos/slashing/v1beta1/slashing.proto";
// GenesisState defines the slashing module's genesis state.
message GenesisState {
// params defines all the paramaters of related to deposit.
Params params = 1 [(gogoproto.nullable) = false];
// signing_infos represents a map between validator addresses and their
// signing infos.
repeated SigningInfo signing_infos = 2
[(gogoproto.moretags) = "yaml:\"signing_infos\"", (gogoproto.nullable) = false];
// signing_infos represents a map between validator addresses and their
// missed blocks.
repeated ValidatorMissedBlocks missed_blocks = 3
[(gogoproto.moretags) = "yaml:\"missed_blocks\"", (gogoproto.nullable) = false];
}
// SigningInfo stores validator signing info of corresponding address.
message SigningInfo {
// address is the validator address.
string address = 1;
// validator_signing_info represents the signing info of this validator.
ValidatorSigningInfo validator_signing_info = 2
[(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"validator_signing_info\""];
}
// ValidatorMissedBlocks contains array of missed blocks of corresponding
// address.
message ValidatorMissedBlocks {
// address is the validator address.
string address = 1;
// missed_blocks is an array of missed blocks by the validator.
repeated MissedBlock missed_blocks = 2
[(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"missed_blocks\""];
}
// MissedBlock contains height and missed status as boolean.
message MissedBlock {
// index is the height at which the block was missed.
int64 index = 1;
// missed is the missed status.
bool missed = 2;
}

View File

@ -0,0 +1,63 @@
syntax = "proto3";
package cosmos.slashing.v1beta1;
import "cosmos/base/query/v1beta1/pagination.proto";
import "gogoproto/gogo.proto";
import "google/api/annotations.proto";
import "cosmos/slashing/v1beta1/slashing.proto";
option go_package = "github.com/cosmos/cosmos-sdk/x/slashing/types";
// Query provides defines the gRPC querier service
service Query {
// Params queries the parameters of slashing module
rpc Params(QueryParamsRequest) returns (QueryParamsResponse) {
option (google.api.http).get = "/cosmos/slashing/v1beta1/params";
}
// SigningInfo queries the signing info of given cons address
rpc SigningInfo(QuerySigningInfoRequest) returns (QuerySigningInfoResponse) {
option (google.api.http).get = "/cosmos/slashing/v1beta1/signing_infos/{cons_address}";
}
// SigningInfos queries signing info of all validators
rpc SigningInfos(QuerySigningInfosRequest) returns (QuerySigningInfosResponse) {
option (google.api.http).get = "/cosmos/slashing/v1beta1/signing_infos";
}
}
// QueryParamsRequest is the request type for the Query/Params RPC method
message QueryParamsRequest {}
// QueryParamsResponse is the response type for the Query/Params RPC method
message QueryParamsResponse {
Params params = 1 [(gogoproto.nullable) = false];
}
// QuerySigningInfoRequest is the request type for the Query/SigningInfo RPC
// method
message QuerySigningInfoRequest {
// cons_address is the address to query signing info of
string cons_address = 1;
}
// QuerySigningInfoResponse is the response type for the Query/SigningInfo RPC
// method
message QuerySigningInfoResponse {
// val_signing_info is the signing info of requested val cons address
ValidatorSigningInfo val_signing_info = 1 [(gogoproto.nullable) = false];
}
// QuerySigningInfosRequest is the request type for the Query/SigningInfos RPC
// method
message QuerySigningInfosRequest {
cosmos.base.query.v1beta1.PageRequest pagination = 1;
}
// QuerySigningInfosResponse is the response type for the Query/SigningInfos RPC
// method
message QuerySigningInfosResponse {
// info is the signing info of all validators
repeated cosmos.slashing.v1beta1.ValidatorSigningInfo info = 1 [(gogoproto.nullable) = false];
cosmos.base.query.v1beta1.PageResponse pagination = 2;
}

View File

@ -0,0 +1,58 @@
syntax = "proto3";
package cosmos.slashing.v1beta1;
option go_package = "github.com/cosmos/cosmos-sdk/x/slashing/types";
option (gogoproto.equal_all) = true;
import "gogoproto/gogo.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/timestamp.proto";
// ValidatorSigningInfo defines a validator's signing info for monitoring their
// liveness activity.
message ValidatorSigningInfo {
option (gogoproto.equal) = true;
option (gogoproto.goproto_stringer) = false;
string address = 1;
// Height at which validator was first a candidate OR was unjailed
int64 start_height = 2 [(gogoproto.moretags) = "yaml:\"start_height\""];
// Index which is incremented each time the validator was a bonded
// in a block and may have signed a precommit or not. This in conjunction with the
// `SignedBlocksWindow` param determines the index in the `MissedBlocksBitArray`.
int64 index_offset = 3 [(gogoproto.moretags) = "yaml:\"index_offset\""];
// Timestamp until which the validator is jailed due to liveness downtime.
google.protobuf.Timestamp jailed_until = 4
[(gogoproto.moretags) = "yaml:\"jailed_until\"", (gogoproto.stdtime) = true, (gogoproto.nullable) = false];
// Whether or not a validator has been tombstoned (killed out of validator set). It is set
// once the validator commits an equivocation or for any other configured misbehiavor.
bool tombstoned = 5;
// A counter kept to avoid unnecessary array reads.
// Note that `Sum(MissedBlocksBitArray)` always equals `MissedBlocksCounter`.
int64 missed_blocks_counter = 6 [(gogoproto.moretags) = "yaml:\"missed_blocks_counter\""];
}
// Params represents the parameters used for by the slashing module.
message Params {
int64 signed_blocks_window = 1 [(gogoproto.moretags) = "yaml:\"signed_blocks_window\""];
bytes min_signed_per_window = 2 [
(gogoproto.moretags) = "yaml:\"min_signed_per_window\"",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
google.protobuf.Duration downtime_jail_duration = 3 [
(gogoproto.nullable) = false,
(gogoproto.stdduration) = true,
(gogoproto.moretags) = "yaml:\"downtime_jail_duration\""
];
bytes slash_fraction_double_sign = 4 [
(gogoproto.moretags) = "yaml:\"slash_fraction_double_sign\"",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
bytes slash_fraction_downtime = 5 [
(gogoproto.moretags) = "yaml:\"slash_fraction_downtime\"",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
}

View File

@ -0,0 +1,26 @@
syntax = "proto3";
package cosmos.slashing.v1beta1;
option go_package = "github.com/cosmos/cosmos-sdk/x/slashing/types";
option (gogoproto.equal_all) = true;
import "gogoproto/gogo.proto";
// Msg defines the slashing Msg service.
service Msg {
// Unjail defines a method for unjailing a jailed validator, thus returning
// them into the bonded validator set, so they can begin receiving provisions
// and rewards again.
rpc Unjail(MsgUnjail) returns (MsgUnjailResponse);
}
// MsgUnjail defines the Msg/Unjail request type
message MsgUnjail {
option (gogoproto.goproto_getters) = false;
option (gogoproto.goproto_stringer) = true;
string validator_addr = 1 [(gogoproto.moretags) = "yaml:\"address\"", (gogoproto.jsontag) = "address"];
}
// MsgUnjailResponse defines the Msg/Unjail response type
message MsgUnjailResponse {}

View File

@ -0,0 +1,53 @@
syntax = "proto3";
package cosmos.staking.v1beta1;
option go_package = "github.com/cosmos/cosmos-sdk/x/staking/types";
import "gogoproto/gogo.proto";
import "cosmos/staking/v1beta1/staking.proto";
// GenesisState defines the staking module's genesis state.
message GenesisState {
// params defines all the paramaters of related to deposit.
Params params = 1 [(gogoproto.nullable) = false];
// last_total_power tracks the total amounts of bonded tokens recorded during
// the previous end block.
bytes last_total_power = 2 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.moretags) = "yaml:\"last_total_power\"",
(gogoproto.nullable) = false
];
// last_validator_powers is a special index that provides a historical list
// of the last-block's bonded validators.
repeated LastValidatorPower last_validator_powers = 3
[(gogoproto.moretags) = "yaml:\"last_validator_powers\"", (gogoproto.nullable) = false];
// delegations defines the validator set at genesis.
repeated Validator validators = 4 [(gogoproto.nullable) = false];
// delegations defines the delegations active at genesis.
repeated Delegation delegations = 5 [(gogoproto.nullable) = false];
// unbonding_delegations defines the unbonding delegations active at genesis.
repeated UnbondingDelegation unbonding_delegations = 6
[(gogoproto.moretags) = "yaml:\"unbonding_delegations\"", (gogoproto.nullable) = false];
// redelegations defines the redelegations active at genesis.
repeated Redelegation redelegations = 7 [(gogoproto.nullable) = false];
bool exported = 8;
}
// LastValidatorPower required for validator set update logic.
message LastValidatorPower {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
// address is the address of the validator.
string address = 1;
// power defines the power of the validator.
int64 power = 2;
}

View File

@ -0,0 +1,348 @@
syntax = "proto3";
package cosmos.staking.v1beta1;
import "cosmos/base/query/v1beta1/pagination.proto";
import "gogoproto/gogo.proto";
import "google/api/annotations.proto";
import "cosmos/staking/v1beta1/staking.proto";
option go_package = "github.com/cosmos/cosmos-sdk/x/staking/types";
// Query defines the gRPC querier service.
service Query {
// Validators queries all validators that match the given status.
rpc Validators(QueryValidatorsRequest) returns (QueryValidatorsResponse) {
option (google.api.http).get = "/cosmos/staking/v1beta1/validators";
}
// Validator queries validator info for given validator address.
rpc Validator(QueryValidatorRequest) returns (QueryValidatorResponse) {
option (google.api.http).get = "/cosmos/staking/v1beta1/validators/{validator_addr}";
}
// ValidatorDelegations queries delegate info for given validator.
rpc ValidatorDelegations(QueryValidatorDelegationsRequest) returns (QueryValidatorDelegationsResponse) {
option (google.api.http).get = "/cosmos/staking/v1beta1/validators/{validator_addr}/delegations";
}
// ValidatorUnbondingDelegations queries unbonding delegations of a validator.
rpc ValidatorUnbondingDelegations(QueryValidatorUnbondingDelegationsRequest)
returns (QueryValidatorUnbondingDelegationsResponse) {
option (google.api.http).get = "/cosmos/staking/v1beta1/validators/"
"{validator_addr}/unbonding_delegations";
}
// Delegation queries delegate info for given validator delegator pair.
rpc Delegation(QueryDelegationRequest) returns (QueryDelegationResponse) {
option (google.api.http).get = "/cosmos/staking/v1beta1/validators/{validator_addr}/delegations/"
"{delegator_addr}";
}
// UnbondingDelegation queries unbonding info for given validator delegator
// pair.
rpc UnbondingDelegation(QueryUnbondingDelegationRequest) returns (QueryUnbondingDelegationResponse) {
option (google.api.http).get = "/cosmos/staking/v1beta1/validators/{validator_addr}/delegations/"
"{delegator_addr}/unbonding_delegation";
}
// DelegatorDelegations queries all delegations of a given delegator address.
rpc DelegatorDelegations(QueryDelegatorDelegationsRequest) returns (QueryDelegatorDelegationsResponse) {
option (google.api.http).get = "/cosmos/staking/v1beta1/delegations/{delegator_addr}";
}
// DelegatorUnbondingDelegations queries all unbonding delegations of a given
// delegator address.
rpc DelegatorUnbondingDelegations(QueryDelegatorUnbondingDelegationsRequest)
returns (QueryDelegatorUnbondingDelegationsResponse) {
option (google.api.http).get = "/cosmos/staking/v1beta1/delegators/"
"{delegator_addr}/unbonding_delegations";
}
// Redelegations queries redelegations of given address.
rpc Redelegations(QueryRedelegationsRequest) returns (QueryRedelegationsResponse) {
option (google.api.http).get = "/cosmos/staking/v1beta1/delegators/{delegator_addr}/redelegations";
}
// DelegatorValidators queries all validators info for given delegator
// address.
rpc DelegatorValidators(QueryDelegatorValidatorsRequest) returns (QueryDelegatorValidatorsResponse) {
option (google.api.http).get = "/cosmos/staking/v1beta1/delegators/{delegator_addr}/validators";
}
// DelegatorValidator queries validator info for given delegator validator
// pair.
rpc DelegatorValidator(QueryDelegatorValidatorRequest) returns (QueryDelegatorValidatorResponse) {
option (google.api.http).get = "/cosmos/staking/v1beta1/delegators/{delegator_addr}/validators/"
"{validator_addr}";
}
// HistoricalInfo queries the historical info for given height.
rpc HistoricalInfo(QueryHistoricalInfoRequest) returns (QueryHistoricalInfoResponse) {
option (google.api.http).get = "/cosmos/staking/v1beta1/historical_info/{height}";
}
// Pool queries the pool info.
rpc Pool(QueryPoolRequest) returns (QueryPoolResponse) {
option (google.api.http).get = "/cosmos/staking/v1beta1/pool";
}
// Parameters queries the staking parameters.
rpc Params(QueryParamsRequest) returns (QueryParamsResponse) {
option (google.api.http).get = "/cosmos/staking/v1beta1/params";
}
}
// QueryValidatorsRequest is request type for Query/Validators RPC method.
message QueryValidatorsRequest {
// status enables to query for validators matching a given status.
string status = 1;
// pagination defines an optional pagination for the request.
cosmos.base.query.v1beta1.PageRequest pagination = 2;
}
// QueryValidatorsResponse is response type for the Query/Validators RPC method
message QueryValidatorsResponse {
// validators contains all the queried validators.
repeated Validator validators = 1 [(gogoproto.nullable) = false];
// pagination defines the pagination in the response.
cosmos.base.query.v1beta1.PageResponse pagination = 2;
}
// QueryValidatorRequest is response type for the Query/Validator RPC method
message QueryValidatorRequest {
// validator_addr defines the validator address to query for.
string validator_addr = 1;
}
// QueryValidatorResponse is response type for the Query/Validator RPC method
message QueryValidatorResponse {
// validator defines the the validator info.
Validator validator = 1 [(gogoproto.nullable) = false];
}
// QueryValidatorDelegationsRequest is request type for the
// Query/ValidatorDelegations RPC method
message QueryValidatorDelegationsRequest {
// validator_addr defines the validator address to query for.
string validator_addr = 1;
// pagination defines an optional pagination for the request.
cosmos.base.query.v1beta1.PageRequest pagination = 2;
}
// QueryValidatorDelegationsResponse is response type for the
// Query/ValidatorDelegations RPC method
message QueryValidatorDelegationsResponse {
repeated DelegationResponse delegation_responses = 1
[(gogoproto.nullable) = false, (gogoproto.castrepeated) = "DelegationResponses"];
// pagination defines the pagination in the response.
cosmos.base.query.v1beta1.PageResponse pagination = 2;
}
// QueryValidatorUnbondingDelegationsRequest is required type for the
// Query/ValidatorUnbondingDelegations RPC method
message QueryValidatorUnbondingDelegationsRequest {
// validator_addr defines the validator address to query for.
string validator_addr = 1;
// pagination defines an optional pagination for the request.
cosmos.base.query.v1beta1.PageRequest pagination = 2;
}
// QueryValidatorUnbondingDelegationsResponse is response type for the
// Query/ValidatorUnbondingDelegations RPC method.
message QueryValidatorUnbondingDelegationsResponse {
repeated UnbondingDelegation unbonding_responses = 1 [(gogoproto.nullable) = false];
// pagination defines the pagination in the response.
cosmos.base.query.v1beta1.PageResponse pagination = 2;
}
// QueryDelegationRequest is request type for the Query/Delegation RPC method.
message QueryDelegationRequest {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
// delegator_addr defines the delegator address to query for.
string delegator_addr = 1;
// validator_addr defines the validator address to query for.
string validator_addr = 2;
}
// QueryDelegationResponse is response type for the Query/Delegation RPC method.
message QueryDelegationResponse {
// delegation_responses defines the delegation info of a delegation.
DelegationResponse delegation_response = 1;
}
// QueryUnbondingDelegationRequest is request type for the
// Query/UnbondingDelegation RPC method.
message QueryUnbondingDelegationRequest {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
// delegator_addr defines the delegator address to query for.
string delegator_addr = 1;
// validator_addr defines the validator address to query for.
string validator_addr = 2;
}
// QueryDelegationResponse is response type for the Query/UnbondingDelegation
// RPC method.
message QueryUnbondingDelegationResponse {
// unbond defines the unbonding information of a delegation.
UnbondingDelegation unbond = 1 [(gogoproto.nullable) = false];
}
// QueryDelegatorDelegationsRequest is request type for the
// Query/DelegatorDelegations RPC method.
message QueryDelegatorDelegationsRequest {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
// delegator_addr defines the delegator address to query for.
string delegator_addr = 1;
// pagination defines an optional pagination for the request.
cosmos.base.query.v1beta1.PageRequest pagination = 2;
}
// QueryDelegatorDelegationsResponse is response type for the
// Query/DelegatorDelegations RPC method.
message QueryDelegatorDelegationsResponse {
// delegation_responses defines all the delegations' info of a delegator.
repeated DelegationResponse delegation_responses = 1 [(gogoproto.nullable) = false];
// pagination defines the pagination in the response.
cosmos.base.query.v1beta1.PageResponse pagination = 2;
}
// QueryDelegatorUnbondingDelegationsRequest is request type for the
// Query/DelegatorUnbondingDelegations RPC method.
message QueryDelegatorUnbondingDelegationsRequest {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
// delegator_addr defines the delegator address to query for.
string delegator_addr = 1;
// pagination defines an optional pagination for the request.
cosmos.base.query.v1beta1.PageRequest pagination = 2;
}
// QueryUnbondingDelegatorDelegationsResponse is response type for the
// Query/UnbondingDelegatorDelegations RPC method.
message QueryDelegatorUnbondingDelegationsResponse {
repeated UnbondingDelegation unbonding_responses = 1 [(gogoproto.nullable) = false];
// pagination defines the pagination in the response.
cosmos.base.query.v1beta1.PageResponse pagination = 2;
}
// QueryRedelegationsRequest is request type for the Query/Redelegations RPC
// method.
message QueryRedelegationsRequest {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
// delegator_addr defines the delegator address to query for.
string delegator_addr = 1;
// src_validator_addr defines the validator address to redelegate from.
string src_validator_addr = 2;
// dst_validator_addr defines the validator address to redelegate to.
string dst_validator_addr = 3;
// pagination defines an optional pagination for the request.
cosmos.base.query.v1beta1.PageRequest pagination = 4;
}
// QueryRedelegationsResponse is response type for the Query/Redelegations RPC
// method.
message QueryRedelegationsResponse {
repeated RedelegationResponse redelegation_responses = 1 [(gogoproto.nullable) = false];
// pagination defines the pagination in the response.
cosmos.base.query.v1beta1.PageResponse pagination = 2;
}
// QueryDelegatorValidatorsRequest is request type for the
// Query/DelegatorValidators RPC method.
message QueryDelegatorValidatorsRequest {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
// delegator_addr defines the delegator address to query for.
string delegator_addr = 1;
// pagination defines an optional pagination for the request.
cosmos.base.query.v1beta1.PageRequest pagination = 2;
}
// QueryDelegatorValidatorsResponse is response type for the
// Query/DelegatorValidators RPC method.
message QueryDelegatorValidatorsResponse {
// validators defines the the validators' info of a delegator.
repeated Validator validators = 1 [(gogoproto.nullable) = false];
// pagination defines the pagination in the response.
cosmos.base.query.v1beta1.PageResponse pagination = 2;
}
// QueryDelegatorValidatorRequest is request type for the
// Query/DelegatorValidator RPC method.
message QueryDelegatorValidatorRequest {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
// delegator_addr defines the delegator address to query for.
string delegator_addr = 1;
// validator_addr defines the validator address to query for.
string validator_addr = 2;
}
// QueryDelegatorValidatorResponse response type for the
// Query/DelegatorValidator RPC method.
message QueryDelegatorValidatorResponse {
// validator defines the the validator info.
Validator validator = 1 [(gogoproto.nullable) = false];
}
// QueryHistoricalInfoRequest is request type for the Query/HistoricalInfo RPC
// method.
message QueryHistoricalInfoRequest {
// height defines at which height to query the historical info.
int64 height = 1;
}
// QueryHistoricalInfoResponse is response type for the Query/HistoricalInfo RPC
// method.
message QueryHistoricalInfoResponse {
// hist defines the historical info at the given height.
HistoricalInfo hist = 1;
}
// QueryPoolRequest is request type for the Query/Pool RPC method.
message QueryPoolRequest {}
// QueryPoolResponse is response type for the Query/Pool RPC method.
message QueryPoolResponse {
// pool defines the pool info.
Pool pool = 1 [(gogoproto.nullable) = false];
}
// QueryParamsRequest is request type for the Query/Params RPC method.
message QueryParamsRequest {}
// QueryParamsResponse is response type for the Query/Params RPC method.
message QueryParamsResponse {
// params holds all the parameters of this module.
Params params = 1 [(gogoproto.nullable) = false];
}

View File

@ -0,0 +1,290 @@
syntax = "proto3";
package cosmos.staking.v1beta1;
import "gogoproto/gogo.proto";
import "google/protobuf/any.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/timestamp.proto";
import "cosmos_proto/cosmos.proto";
import "cosmos/base/v1beta1/coin.proto";
import "tendermint/types/types.proto";
option go_package = "github.com/cosmos/cosmos-sdk/x/staking/types";
// HistoricalInfo contains header and validator information for a given block.
// It is stored as part of staking module's state, which persists the `n` most
// recent HistoricalInfo
// (`n` is set by the staking module's `historical_entries` parameter).
message HistoricalInfo {
tendermint.types.Header header = 1 [(gogoproto.nullable) = false];
repeated Validator valset = 2 [(gogoproto.nullable) = false];
}
// CommissionRates defines the initial commission rates to be used for creating
// a validator.
message CommissionRates {
option (gogoproto.equal) = true;
option (gogoproto.goproto_stringer) = false;
string rate = 1 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false];
string max_rate = 2 [
(gogoproto.moretags) = "yaml:\"max_rate\"",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
string max_change_rate = 3 [
(gogoproto.moretags) = "yaml:\"max_change_rate\"",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
}
// Commission defines commission parameters for a given validator.
message Commission {
option (gogoproto.equal) = true;
option (gogoproto.goproto_stringer) = false;
CommissionRates commission_rates = 1 [(gogoproto.embed) = true, (gogoproto.nullable) = false];
google.protobuf.Timestamp update_time = 2
[(gogoproto.nullable) = false, (gogoproto.stdtime) = true, (gogoproto.moretags) = "yaml:\"update_time\""];
}
// Description defines a validator description.
message Description {
option (gogoproto.equal) = true;
option (gogoproto.goproto_stringer) = false;
string moniker = 1;
string identity = 2;
string website = 3;
string security_contact = 4 [(gogoproto.moretags) = "yaml:\"security_contact\""];
string details = 5;
}
// Validator defines a validator, together with the total amount of the
// Validator's bond shares and their exchange rate to coins. Slashing results in
// a decrease in the exchange rate, allowing correct calculation of future
// undelegations without iterating over delegators. When coins are delegated to
// this validator, the validator is credited with a delegation whose number of
// bond shares is based on the amount of coins delegated divided by the current
// exchange rate. Voting power can be calculated as total bonded shares
// multiplied by exchange rate.
message Validator {
option (gogoproto.equal) = false;
option (gogoproto.goproto_stringer) = false;
option (gogoproto.goproto_getters) = false;
string operator_address = 1 [(gogoproto.moretags) = "yaml:\"operator_address\""];
google.protobuf.Any consensus_pubkey = 2
[(cosmos_proto.accepts_interface) = "cosmos.crypto.PubKey", (gogoproto.moretags) = "yaml:\"consensus_pubkey\""];
bool jailed = 3;
BondStatus status = 4;
string tokens = 5 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", (gogoproto.nullable) = false];
string delegator_shares = 6 [
(gogoproto.moretags) = "yaml:\"delegator_shares\"",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
Description description = 7 [(gogoproto.nullable) = false];
int64 unbonding_height = 8 [(gogoproto.moretags) = "yaml:\"unbonding_height\""];
google.protobuf.Timestamp unbonding_time = 9
[(gogoproto.nullable) = false, (gogoproto.stdtime) = true, (gogoproto.moretags) = "yaml:\"unbonding_time\""];
Commission commission = 10 [(gogoproto.nullable) = false];
string min_self_delegation = 11 [
(gogoproto.moretags) = "yaml:\"min_self_delegation\"",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false
];
}
// BondStatus is the status of a validator.
enum BondStatus {
option (gogoproto.goproto_enum_prefix) = false;
// UNSPECIFIED defines an invalid validator status.
BOND_STATUS_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "Unspecified"];
// UNBONDED defines a validator that is not bonded.
BOND_STATUS_UNBONDED = 1 [(gogoproto.enumvalue_customname) = "Unbonded"];
// UNBONDING defines a validator that is unbonding.
BOND_STATUS_UNBONDING = 2 [(gogoproto.enumvalue_customname) = "Unbonding"];
// BONDED defines a validator that is bonded.
BOND_STATUS_BONDED = 3 [(gogoproto.enumvalue_customname) = "Bonded"];
}
// ValAddresses defines a repeated set of validator addresses.
message ValAddresses {
option (gogoproto.goproto_stringer) = false;
option (gogoproto.stringer) = true;
repeated string addresses = 1;
}
// DVPair is struct that just has a delegator-validator pair with no other data.
// It is intended to be used as a marshalable pointer. For example, a DVPair can
// be used to construct the key to getting an UnbondingDelegation from state.
message DVPair {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
option (gogoproto.goproto_stringer) = false;
string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""];
string validator_address = 2 [(gogoproto.moretags) = "yaml:\"validator_address\""];
}
// DVPairs defines an array of DVPair objects.
message DVPairs {
repeated DVPair pairs = 1 [(gogoproto.nullable) = false];
}
// DVVTriplet is struct that just has a delegator-validator-validator triplet
// with no other data. It is intended to be used as a marshalable pointer. For
// example, a DVVTriplet can be used to construct the key to getting a
// Redelegation from state.
message DVVTriplet {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
option (gogoproto.goproto_stringer) = false;
string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""];
string validator_src_address = 2 [(gogoproto.moretags) = "yaml:\"validator_src_address\""];
string validator_dst_address = 3 [(gogoproto.moretags) = "yaml:\"validator_dst_address\""];
}
// DVVTriplets defines an array of DVVTriplet objects.
message DVVTriplets {
repeated DVVTriplet triplets = 1 [(gogoproto.nullable) = false];
}
// Delegation represents the bond with tokens held by an account. It is
// owned by one delegator, and is associated with the voting power of one
// validator.
message Delegation {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
option (gogoproto.goproto_stringer) = false;
string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""];
string validator_address = 2 [(gogoproto.moretags) = "yaml:\"validator_address\""];
string shares = 3 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false];
}
// UnbondingDelegation stores all of a single delegator's unbonding bonds
// for a single validator in an time-ordered list.
message UnbondingDelegation {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
option (gogoproto.goproto_stringer) = false;
string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""];
string validator_address = 2 [(gogoproto.moretags) = "yaml:\"validator_address\""];
repeated UnbondingDelegationEntry entries = 3 [(gogoproto.nullable) = false]; // unbonding delegation entries
}
// UnbondingDelegationEntry defines an unbonding object with relevant metadata.
message UnbondingDelegationEntry {
option (gogoproto.equal) = true;
option (gogoproto.goproto_stringer) = false;
int64 creation_height = 1 [(gogoproto.moretags) = "yaml:\"creation_height\""];
google.protobuf.Timestamp completion_time = 2
[(gogoproto.nullable) = false, (gogoproto.stdtime) = true, (gogoproto.moretags) = "yaml:\"completion_time\""];
string initial_balance = 3 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false,
(gogoproto.moretags) = "yaml:\"initial_balance\""
];
string balance = 4 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", (gogoproto.nullable) = false];
}
// RedelegationEntry defines a redelegation object with relevant metadata.
message RedelegationEntry {
option (gogoproto.equal) = true;
option (gogoproto.goproto_stringer) = false;
int64 creation_height = 1 [(gogoproto.moretags) = "yaml:\"creation_height\""];
google.protobuf.Timestamp completion_time = 2
[(gogoproto.nullable) = false, (gogoproto.stdtime) = true, (gogoproto.moretags) = "yaml:\"completion_time\""];
string initial_balance = 3 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false,
(gogoproto.moretags) = "yaml:\"initial_balance\""
];
string shares_dst = 4
[(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false];
}
// Redelegation contains the list of a particular delegator's redelegating bonds
// from a particular source validator to a particular destination validator.
message Redelegation {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
option (gogoproto.goproto_stringer) = false;
string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""];
string validator_src_address = 2 [(gogoproto.moretags) = "yaml:\"validator_src_address\""];
string validator_dst_address = 3 [(gogoproto.moretags) = "yaml:\"validator_dst_address\""];
repeated RedelegationEntry entries = 4 [(gogoproto.nullable) = false]; // redelegation entries
}
// Params defines the parameters for the staking module.
message Params {
option (gogoproto.equal) = true;
option (gogoproto.goproto_stringer) = false;
google.protobuf.Duration unbonding_time = 1
[(gogoproto.nullable) = false, (gogoproto.stdduration) = true, (gogoproto.moretags) = "yaml:\"unbonding_time\""];
uint32 max_validators = 2 [(gogoproto.moretags) = "yaml:\"max_validators\""];
uint32 max_entries = 3 [(gogoproto.moretags) = "yaml:\"max_entries\""];
uint32 historical_entries = 4 [(gogoproto.moretags) = "yaml:\"historical_entries\""];
string bond_denom = 5 [(gogoproto.moretags) = "yaml:\"bond_denom\""];
}
// DelegationResponse is equivalent to Delegation except that it contains a
// balance in addition to shares which is more suitable for client responses.
message DelegationResponse {
option (gogoproto.equal) = false;
option (gogoproto.goproto_stringer) = false;
Delegation delegation = 1 [(gogoproto.nullable) = false];
cosmos.base.v1beta1.Coin balance = 2 [(gogoproto.nullable) = false];
}
// RedelegationEntryResponse is equivalent to a RedelegationEntry except that it
// contains a balance in addition to shares which is more suitable for client
// responses.
message RedelegationEntryResponse {
option (gogoproto.equal) = true;
RedelegationEntry redelegation_entry = 1 [(gogoproto.nullable) = false];
string balance = 4 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", (gogoproto.nullable) = false];
}
// RedelegationResponse is equivalent to a Redelegation except that its entries
// contain a balance in addition to shares which is more suitable for client
// responses.
message RedelegationResponse {
option (gogoproto.equal) = false;
Redelegation redelegation = 1 [(gogoproto.nullable) = false];
repeated RedelegationEntryResponse entries = 2 [(gogoproto.nullable) = false];
}
// Pool is used for tracking bonded and not-bonded token supply of the bond
// denomination.
message Pool {
option (gogoproto.description) = true;
option (gogoproto.equal) = true;
string not_bonded_tokens = 1 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.jsontag) = "not_bonded_tokens",
(gogoproto.nullable) = false
];
string bonded_tokens = 2 [
(gogoproto.jsontag) = "bonded_tokens",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false,
(gogoproto.moretags) = "yaml:\"bonded_tokens\""
];
}

View File

@ -0,0 +1,126 @@
syntax = "proto3";
package cosmos.staking.v1beta1;
import "google/protobuf/any.proto";
import "google/protobuf/timestamp.proto";
import "gogoproto/gogo.proto";
import "cosmos_proto/cosmos.proto";
import "cosmos/base/v1beta1/coin.proto";
import "cosmos/staking/v1beta1/staking.proto";
option go_package = "github.com/cosmos/cosmos-sdk/x/staking/types";
// Msg defines the staking Msg service.
service Msg {
// CreateValidator defines a method for creating a new validator.
rpc CreateValidator(MsgCreateValidator) returns (MsgCreateValidatorResponse);
// EditValidator defines a method for editing an existing validator.
rpc EditValidator(MsgEditValidator) returns (MsgEditValidatorResponse);
// Delegate defines a method for performing a delegation of coins
// from a delegator to a validator.
rpc Delegate(MsgDelegate) returns (MsgDelegateResponse);
// BeginRedelegate defines a method for performing a redelegation
// of coins from a delegator and source validator to a destination validator.
rpc BeginRedelegate(MsgBeginRedelegate) returns (MsgBeginRedelegateResponse);
// Undelegate defines a method for performing an undelegation from a
// delegate and a validator.
rpc Undelegate(MsgUndelegate) returns (MsgUndelegateResponse);
}
// MsgCreateValidator defines a SDK message for creating a new validator.
message MsgCreateValidator {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
Description description = 1 [(gogoproto.nullable) = false];
CommissionRates commission = 2 [(gogoproto.nullable) = false];
string min_self_delegation = 3 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.moretags) = "yaml:\"min_self_delegation\"",
(gogoproto.nullable) = false
];
string delegator_address = 4 [(gogoproto.moretags) = "yaml:\"delegator_address\""];
string validator_address = 5 [(gogoproto.moretags) = "yaml:\"validator_address\""];
google.protobuf.Any pubkey = 6 [(cosmos_proto.accepts_interface) = "cosmos.crypto.PubKey"];
cosmos.base.v1beta1.Coin value = 7 [(gogoproto.nullable) = false];
}
// MsgCreateValidatorResponse defines the Msg/CreateValidator response type.
message MsgCreateValidatorResponse {}
// MsgEditValidator defines a SDK message for editing an existing validator.
message MsgEditValidator {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
Description description = 1 [(gogoproto.nullable) = false];
string validator_address = 2 [(gogoproto.moretags) = "yaml:\"address\""];
// We pass a reference to the new commission rate and min self delegation as
// it's not mandatory to update. If not updated, the deserialized rate will be
// zero with no way to distinguish if an update was intended.
// REF: #2373
string commission_rate = 3 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.moretags) = "yaml:\"commission_rate\""
];
string min_self_delegation = 4 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.moretags) = "yaml:\"min_self_delegation\""
];
}
// MsgEditValidatorResponse defines the Msg/EditValidator response type.
message MsgEditValidatorResponse {}
// MsgDelegate defines a SDK message for performing a delegation of coins
// from a delegator to a validator.
message MsgDelegate {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""];
string validator_address = 2 [(gogoproto.moretags) = "yaml:\"validator_address\""];
cosmos.base.v1beta1.Coin amount = 3 [(gogoproto.nullable) = false];
}
// MsgDelegateResponse defines the Msg/Delegate response type.
message MsgDelegateResponse {}
// MsgBeginRedelegate defines a SDK message for performing a redelegation
// of coins from a delegator and source validator to a destination validator.
message MsgBeginRedelegate {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""];
string validator_src_address = 2 [(gogoproto.moretags) = "yaml:\"validator_src_address\""];
string validator_dst_address = 3 [(gogoproto.moretags) = "yaml:\"validator_dst_address\""];
cosmos.base.v1beta1.Coin amount = 4 [(gogoproto.nullable) = false];
}
// MsgBeginRedelegateResponse defines the Msg/BeginRedelegate response type.
message MsgBeginRedelegateResponse {
google.protobuf.Timestamp completion_time = 1 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
}
// MsgUndelegate defines a SDK message for performing an undelegation from a
// delegate and a validator.
message MsgUndelegate {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""];
string validator_address = 2 [(gogoproto.moretags) = "yaml:\"validator_address\""];
cosmos.base.v1beta1.Coin amount = 3 [(gogoproto.nullable) = false];
}
// MsgUndelegateResponse defines the Msg/Undelegate response type.
message MsgUndelegateResponse {
google.protobuf.Timestamp completion_time = 1 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
}

View File

@ -43,14 +43,13 @@ message SignatureDescriptor {
Data data = 2; Data data = 2;
// sequence is the sequence of the account, which describes the // sequence is the sequence of the account, which describes the
// number of committed transactions signed by a given address. It is used to // number of committed transactions signed by a given address. It is used to prevent
// prevent replay attacks. // replay attacks.
uint64 sequence = 3; uint64 sequence = 3;
// Data represents signature data // Data represents signature data
message Data { message Data {
// sum is the oneof that specifies whether this represents single or // sum is the oneof that specifies whether this represents single or multi-signature data
// multi-signature data
oneof sum { oneof sum {
// single represents a single signer // single represents a single signer
Single single = 1; Single single = 1;

View File

@ -0,0 +1,117 @@
syntax = "proto3";
package cosmos.tx.v1beta1;
import "google/api/annotations.proto";
import "cosmos/base/abci/v1beta1/abci.proto";
import "cosmos/tx/v1beta1/tx.proto";
import "gogoproto/gogo.proto";
import "cosmos/base/query/v1beta1/pagination.proto";
option go_package = "github.com/cosmos/cosmos-sdk/types/tx";
// Service defines a gRPC service for interacting with transactions.
service Service {
// Simulate simulates executing a transaction for estimating gas usage.
rpc Simulate(SimulateRequest) returns (SimulateResponse) {
option (google.api.http) = {
post: "/cosmos/tx/v1beta1/simulate"
body: "*"
};
}
// GetTx fetches a tx by hash.
rpc GetTx(GetTxRequest) returns (GetTxResponse) {
option (google.api.http).get = "/cosmos/tx/v1beta1/txs/{hash}";
}
// BroadcastTx broadcast transaction.
rpc BroadcastTx(BroadcastTxRequest) returns (BroadcastTxResponse) {
option (google.api.http) = {
post: "/cosmos/tx/v1beta1/txs"
body: "*"
};
}
// GetTxsEvent fetches txs by event.
rpc GetTxsEvent(GetTxsEventRequest) returns (GetTxsEventResponse) {
option (google.api.http).get = "/cosmos/tx/v1beta1/txs";
}
}
// GetTxsEventRequest is the request type for the Service.TxsByEvents
// RPC method.
message GetTxsEventRequest {
// events is the list of transaction event type.
repeated string events = 1;
// pagination defines an pagination for the request.
cosmos.base.query.v1beta1.PageRequest pagination = 2;
}
// GetTxsEventResponse is the response type for the Service.TxsByEvents
// RPC method.
message GetTxsEventResponse {
// txs is the list of queried transactions.
repeated cosmos.tx.v1beta1.Tx txs = 1;
// tx_responses is the list of queried TxResponses.
repeated cosmos.base.abci.v1beta1.TxResponse tx_responses = 2;
// pagination defines an pagination for the response.
cosmos.base.query.v1beta1.PageResponse pagination = 3;
}
// BroadcastTxRequest is the request type for the Service.BroadcastTxRequest
// RPC method.
message BroadcastTxRequest {
// tx_bytes is the raw transaction.
bytes tx_bytes = 1;
BroadcastMode mode = 2;
}
// BroadcastMode specifies the broadcast mode for the TxService.Broadcast RPC method.
enum BroadcastMode {
// zero-value for mode ordering
BROADCAST_MODE_UNSPECIFIED = 0;
// BROADCAST_MODE_BLOCK defines a tx broadcasting mode where the client waits for
// the tx to be committed in a block.
BROADCAST_MODE_BLOCK = 1;
// BROADCAST_MODE_SYNC defines a tx broadcasting mode where the client waits for
// a CheckTx execution response only.
BROADCAST_MODE_SYNC = 2;
// BROADCAST_MODE_ASYNC defines a tx broadcasting mode where the client returns
// immediately.
BROADCAST_MODE_ASYNC = 3;
}
// BroadcastTxResponse is the response type for the
// Service.BroadcastTx method.
message BroadcastTxResponse {
// tx_response is the queried TxResponses.
cosmos.base.abci.v1beta1.TxResponse tx_response = 1;
}
// SimulateRequest is the request type for the Service.Simulate
// RPC method.
message SimulateRequest {
// tx is the transaction to simulate.
cosmos.tx.v1beta1.Tx tx = 1;
}
// SimulateResponse is the response type for the
// Service.SimulateRPC method.
message SimulateResponse {
// gas_info is the information about gas used in the simulation.
cosmos.base.abci.v1beta1.GasInfo gas_info = 1;
// result is the result of the simulation.
cosmos.base.abci.v1beta1.Result result = 2;
}
// GetTxRequest is the request type for the Service.GetTx
// RPC method.
message GetTxRequest {
// hash is the tx hash to query, encoded as a hex string.
string hash = 1;
}
// GetTxResponse is the response type for the Service.GetTx method.
message GetTxResponse {
// tx is the queried transaction.
cosmos.tx.v1beta1.Tx tx = 1;
// tx_response is the queried TxResponses.
cosmos.base.abci.v1beta1.TxResponse tx_response = 2;
}

View File

@ -69,7 +69,6 @@ message TxBody {
// those messages define the number and order of elements in AuthInfo's // those messages define the number and order of elements in AuthInfo's
// signer_infos and Tx's signatures. Each required signer address is added to // signer_infos and Tx's signatures. Each required signer address is added to
// the list only the first time it occurs. // the list only the first time it occurs.
//
// By convention, the first required signer (usually from the first message) // By convention, the first required signer (usually from the first message)
// is referred to as the primary signer and pays the fee for the whole // is referred to as the primary signer and pays the fee for the whole
// transaction. // transaction.
@ -163,24 +162,20 @@ message ModeInfo {
// which must be above some miminum to be accepted into the mempool. // which must be above some miminum to be accepted into the mempool.
message Fee { message Fee {
// amount is the amount of coins to be paid as a fee // amount is the amount of coins to be paid as a fee
repeated cosmos.base.v1beta1.Coin amount = 1 [ repeated cosmos.base.v1beta1.Coin amount = 1
(gogoproto.nullable) = false, [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"];
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"
];
// gas_limit is the maximum gas that can be used in transaction processing // gas_limit is the maximum gas that can be used in transaction processing
// before an out of gas error occurs // before an out of gas error occurs
uint64 gas_limit = 2; uint64 gas_limit = 2;
// if unset, the first signer is responsible for paying the fees. If set, the // if unset, the first signer is responsible for paying the fees. If set, the specified account must pay the fees.
// specified account must pay the fees. the payer must be a tx signer (and // the payer must be a tx signer (and thus have signed this field in AuthInfo).
// thus have signed this field in AuthInfo). setting this field does *not* // setting this field does *not* change the ordering of required signers for the transaction.
// change the ordering of required signers for the transaction.
string payer = 3; string payer = 3;
// if set, the fee payer (either the first signer or the value of the payer // if set, the fee payer (either the first signer or the value of the payer field) requests that a fee grant be used
// field) requests that a fee grant be used to pay fees instead of the fee // to pay fees instead of the fee payer's own balance. If an appropriate fee grant does not exist or the chain does
// payer's own balance. If an appropriate fee grant does not exist or the // not support fee grants, this will fail
// chain does not support fee grants, this will fail
string granter = 4; string granter = 4;
} }

View File

@ -0,0 +1,68 @@
syntax = "proto3";
package cosmos.upgrade.v1beta1;
import "google/protobuf/any.proto";
import "google/api/annotations.proto";
import "cosmos/upgrade/v1beta1/upgrade.proto";
option go_package = "github.com/cosmos/cosmos-sdk/x/upgrade/types";
// Query defines the gRPC upgrade querier service.
service Query {
// CurrentPlan queries the current upgrade plan.
rpc CurrentPlan(QueryCurrentPlanRequest) returns (QueryCurrentPlanResponse) {
option (google.api.http).get = "/cosmos/upgrade/v1beta1/current_plan";
}
// AppliedPlan queries a previously applied upgrade plan by its name.
rpc AppliedPlan(QueryAppliedPlanRequest) returns (QueryAppliedPlanResponse) {
option (google.api.http).get = "/cosmos/upgrade/v1beta1/applied_plan/{name}";
}
// UpgradedConsensusState queries the consensus state that will serve
// as a trusted kernel for the next version of this chain. It will only be
// stored at the last height of this chain.
// UpgradedConsensusState RPC not supported with legacy querier
rpc UpgradedConsensusState(QueryUpgradedConsensusStateRequest) returns (QueryUpgradedConsensusStateResponse) {
option (google.api.http).get = "/cosmos/upgrade/v1beta1/upgraded_consensus_state/{last_height}";
}
}
// QueryCurrentPlanRequest is the request type for the Query/CurrentPlan RPC
// method.
message QueryCurrentPlanRequest {}
// QueryCurrentPlanResponse is the response type for the Query/CurrentPlan RPC
// method.
message QueryCurrentPlanResponse {
// plan is the current upgrade plan.
Plan plan = 1;
}
// QueryCurrentPlanRequest is the request type for the Query/AppliedPlan RPC
// method.
message QueryAppliedPlanRequest {
// name is the name of the applied plan to query for.
string name = 1;
}
// QueryAppliedPlanResponse is the response type for the Query/AppliedPlan RPC
// method.
message QueryAppliedPlanResponse {
// height is the block height at which the plan was applied.
int64 height = 1;
}
// QueryUpgradedConsensusStateRequest is the request type for the Query/UpgradedConsensusState
// RPC method.
message QueryUpgradedConsensusStateRequest {
// last height of the current chain must be sent in request
// as this is the height under which next consensus state is stored
int64 last_height = 1;
}
// QueryUpgradedConsensusStateResponse is the response type for the Query/UpgradedConsensusState
// RPC method.
message QueryUpgradedConsensusStateResponse {
google.protobuf.Any upgraded_consensus_state = 1;
}

View File

@ -0,0 +1,62 @@
syntax = "proto3";
package cosmos.upgrade.v1beta1;
import "google/protobuf/any.proto";
import "gogoproto/gogo.proto";
import "google/protobuf/timestamp.proto";
option go_package = "github.com/cosmos/cosmos-sdk/x/upgrade/types";
option (gogoproto.goproto_stringer_all) = false;
option (gogoproto.goproto_getters_all) = false;
// Plan specifies information about a planned upgrade and when it should occur.
message Plan {
option (gogoproto.equal) = true;
// Sets the name for the upgrade. This name will be used by the upgraded
// version of the software to apply any special "on-upgrade" commands during
// the first BeginBlock method after the upgrade is applied. It is also used
// to detect whether a software version can handle a given upgrade. If no
// upgrade handler with this name has been set in the software, it will be
// assumed that the software is out-of-date when the upgrade Time or Height is
// reached and the software will exit.
string name = 1;
// The time after which the upgrade must be performed.
// Leave set to its zero value to use a pre-defined Height instead.
google.protobuf.Timestamp time = 2 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false];
// The height at which the upgrade must be performed.
// Only used if Time is not set.
int64 height = 3;
// Any application specific upgrade info to be included on-chain
// such as a git commit that validators could automatically upgrade to
string info = 4;
// IBC-enabled chains can opt-in to including the upgraded client state in its upgrade plan
// This will make the chain commit to the correct upgraded (self) client state before the upgrade occurs,
// so that connecting chains can verify that the new upgraded client is valid by verifying a proof on the
// previous version of the chain.
// This will allow IBC connections to persist smoothly across planned chain upgrades
google.protobuf.Any upgraded_client_state = 5 [(gogoproto.moretags) = "yaml:\"upgraded_client_state\""];
}
// SoftwareUpgradeProposal is a gov Content type for initiating a software
// upgrade.
message SoftwareUpgradeProposal {
option (gogoproto.equal) = true;
string title = 1;
string description = 2;
Plan plan = 3 [(gogoproto.nullable) = false];
}
// CancelSoftwareUpgradeProposal is a gov Content type for cancelling a software
// upgrade.
message CancelSoftwareUpgradeProposal {
option (gogoproto.equal) = true;
string title = 1;
string description = 2;
}

View File

@ -0,0 +1,31 @@
syntax = "proto3";
package cosmos.vesting.v1beta1;
import "gogoproto/gogo.proto";
import "cosmos/base/v1beta1/coin.proto";
option go_package = "github.com/cosmos/cosmos-sdk/x/auth/vesting/types";
// Msg defines the bank Msg service.
service Msg {
// CreateVestingAccount defines a method that enables creating a vesting
// account.
rpc CreateVestingAccount(MsgCreateVestingAccount) returns (MsgCreateVestingAccountResponse);
}
// MsgCreateVestingAccount defines a message that enables creating a vesting
// account.
message MsgCreateVestingAccount {
option (gogoproto.equal) = true;
string from_address = 1 [(gogoproto.moretags) = "yaml:\"from_address\""];
string to_address = 2 [(gogoproto.moretags) = "yaml:\"to_address\""];
repeated cosmos.base.v1beta1.Coin amount = 3
[(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"];
int64 end_time = 4 [(gogoproto.moretags) = "yaml:\"end_time\""];
bool delayed = 5;
}
// MsgCreateVestingAccountResponse defines the Msg/CreateVestingAccount response type.
message MsgCreateVestingAccountResponse {}

View File

@ -0,0 +1,73 @@
syntax = "proto3";
package cosmos.vesting.v1beta1;
import "gogoproto/gogo.proto";
import "cosmos/base/v1beta1/coin.proto";
import "cosmos/auth/v1beta1/auth.proto";
option go_package = "github.com/cosmos/cosmos-sdk/x/auth/vesting/types";
// BaseVestingAccount implements the VestingAccount interface. It contains all
// the necessary fields needed for any vesting account implementation.
message BaseVestingAccount {
option (gogoproto.goproto_getters) = false;
option (gogoproto.goproto_stringer) = false;
cosmos.auth.v1beta1.BaseAccount base_account = 1 [(gogoproto.embed) = true];
repeated cosmos.base.v1beta1.Coin original_vesting = 2 [
(gogoproto.nullable) = false,
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins",
(gogoproto.moretags) = "yaml:\"original_vesting\""
];
repeated cosmos.base.v1beta1.Coin delegated_free = 3 [
(gogoproto.nullable) = false,
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins",
(gogoproto.moretags) = "yaml:\"delegated_free\""
];
repeated cosmos.base.v1beta1.Coin delegated_vesting = 4 [
(gogoproto.nullable) = false,
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins",
(gogoproto.moretags) = "yaml:\"delegated_vesting\""
];
int64 end_time = 5 [(gogoproto.moretags) = "yaml:\"end_time\""];
}
// ContinuousVestingAccount implements the VestingAccount interface. It
// continuously vests by unlocking coins linearly with respect to time.
message ContinuousVestingAccount {
option (gogoproto.goproto_getters) = false;
option (gogoproto.goproto_stringer) = false;
BaseVestingAccount base_vesting_account = 1 [(gogoproto.embed) = true];
int64 start_time = 2 [(gogoproto.moretags) = "yaml:\"start_time\""];
}
// DelayedVestingAccount implements the VestingAccount interface. It vests all
// coins after a specific time, but non prior. In other words, it keeps them
// locked until a specified time.
message DelayedVestingAccount {
option (gogoproto.goproto_getters) = false;
option (gogoproto.goproto_stringer) = false;
BaseVestingAccount base_vesting_account = 1 [(gogoproto.embed) = true];
}
// Period defines a length of time and amount of coins that will vest.
message Period {
option (gogoproto.goproto_stringer) = false;
int64 length = 1;
repeated cosmos.base.v1beta1.Coin amount = 2
[(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"];
}
// PeriodicVestingAccount implements the VestingAccount interface. It
// periodically vests by unlocking coins during each specified period.
message PeriodicVestingAccount {
option (gogoproto.goproto_getters) = false;
option (gogoproto.goproto_stringer) = false;
BaseVestingAccount base_vesting_account = 1 [(gogoproto.embed) = true];
int64 start_time = 2 [(gogoproto.moretags) = "yaml:\"start_time\""];
repeated Period vesting_periods = 3 [(gogoproto.moretags) = "yaml:\"vesting_periods\"", (gogoproto.nullable) = false];
}

View File

@ -11,6 +11,4 @@ extend google.protobuf.MessageOptions {
string implements_interface = 93002; string implements_interface = 93002;
} }
extend google.protobuf.FieldOptions { extend google.protobuf.FieldOptions { string accepts_interface = 93001; }
string accepts_interface = 93001;
}

View File

@ -56,7 +56,8 @@ message Http {
// //
// service Messaging { // service Messaging {
// rpc GetMessage(GetMessageRequest) returns (Message) { // rpc GetMessage(GetMessageRequest) returns (Message) {
// option (google.api.http).get = "/v1/messages/{message_id}/{sub.subfield}"; // option (google.api.http).get =
// "/v1/messages/{message_id}/{sub.subfield}";
// } // }
// } // }
// message GetMessageRequest { // message GetMessageRequest {
@ -83,7 +84,8 @@ message Http {
// //
// HTTP | RPC // HTTP | RPC
// -----|----- // -----|-----
// `GET /v1/messages/123456/foo` | `GetMessage(message_id: "123456" sub: SubMessage(subfield: "foo"))` // `GET /v1/messages/123456/foo` | `GetMessage(message_id: "123456" sub:
// SubMessage(subfield: "foo"))`
// //
// In general, not only fields but also field paths can be referenced // In general, not only fields but also field paths can be referenced
// from a path pattern. Fields mapped to the path pattern cannot be // from a path pattern. Fields mapped to the path pattern cannot be
@ -113,7 +115,9 @@ message Http {
// //
// HTTP | RPC // HTTP | RPC
// -----|----- // -----|-----
// `GET /v1/messages/123456?revision=2&sub.subfield=foo` | `GetMessage(message_id: "123456" revision: 2 sub: SubMessage(subfield: "foo"))` // `GET /v1/messages/123456?revision=2&sub.subfield=foo` |
// `GetMessage(message_id: "123456" revision: 2 sub: SubMessage(subfield:
// "foo"))`
// //
// Note that fields which are mapped to HTTP parameters must have a // Note that fields which are mapped to HTTP parameters must have a
// primitive type or a repeated primitive type. Message types are not // primitive type or a repeated primitive type. Message types are not
@ -145,7 +149,8 @@ message Http {
// //
// HTTP | RPC // HTTP | RPC
// -----|----- // -----|-----
// `PUT /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id: "123456" message { text: "Hi!" })` // `PUT /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id:
// "123456" message { text: "Hi!" })`
// //
// The special name `*` can be used in the body mapping to define that // The special name `*` can be used in the body mapping to define that
// every field not bound by the path template should be mapped to the // every field not bound by the path template should be mapped to the
@ -170,7 +175,8 @@ message Http {
// //
// HTTP | RPC // HTTP | RPC
// -----|----- // -----|-----
// `PUT /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id: "123456" text: "Hi!")` // `PUT /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id:
// "123456" text: "Hi!")`
// //
// Note that when using `*` in the body mapping, it is not possible to // Note that when using `*` in the body mapping, it is not possible to
// have HTTP parameters, as all fields not bound by the path end in // have HTTP parameters, as all fields not bound by the path end in
@ -203,7 +209,8 @@ message Http {
// HTTP | RPC // HTTP | RPC
// -----|----- // -----|-----
// `GET /v1/messages/123456` | `GetMessage(message_id: "123456")` // `GET /v1/messages/123456` | `GetMessage(message_id: "123456")`
// `GET /v1/users/me/messages/123456` | `GetMessage(user_id: "me" message_id: "123456")` // `GET /v1/users/me/messages/123456` | `GetMessage(user_id: "me" message_id:
// "123456")`
// //
// # Rules for HTTP mapping // # Rules for HTTP mapping
// //
@ -261,7 +268,8 @@ message Http {
message HttpRule { message HttpRule {
// Selects methods to which this rule applies. // Selects methods to which this rule applies.
// //
// Refer to [selector][google.api.DocumentationRule.selector] for syntax details. // Refer to [selector][google.api.DocumentationRule.selector] for syntax
// details.
string selector = 1; string selector = 1;
// Determines the URL pattern is matched by this rules. This pattern can be // Determines the URL pattern is matched by this rules. This pattern can be

View File

@ -89,7 +89,7 @@ option objc_class_prefix = "GPB";
// The pack methods provided by protobuf library will by default use // The pack methods provided by protobuf library will by default use
// 'type.googleapis.com/full.type.name' as the type URL and the unpack // 'type.googleapis.com/full.type.name' as the type URL and the unpack
// methods only use the fully qualified type name after the last '/' // methods only use the fully qualified type name after the last '/'
// in the type URL, for example "foo.bar.com/x/y.z" will yield type // in the type URL, for example "foo.bar.com/modules/y.z" will yield type
// name "y.z". // name "y.z".
// //
// //

View File

@ -0,0 +1,894 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
//
// The messages in this file describe the definitions found in .proto files.
// A valid .proto file can be translated directly to a FileDescriptorProto
// without any other information (e.g. without reading its imports).
syntax = "proto2";
package google.protobuf;
option go_package = "google.golang.org/protobuf/types/descriptorpb";
option java_package = "com.google.protobuf";
option java_outer_classname = "DescriptorProtos";
option csharp_namespace = "Google.Protobuf.Reflection";
option objc_class_prefix = "GPB";
option cc_enable_arenas = true;
// descriptor.proto must be optimized for speed because reflection-based
// algorithms don't work during bootstrapping.
option optimize_for = SPEED;
// The protocol compiler can output a FileDescriptorSet containing the .proto
// files it parses.
message FileDescriptorSet { repeated FileDescriptorProto file = 1; }
// Describes a complete .proto file.
message FileDescriptorProto {
optional string name = 1; // file name, relative to root of source tree
optional string package = 2; // e.g. "foo", "foo.bar", etc.
// Names of files imported by this file.
repeated string dependency = 3;
// Indexes of the public imported files in the dependency list above.
repeated int32 public_dependency = 10;
// Indexes of the weak imported files in the dependency list.
// For Google-internal migration only. Do not use.
repeated int32 weak_dependency = 11;
// All top-level definitions in this file.
repeated DescriptorProto message_type = 4;
repeated EnumDescriptorProto enum_type = 5;
repeated ServiceDescriptorProto service = 6;
repeated FieldDescriptorProto extension = 7;
optional FileOptions options = 8;
// This field contains optional information about the original source code.
// You may safely remove this entire field without harming runtime
// functionality of the descriptors -- the information is needed only by
// development tools.
optional SourceCodeInfo source_code_info = 9;
// The syntax of the proto file.
// The supported values are "proto2" and "proto3".
optional string syntax = 12;
}
// Describes a message type.
message DescriptorProto {
optional string name = 1;
repeated FieldDescriptorProto field = 2;
repeated FieldDescriptorProto extension = 6;
repeated DescriptorProto nested_type = 3;
repeated EnumDescriptorProto enum_type = 4;
message ExtensionRange {
optional int32 start = 1; // Inclusive.
optional int32 end = 2; // Exclusive.
optional ExtensionRangeOptions options = 3;
}
repeated ExtensionRange extension_range = 5;
repeated OneofDescriptorProto oneof_decl = 8;
optional MessageOptions options = 7;
// Range of reserved tag numbers. Reserved tag numbers may not be used by
// fields or extension ranges in the same message. Reserved ranges may
// not overlap.
message ReservedRange {
optional int32 start = 1; // Inclusive.
optional int32 end = 2; // Exclusive.
}
repeated ReservedRange reserved_range = 9;
// Reserved field names, which may not be used by fields in the same message.
// A given name may only be reserved once.
repeated string reserved_name = 10;
}
message ExtensionRangeOptions {
// The parser stores options it doesn't recognize here. See above.
repeated UninterpretedOption uninterpreted_option = 999;
// Clients can define custom options in extensions of this message. See above.
extensions 1000 to max;
}
// Describes a field within a message.
message FieldDescriptorProto {
enum Type {
// 0 is reserved for errors.
// Order is weird for historical reasons.
TYPE_DOUBLE = 1;
TYPE_FLOAT = 2;
// Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT64 if
// negative values are likely.
TYPE_INT64 = 3;
TYPE_UINT64 = 4;
// Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT32 if
// negative values are likely.
TYPE_INT32 = 5;
TYPE_FIXED64 = 6;
TYPE_FIXED32 = 7;
TYPE_BOOL = 8;
TYPE_STRING = 9;
// Tag-delimited aggregate.
// Group type is deprecated and not supported in proto3. However, Proto3
// implementations should still be able to parse the group wire format and
// treat group fields as unknown fields.
TYPE_GROUP = 10;
TYPE_MESSAGE = 11; // Length-delimited aggregate.
// New in version 2.
TYPE_BYTES = 12;
TYPE_UINT32 = 13;
TYPE_ENUM = 14;
TYPE_SFIXED32 = 15;
TYPE_SFIXED64 = 16;
TYPE_SINT32 = 17; // Uses ZigZag encoding.
TYPE_SINT64 = 18; // Uses ZigZag encoding.
}
enum Label {
// 0 is reserved for errors
LABEL_OPTIONAL = 1;
LABEL_REQUIRED = 2;
LABEL_REPEATED = 3;
}
optional string name = 1;
optional int32 number = 3;
optional Label label = 4;
// If type_name is set, this need not be set. If both this and type_name
// are set, this must be one of TYPE_ENUM, TYPE_MESSAGE or TYPE_GROUP.
optional Type type = 5;
// For message and enum types, this is the name of the type. If the name
// starts with a '.', it is fully-qualified. Otherwise, C++-like scoping
// rules are used to find the type (i.e. first the nested types within this
// message are searched, then within the parent, on up to the root
// namespace).
optional string type_name = 6;
// For extensions, this is the name of the type being extended. It is
// resolved in the same manner as type_name.
optional string extendee = 2;
// For numeric types, contains the original text representation of the value.
// For booleans, "true" or "false".
// For strings, contains the default text contents (not escaped in any way).
// For bytes, contains the C escaped value. All bytes >= 128 are escaped.
// TODO(kenton): Base-64 encode?
optional string default_value = 7;
// If set, gives the index of a oneof in the containing type's oneof_decl
// list. This field is a member of that oneof.
optional int32 oneof_index = 9;
// JSON name of this field. The value is set by protocol compiler. If the
// user has set a "json_name" option on this field, that option's value
// will be used. Otherwise, it's deduced from the field's name by converting
// it to camelCase.
optional string json_name = 10;
optional FieldOptions options = 8;
// If true, this is a proto3 "optional". When a proto3 field is optional, it
// tracks presence regardless of field type.
//
// When proto3_optional is true, this field must be belong to a oneof to
// signal to old proto3 clients that presence is tracked for this field. This
// oneof is known as a "synthetic" oneof, and this field must be its sole
// member (each proto3 optional field gets its own synthetic oneof). Synthetic
// oneofs exist in the descriptor only, and do not generate any API. Synthetic
// oneofs must be ordered after all "real" oneofs.
//
// For message fields, proto3_optional doesn't create any semantic change,
// since non-repeated message fields always track presence. However it still
// indicates the semantic detail of whether the user wrote "optional" or not.
// This can be useful for round-tripping the .proto file. For consistency we
// give message fields a synthetic oneof also, even though it is not required
// to track presence. This is especially important because the parser can't
// tell if a field is a message or an enum, so it must always create a
// synthetic oneof.
//
// Proto2 optional fields do not set this flag, because they already indicate
// optional with `LABEL_OPTIONAL`.
optional bool proto3_optional = 17;
}
// Describes a oneof.
message OneofDescriptorProto {
optional string name = 1;
optional OneofOptions options = 2;
}
// Describes an enum type.
message EnumDescriptorProto {
optional string name = 1;
repeated EnumValueDescriptorProto value = 2;
optional EnumOptions options = 3;
// Range of reserved numeric values. Reserved values may not be used by
// entries in the same enum. Reserved ranges may not overlap.
//
// Note that this is distinct from DescriptorProto.ReservedRange in that it
// is inclusive such that it can appropriately represent the entire int32
// domain.
message EnumReservedRange {
optional int32 start = 1; // Inclusive.
optional int32 end = 2; // Inclusive.
}
// Range of reserved numeric values. Reserved numeric values may not be used
// by enum values in the same enum declaration. Reserved ranges may not
// overlap.
repeated EnumReservedRange reserved_range = 4;
// Reserved enum value names, which may not be reused. A given name may only
// be reserved once.
repeated string reserved_name = 5;
}
// Describes a value within an enum.
message EnumValueDescriptorProto {
optional string name = 1;
optional int32 number = 2;
optional EnumValueOptions options = 3;
}
// Describes a service.
message ServiceDescriptorProto {
optional string name = 1;
repeated MethodDescriptorProto method = 2;
optional ServiceOptions options = 3;
}
// Describes a method of a service.
message MethodDescriptorProto {
optional string name = 1;
// Input and output type names. These are resolved in the same way as
// FieldDescriptorProto.type_name, but must refer to a message type.
optional string input_type = 2;
optional string output_type = 3;
optional MethodOptions options = 4;
// Identifies if client streams multiple client messages
optional bool client_streaming = 5 [ default = false ];
// Identifies if server streams multiple server messages
optional bool server_streaming = 6 [ default = false ];
}
// ===================================================================
// Options
// Each of the definitions above may have "options" attached. These are
// just annotations which may cause code to be generated slightly differently
// or may contain hints for code that manipulates protocol messages.
//
// Clients may define custom options as extensions of the *Options messages.
// These extensions may not yet be known at parsing time, so the parser cannot
// store the values in them. Instead it stores them in a field in the *Options
// message called uninterpreted_option. This field must have the same name
// across all *Options messages. We then use this field to populate the
// extensions when we build a descriptor, at which point all protos have been
// parsed and so all extensions are known.
//
// Extension numbers for custom options may be chosen as follows:
// * For options which will only be used within a single application or
// organization, or for experimental options, use field numbers 50000
// through 99999. It is up to you to ensure that you do not use the
// same number for multiple options.
// * For options which will be published and used publicly by multiple
// independent entities, e-mail protobuf-global-extension-registry@google.com
// to reserve extension numbers. Simply provide your project name (e.g.
// Objective-C plugin) and your project website (if available) -- there's no
// need to explain how you intend to use them. Usually you only need one
// extension number. You can declare multiple options with only one extension
// number by putting them in a sub-message. See the Custom Options section of
// the docs for examples:
// https://developers.google.com/protocol-buffers/docs/proto#options
// If this turns out to be popular, a web service will be set up
// to automatically assign option numbers.
message FileOptions {
// Sets the Java package where classes generated from this .proto will be
// placed. By default, the proto package is used, but this is often
// inappropriate because proto packages do not normally start with backwards
// domain names.
optional string java_package = 1;
// If set, all the classes from the .proto file are wrapped in a single
// outer class with the given name. This applies to both Proto1
// (equivalent to the old "--one_java_file" option) and Proto2 (where
// a .proto always translates to a single class, but you may want to
// explicitly choose the class name).
optional string java_outer_classname = 8;
// If set true, then the Java code generator will generate a separate .java
// file for each top-level message, enum, and service defined in the .proto
// file. Thus, these types will *not* be nested inside the outer class
// named by java_outer_classname. However, the outer class will still be
// generated to contain the file's getDescriptor() method as well as any
// top-level extensions defined in the file.
optional bool java_multiple_files = 10 [ default = false ];
// This option does nothing.
optional bool java_generate_equals_and_hash = 20 [ deprecated = true ];
// If set true, then the Java2 code generator will generate code that
// throws an exception whenever an attempt is made to assign a non-UTF-8
// byte sequence to a string field.
// Message reflection will do the same.
// However, an extension field still accepts non-UTF-8 byte sequences.
// This option has no effect on when used with the lite runtime.
optional bool java_string_check_utf8 = 27 [ default = false ];
// Generated classes can be optimized for speed or code size.
enum OptimizeMode {
SPEED = 1; // Generate complete code for parsing, serialization,
// etc.
CODE_SIZE = 2; // Use ReflectionOps to implement these methods.
LITE_RUNTIME = 3; // Generate code using MessageLite and the lite runtime.
}
optional OptimizeMode optimize_for = 9 [ default = SPEED ];
// Sets the Go package where structs generated from this .proto will be
// placed. If omitted, the Go package will be derived from the following:
// - The basename of the package import path, if provided.
// - Otherwise, the package statement in the .proto file, if present.
// - Otherwise, the basename of the .proto file, without extension.
optional string go_package = 11;
// Should generic services be generated in each language? "Generic" services
// are not specific to any particular RPC system. They are generated by the
// main code generators in each language (without additional plugins).
// Generic services were the only kind of service generation supported by
// early versions of google.protobuf.
//
// Generic services are now considered deprecated in favor of using plugins
// that generate code specific to your particular RPC system. Therefore,
// these default to false. Old code which depends on generic services should
// explicitly set them to true.
optional bool cc_generic_services = 16 [ default = false ];
optional bool java_generic_services = 17 [ default = false ];
optional bool py_generic_services = 18 [ default = false ];
optional bool php_generic_services = 42 [ default = false ];
// Is this file deprecated?
// Depending on the target platform, this can emit Deprecated annotations
// for everything in the file, or it will be completely ignored; in the very
// least, this is a formalization for deprecating files.
optional bool deprecated = 23 [ default = false ];
// Enables the use of arenas for the proto messages in this file. This applies
// only to generated classes for C++.
optional bool cc_enable_arenas = 31 [ default = true ];
// Sets the objective c class prefix which is prepended to all objective c
// generated classes from this .proto. There is no default.
optional string objc_class_prefix = 36;
// Namespace for generated classes; defaults to the package.
optional string csharp_namespace = 37;
// By default Swift generators will take the proto package and CamelCase it
// replacing '.' with underscore and use that to prefix the types/symbols
// defined. When this options is provided, they will use this value instead
// to prefix the types/symbols defined.
optional string swift_prefix = 39;
// Sets the php class prefix which is prepended to all php generated classes
// from this .proto. Default is empty.
optional string php_class_prefix = 40;
// Use this option to change the namespace of php generated classes. Default
// is empty. When this option is empty, the package name will be used for
// determining the namespace.
optional string php_namespace = 41;
// Use this option to change the namespace of php generated metadata classes.
// Default is empty. When this option is empty, the proto file name will be
// used for determining the namespace.
optional string php_metadata_namespace = 44;
// Use this option to change the package of ruby generated classes. Default
// is empty. When this option is not set, the package name will be used for
// determining the ruby package.
optional string ruby_package = 45;
// The parser stores options it doesn't recognize here.
// See the documentation for the "Options" section above.
repeated UninterpretedOption uninterpreted_option = 999;
// Clients can define custom options in extensions of this message.
// See the documentation for the "Options" section above.
extensions 1000 to max;
reserved 38;
}
message MessageOptions {
// Set true to use the old proto1 MessageSet wire format for extensions.
// This is provided for backwards-compatibility with the MessageSet wire
// format. You should not use this for any other reason: It's less
// efficient, has fewer features, and is more complicated.
//
// The message must be defined exactly as follows:
// message Foo {
// option message_set_wire_format = true;
// extensions 4 to max;
// }
// Note that the message cannot have any defined fields; MessageSets only
// have extensions.
//
// All extensions of your type must be singular messages; e.g. they cannot
// be int32s, enums, or repeated messages.
//
// Because this is an option, the above two restrictions are not enforced by
// the protocol compiler.
optional bool message_set_wire_format = 1 [ default = false ];
// Disables the generation of the standard "descriptor()" accessor, which can
// conflict with a field of the same name. This is meant to make migration
// from proto1 easier; new code should avoid fields named "descriptor".
optional bool no_standard_descriptor_accessor = 2 [ default = false ];
// Is this message deprecated?
// Depending on the target platform, this can emit Deprecated annotations
// for the message, or it will be completely ignored; in the very least,
// this is a formalization for deprecating messages.
optional bool deprecated = 3 [ default = false ];
// Whether the message is an automatically generated map entry type for the
// maps field.
//
// For maps fields:
// map<KeyType, ValueType> map_field = 1;
// The parsed descriptor looks like:
// message MapFieldEntry {
// option map_entry = true;
// optional KeyType key = 1;
// optional ValueType value = 2;
// }
// repeated MapFieldEntry map_field = 1;
//
// Implementations may choose not to generate the map_entry=true message, but
// use a native map in the target language to hold the keys and values.
// The reflection APIs in such implementations still need to work as
// if the field is a repeated message field.
//
// NOTE: Do not set the option in .proto files. Always use the maps syntax
// instead. The option should only be implicitly set by the proto compiler
// parser.
optional bool map_entry = 7;
reserved 8; // javalite_serializable
reserved 9; // javanano_as_lite
// The parser stores options it doesn't recognize here. See above.
repeated UninterpretedOption uninterpreted_option = 999;
// Clients can define custom options in extensions of this message. See above.
extensions 1000 to max;
}
message FieldOptions {
// The ctype option instructs the C++ code generator to use a different
// representation of the field than it normally would. See the specific
// options below. This option is not yet implemented in the open source
// release -- sorry, we'll try to include it in a future version!
optional CType ctype = 1 [ default = STRING ];
enum CType {
// Default mode.
STRING = 0;
CORD = 1;
STRING_PIECE = 2;
}
// The packed option can be enabled for repeated primitive fields to enable
// a more efficient representation on the wire. Rather than repeatedly
// writing the tag and type for each element, the entire array is encoded as
// a single length-delimited blob. In proto3, only explicit setting it to
// false will avoid using packed encoding.
optional bool packed = 2;
// The jstype option determines the JavaScript type used for values of the
// field. The option is permitted only for 64 bit integral and fixed types
// (int64, uint64, sint64, fixed64, sfixed64). A field with jstype JS_STRING
// is represented as JavaScript string, which avoids loss of precision that
// can happen when a large value is converted to a floating point JavaScript.
// Specifying JS_NUMBER for the jstype causes the generated JavaScript code to
// use the JavaScript "number" type. The behavior of the default option
// JS_NORMAL is implementation dependent.
//
// This option is an enum to permit additional types to be added, e.g.
// goog.math.Integer.
optional JSType jstype = 6 [ default = JS_NORMAL ];
enum JSType {
// Use the default type.
JS_NORMAL = 0;
// Use JavaScript strings.
JS_STRING = 1;
// Use JavaScript numbers.
JS_NUMBER = 2;
}
// Should this field be parsed lazily? Lazy applies only to message-type
// fields. It means that when the outer message is initially parsed, the
// inner message's contents will not be parsed but instead stored in encoded
// form. The inner message will actually be parsed when it is first accessed.
//
// This is only a hint. Implementations are free to choose whether to use
// eager or lazy parsing regardless of the value of this option. However,
// setting this option true suggests that the protocol author believes that
// using lazy parsing on this field is worth the additional bookkeeping
// overhead typically needed to implement it.
//
// This option does not affect the public interface of any generated code;
// all method signatures remain the same. Furthermore, thread-safety of the
// interface is not affected by this option; const methods remain safe to
// call from multiple threads concurrently, while non-const methods continue
// to require exclusive access.
//
//
// Note that implementations may choose not to check required fields within
// a lazy sub-message. That is, calling IsInitialized() on the outer message
// may return true even if the inner message has missing required fields.
// This is necessary because otherwise the inner message would have to be
// parsed in order to perform the check, defeating the purpose of lazy
// parsing. An implementation which chooses not to check required fields
// must be consistent about it. That is, for any particular sub-message, the
// implementation must either *always* check its required fields, or *never*
// check its required fields, regardless of whether or not the message has
// been parsed.
optional bool lazy = 5 [ default = false ];
// Is this field deprecated?
// Depending on the target platform, this can emit Deprecated annotations
// for accessors, or it will be completely ignored; in the very least, this
// is a formalization for deprecating fields.
optional bool deprecated = 3 [ default = false ];
// For Google-internal migration only. Do not use.
optional bool weak = 10 [ default = false ];
// The parser stores options it doesn't recognize here. See above.
repeated UninterpretedOption uninterpreted_option = 999;
// Clients can define custom options in extensions of this message. See above.
extensions 1000 to max;
reserved 4; // removed jtype
}
message OneofOptions {
// The parser stores options it doesn't recognize here. See above.
repeated UninterpretedOption uninterpreted_option = 999;
// Clients can define custom options in extensions of this message. See above.
extensions 1000 to max;
}
message EnumOptions {
// Set this option to true to allow mapping different tag names to the same
// value.
optional bool allow_alias = 2;
// Is this enum deprecated?
// Depending on the target platform, this can emit Deprecated annotations
// for the enum, or it will be completely ignored; in the very least, this
// is a formalization for deprecating enums.
optional bool deprecated = 3 [ default = false ];
reserved 5; // javanano_as_lite
// The parser stores options it doesn't recognize here. See above.
repeated UninterpretedOption uninterpreted_option = 999;
// Clients can define custom options in extensions of this message. See above.
extensions 1000 to max;
}
message EnumValueOptions {
// Is this enum value deprecated?
// Depending on the target platform, this can emit Deprecated annotations
// for the enum value, or it will be completely ignored; in the very least,
// this is a formalization for deprecating enum values.
optional bool deprecated = 1 [ default = false ];
// The parser stores options it doesn't recognize here. See above.
repeated UninterpretedOption uninterpreted_option = 999;
// Clients can define custom options in extensions of this message. See above.
extensions 1000 to max;
}
message ServiceOptions {
// Note: Field numbers 1 through 32 are reserved for Google's internal RPC
// framework. We apologize for hoarding these numbers to ourselves, but
// we were already using them long before we decided to release Protocol
// Buffers.
// Is this service deprecated?
// Depending on the target platform, this can emit Deprecated annotations
// for the service, or it will be completely ignored; in the very least,
// this is a formalization for deprecating services.
optional bool deprecated = 33 [ default = false ];
// The parser stores options it doesn't recognize here. See above.
repeated UninterpretedOption uninterpreted_option = 999;
// Clients can define custom options in extensions of this message. See above.
extensions 1000 to max;
}
message MethodOptions {
// Note: Field numbers 1 through 32 are reserved for Google's internal RPC
// framework. We apologize for hoarding these numbers to ourselves, but
// we were already using them long before we decided to release Protocol
// Buffers.
// Is this method deprecated?
// Depending on the target platform, this can emit Deprecated annotations
// for the method, or it will be completely ignored; in the very least,
// this is a formalization for deprecating methods.
optional bool deprecated = 33 [ default = false ];
// Is this method side-effect-free (or safe in HTTP parlance), or idempotent,
// or neither? HTTP based RPC implementation may choose GET verb for safe
// methods, and PUT verb for idempotent methods instead of the default POST.
enum IdempotencyLevel {
IDEMPOTENCY_UNKNOWN = 0;
NO_SIDE_EFFECTS = 1; // implies idempotent
IDEMPOTENT = 2; // idempotent, but may have side effects
}
optional IdempotencyLevel idempotency_level = 34
[ default = IDEMPOTENCY_UNKNOWN ];
// The parser stores options it doesn't recognize here. See above.
repeated UninterpretedOption uninterpreted_option = 999;
// Clients can define custom options in extensions of this message. See above.
extensions 1000 to max;
}
// A message representing a option the parser does not recognize. This only
// appears in options protos created by the compiler::Parser class.
// DescriptorPool resolves these when building Descriptor objects. Therefore,
// options protos in descriptor objects (e.g. returned by Descriptor::options(),
// or produced by Descriptor::CopyTo()) will never have UninterpretedOptions
// in them.
message UninterpretedOption {
// The name of the uninterpreted option. Each string represents a segment in
// a dot-separated name. is_extension is true iff a segment represents an
// extension (denoted with parentheses in options specs in .proto files).
// E.g.,{ ["foo", false], ["bar.baz", true], ["qux", false] } represents
// "foo.(bar.baz).qux".
message NamePart {
required string name_part = 1;
required bool is_extension = 2;
}
repeated NamePart name = 2;
// The value of the uninterpreted option, in whatever type the tokenizer
// identified it as during parsing. Exactly one of these should be set.
optional string identifier_value = 3;
optional uint64 positive_int_value = 4;
optional int64 negative_int_value = 5;
optional double double_value = 6;
optional bytes string_value = 7;
optional string aggregate_value = 8;
}
// ===================================================================
// Optional source code info
// Encapsulates information about the original source file from which a
// FileDescriptorProto was generated.
message SourceCodeInfo {
// A Location identifies a piece of source code in a .proto file which
// corresponds to a particular definition. This information is intended
// to be useful to IDEs, code indexers, documentation generators, and similar
// tools.
//
// For example, say we have a file like:
// message Foo {
// optional string foo = 1;
// }
// Let's look at just the field definition:
// optional string foo = 1;
// ^ ^^ ^^ ^ ^^^
// a bc de f ghi
// We have the following locations:
// span path represents
// [a,i) [ 4, 0, 2, 0 ] The whole field definition.
// [a,b) [ 4, 0, 2, 0, 4 ] The label (optional).
// [c,d) [ 4, 0, 2, 0, 5 ] The type (string).
// [e,f) [ 4, 0, 2, 0, 1 ] The name (foo).
// [g,h) [ 4, 0, 2, 0, 3 ] The number (1).
//
// Notes:
// - A location may refer to a repeated field itself (i.e. not to any
// particular index within it). This is used whenever a set of elements are
// logically enclosed in a single code segment. For example, an entire
// extend block (possibly containing multiple extension definitions) will
// have an outer location whose path refers to the "extensions" repeated
// field without an index.
// - Multiple locations may have the same path. This happens when a single
// logical declaration is spread out across multiple places. The most
// obvious example is the "extend" block again -- there may be multiple
// extend blocks in the same scope, each of which will have the same path.
// - A location's span is not always a subset of its parent's span. For
// example, the "extendee" of an extension declaration appears at the
// beginning of the "extend" block and is shared by all extensions within
// the block.
// - Just because a location's span is a subset of some other location's span
// does not mean that it is a descendant. For example, a "group" defines
// both a type and a field in a single declaration. Thus, the locations
// corresponding to the type and field and their components will overlap.
// - Code which tries to interpret locations should probably be designed to
// ignore those that it doesn't understand, as more types of locations could
// be recorded in the future.
repeated Location location = 1;
message Location {
// Identifies which part of the FileDescriptorProto was defined at this
// location.
//
// Each element is a field number or an index. They form a path from
// the root FileDescriptorProto to the place where the definition. For
// example, this path:
// [ 4, 3, 2, 7, 1 ]
// refers to:
// file.message_type(3) // 4, 3
// .field(7) // 2, 7
// .name() // 1
// This is because FileDescriptorProto.message_type has field number 4:
// repeated DescriptorProto message_type = 4;
// and DescriptorProto.field has field number 2:
// repeated FieldDescriptorProto field = 2;
// and FieldDescriptorProto.name has field number 1:
// optional string name = 1;
//
// Thus, the above path gives the location of a field name. If we removed
// the last element:
// [ 4, 3, 2, 7 ]
// this path refers to the whole field declaration (from the beginning
// of the label to the terminating semicolon).
repeated int32 path = 1 [ packed = true ];
// Always has exactly three or four elements: start line, start column,
// end line (optional, otherwise assumed same as start line), end column.
// These are packed into a single field for efficiency. Note that line
// and column numbers are zero-based -- typically you will want to add
// 1 to each before displaying to a user.
repeated int32 span = 2 [ packed = true ];
// If this SourceCodeInfo represents a complete declaration, these are any
// comments appearing before and after the declaration which appear to be
// attached to the declaration.
//
// A series of line comments appearing on consecutive lines, with no other
// tokens appearing on those lines, will be treated as a single comment.
//
// leading_detached_comments will keep paragraphs of comments that appear
// before (but not connected to) the current element. Each paragraph,
// separated by empty lines, will be one comment element in the repeated
// field.
//
// Only the comment content is provided; comment markers (e.g. //) are
// stripped out. For block comments, leading whitespace and an asterisk
// will be stripped from the beginning of each line other than the first.
// Newlines are included in the output.
//
// Examples:
//
// optional int32 foo = 1; // Comment attached to foo.
// // Comment attached to bar.
// optional int32 bar = 2;
//
// optional string baz = 3;
// // Comment attached to baz.
// // Another line attached to baz.
//
// // Comment attached to qux.
// //
// // Another line attached to qux.
// optional double qux = 4;
//
// // Detached comment for corge. This is not leading or trailing comments
// // to qux or corge because there are blank lines separating it from
// // both.
//
// // Detached comment for corge paragraph 2.
//
// optional string corge = 5;
// /* Block comment attached
// * to corge. Leading asterisks
// * will be removed. */
// /* Block comment attached to
// * grault. */
// optional int32 grault = 6;
//
// // ignored detached comments.
optional string leading_comments = 3;
optional string trailing_comments = 4;
repeated string leading_detached_comments = 6;
}
}
// Describes the relationship between generated code and its original source
// file. A GeneratedCodeInfo message is associated with only one generated
// source file, but may contain references to different source .proto files.
message GeneratedCodeInfo {
// An Annotation connects some span of text in generated code to an element
// of its generating .proto file.
repeated Annotation annotation = 1;
message Annotation {
// Identifies the element in the original source .proto file. This field
// is formatted the same as SourceCodeInfo.Location.path.
repeated int32 path = 1 [ packed = true ];
// Identifies the filesystem path to the original source .proto.
optional string source_file = 2;
// Identifies the starting offset in bytes in the generated code
// that relates to the identified object.
optional int32 begin = 3;
// Identifies the ending offset in bytes in the generated code that
// relates to the identified offset. The end offset should be one past
// the last relevant byte (so the length of the text = end - begin).
optional int32 end = 4;
}
}

View File

@ -0,0 +1,34 @@
syntax = "proto3";
package tendermint.p2p;
option go_package = "github.com/tendermint/tendermint/proto/tendermint/p2p";
import "gogoproto/gogo.proto";
message NetAddress {
string id = 1 [(gogoproto.customname) = "ID"];
string ip = 2 [(gogoproto.customname) = "IP"];
uint32 port = 3;
}
message ProtocolVersion {
uint64 p2p = 1 [(gogoproto.customname) = "P2P"];
uint64 block = 2;
uint64 app = 3;
}
message DefaultNodeInfo {
ProtocolVersion protocol_version = 1 [(gogoproto.nullable) = false];
string default_node_id = 2 [(gogoproto.customname) = "DefaultNodeID"];
string listen_addr = 3;
string network = 4;
string version = 5;
bytes channels = 6;
string moniker = 7;
DefaultNodeInfoOther other = 8 [(gogoproto.nullable) = false];
}
message DefaultNodeInfoOther {
string tx_index = 1;
string rpc_address = 2 [(gogoproto.customname) = "RPCAddress"];
}

View File

@ -0,0 +1,15 @@
syntax = "proto3";
package tendermint.types;
option go_package = "github.com/tendermint/tendermint/proto/tendermint/types";
import "gogoproto/gogo.proto";
import "tendermint/types/types.proto";
import "tendermint/types/evidence.proto";
message Block {
Header header = 1 [(gogoproto.nullable) = false];
Data data = 2 [(gogoproto.nullable) = false];
tendermint.types.EvidenceList evidence = 3 [(gogoproto.nullable) = false];
Commit last_commit = 4;
}

View File

@ -4,19 +4,9 @@ package tendermint.types;
option go_package = "github.com/tendermint/tendermint/proto/tendermint/types"; option go_package = "github.com/tendermint/tendermint/proto/tendermint/types";
import "gogoproto/gogo.proto"; import "gogoproto/gogo.proto";
import "google/protobuf/timestamp.proto";
import "tendermint/types/types.proto"; import "tendermint/types/types.proto";
import "tendermint/types/validator.proto";
// DuplicateVoteEvidence contains evidence a validator signed two conflicting
// votes.
message DuplicateVoteEvidence {
Vote vote_a = 1;
Vote vote_b = 2;
}
message LightClientAttackEvidence {
LightBlock conflicting_block = 1;
int64 common_height = 2;
}
message Evidence { message Evidence {
oneof sum { oneof sum {
@ -25,8 +15,24 @@ message Evidence {
} }
} }
// EvidenceData contains any evidence of malicious wrong-doing by validators // DuplicateVoteEvidence contains evidence of a validator signed two conflicting votes.
message EvidenceData { message DuplicateVoteEvidence {
repeated Evidence evidence = 1 [ (gogoproto.nullable) = false ]; tendermint.types.Vote vote_a = 1;
bytes hash = 2; tendermint.types.Vote vote_b = 2;
int64 total_voting_power = 3;
int64 validator_power = 4;
google.protobuf.Timestamp timestamp = 5 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
}
// LightClientAttackEvidence contains evidence of a set of validators attempting to mislead a light client.
message LightClientAttackEvidence {
tendermint.types.LightBlock conflicting_block = 1;
int64 common_height = 2;
repeated tendermint.types.Validator byzantine_validators = 3;
int64 total_voting_power = 4;
google.protobuf.Timestamp timestamp = 5 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
}
message EvidenceList {
repeated Evidence evidence = 1 [(gogoproto.nullable) = false];
} }

View File

@ -48,11 +48,10 @@ message EvidenceParams {
google.protobuf.Duration max_age_duration = 2 google.protobuf.Duration max_age_duration = 2
[(gogoproto.nullable) = false, (gogoproto.stdduration) = true]; [(gogoproto.nullable) = false, (gogoproto.stdduration) = true];
// This sets the maximum number of evidence that can be committed in a single // This sets the maximum size of total evidence in bytes that can be committed in a single block.
// block. and should fall comfortably under the max block bytes when we // and should fall comfortably under the max block bytes.
// consider the size of each evidence (See MaxEvidenceBytes). The maximum // Default is 1048576 or 1MB
// number is MaxEvidencePerBlock. Default is 50 int64 max_bytes = 3;
uint32 max_num = 3;
} }
// ValidatorParams restrict the public key types validators can use. // ValidatorParams restrict the public key types validators can use.

View File

@ -13,9 +13,9 @@ message App {
string software = 2; string software = 2;
} }
// Consensus captures the consensus rules for processing a block in the // Consensus captures the consensus rules for processing a block in the blockchain,
// blockchain, including all blockchain data structures and the rules of the // including all blockchain data structures and the rules of the application's
// application's state transition machine. // state transition machine.
message Consensus { message Consensus {
option (gogoproto.equal) = true; option (gogoproto.equal) = true;

View File

@ -1,12 +1,19 @@
package cli package cli
import ( import (
"math/big"
"strings"
rpctypes "github.com/cosmos/ethermint/ethereum/rpc/types"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/client/flags"
rpctypes "github.com/cosmos/ethermint/rpc/types" "github.com/InjectiveLabs/sdk-go/ethereum/rpc"
"github.com/InjectiveLabs/sdk-go/wrappers"
"github.com/cosmos/ethermint/x/evm/types" "github.com/cosmos/ethermint/x/evm/types"
) )
@ -23,6 +30,8 @@ func GetQueryCmd() *cobra.Command {
cmd.AddCommand( cmd.AddCommand(
GetStorageCmd(), GetStorageCmd(),
GetCodeCmd(), GetCodeCmd(),
GetErc20Balance(),
GetAccount(),
) )
return cmd return cmd
} }
@ -103,3 +112,88 @@ func GetCodeCmd() *cobra.Command {
flags.AddQueryFlagsToCmd(cmd) flags.AddQueryFlagsToCmd(cmd)
return cmd return cmd
} }
// GetErc20Balance queries the erc20 balance of an address
func GetErc20Balance() *cobra.Command {
cmd := &cobra.Command{
Use: "erc20balance [contract] [address]",
Short: "Gets erc20 balance of an account",
Long: "Gets erc20 balance of an account.",
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx := client.GetClientContextFromCmd(cmd)
clientCtx, err := client.GetClientQueryContext(cmd)
if err != nil {
return err
}
queryClient := types.NewQueryClient(clientCtx)
contract := args[0]
address := args[1]
erc20ABI, err := abi.JSON(strings.NewReader(wrappers.ERC20ABI))
if err != nil {
return err
}
input, err := erc20ABI.Pack("balanceOf", common.HexToAddress(address))
if err != nil {
return err
}
req := &types.QueryStaticCallRequest{
Address: contract,
Input: input,
}
res, err := queryClient.StaticCall(rpc.ContextWithHeight(clientCtx.Height), req)
if err != nil {
return err
}
ret := big.NewInt(0)
err = erc20ABI.UnpackIntoInterface(&ret, "balanceOf", res.Data)
if err != nil {
return err
}
return clientCtx.PrintString(ret.String())
},
}
flags.AddQueryFlagsToCmd(cmd)
return cmd
}
// GetAccount queries the account by address
func GetAccount() *cobra.Command {
cmd := &cobra.Command{
Use: "account [address]",
Short: "Get an account by address",
Long: "Get an account by address",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx := client.GetClientContextFromCmd(cmd)
clientCtx, err := client.GetClientQueryContext(cmd)
if err != nil {
return err
}
queryClient := types.NewQueryClient(clientCtx)
address := args[0]
req := &types.QueryAccountRequest{
Address: address,
}
res, err := queryClient.Account(rpc.ContextWithHeight(clientCtx.Height), req)
if err != nil {
return err
}
return clientCtx.PrintProto(res)
},
}
flags.AddQueryFlagsToCmd(cmd)
return cmd
}

View File

@ -45,3 +45,19 @@ func formatKeyToHash(key string) string {
return ethkey.Hex() return ethkey.Hex()
} }
func cosmosAddressFromArg(addr string) (sdk.AccAddress, error) {
if strings.HasPrefix(addr, sdk.GetConfig().GetBech32AccountAddrPrefix()) {
// Check to see if address is Cosmos bech32 formatted
toAddr, err := sdk.AccAddressFromBech32(addr)
if err != nil {
return nil, errors.Wrap(err, "invalid bech32 formatted address")
}
return toAddr, nil
}
// Strip 0x prefix if exists
addr = strings.TrimPrefix(addr, "0x")
return sdk.AccAddressFromHex(addr)
}

View File

@ -61,3 +61,24 @@ func TestCosmosToEthereumTypes(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, hexString, ethDecoded) require.Equal(t, hexString, ethDecoded)
} }
func TestAddressToCosmosAddress(t *testing.T) {
baseAddr, err := sdk.AccAddressFromHex("6A98D72760f7bbA69d62Ed6F48278451251948E7")
require.NoError(t, err)
// Test cosmos string back to address
cosmosFormatted, err := cosmosAddressFromArg(baseAddr.String())
require.NoError(t, err)
require.Equal(t, baseAddr, cosmosFormatted)
// Test account address from Ethereum address
ethAddr := common.BytesToAddress(baseAddr.Bytes())
ethFormatted, err := cosmosAddressFromArg(ethAddr.Hex())
require.NoError(t, err)
require.Equal(t, baseAddr, ethFormatted)
// Test encoding without the 0x prefix
ethFormatted, err = cosmosAddressFromArg(ethAddr.Hex()[2:])
require.NoError(t, err)
require.Equal(t, baseAddr, ethFormatted)
}

View File

@ -14,7 +14,7 @@ import (
"github.com/cosmos/cosmos-sdk/types/rest" "github.com/cosmos/cosmos-sdk/types/rest"
authrest "github.com/cosmos/cosmos-sdk/x/auth/client/rest" authrest "github.com/cosmos/cosmos-sdk/x/auth/client/rest"
rpctypes "github.com/cosmos/ethermint/rpc/types" rpctypes "github.com/cosmos/ethermint/ethereum/rpc/types"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
) )
@ -81,7 +81,7 @@ func getEthTransactionByHash(clientCtx client.Context, hashHex string) ([]byte,
return nil, err return nil, err
} }
blockHash := common.BytesToHash(block.Block.Hash()) blockHash := common.BytesToHash(block.Block.Header.Hash())
ethTx, err := rpctypes.RawTxToEthTx(clientCtx, tx.Tx) ethTx, err := rpctypes.RawTxToEthTx(clientCtx, tx.Tx)
if err != nil { if err != nil {

View File

@ -5,14 +5,12 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
ethcmn "github.com/ethereum/go-ethereum/common" ethcmn "github.com/ethereum/go-ethereum/common"
abci "github.com/tendermint/tendermint/abci/types"
ethermint "github.com/cosmos/ethermint/types" ethermint "github.com/cosmos/ethermint/types"
"github.com/cosmos/ethermint/x/evm/keeper" "github.com/cosmos/ethermint/x/evm/keeper"
"github.com/cosmos/ethermint/x/evm/types" "github.com/cosmos/ethermint/x/evm/types"
abci "github.com/tendermint/tendermint/abci/types"
) )
// InitGenesis initializes genesis state based on exported genesis // InitGenesis initializes genesis state based on exported genesis

File diff suppressed because one or more lines are too long

View File

@ -2,53 +2,23 @@ package evm
import ( import (
"fmt" "fmt"
"time" "runtime/debug"
log "github.com/xlab/suplog"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
ethcmn "github.com/ethereum/go-ethereum/common"
"github.com/cosmos/ethermint/x/evm/keeper" "github.com/cosmos/ethermint/x/evm/keeper"
"github.com/cosmos/ethermint/x/evm/types" "github.com/cosmos/ethermint/x/evm/types"
ethcmn "github.com/ethereum/go-ethereum/common"
"github.com/cosmos/cosmos-sdk/telemetry"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
) )
// NewHandler returns a handler for Ethermint type messages. // NewHandler returns a handler for Ethermint type messages.
func NewHandler(k keeper.Keeper) sdk.Handler { func NewHandler(k *keeper.Keeper) sdk.Handler {
defer telemetry.MeasureSince(time.Now(), "evm", "state_transition") return func(ctx sdk.Context, msg sdk.Msg) (result *sdk.Result, err error) {
defer Recover(&err)
return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) {
snapshotStateDB := k.CommitStateDB.Copy()
// The "recover" code here is used to solve the problem of dirty data
// in CommitStateDB due to insufficient gas.
// The following is a detailed description:
// If the gas is insufficient during the execution of the "handler",
// panic will be thrown from the function "ConsumeGas" and finally
// caught by the function "runTx" from Cosmos. The function "runTx"
// will think that the execution of Msg has failed and the modified
// data in the Store will not take effect.
// StacktracerunTx->runMsgs->handler->...->gaskv.Store.Set->ConsumeGas
// The problem is that when the modified data in the Store does not take
// effect, the data in the modified CommitStateDB is not rolled back,
// they take effect, and dirty data is generated.
// Therefore, the code here specifically deals with this situation.
// See https://github.com/cosmos/ethermint/issues/668 for more information.
defer func() {
if r := recover(); r != nil {
// We first used "k.CommitStateDB = snapshotStateDB" to roll back
// CommitStateDB, but this can only change the CommitStateDB in the
// current Keeper object, but the Keeper object will be destroyed
// soon, it is not a global variable, so the content pointed to by
// the CommitStateDB pointer can be modified to take effect.
types.CopyCommitStateDB(snapshotStateDB, k.CommitStateDB)
panic(r)
}
}()
ctx = ctx.WithEventManager(sdk.NewEventManager()) ctx = ctx.WithEventManager(sdk.NewEventManager())
switch msg := msg.(type) { switch msg := msg.(type) {
@ -56,11 +26,8 @@ func NewHandler(k keeper.Keeper) sdk.Handler {
// execute state transition // execute state transition
res, err := k.EthereumTx(sdk.WrapSDKContext(ctx), msg) res, err := k.EthereumTx(sdk.WrapSDKContext(ctx), msg)
if err != nil { if err != nil {
return nil, err return sdk.WrapServiceResult(ctx, res, err)
} } else if result, err = sdk.WrapServiceResult(ctx, res, nil); err != nil {
result, err := sdk.WrapServiceResult(ctx, res, err)
if err != nil {
return nil, err return nil, err
} }
@ -69,22 +36,48 @@ func NewHandler(k keeper.Keeper) sdk.Handler {
if res.ContractAddress != "" { if res.ContractAddress != "" {
recipientLog = fmt.Sprintf("contract address %s", res.ContractAddress) recipientLog = fmt.Sprintf("contract address %s", res.ContractAddress)
} else { } else {
recipientLog = fmt.Sprintf("recipient address %s", msg.Data.Recipient) var recipient string
if to := msg.To(); to != nil {
recipient = to.Hex()
}
recipientLog = fmt.Sprintf("recipient address %s", recipient)
} }
sender := ethcmn.BytesToAddress(msg.GetFrom().Bytes()) sender := ethcmn.BytesToAddress(msg.GetFrom().Bytes())
if res.Reverted {
result.Log = "transaction reverted"
log := fmt.Sprintf( log := fmt.Sprintf(
"executed EVM state transition; sender address %s; %s", sender, recipientLog, "reverted EVM state transition; sender address %s; %s", sender.Hex(), recipientLog,
) )
k.Logger(ctx).Info(log) k.Logger(ctx).Info(log)
} else {
log := fmt.Sprintf(
"executed EVM state transition; sender address %s; %s", sender.Hex(), recipientLog,
)
result.Log = log result.Log = log
k.Logger(ctx).Info(log)
}
return result, nil return result, nil
default: default:
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized %s message type: %T", types.ModuleName, msg) err := sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized %s message type: %T", types.ModuleName, msg)
return nil, err
}
}
}
func Recover(err *error) {
if r := recover(); r != nil {
*err = sdkerrors.Wrapf(sdkerrors.ErrPanic, "%v", r)
if e, ok := r.(error); ok {
log.WithError(e).Errorln("evm msg handler panicked with an error")
log.Debugln(string(debug.Stack()))
} else {
log.Errorln(r)
} }
} }
} }

View File

@ -33,7 +33,7 @@ type EvmTestSuite struct {
ctx sdk.Context ctx sdk.Context
handler sdk.Handler handler sdk.Handler
app *app.EthermintApp app *app.InjectiveApp
codec codec.BinaryMarshaler codec codec.BinaryMarshaler
privKey *ethsecp256k1.PrivKey privKey *ethsecp256k1.PrivKey
@ -45,8 +45,8 @@ func (suite *EvmTestSuite) SetupTest() {
checkTx := false checkTx := false
suite.app = app.Setup(checkTx) suite.app = app.Setup(checkTx)
suite.ctx = suite.app.BaseApp.NewContext(checkTx, tmproto.Header{Height: 1, ChainID: "ethermint-3", Time: time.Now().UTC()}) suite.ctx = suite.app.BaseApp.NewContext(checkTx, tmproto.Header{Height: 1, ChainID: "888", Time: time.Now().UTC()})
suite.handler = evm.NewHandler(*suite.app.EvmKeeper) suite.handler = evm.NewHandler(suite.app.EvmKeeper)
suite.codec = suite.app.AppCodec() suite.codec = suite.app.AppCodec()
privKey, err := ethsecp256k1.GenerateKey() privKey, err := ethsecp256k1.GenerateKey()
@ -78,7 +78,7 @@ func (suite *EvmTestSuite) TestHandleMsgEthereumTx() {
"passed", "passed",
func() { func() {
suite.app.EvmKeeper.SetBalance(suite.ctx, suite.from, big.NewInt(100)) suite.app.EvmKeeper.SetBalance(suite.ctx, suite.from, big.NewInt(100))
tx = types.NewMsgEthereumTx(0, &suite.from, big.NewInt(0), 0, big.NewInt(10000), nil) tx = types.NewMsgEthereumTx(0, &suite.from, big.NewInt(100), 0, big.NewInt(10000), nil)
// parse context chain ID to big.Int // parse context chain ID to big.Int
chainID, err := ethermint.ParseChainID(suite.ctx.ChainID()) chainID, err := ethermint.ParseChainID(suite.ctx.ChainID())
@ -176,7 +176,7 @@ func (suite *EvmTestSuite) TestHandlerLogs() {
bytecode := common.FromHex("0x6080604052348015600f57600080fd5b5060117f775a94827b8fd9b519d36cd827093c664f93347070a554f65e4a6f56cd73889860405160405180910390a2603580604b6000396000f3fe6080604052600080fdfea165627a7a723058206cab665f0f557620554bb45adf266708d2bd349b8a4314bdff205ee8440e3c240029") bytecode := common.FromHex("0x6080604052348015600f57600080fd5b5060117f775a94827b8fd9b519d36cd827093c664f93347070a554f65e4a6f56cd73889860405160405180910390a2603580604b6000396000f3fe6080604052600080fdfea165627a7a723058206cab665f0f557620554bb45adf266708d2bd349b8a4314bdff205ee8440e3c240029")
tx := types.NewMsgEthereumTx(1, nil, big.NewInt(0), gasLimit, gasPrice, bytecode) tx := types.NewMsgEthereumTx(1, nil, big.NewInt(0), gasLimit, gasPrice, bytecode)
err = tx.Sign(big.NewInt(3), priv.ToECDSA()) err = tx.Sign(big.NewInt(888), priv.ToECDSA())
suite.Require().NoError(err) suite.Require().NoError(err)
result, err := suite.handler(suite.ctx, tx) result, err := suite.handler(suite.ctx, tx)
@ -195,34 +195,7 @@ func (suite *EvmTestSuite) TestHandlerLogs() {
logs, err := suite.app.EvmKeeper.GetLogs(suite.ctx, ethcmn.BytesToHash(hash)) logs, err := suite.app.EvmKeeper.GetLogs(suite.ctx, ethcmn.BytesToHash(hash))
suite.Require().NoError(err, "failed to get logs") suite.Require().NoError(err, "failed to get logs")
suite.Require().Equal(len(logs), len(txResponse.TxLogs.Logs)) suite.Require().Equal(logs, txResponse.TxLogs.Logs)
for i, logI := range logs {
for j, logJ := range txResponse.TxLogs.Logs {
if i != j {
continue
}
suite.Require().Equal(uint64(logI.Index), logJ.Index)
suite.Require().Equal(logI.Data, logJ.Data)
suite.Require().Equal(logI.Address.String(), logJ.Address)
suite.Require().Equal(logI.BlockHash.String(), logJ.BlockHash)
suite.Require().Equal(logI.BlockNumber, logJ.BlockNumber)
suite.Require().Equal(logI.Removed, logJ.Removed)
suite.Require().Equal(logI.TxHash.String(), logJ.TxHash)
suite.Require().Equal(uint64(logI.TxIndex), logJ.TxIndex)
suite.Require().Equal(len(logI.Topics), len(logJ.Topics))
for i2, topicI := range logI.Topics {
for j2, topicJ := range logJ.Topics {
if i2 != j2 {
continue
}
suite.Require().Equal(topicI.String(), topicJ)
}
}
}
}
} }
func (suite *EvmTestSuite) TestQueryTxLogs() { func (suite *EvmTestSuite) TestQueryTxLogs() {
@ -235,7 +208,7 @@ func (suite *EvmTestSuite) TestQueryTxLogs() {
// send contract deployment transaction with an event in the constructor // send contract deployment transaction with an event in the constructor
bytecode := common.FromHex("0x6080604052348015600f57600080fd5b5060117f775a94827b8fd9b519d36cd827093c664f93347070a554f65e4a6f56cd73889860405160405180910390a2603580604b6000396000f3fe6080604052600080fdfea165627a7a723058206cab665f0f557620554bb45adf266708d2bd349b8a4314bdff205ee8440e3c240029") bytecode := common.FromHex("0x6080604052348015600f57600080fd5b5060117f775a94827b8fd9b519d36cd827093c664f93347070a554f65e4a6f56cd73889860405160405180910390a2603580604b6000396000f3fe6080604052600080fdfea165627a7a723058206cab665f0f557620554bb45adf266708d2bd349b8a4314bdff205ee8440e3c240029")
tx := types.NewMsgEthereumTx(1, nil, big.NewInt(0), gasLimit, gasPrice, bytecode) tx := types.NewMsgEthereumTx(1, nil, big.NewInt(0), gasLimit, gasPrice, bytecode)
err = tx.Sign(big.NewInt(3), priv.ToECDSA()) err = tx.Sign(big.NewInt(888), priv.ToECDSA())
suite.Require().NoError(err) suite.Require().NoError(err)
result, err := suite.handler(suite.ctx, tx) result, err := suite.handler(suite.ctx, tx)
@ -321,7 +294,7 @@ func (suite *EvmTestSuite) TestDeployAndCallContract() {
bytecode := common.FromHex("0x608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f342827c97908e5e2f71151c08502a66d44b6f758e3ac2f1de95f02eb95f0a73560405160405180910390a36102c4806100dc6000396000f3fe608060405234801561001057600080fd5b5060043610610053576000357c010000000000000000000000000000000000000000000000000000000090048063893d20e814610058578063a6f9dae1146100a2575b600080fd5b6100606100e6565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100e4600480360360208110156100b857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061010f565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146101d1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f43616c6c6572206973206e6f74206f776e65720000000000000000000000000081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f342827c97908e5e2f71151c08502a66d44b6f758e3ac2f1de95f02eb95f0a73560405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505056fea265627a7a72315820f397f2733a89198bc7fed0764083694c5b828791f39ebcbc9e414bccef14b48064736f6c63430005100032") bytecode := common.FromHex("0x608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f342827c97908e5e2f71151c08502a66d44b6f758e3ac2f1de95f02eb95f0a73560405160405180910390a36102c4806100dc6000396000f3fe608060405234801561001057600080fd5b5060043610610053576000357c010000000000000000000000000000000000000000000000000000000090048063893d20e814610058578063a6f9dae1146100a2575b600080fd5b6100606100e6565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100e4600480360360208110156100b857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061010f565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146101d1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f43616c6c6572206973206e6f74206f776e65720000000000000000000000000081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f342827c97908e5e2f71151c08502a66d44b6f758e3ac2f1de95f02eb95f0a73560405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505056fea265627a7a72315820f397f2733a89198bc7fed0764083694c5b828791f39ebcbc9e414bccef14b48064736f6c63430005100032")
tx := types.NewMsgEthereumTx(1, nil, big.NewInt(0), gasLimit, gasPrice, bytecode) tx := types.NewMsgEthereumTx(1, nil, big.NewInt(0), gasLimit, gasPrice, bytecode)
tx.Sign(big.NewInt(3), priv.ToECDSA()) tx.Sign(big.NewInt(888), priv.ToECDSA())
suite.Require().NoError(err) suite.Require().NoError(err)
result, err := suite.handler(suite.ctx, tx) result, err := suite.handler(suite.ctx, tx)
@ -338,7 +311,7 @@ func (suite *EvmTestSuite) TestDeployAndCallContract() {
storeAddr := "0xa6f9dae10000000000000000000000006a82e4a67715c8412a9114fbd2cbaefbc8181424" storeAddr := "0xa6f9dae10000000000000000000000006a82e4a67715c8412a9114fbd2cbaefbc8181424"
bytecode = common.FromHex(storeAddr) bytecode = common.FromHex(storeAddr)
tx = types.NewMsgEthereumTx(2, &receiver, big.NewInt(0), gasLimit, gasPrice, bytecode) tx = types.NewMsgEthereumTx(2, &receiver, big.NewInt(0), gasLimit, gasPrice, bytecode)
tx.Sign(big.NewInt(3), priv.ToECDSA()) tx.Sign(big.NewInt(888), priv.ToECDSA())
suite.Require().NoError(err) suite.Require().NoError(err)
result, err = suite.handler(suite.ctx, tx) result, err = suite.handler(suite.ctx, tx)
@ -350,7 +323,7 @@ func (suite *EvmTestSuite) TestDeployAndCallContract() {
// query - getOwner // query - getOwner
bytecode = common.FromHex("0x893d20e8") bytecode = common.FromHex("0x893d20e8")
tx = types.NewMsgEthereumTx(2, &receiver, big.NewInt(0), gasLimit, gasPrice, bytecode) tx = types.NewMsgEthereumTx(2, &receiver, big.NewInt(0), gasLimit, gasPrice, bytecode)
tx.Sign(big.NewInt(3), priv.ToECDSA()) tx.Sign(big.NewInt(888), priv.ToECDSA())
suite.Require().NoError(err) suite.Require().NoError(err)
result, err = suite.handler(suite.ctx, tx) result, err = suite.handler(suite.ctx, tx)
@ -375,7 +348,7 @@ func (suite *EvmTestSuite) TestSendTransaction() {
// send simple value transfer with gasLimit=21000 // send simple value transfer with gasLimit=21000
tx := types.NewMsgEthereumTx(1, &ethcmn.Address{0x1}, big.NewInt(1), gasLimit, gasPrice, nil) tx := types.NewMsgEthereumTx(1, &ethcmn.Address{0x1}, big.NewInt(1), gasLimit, gasPrice, nil)
err = tx.Sign(big.NewInt(3), priv.ToECDSA()) err = tx.Sign(big.NewInt(888), priv.ToECDSA())
suite.Require().NoError(err) suite.Require().NoError(err)
result, err := suite.handler(suite.ctx, tx) result, err := suite.handler(suite.ctx, tx)
@ -448,7 +421,7 @@ func (suite *EvmTestSuite) TestOutOfGasWhenDeployContract() {
bytecode := common.FromHex("0x608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f342827c97908e5e2f71151c08502a66d44b6f758e3ac2f1de95f02eb95f0a73560405160405180910390a36102c4806100dc6000396000f3fe608060405234801561001057600080fd5b5060043610610053576000357c010000000000000000000000000000000000000000000000000000000090048063893d20e814610058578063a6f9dae1146100a2575b600080fd5b6100606100e6565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100e4600480360360208110156100b857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061010f565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146101d1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f43616c6c6572206973206e6f74206f776e65720000000000000000000000000081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f342827c97908e5e2f71151c08502a66d44b6f758e3ac2f1de95f02eb95f0a73560405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505056fea265627a7a72315820f397f2733a89198bc7fed0764083694c5b828791f39ebcbc9e414bccef14b48064736f6c63430005100032") bytecode := common.FromHex("0x608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f342827c97908e5e2f71151c08502a66d44b6f758e3ac2f1de95f02eb95f0a73560405160405180910390a36102c4806100dc6000396000f3fe608060405234801561001057600080fd5b5060043610610053576000357c010000000000000000000000000000000000000000000000000000000090048063893d20e814610058578063a6f9dae1146100a2575b600080fd5b6100606100e6565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100e4600480360360208110156100b857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061010f565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146101d1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f43616c6c6572206973206e6f74206f776e65720000000000000000000000000081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f342827c97908e5e2f71151c08502a66d44b6f758e3ac2f1de95f02eb95f0a73560405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505056fea265627a7a72315820f397f2733a89198bc7fed0764083694c5b828791f39ebcbc9e414bccef14b48064736f6c63430005100032")
tx := types.NewMsgEthereumTx(1, nil, big.NewInt(0), gasLimit, gasPrice, bytecode) tx := types.NewMsgEthereumTx(1, nil, big.NewInt(0), gasLimit, gasPrice, bytecode)
tx.Sign(big.NewInt(3), priv.ToECDSA()) tx.Sign(big.NewInt(888), priv.ToECDSA())
suite.Require().NoError(err) suite.Require().NoError(err)
snapshotCommitStateDBJson, err := json.Marshal(suite.app.EvmKeeper.CommitStateDB) snapshotCommitStateDBJson, err := json.Marshal(suite.app.EvmKeeper.CommitStateDB)
@ -478,7 +451,7 @@ func (suite *EvmTestSuite) TestErrorWhenDeployContract() {
bytecode := common.FromHex("0xa6f9dae10000000000000000000000006a82e4a67715c8412a9114fbd2cbaefbc8181424") bytecode := common.FromHex("0xa6f9dae10000000000000000000000006a82e4a67715c8412a9114fbd2cbaefbc8181424")
tx := types.NewMsgEthereumTx(1, nil, big.NewInt(0), gasLimit, gasPrice, bytecode) tx := types.NewMsgEthereumTx(1, nil, big.NewInt(0), gasLimit, gasPrice, bytecode)
tx.Sign(big.NewInt(3), priv.ToECDSA()) tx.Sign(big.NewInt(888), priv.ToECDSA())
suite.Require().NoError(err) suite.Require().NoError(err)
snapshotCommitStateDBJson, err := json.Marshal(suite.app.EvmKeeper.CommitStateDB) snapshotCommitStateDBJson, err := json.Marshal(suite.app.EvmKeeper.CommitStateDB)

View File

@ -3,29 +3,29 @@ package keeper
import ( import (
"math/big" "math/big"
abci "github.com/tendermint/tendermint/abci/types" "github.com/cosmos/ethermint/metrics"
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
ethtypes "github.com/ethereum/go-ethereum/core/types" ethtypes "github.com/ethereum/go-ethereum/core/types"
abci "github.com/tendermint/tendermint/abci/types"
) )
// BeginBlock sets the block height -> header hash map for the previous block height // BeginBlock sets the block hash -> block height map for the previous block height
// and resets the Bloom filter and the transaction count to 0. // and resets the Bloom filter and the transaction count to 0.
func (k *Keeper) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) { func (k *Keeper) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) {
if req.Header.LastBlockId.GetHash() == nil || req.Header.GetHeight() < 1 { if req.Header.Height < 1 {
return return
} }
// Gas costs are handled within msg handler so costs should be ignored // Gas costs are handled within msg handler so costs should be ignored
ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter())
// Set the hash -> height and height -> hash mapping. k.SetBlockHash(ctx, req.Hash, req.Header.Height)
currentHash := req.Hash k.SetBlockHeightToHash(ctx, req.Hash, req.Header.Height)
height := req.Header.GetHeight()
k.SetHeightHash(ctx, uint64(height), common.BytesToHash(hash)) // special setter for csdb
k.SetHeightHash(ctx, uint64(req.Header.Height), common.BytesToHash(req.Hash))
// reset counters that are used on CommitStateDB.Prepare // reset counters that are used on CommitStateDB.Prepare
k.Bloom = big.NewInt(0) k.Bloom = big.NewInt(0)
@ -37,6 +37,10 @@ func (k *Keeper) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) {
// the store. The EVM end block logic doesn't update the validator set, thus it returns // the store. The EVM end block logic doesn't update the validator set, thus it returns
// an empty slice. // an empty slice.
func (k Keeper) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) []abci.ValidatorUpdate { func (k Keeper) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) []abci.ValidatorUpdate {
metrics.ReportFuncCall(k.svcTags)
doneFn := metrics.ReportFuncTiming(k.svcTags)
defer doneFn()
// Gas costs are handled within msg handler so costs should be ignored // Gas costs are handled within msg handler so costs should be ignored
ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter())

View File

@ -1,32 +0,0 @@
package keeper_test
import (
abci "github.com/tendermint/tendermint/abci/types"
)
func (suite *KeeperTestSuite) TestBeginBlock() {
// update the counters
suite.app.EvmKeeper.Bloom.SetInt64(10)
suite.app.EvmKeeper.TxCount = 10
suite.app.EvmKeeper.BeginBlock(suite.ctx, abci.RequestBeginBlock{})
suite.Require().NotZero(suite.app.EvmKeeper.Bloom.Int64())
suite.Require().NotZero(suite.app.EvmKeeper.TxCount)
}
func (suite *KeeperTestSuite) TestEndBlock() {
// update the counters
suite.app.EvmKeeper.Bloom.SetInt64(10)
// set gas limit to 1 to ensure no gas is consumed during the operation
initialConsumed := suite.ctx.GasMeter().GasConsumed()
_ = suite.app.EvmKeeper.EndBlock(suite.ctx, abci.RequestEndBlock{Height: 100})
suite.Require().Equal(int64(initialConsumed), int64(suite.ctx.GasMeter().GasConsumed()))
bloom, found := suite.app.EvmKeeper.GetBlockBloom(suite.ctx, 100)
suite.Require().True(found)
suite.Require().Equal(int64(10), bloom.Big().Int64())
}

View File

@ -2,14 +2,17 @@ package keeper
import ( import (
"context" "context"
"math/big"
"google.golang.org/grpc/codes" "google.golang.org/grpc/codes"
"google.golang.org/grpc/status" "google.golang.org/grpc/status"
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
tmtypes "github.com/tendermint/tendermint/types"
ethcmn "github.com/ethereum/go-ethereum/common" ethcmn "github.com/ethereum/go-ethereum/common"
"github.com/cosmos/ethermint/metrics"
ethermint "github.com/cosmos/ethermint/types" ethermint "github.com/cosmos/ethermint/types"
"github.com/cosmos/ethermint/x/evm/types" "github.com/cosmos/ethermint/x/evm/types"
) )
@ -17,12 +20,18 @@ import (
var _ types.QueryServer = Keeper{} var _ types.QueryServer = Keeper{}
// Account implements the Query/Account gRPC method // Account implements the Query/Account gRPC method
func (q Keeper) Account(c context.Context, req *types.QueryAccountRequest) (*types.QueryAccountResponse, error) { func (k Keeper) Account(c context.Context, req *types.QueryAccountRequest) (*types.QueryAccountResponse, error) {
metrics.ReportFuncCall(k.svcTags)
doneFn := metrics.ReportFuncTiming(k.svcTags)
defer doneFn()
if req == nil { if req == nil {
metrics.ReportFuncError(k.svcTags)
return nil, status.Error(codes.InvalidArgument, "empty request") return nil, status.Error(codes.InvalidArgument, "empty request")
} }
if len(req.Address) == 0 { if types.IsZeroAddress(req.Address) {
metrics.ReportFuncError(k.svcTags)
return nil, status.Error( return nil, status.Error(
codes.InvalidArgument, codes.InvalidArgument,
types.ErrZeroAddress.Error(), types.ErrZeroAddress.Error(),
@ -30,9 +39,10 @@ func (q Keeper) Account(c context.Context, req *types.QueryAccountRequest) (*typ
} }
ctx := sdk.UnwrapSDKContext(c) ctx := sdk.UnwrapSDKContext(c)
so := q.GetOrNewStateObject(ctx, ethcmn.HexToAddress(req.Address)) so := k.GetOrNewStateObject(ctx, ethcmn.HexToAddress(req.Address))
balance, err := ethermint.MarshalBigInt(so.Balance()) balance, err := ethermint.MarshalBigInt(so.Balance())
if err != nil { if err != nil {
metrics.ReportFuncError(k.svcTags)
return nil, err return nil, err
} }
@ -43,13 +53,18 @@ func (q Keeper) Account(c context.Context, req *types.QueryAccountRequest) (*typ
}, nil }, nil
} }
// Balance implements the Query/Balance gRPC method func (k Keeper) CosmosAccount(c context.Context, req *types.QueryCosmosAccountRequest) (*types.QueryCosmosAccountResponse, error) {
func (q Keeper) Balance(c context.Context, req *types.QueryBalanceRequest) (*types.QueryBalanceResponse, error) { metrics.ReportFuncCall(k.svcTags)
doneFn := metrics.ReportFuncTiming(k.svcTags)
defer doneFn()
if req == nil { if req == nil {
metrics.ReportFuncError(k.svcTags)
return nil, status.Error(codes.InvalidArgument, "empty request") return nil, status.Error(codes.InvalidArgument, "empty request")
} }
if len(req.Address) == 0 { if types.IsZeroAddress(req.Address) {
metrics.ReportFuncError(k.svcTags)
return nil, status.Error( return nil, status.Error(
codes.InvalidArgument, codes.InvalidArgument,
types.ErrZeroAddress.Error(), types.ErrZeroAddress.Error(),
@ -58,9 +73,48 @@ func (q Keeper) Balance(c context.Context, req *types.QueryBalanceRequest) (*typ
ctx := sdk.UnwrapSDKContext(c) ctx := sdk.UnwrapSDKContext(c)
balanceInt := q.GetBalance(ctx, ethcmn.HexToAddress(req.Address)) ethStr := req.Address
ethAddr := ethcmn.FromHex(ethStr)
ethToCosmosAddr := sdk.AccAddress(ethAddr[:]).String()
cosmosToEthAddr, _ := sdk.AccAddressFromBech32(ethToCosmosAddr)
acc := k.accountKeeper.GetAccount(ctx, cosmosToEthAddr)
res := types.QueryCosmosAccountResponse{
CosmosAddress: cosmosToEthAddr.String(),
}
if acc != nil {
res.Sequence = acc.GetSequence()
res.AccountNumber = acc.GetAccountNumber()
}
return &res, nil
}
// Balance implements the Query/Balance gRPC method
func (k Keeper) Balance(c context.Context, req *types.QueryBalanceRequest) (*types.QueryBalanceResponse, error) {
metrics.ReportFuncCall(k.svcTags)
doneFn := metrics.ReportFuncTiming(k.svcTags)
defer doneFn()
if req == nil {
metrics.ReportFuncError(k.svcTags)
return nil, status.Error(codes.InvalidArgument, "empty request")
}
if types.IsZeroAddress(req.Address) {
metrics.ReportFuncError(k.svcTags)
return nil, status.Error(
codes.InvalidArgument,
types.ErrZeroAddress.Error(),
)
}
ctx := sdk.UnwrapSDKContext(c)
balanceInt := k.GetBalance(ctx, ethcmn.HexToAddress(req.Address))
balance, err := ethermint.MarshalBigInt(balanceInt) balance, err := ethermint.MarshalBigInt(balanceInt)
if err != nil { if err != nil {
metrics.ReportFuncError(k.svcTags)
return nil, status.Error( return nil, status.Error(
codes.Internal, codes.Internal,
"failed to marshal big.Int to string", "failed to marshal big.Int to string",
@ -73,31 +127,30 @@ func (q Keeper) Balance(c context.Context, req *types.QueryBalanceRequest) (*typ
} }
// Storage implements the Query/Storage gRPC method // Storage implements the Query/Storage gRPC method
func (q Keeper) Storage(c context.Context, req *types.QueryStorageRequest) (*types.QueryStorageResponse, error) { func (k Keeper) Storage(c context.Context, req *types.QueryStorageRequest) (*types.QueryStorageResponse, error) {
metrics.ReportFuncCall(k.svcTags)
doneFn := metrics.ReportFuncTiming(k.svcTags)
defer doneFn()
if req == nil { if req == nil {
metrics.ReportFuncError(k.svcTags)
return nil, status.Error(codes.InvalidArgument, "empty request") return nil, status.Error(codes.InvalidArgument, "empty request")
} }
if len(req.Address) == 0 { if types.IsZeroAddress(req.Address) {
metrics.ReportFuncError(k.svcTags)
return nil, status.Error( return nil, status.Error(
codes.InvalidArgument, codes.InvalidArgument,
types.ErrZeroAddress.Error(), types.ErrZeroAddress.Error(),
) )
} }
if len(req.Key) == 0 {
return nil, status.Error(
codes.InvalidArgument,
types.ErrEmptyHash.Error(),
)
}
ctx := sdk.UnwrapSDKContext(c) ctx := sdk.UnwrapSDKContext(c)
address := ethcmn.HexToAddress(req.Address) address := ethcmn.HexToAddress(req.Address)
key := ethcmn.HexToHash(req.Key) key := ethcmn.HexToHash(req.Key)
state := q.GetState(ctx, address, key) state := k.GetState(ctx, address, key)
return &types.QueryStorageResponse{ return &types.QueryStorageResponse{
Value: state.String(), Value: state.String(),
@ -105,12 +158,18 @@ func (q Keeper) Storage(c context.Context, req *types.QueryStorageRequest) (*typ
} }
// Code implements the Query/Code gRPC method // Code implements the Query/Code gRPC method
func (q Keeper) Code(c context.Context, req *types.QueryCodeRequest) (*types.QueryCodeResponse, error) { func (k Keeper) Code(c context.Context, req *types.QueryCodeRequest) (*types.QueryCodeResponse, error) {
metrics.ReportFuncCall(k.svcTags)
doneFn := metrics.ReportFuncTiming(k.svcTags)
defer doneFn()
if req == nil { if req == nil {
metrics.ReportFuncError(k.svcTags)
return nil, status.Error(codes.InvalidArgument, "empty request") return nil, status.Error(codes.InvalidArgument, "empty request")
} }
if len(req.Address) == 0 { if types.IsZeroAddress(req.Address) {
metrics.ReportFuncError(k.svcTags)
return nil, status.Error( return nil, status.Error(
codes.InvalidArgument, codes.InvalidArgument,
types.ErrZeroAddress.Error(), types.ErrZeroAddress.Error(),
@ -120,7 +179,7 @@ func (q Keeper) Code(c context.Context, req *types.QueryCodeRequest) (*types.Que
ctx := sdk.UnwrapSDKContext(c) ctx := sdk.UnwrapSDKContext(c)
address := ethcmn.HexToAddress(req.Address) address := ethcmn.HexToAddress(req.Address)
code := q.GetCode(ctx, address) code := k.GetCode(ctx, address)
return &types.QueryCodeResponse{ return &types.QueryCodeResponse{
Code: code, Code: code,
@ -128,12 +187,18 @@ func (q Keeper) Code(c context.Context, req *types.QueryCodeRequest) (*types.Que
} }
// TxLogs implements the Query/TxLogs gRPC method // TxLogs implements the Query/TxLogs gRPC method
func (q Keeper) TxLogs(c context.Context, req *types.QueryTxLogsRequest) (*types.QueryTxLogsResponse, error) { func (k Keeper) TxLogs(c context.Context, req *types.QueryTxLogsRequest) (*types.QueryTxLogsResponse, error) {
metrics.ReportFuncCall(k.svcTags)
doneFn := metrics.ReportFuncTiming(k.svcTags)
defer doneFn()
if req == nil { if req == nil {
metrics.ReportFuncError(k.svcTags)
return nil, status.Error(codes.InvalidArgument, "empty request") return nil, status.Error(codes.InvalidArgument, "empty request")
} }
if types.IsEmptyHash(req.Hash) { if types.IsEmptyHash(req.Hash) {
metrics.ReportFuncError(k.svcTags)
return nil, status.Error( return nil, status.Error(
codes.InvalidArgument, codes.InvalidArgument,
types.ErrEmptyHash.Error(), types.ErrEmptyHash.Error(),
@ -143,8 +208,9 @@ func (q Keeper) TxLogs(c context.Context, req *types.QueryTxLogsRequest) (*types
ctx := sdk.UnwrapSDKContext(c) ctx := sdk.UnwrapSDKContext(c)
hash := ethcmn.HexToHash(req.Hash) hash := ethcmn.HexToHash(req.Hash)
logs, err := q.GetLogs(ctx, hash) logs, err := k.GetLogs(ctx, hash)
if err != nil { if err != nil {
metrics.ReportFuncError(k.svcTags)
return nil, status.Error( return nil, status.Error(
codes.Internal, codes.Internal,
err.Error(), err.Error(),
@ -156,13 +222,19 @@ func (q Keeper) TxLogs(c context.Context, req *types.QueryTxLogsRequest) (*types
}, nil }, nil
} }
// BlockLogs implements the Query/BlockLogs gRPC method // TxReceipt implements the Query/TxReceipt gRPC method
func (q Keeper) BlockLogs(c context.Context, req *types.QueryBlockLogsRequest) (*types.QueryBlockLogsResponse, error) { func (k Keeper) TxReceipt(c context.Context, req *types.QueryTxReceiptRequest) (*types.QueryTxReceiptResponse, error) {
metrics.ReportFuncCall(k.svcTags)
doneFn := metrics.ReportFuncTiming(k.svcTags)
defer doneFn()
if req == nil { if req == nil {
metrics.ReportFuncError(k.svcTags)
return nil, status.Error(codes.InvalidArgument, "empty request") return nil, status.Error(codes.InvalidArgument, "empty request")
} }
if types.IsEmptyHash(req.Hash) { if types.IsEmptyHash(req.Hash) {
metrics.ReportFuncError(k.svcTags)
return nil, status.Error( return nil, status.Error(
codes.InvalidArgument, codes.InvalidArgument,
types.ErrEmptyHash.Error(), types.ErrEmptyHash.Error(),
@ -171,7 +243,90 @@ func (q Keeper) BlockLogs(c context.Context, req *types.QueryBlockLogsRequest) (
ctx := sdk.UnwrapSDKContext(c) ctx := sdk.UnwrapSDKContext(c)
txLogs := q.GetAllTxLogs(ctx) hash := ethcmn.HexToHash(req.Hash)
receipt, found := k.GetTxReceiptFromHash(ctx, hash)
if !found {
metrics.ReportFuncError(k.svcTags)
return nil, status.Error(
codes.NotFound, types.ErrTxReceiptNotFound.Error(),
)
}
return &types.QueryTxReceiptResponse{
Receipt: receipt,
}, nil
}
// TxReceiptsByBlockHeight implements the Query/TxReceiptsByBlockHeight gRPC method
func (k Keeper) TxReceiptsByBlockHeight(c context.Context, req *types.QueryTxReceiptsByBlockHeightRequest) (*types.QueryTxReceiptsByBlockHeightResponse, error) {
metrics.ReportFuncCall(k.svcTags)
doneFn := metrics.ReportFuncTiming(k.svcTags)
defer doneFn()
if req == nil {
metrics.ReportFuncError(k.svcTags)
return nil, status.Error(codes.InvalidArgument, "empty request")
}
ctx := sdk.UnwrapSDKContext(c)
receipts := k.GetTxReceiptsByBlockHeight(ctx, req.Height)
return &types.QueryTxReceiptsByBlockHeightResponse{
Receipts: receipts,
}, nil
}
// TxReceiptsByBlockHash implements the Query/TxReceiptsByBlockHash gRPC method
func (k Keeper) TxReceiptsByBlockHash(c context.Context, req *types.QueryTxReceiptsByBlockHashRequest) (*types.QueryTxReceiptsByBlockHashResponse, error) {
metrics.ReportFuncCall(k.svcTags)
doneFn := metrics.ReportFuncTiming(k.svcTags)
defer doneFn()
if req == nil {
metrics.ReportFuncError(k.svcTags)
return nil, status.Error(codes.InvalidArgument, "empty request")
}
if types.IsEmptyHash(req.Hash) {
metrics.ReportFuncError(k.svcTags)
return nil, status.Error(
codes.InvalidArgument,
types.ErrEmptyHash.Error(),
)
}
ctx := sdk.UnwrapSDKContext(c)
hash := ethcmn.HexToHash(req.Hash)
receipts := k.GetTxReceiptsByBlockHash(ctx, hash)
return &types.QueryTxReceiptsByBlockHashResponse{
Receipts: receipts,
}, nil
}
// BlockLogs implements the Query/BlockLogs gRPC method
func (k Keeper) BlockLogs(c context.Context, req *types.QueryBlockLogsRequest) (*types.QueryBlockLogsResponse, error) {
metrics.ReportFuncCall(k.svcTags)
doneFn := metrics.ReportFuncTiming(k.svcTags)
defer doneFn()
if req == nil {
metrics.ReportFuncError(k.svcTags)
return nil, status.Error(codes.InvalidArgument, "empty request")
}
if types.IsEmptyHash(req.Hash) {
metrics.ReportFuncError(k.svcTags)
return nil, status.Error(
codes.InvalidArgument,
types.ErrEmptyHash.Error(),
)
}
ctx := sdk.UnwrapSDKContext(c)
txLogs := k.GetAllTxLogs(ctx)
return &types.QueryBlockLogsResponse{ return &types.QueryBlockLogsResponse{
TxLogs: txLogs, TxLogs: txLogs,
@ -179,14 +334,28 @@ func (q Keeper) BlockLogs(c context.Context, req *types.QueryBlockLogsRequest) (
} }
// BlockBloom implements the Query/BlockBloom gRPC method // BlockBloom implements the Query/BlockBloom gRPC method
func (q Keeper) BlockBloom(c context.Context, _ *types.QueryBlockBloomRequest) (*types.QueryBlockBloomResponse, error) { func (k Keeper) BlockBloom(c context.Context, req *types.QueryBlockBloomRequest) (*types.QueryBlockBloomResponse, error) {
metrics.ReportFuncCall(k.svcTags)
doneFn := metrics.ReportFuncTiming(k.svcTags)
defer doneFn()
if req == nil {
metrics.ReportFuncError(k.svcTags)
return nil, status.Error(codes.InvalidArgument, "empty request")
}
ctx := sdk.UnwrapSDKContext(c) ctx := sdk.UnwrapSDKContext(c)
// use block height provided through the gRPC header height := ctx.BlockHeight()
bloom, found := q.GetBlockBloom(ctx, ctx.BlockHeight()) if setHeight := req.Height; setHeight > 0 {
height = setHeight
}
bloom, found := k.GetBlockBloom(ctx, height)
if !found { if !found {
return nil, status.Errorf( metrics.ReportFuncError(k.svcTags)
codes.NotFound, "%s: height %d", types.ErrBloomNotFound.Error(), ctx.BlockHeight(), return nil, status.Error(
codes.NotFound, types.ErrBloomNotFound.Error(),
) )
} }
@ -196,11 +365,73 @@ func (q Keeper) BlockBloom(c context.Context, _ *types.QueryBlockBloomRequest) (
} }
// Params implements the Query/Params gRPC method // Params implements the Query/Params gRPC method
func (q Keeper) Params(c context.Context, _ *types.QueryParamsRequest) (*types.QueryParamsResponse, error) { func (k Keeper) Params(c context.Context, req *types.QueryParamsRequest) (*types.QueryParamsResponse, error) {
metrics.ReportFuncCall(k.svcTags)
doneFn := metrics.ReportFuncTiming(k.svcTags)
defer doneFn()
if req == nil {
metrics.ReportFuncError(k.svcTags)
return nil, status.Error(codes.InvalidArgument, "empty request")
}
ctx := sdk.UnwrapSDKContext(c) ctx := sdk.UnwrapSDKContext(c)
params := q.GetParams(ctx) params := k.GetParams(ctx)
return &types.QueryParamsResponse{ return &types.QueryParamsResponse{
Params: params, Params: params,
}, nil }, nil
} }
// StaticCall implements Query/StaticCall gRPCP method
func (k Keeper) StaticCall(c context.Context, req *types.QueryStaticCallRequest) (*types.QueryStaticCallResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "empty request")
}
ctx := sdk.UnwrapSDKContext(c)
// parse the chainID from a string to a base-10 integer
chainIDEpoch, err := ethermint.ParseChainID(ctx.ChainID())
if err != nil {
return nil, err
}
txHash := tmtypes.Tx(ctx.TxBytes()).Hash()
ethHash := ethcmn.BytesToHash(txHash)
var recipient *ethcmn.Address
if len(req.Address) > 0 {
addr := ethcmn.HexToAddress(req.Address)
recipient = &addr
}
so := k.GetOrNewStateObject(ctx, *recipient)
sender := ethcmn.HexToAddress("0xaDd00275E3d9d213654Ce5223f0FADE8b106b707")
st := &types.StateTransition{
AccountNonce: so.Nonce(),
Price: new(big.Int).SetBytes(big.NewInt(0).Bytes()),
GasLimit: 100000000,
Recipient: recipient,
Amount: new(big.Int).SetBytes(big.NewInt(0).Bytes()),
Payload: req.Input,
Csdb: k.CommitStateDB.WithContext(ctx),
ChainID: chainIDEpoch,
TxHash: &ethHash,
Sender: sender,
Simulate: ctx.IsCheckTx(),
}
config, found := k.GetChainConfig(ctx)
if !found {
return nil, types.ErrChainConfigNotFound
}
ret, err := st.StaticCall(ctx, config)
if err != nil {
return nil, err
}
return &types.QueryStaticCallResponse{Data: ret}, nil
}

View File

@ -1,499 +0,0 @@
package keeper_test
import (
"fmt"
"google.golang.org/grpc/metadata"
ethcmn "github.com/ethereum/go-ethereum/common"
ethtypes "github.com/ethereum/go-ethereum/core/types"
ethcrypto "github.com/ethereum/go-ethereum/crypto"
sdk "github.com/cosmos/cosmos-sdk/types"
ethermint "github.com/cosmos/ethermint/types"
"github.com/cosmos/ethermint/x/evm/types"
grpctypes "github.com/cosmos/cosmos-sdk/types/grpc"
)
func (suite *KeeperTestSuite) TestQueryAccount() {
var (
req *types.QueryAccountRequest
expAccount *types.QueryAccountResponse
)
testCases := []struct {
msg string
malleate func()
expPass bool
}{
{"zero address",
func() {
suite.app.BankKeeper.SetBalance(suite.ctx, suite.address.Bytes(), ethermint.NewPhotonCoinInt64(0))
expAccount = &types.QueryAccountResponse{
Balance: "0",
CodeHash: ethcrypto.Keccak256(nil),
Nonce: 0,
}
req = &types.QueryAccountRequest{
Address: ethcmn.Address{}.String(),
}
},
true,
},
{
"success",
func() {
suite.app.BankKeeper.SetBalance(suite.ctx, suite.address.Bytes(), ethermint.NewPhotonCoinInt64(100))
expAccount = &types.QueryAccountResponse{
Balance: "100",
CodeHash: ethcrypto.Keccak256(nil),
Nonce: 0,
}
req = &types.QueryAccountRequest{
Address: suite.address.String(),
}
},
true,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
suite.SetupTest() // reset
tc.malleate()
ctx := sdk.WrapSDKContext(suite.ctx)
res, err := suite.queryClient.Account(ctx, req)
if tc.expPass {
suite.Require().NoError(err)
suite.Require().NotNil(res)
suite.Require().Equal(expAccount, res)
} else {
suite.Require().Error(err)
}
})
}
}
func (suite *KeeperTestSuite) TestQueryBalance() {
var (
req *types.QueryBalanceRequest
expBalance string
)
testCases := []struct {
msg string
malleate func()
expPass bool
}{
{"zero address",
func() {
suite.app.BankKeeper.SetBalance(suite.ctx, suite.address.Bytes(), ethermint.NewPhotonCoinInt64(0))
expBalance = "0"
req = &types.QueryBalanceRequest{
Address: ethcmn.Address{}.String(),
}
},
true,
},
{
"success",
func() {
suite.app.BankKeeper.SetBalance(suite.ctx, suite.address.Bytes(), ethermint.NewPhotonCoinInt64(100))
expBalance = "100"
req = &types.QueryBalanceRequest{
Address: suite.address.String(),
}
},
true,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
suite.SetupTest() // reset
tc.malleate()
ctx := sdk.WrapSDKContext(suite.ctx)
res, err := suite.queryClient.Balance(ctx, req)
if tc.expPass {
suite.Require().NoError(err)
suite.Require().NotNil(res)
suite.Require().Equal(expBalance, res.Balance)
} else {
suite.Require().Error(err)
}
})
}
}
func (suite *KeeperTestSuite) TestQueryStorage() {
var (
req *types.QueryStorageRequest
expValue string
)
testCases := []struct {
msg string
malleate func()
expPass bool
}{
{"zero address",
func() {
req = &types.QueryStorageRequest{
Address: ethcmn.Address{}.String(),
}
},
false,
},
{"empty hash",
func() {
req = &types.QueryStorageRequest{
Address: suite.address.String(),
Key: ethcmn.Hash{}.String(),
}
exp := &types.QueryStorageResponse{Value: "0x0000000000000000000000000000000000000000000000000000000000000000"}
expValue = exp.Value
},
true,
},
{
"success",
func() {
key := ethcmn.BytesToHash([]byte("key"))
value := ethcmn.BytesToHash([]byte("value"))
expValue = value.String()
suite.app.EvmKeeper.SetState(suite.ctx, suite.address, key, value)
req = &types.QueryStorageRequest{
Address: suite.address.String(),
Key: key.String(),
}
},
true,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
suite.SetupTest() // reset
tc.malleate()
ctx := sdk.WrapSDKContext(suite.ctx)
res, err := suite.queryClient.Storage(ctx, req)
if tc.expPass {
suite.Require().NoError(err)
suite.Require().NotNil(res)
suite.Require().Equal(expValue, res.Value)
} else {
suite.Require().Error(err)
}
})
}
}
func (suite *KeeperTestSuite) TestQueryCode() {
var (
req *types.QueryCodeRequest
expCode []byte
)
testCases := []struct {
msg string
malleate func()
expPass bool
}{
{"zero address",
func() {
req = &types.QueryCodeRequest{
Address: ethcmn.Address{}.String(),
}
exp := &types.QueryCodeResponse{}
expCode = exp.Code
},
true,
},
{
"success",
func() {
expCode = []byte("code")
suite.app.EvmKeeper.SetCode(suite.ctx, suite.address, expCode)
req = &types.QueryCodeRequest{
Address: suite.address.String(),
}
},
true,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
suite.SetupTest() // reset
tc.malleate()
ctx := sdk.WrapSDKContext(suite.ctx)
res, err := suite.queryClient.Code(ctx, req)
if tc.expPass {
suite.Require().NoError(err)
suite.Require().NotNil(res)
suite.Require().Equal(expCode, res.Code)
} else {
suite.Require().Error(err)
}
})
}
}
func (suite *KeeperTestSuite) TestQueryTxLogs() {
var (
req *types.QueryTxLogsRequest
expLogs []*types.Log
)
testCases := []struct {
msg string
malleate func()
expPass bool
}{
{"empty hash",
func() {
req = &types.QueryTxLogsRequest{
Hash: ethcmn.Hash{}.String(),
}
},
false,
},
{"logs not found",
func() {
hash := ethcmn.BytesToHash([]byte("hash"))
req = &types.QueryTxLogsRequest{
Hash: hash.String(),
}
},
true,
},
{
"success",
func() {
hash := ethcmn.BytesToHash([]byte("tx_hash"))
expLogs = []*types.Log{
{
Address: suite.address.String(),
Topics: []string{ethcmn.BytesToHash([]byte("topic")).String()},
Data: []byte("data"),
BlockNumber: 1,
TxHash: hash.String(),
TxIndex: 1,
BlockHash: ethcmn.BytesToHash([]byte("block_hash")).String(),
Index: 0,
Removed: false,
},
}
suite.app.EvmKeeper.SetLogs(suite.ctx, hash, types.LogsToEthereum(expLogs))
req = &types.QueryTxLogsRequest{
Hash: hash.String(),
}
},
true,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
suite.SetupTest() // reset
tc.malleate()
ctx := sdk.WrapSDKContext(suite.ctx)
res, err := suite.queryClient.TxLogs(ctx, req)
if tc.expPass {
suite.Require().NoError(err)
suite.Require().NotNil(res)
suite.Require().Equal(expLogs, res.Logs)
} else {
suite.Require().Error(err)
}
})
}
}
func (suite *KeeperTestSuite) TestQueryBlockLogs() {
var (
req *types.QueryBlockLogsRequest
expLogs []types.TransactionLogs
)
testCases := []struct {
msg string
malleate func()
expPass bool
}{
{"empty hash",
func() {
req = &types.QueryBlockLogsRequest{
Hash: ethcmn.Hash{}.String(),
}
},
false,
},
{"logs not found",
func() {
hash := ethcmn.BytesToHash([]byte("hash"))
req = &types.QueryBlockLogsRequest{
Hash: hash.String(),
}
},
true,
},
{
"success",
func() {
hash := ethcmn.BytesToHash([]byte("block_hash"))
expLogs = []types.TransactionLogs{
{
Hash: ethcmn.BytesToHash([]byte("tx_hash_0")).String(),
Logs: []*types.Log{
{
Address: suite.address.String(),
Topics: []string{ethcmn.BytesToHash([]byte("topic")).String()},
Data: []byte("data"),
BlockNumber: 1,
TxHash: ethcmn.BytesToHash([]byte("tx_hash_0")).String(),
TxIndex: 1,
BlockHash: ethcmn.BytesToHash([]byte("block_hash")).String(),
Index: 0,
Removed: false,
},
},
},
{
Hash: ethcmn.BytesToHash([]byte("tx_hash_1")).String(),
Logs: []*types.Log{
{
Address: suite.address.String(),
Topics: []string{ethcmn.BytesToHash([]byte("topic")).String()},
Data: []byte("data"),
BlockNumber: 1,
TxHash: ethcmn.BytesToHash([]byte("tx_hash_1")).String(),
TxIndex: 1,
BlockHash: ethcmn.BytesToHash([]byte("block_hash")).String(),
Index: 0,
Removed: false,
},
{
Address: suite.address.String(),
Topics: []string{ethcmn.BytesToHash([]byte("topic_1")).String()},
Data: []byte("data_1"),
BlockNumber: 1,
TxHash: ethcmn.BytesToHash([]byte("tx_hash_1")).String(),
TxIndex: 1,
BlockHash: ethcmn.BytesToHash([]byte("block_hash")).String(),
Index: 0,
Removed: false,
},
},
},
}
suite.app.EvmKeeper.SetLogs(suite.ctx, ethcmn.BytesToHash([]byte("tx_hash_0")), types.LogsToEthereum(expLogs[0].Logs))
suite.app.EvmKeeper.SetLogs(suite.ctx, ethcmn.BytesToHash([]byte("tx_hash_1")), types.LogsToEthereum(expLogs[1].Logs))
req = &types.QueryBlockLogsRequest{
Hash: hash.String(),
}
},
true,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
suite.SetupTest() // reset
tc.malleate()
ctx := sdk.WrapSDKContext(suite.ctx)
res, err := suite.queryClient.BlockLogs(ctx, req)
if tc.expPass {
suite.Require().NoError(err)
suite.Require().NotNil(res)
suite.Require().Equal(expLogs, res.TxLogs)
} else {
suite.Require().Error(err)
}
})
}
}
func (suite *KeeperTestSuite) TestQueryBlockBloom() {
var (
req *types.QueryBlockBloomRequest
expBloom []byte
)
testCases := []struct {
msg string
malleate func()
expPass bool
}{
{"bloom bytes not found for height",
func() {},
false,
},
{
"success",
func() {
req = &types.QueryBlockBloomRequest{}
bloom := ethtypes.BytesToBloom([]byte("bloom"))
expBloom = bloom.Bytes()
suite.ctx = suite.ctx.WithBlockHeight(1)
suite.app.EvmKeeper.SetBlockBloom(suite.ctx, 1, bloom)
},
true,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
suite.SetupTest() // reset
tc.malleate()
ctx := sdk.WrapSDKContext(suite.ctx)
ctx = metadata.AppendToOutgoingContext(ctx, grpctypes.GRPCBlockHeightHeader, fmt.Sprintf("%d", suite.ctx.BlockHeight()))
res, err := suite.queryClient.BlockBloom(ctx, req)
if tc.expPass {
suite.Require().NoError(err)
suite.Require().NotNil(res)
suite.Require().Equal(expBloom, res.Bloom)
} else {
suite.Require().Error(err)
}
})
}
}
func (suite *KeeperTestSuite) TestQueryParams() {
ctx := sdk.WrapSDKContext(suite.ctx)
expParams := types.DefaultParams()
res, err := suite.queryClient.Params(ctx, &types.QueryParamsRequest{})
suite.Require().NoError(err)
suite.Require().Equal(expParams, res.Params)
}

View File

@ -4,10 +4,8 @@ import (
"math/big" "math/big"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/cosmos/ethermint/crypto/ethsecp256k1" "github.com/cosmos/ethermint/crypto/ethsecp256k1"
ethermint "github.com/cosmos/ethermint/types" ethermint "github.com/cosmos/ethermint/types"
ethcmn "github.com/ethereum/go-ethereum/common" ethcmn "github.com/ethereum/go-ethereum/common"
) )
@ -27,7 +25,7 @@ func (suite *KeeperTestSuite) TestBalanceInvariant() {
func() { func() {
acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, address.Bytes()) acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, address.Bytes())
suite.Require().NotNil(acc) suite.Require().NotNil(acc)
suite.app.BankKeeper.SetBalance(suite.ctx, acc.GetAddress(), ethermint.NewPhotonCoinInt64(1)) suite.app.BankKeeper.SetBalance(suite.ctx, acc.GetAddress(), ethermint.NewInjectiveCoinInt64(1))
suite.Require().NoError(err) suite.Require().NoError(err)
suite.app.AccountKeeper.SetAccount(suite.ctx, acc) suite.app.AccountKeeper.SetAccount(suite.ctx, acc)
@ -40,7 +38,7 @@ func (suite *KeeperTestSuite) TestBalanceInvariant() {
func() { func() {
acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, address.Bytes()) acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, address.Bytes())
suite.Require().NotNil(acc) suite.Require().NotNil(acc)
suite.app.BankKeeper.SetBalance(suite.ctx, acc.GetAddress(), ethermint.NewPhotonCoinInt64(1)) suite.app.BankKeeper.SetBalance(suite.ctx, acc.GetAddress(), ethermint.NewInjectiveCoinInt64(1))
suite.Require().NoError(err) suite.Require().NoError(err)
suite.app.AccountKeeper.SetAccount(suite.ctx, acc) suite.app.AccountKeeper.SetAccount(suite.ctx, acc)

View File

@ -1,20 +1,17 @@
package keeper package keeper
import ( import (
"fmt"
"math/big" "math/big"
"github.com/tendermint/tendermint/libs/log"
"github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/store/prefix"
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
"github.com/cosmos/ethermint/x/evm/types"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
ethtypes "github.com/ethereum/go-ethereum/core/types" ethtypes "github.com/ethereum/go-ethereum/core/types"
"github.com/tendermint/tendermint/libs/log"
"github.com/cosmos/ethermint/metrics"
"github.com/cosmos/ethermint/x/evm/types"
) )
// Keeper wraps the CommitStateDB, allowing us to pass in SDK context while adhering // Keeper wraps the CommitStateDB, allowing us to pass in SDK context while adhering
@ -27,11 +24,12 @@ type Keeper struct {
// - storing Account's Code // - storing Account's Code
// - storing transaction Logs // - storing transaction Logs
// - storing block height -> bloom filter map. Needed for the Web3 API. // - storing block height -> bloom filter map. Needed for the Web3 API.
// - storing block hash -> block height map. Needed for the Web3 API. // - storing block hash -> block height map. Needed for the Web3 API. TODO: remove
storeKey sdk.StoreKey storeKey sdk.StoreKey
// Account Keeper for fetching accounts
accountKeeper types.AccountKeeper accountKeeper types.AccountKeeper
bankKeeper types.BankKeeper bankKeeper types.BankKeeper
// Ethermint concrete implementation on the EVM StateDB interface // Ethermint concrete implementation on the EVM StateDB interface
CommitStateDB *types.CommitStateDB CommitStateDB *types.CommitStateDB
// Transaction counter in a block. Used on StateSB's Prepare function. // Transaction counter in a block. Used on StateSB's Prepare function.
@ -39,6 +37,12 @@ type Keeper struct {
// on the KVStore or adding it as a field on the EVM genesis state. // on the KVStore or adding it as a field on the EVM genesis state.
TxCount int TxCount int
Bloom *big.Int Bloom *big.Int
// LogsCache keeps mapping of contract address -> eth logs emitted
// during EVM execution in the current block.
LogsCache map[common.Address][]*ethtypes.Log
svcTags metrics.Tags
} }
// NewKeeper generates new evm module keeper // NewKeeper generates new evm module keeper
@ -53,6 +57,10 @@ func NewKeeper(
// NOTE: we pass in the parameter space to the CommitStateDB in order to use custom denominations for the EVM operations // NOTE: we pass in the parameter space to the CommitStateDB in order to use custom denominations for the EVM operations
return &Keeper{ return &Keeper{
svcTags: metrics.Tags{
"svc": "evm_k",
},
cdc: cdc, cdc: cdc,
accountKeeper: ak, accountKeeper: ak,
bankKeeper: bankKeeper, bankKeeper: bankKeeper,
@ -60,19 +68,116 @@ func NewKeeper(
CommitStateDB: types.NewCommitStateDB(sdk.Context{}, storeKey, paramSpace, ak, bankKeeper), CommitStateDB: types.NewCommitStateDB(sdk.Context{}, storeKey, paramSpace, ak, bankKeeper),
TxCount: 0, TxCount: 0,
Bloom: big.NewInt(0), Bloom: big.NewInt(0),
LogsCache: map[common.Address][]*ethtypes.Log{},
} }
} }
// Logger returns a module-specific logger. // Logger returns a module-specific logger.
func (k Keeper) Logger(ctx sdk.Context) log.Logger { func (k Keeper) Logger(ctx sdk.Context) log.Logger {
return ctx.Logger().With("module", fmt.Sprintf("x/%s", types.ModuleName)) return ctx.Logger().With("module", types.ModuleName)
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Epoch Height -> hash mapping functions // Block bloom bits mapping functions
// Required by EVM context's GetHashFunc // Required by Web3 API.
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// GetBlockBloom gets bloombits from block height
func (k Keeper) GetBlockBloom(ctx sdk.Context, height int64) (ethtypes.Bloom, bool) {
metrics.ReportFuncCall(k.svcTags)
doneFn := metrics.ReportFuncTiming(k.svcTags)
defer doneFn()
store := ctx.KVStore(k.storeKey)
key := types.BloomKey(height)
has := store.Has(key)
if !has {
return ethtypes.Bloom{}, true // sometimes bloom not found, fix this
}
bz := store.Get(key)
return ethtypes.BytesToBloom(bz), true
}
// SetBlockBloom sets the mapping from block height to bloom bits
func (k Keeper) SetBlockBloom(ctx sdk.Context, height int64, bloom ethtypes.Bloom) {
metrics.ReportFuncCall(k.svcTags)
doneFn := metrics.ReportFuncTiming(k.svcTags)
defer doneFn()
store := ctx.KVStore(k.storeKey)
key := types.BloomKey(height)
store.Set(key, bloom.Bytes())
}
// GetBlockHash gets block height from block consensus hash
func (k Keeper) GetBlockHashFromHeight(ctx sdk.Context, height int64) ([]byte, bool) {
metrics.ReportFuncCall(k.svcTags)
doneFn := metrics.ReportFuncTiming(k.svcTags)
defer doneFn()
store := ctx.KVStore(k.storeKey)
bz := store.Get(types.KeyBlockHeightHash(uint64(height)))
if len(bz) == 0 {
return common.Hash{}.Bytes(), false
}
return common.BytesToHash(bz).Bytes(), true
}
// SetBlockHash sets the mapping from block consensus hash to block height
func (k Keeper) SetBlockHash(ctx sdk.Context, hash []byte, height int64) {
metrics.ReportFuncCall(k.svcTags)
doneFn := metrics.ReportFuncTiming(k.svcTags)
defer doneFn()
store := ctx.KVStore(k.storeKey)
bz := sdk.Uint64ToBigEndian(uint64(height))
store.Set(types.KeyBlockHash(common.BytesToHash(hash)), bz)
}
// GetBlockHash gets block height from block consensus hash
func (k Keeper) GetBlockHeightByHash(ctx sdk.Context, hash common.Hash) (int64, bool) {
metrics.ReportFuncCall(k.svcTags)
doneFn := metrics.ReportFuncTiming(k.svcTags)
defer doneFn()
store := ctx.KVStore(k.storeKey)
bz := store.Get(types.KeyBlockHash(hash))
if len(bz) == 0 {
return 0, false
}
height := sdk.BigEndianToUint64(bz)
return int64(height), true
}
// SetBlockHash sets the mapping from block consensus hash to block height
func (k Keeper) SetBlockHeightToHash(ctx sdk.Context, hash []byte, height int64) {
metrics.ReportFuncCall(k.svcTags)
doneFn := metrics.ReportFuncTiming(k.svcTags)
defer doneFn()
store := ctx.KVStore(k.storeKey)
store.Set(types.KeyBlockHeightHash(uint64(height)), hash)
}
// SetTxReceiptToHash sets the mapping from tx hash to tx receipt
func (k Keeper) SetTxReceiptToHash(ctx sdk.Context, hash common.Hash, receipt *types.TxReceipt) {
metrics.ReportFuncCall(k.svcTags)
doneFn := metrics.ReportFuncTiming(k.svcTags)
defer doneFn()
ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter())
data := k.cdc.MustMarshalBinaryBare(receipt)
store := ctx.KVStore(k.storeKey)
store.Set(types.KeyHashTxReceipt(hash), data)
}
// GetHeightHash returns the block header hash associated with a given block height and chain epoch number. // GetHeightHash returns the block header hash associated with a given block height and chain epoch number.
func (k Keeper) GetHeightHash(ctx sdk.Context, height uint64) common.Hash { func (k Keeper) GetHeightHash(ctx sdk.Context, height uint64) common.Hash {
return k.CommitStateDB.WithContext(ctx).GetHeightHash(height) return k.CommitStateDB.WithContext(ctx).GetHeightHash(height)
@ -83,31 +188,121 @@ func (k Keeper) SetHeightHash(ctx sdk.Context, height uint64, hash common.Hash)
k.CommitStateDB.WithContext(ctx).SetHeightHash(height, hash) k.CommitStateDB.WithContext(ctx).SetHeightHash(height, hash)
} }
// ---------------------------------------------------------------------------- // GetTxReceiptFromHash gets tx receipt by tx hash.
// Block bloom bits mapping functions func (k Keeper) GetTxReceiptFromHash(ctx sdk.Context, hash common.Hash) (*types.TxReceipt, bool) {
// Required by Web3 API. metrics.ReportFuncCall(k.svcTags)
// ---------------------------------------------------------------------------- doneFn := metrics.ReportFuncTiming(k.svcTags)
defer doneFn()
// GetBlockBloom gets bloombits from block height store := ctx.KVStore(k.storeKey)
func (k Keeper) GetBlockBloom(ctx sdk.Context, height int64) (ethtypes.Bloom, bool) { data := store.Get(types.KeyHashTxReceipt(hash))
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixBloom) if data == nil || len(data) == 0 {
has := store.Has(types.BloomKey(height)) return nil, false
if !has {
return ethtypes.Bloom{}, false
} }
bz := store.Get(types.BloomKey(height)) var receipt types.TxReceipt
return ethtypes.BytesToBloom(bz), true k.cdc.MustUnmarshalBinaryBare(data, &receipt)
return &receipt, true
} }
// SetBlockBloom sets the mapping from block height to bloom bits // AddTxHashToBlock stores tx hash in the list of tx for the block.
func (k Keeper) SetBlockBloom(ctx sdk.Context, height int64, bloom ethtypes.Bloom) { func (k Keeper) AddTxHashToBlock(ctx sdk.Context, blockHeight int64, txHash common.Hash) {
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixBloom) metrics.ReportFuncCall(k.svcTags)
store.Set(types.BloomKey(height), bloom.Bytes()) doneFn := metrics.ReportFuncTiming(k.svcTags)
defer doneFn()
key := types.KeyBlockHeightTxs(uint64(blockHeight))
list := types.BytesList{}
store := ctx.KVStore(k.storeKey)
data := store.Get(key)
if len(data) > 0 {
k.cdc.MustUnmarshalBinaryBare(data, &list)
}
list.Bytes = append(list.Bytes, txHash.Bytes())
data = k.cdc.MustMarshalBinaryBare(&list)
store.Set(key, data)
}
// GetTxsFromBlock returns list of tx hash in the block by height.
func (k Keeper) GetTxsFromBlock(ctx sdk.Context, blockHeight int64) []common.Hash {
metrics.ReportFuncCall(k.svcTags)
doneFn := metrics.ReportFuncTiming(k.svcTags)
defer doneFn()
key := types.KeyBlockHeightTxs(uint64(blockHeight))
store := ctx.KVStore(k.storeKey)
data := store.Get(key)
if len(data) > 0 {
list := types.BytesList{}
k.cdc.MustUnmarshalBinaryBare(data, &list)
txs := make([]common.Hash, 0, len(list.Bytes))
for _, b := range list.Bytes {
txs = append(txs, common.BytesToHash(b))
}
return txs
}
return nil
}
// GetTxReceiptsByBlockHeight gets tx receipts by block height.
func (k Keeper) GetTxReceiptsByBlockHeight(ctx sdk.Context, blockHeight int64) []*types.TxReceipt {
metrics.ReportFuncCall(k.svcTags)
doneFn := metrics.ReportFuncTiming(k.svcTags)
defer doneFn()
txs := k.GetTxsFromBlock(ctx, blockHeight)
if len(txs) == 0 {
return nil
}
store := ctx.KVStore(k.storeKey)
receipts := make([]*types.TxReceipt, 0, len(txs))
for idx, txHash := range txs {
data := store.Get(types.KeyHashTxReceipt(txHash))
if data == nil || len(data) == 0 {
continue
}
var receipt types.TxReceipt
k.cdc.MustUnmarshalBinaryBare(data, &receipt)
receipt.Index = uint64(idx)
receipts = append(receipts, &receipt)
}
return receipts
}
// GetTxReceiptsByBlockHash gets tx receipts by block hash.
func (k Keeper) GetTxReceiptsByBlockHash(ctx sdk.Context, hash common.Hash) []*types.TxReceipt {
metrics.ReportFuncCall(k.svcTags)
doneFn := metrics.ReportFuncTiming(k.svcTags)
defer doneFn()
blockHeight, ok := k.GetBlockHeightByHash(ctx, hash)
if !ok {
return nil
}
return k.GetTxReceiptsByBlockHeight(ctx, blockHeight)
} }
// GetAllTxLogs return all the transaction logs from the store. // GetAllTxLogs return all the transaction logs from the store.
func (k Keeper) GetAllTxLogs(ctx sdk.Context) []types.TransactionLogs { func (k Keeper) GetAllTxLogs(ctx sdk.Context) []types.TransactionLogs {
metrics.ReportFuncCall(k.svcTags)
doneFn := metrics.ReportFuncTiming(k.svcTags)
defer doneFn()
store := ctx.KVStore(k.storeKey) store := ctx.KVStore(k.storeKey)
iterator := sdk.KVStorePrefixIterator(store, types.KeyPrefixLogs) iterator := sdk.KVStorePrefixIterator(store, types.KeyPrefixLogs)
defer iterator.Close() defer iterator.Close()
@ -125,6 +320,10 @@ func (k Keeper) GetAllTxLogs(ctx sdk.Context) []types.TransactionLogs {
// GetAccountStorage return state storage associated with an account // GetAccountStorage return state storage associated with an account
func (k Keeper) GetAccountStorage(ctx sdk.Context, address common.Address) (types.Storage, error) { func (k Keeper) GetAccountStorage(ctx sdk.Context, address common.Address) (types.Storage, error) {
metrics.ReportFuncCall(k.svcTags)
doneFn := metrics.ReportFuncTiming(k.svcTags)
defer doneFn()
storage := types.Storage{} storage := types.Storage{}
err := k.ForEachStorage(ctx, address, func(key, value common.Hash) bool { err := k.ForEachStorage(ctx, address, func(key, value common.Hash) bool {
@ -140,6 +339,10 @@ func (k Keeper) GetAccountStorage(ctx sdk.Context, address common.Address) (type
// GetChainConfig gets block height from block consensus hash // GetChainConfig gets block height from block consensus hash
func (k Keeper) GetChainConfig(ctx sdk.Context) (types.ChainConfig, bool) { func (k Keeper) GetChainConfig(ctx sdk.Context) (types.ChainConfig, bool) {
metrics.ReportFuncCall(k.svcTags)
doneFn := metrics.ReportFuncTiming(k.svcTags)
defer doneFn()
store := ctx.KVStore(k.storeKey) store := ctx.KVStore(k.storeKey)
bz := store.Get(types.KeyPrefixChainConfig) bz := store.Get(types.KeyPrefixChainConfig)
if len(bz) == 0 { if len(bz) == 0 {
@ -153,6 +356,10 @@ func (k Keeper) GetChainConfig(ctx sdk.Context) (types.ChainConfig, bool) {
// SetChainConfig sets the mapping from block consensus hash to block height // SetChainConfig sets the mapping from block consensus hash to block height
func (k Keeper) SetChainConfig(ctx sdk.Context, config types.ChainConfig) { func (k Keeper) SetChainConfig(ctx sdk.Context, config types.ChainConfig) {
metrics.ReportFuncCall(k.svcTags)
doneFn := metrics.ReportFuncTiming(k.svcTags)
defer doneFn()
store := ctx.KVStore(k.storeKey) store := ctx.KVStore(k.storeKey)
bz := k.cdc.MustMarshalBinaryBare(&config) bz := k.cdc.MustMarshalBinaryBare(&config)
store.Set(types.KeyPrefixChainConfig, bz) store.Set(types.KeyPrefixChainConfig, bz)

View File

@ -7,7 +7,6 @@ import (
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
"github.com/cosmos/cosmos-sdk/baseapp"
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
@ -33,8 +32,8 @@ type KeeperTestSuite struct {
suite.Suite suite.Suite
ctx sdk.Context ctx sdk.Context
app *app.EthermintApp querier sdk.Querier
queryClient types.QueryClient app *app.InjectiveApp
address ethcmn.Address address ethcmn.Address
} }
@ -42,14 +41,10 @@ func (suite *KeeperTestSuite) SetupTest() {
checkTx := false checkTx := false
suite.app = app.Setup(checkTx) suite.app = app.Setup(checkTx)
suite.ctx = suite.app.BaseApp.NewContext(checkTx, tmproto.Header{Height: 1, ChainID: "ethermint-3", Time: time.Now().UTC()}) suite.ctx = suite.app.BaseApp.NewContext(checkTx, tmproto.Header{Height: 1, ChainID: "3", Time: time.Now().UTC()})
suite.address = ethcmn.HexToAddress(addrHex) suite.address = ethcmn.HexToAddress(addrHex)
queryHelper := baseapp.NewQueryServerTestHelper(suite.ctx, suite.app.InterfaceRegistry()) balance := ethermint.NewInjectiveCoin(sdk.ZeroInt())
types.RegisterQueryServer(queryHelper, suite.app.EvmKeeper)
suite.queryClient = types.NewQueryClient(queryHelper)
balance := ethermint.NewPhotonCoin(sdk.ZeroInt())
acc := &ethermint.EthAccount{ acc := &ethermint.EthAccount{
BaseAccount: authtypes.NewBaseAccount(sdk.AccAddress(suite.address.Bytes()), nil, 0, 0), BaseAccount: authtypes.NewBaseAccount(sdk.AccAddress(suite.address.Bytes()), nil, 0, 0),
CodeHash: ethcrypto.Keccak256(nil), CodeHash: ethcrypto.Keccak256(nil),
@ -69,13 +64,11 @@ func (suite *KeeperTestSuite) TestTransactionLogs() {
Address: suite.address, Address: suite.address,
Data: []byte("log"), Data: []byte("log"),
BlockNumber: 10, BlockNumber: 10,
Topics: []ethcmn.Hash{},
} }
log2 := &ethtypes.Log{ log2 := &ethtypes.Log{
Address: suite.address, Address: suite.address,
Data: []byte("log2"), Data: []byte("log2"),
BlockNumber: 11, BlockNumber: 11,
Topics: []ethcmn.Hash{},
} }
expLogs := []*ethtypes.Log{log} expLogs := []*ethtypes.Log{log}
@ -90,7 +83,6 @@ func (suite *KeeperTestSuite) TestTransactionLogs() {
// add another log under the zero hash // add another log under the zero hash
suite.app.EvmKeeper.AddLog(suite.ctx, log2) suite.app.EvmKeeper.AddLog(suite.ctx, log2)
log2.Index = 0
logs = suite.app.EvmKeeper.AllLogs(suite.ctx) logs = suite.app.EvmKeeper.AllLogs(suite.ctx)
suite.Require().Equal(expLogs, logs) suite.Require().Equal(expLogs, logs)
@ -99,19 +91,17 @@ func (suite *KeeperTestSuite) TestTransactionLogs() {
Address: suite.address, Address: suite.address,
Data: []byte("log3"), Data: []byte("log3"),
BlockNumber: 10, BlockNumber: 10,
Topics: []ethcmn.Hash{},
} }
suite.app.EvmKeeper.AddLog(suite.ctx, log3) suite.app.EvmKeeper.AddLog(suite.ctx, log3)
log3.Index = 0
txLogs := suite.app.EvmKeeper.GetAllTxLogs(suite.ctx) txLogs := suite.app.EvmKeeper.GetAllTxLogs(suite.ctx)
suite.Require().Equal(2, len(txLogs)) suite.Require().Equal(2, len(txLogs))
suite.Require().Equal(ethcmn.Hash{}.String(), txLogs[0].Hash) suite.Require().Equal(ethcmn.Hash{}.String(), txLogs[0].Hash)
suite.Require().Equal([]*ethtypes.Log{log2, log3}, txLogs[0].EthLogs()) suite.Require().Equal([]*ethtypes.Log{log2, log3}, txLogs[0].Logs)
suite.Require().Equal(ethHash.String(), txLogs[1].Hash) suite.Require().Equal(ethHash.String(), txLogs[1].Hash)
suite.Require().Equal([]*ethtypes.Log{log}, txLogs[1].EthLogs()) suite.Require().Equal([]*ethtypes.Log{log}, txLogs[1].Logs)
} }
func (suite *KeeperTestSuite) TestDBStorage() { func (suite *KeeperTestSuite) TestDBStorage() {

View File

@ -2,57 +2,68 @@ package keeper
import ( import (
"context" "context"
"math/big"
"github.com/armon/go-metrics" "github.com/pkg/errors"
log "github.com/xlab/suplog"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/ethereum/go-ethereum/common"
ethcmn "github.com/ethereum/go-ethereum/common"
tmtypes "github.com/tendermint/tendermint/types" tmtypes "github.com/tendermint/tendermint/types"
ethcmn "github.com/ethereum/go-ethereum/common" "github.com/cosmos/ethermint/metrics"
"github.com/cosmos/cosmos-sdk/telemetry"
sdk "github.com/cosmos/cosmos-sdk/types"
ethermint "github.com/cosmos/ethermint/types" ethermint "github.com/cosmos/ethermint/types"
"github.com/cosmos/ethermint/x/evm/types" "github.com/cosmos/ethermint/x/evm/types"
) )
var _ types.MsgServer = Keeper{} var _ types.MsgServer = &Keeper{}
func (k *Keeper) EthereumTx(goCtx context.Context, msg *types.MsgEthereumTx) (*types.MsgEthereumTxResponse, error) {
metrics.ReportFuncCall(k.svcTags)
doneFn := metrics.ReportFuncTiming(k.svcTags)
defer doneFn()
// EthereumTx implements the Msg/EthereumTx gRPC method.
func (k Keeper) EthereumTx(goCtx context.Context, msg *types.MsgEthereumTx) (*types.MsgEthereumTxResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx) ctx := sdk.UnwrapSDKContext(goCtx)
// parse the chainID from a string to a base-10 integer // parse the chainID from a string to a base-10 integer
chainIDEpoch, err := ethermint.ParseChainID(ctx.ChainID()) chainIDEpoch, err := ethermint.ParseChainID(ctx.ChainID())
if err != nil { if err != nil {
metrics.ReportFuncError(k.svcTags)
return nil, err return nil, err
} }
// Verify signature and retrieve sender address // Verify signature and retrieve sender address
sender, err := msg.VerifySig(chainIDEpoch) var homesteadErr error
if err != nil { sender, eip155Err := msg.VerifySig(chainIDEpoch)
return nil, err if eip155Err != nil {
sender, homesteadErr = msg.VerifySigHomestead()
if homesteadErr != nil {
log.WithFields(log.Fields{
"eip155_err": eip155Err.Error(),
"homestead_err": homesteadErr.Error(),
}).Warningln("failed to verify signatures with EIP155 and Homestead signers")
metrics.ReportFuncError(k.svcTags)
return nil, errors.New("no valid signatures")
}
} }
txHash := tmtypes.Tx(ctx.TxBytes()).Hash() txHash := tmtypes.Tx(ctx.TxBytes()).Hash()
ethHash := ethcmn.BytesToHash(txHash) ethHash := ethcmn.BytesToHash(txHash)
var recipient *ethcmn.Address var recipient *ethcmn.Address
if len(msg.Data.Recipient) > 0 {
labels := []metrics.Label{telemetry.NewLabel("operation", "create")} addr := ethcmn.BytesToAddress(msg.Data.Recipient)
if msg.Data.Recipient != nil {
addr := ethcmn.HexToAddress(msg.Data.Recipient.Address)
recipient = &addr recipient = &addr
labels = []metrics.Label{telemetry.NewLabel("operation", "call")}
} }
st := types.StateTransition{ st := &types.StateTransition{
AccountNonce: msg.Data.AccountNonce, AccountNonce: msg.Data.AccountNonce,
Price: msg.Data.Price.BigInt(), Price: new(big.Int).SetBytes(msg.Data.Price),
GasLimit: msg.Data.GasLimit, GasLimit: msg.Data.GasLimit,
Recipient: recipient, Recipient: recipient,
Amount: msg.Data.Amount.BigInt(), Amount: new(big.Int).SetBytes(msg.Data.Amount),
Payload: msg.Data.Payload, Payload: msg.Data.Payload,
Csdb: k.CommitStateDB.WithContext(ctx), Csdb: k.CommitStateDB.WithContext(ctx),
ChainID: chainIDEpoch, ChainID: chainIDEpoch,
@ -66,18 +77,47 @@ func (k Keeper) EthereumTx(goCtx context.Context, msg *types.MsgEthereumTx) (*ty
// other nodes, causing a consensus error // other nodes, causing a consensus error
if !st.Simulate { if !st.Simulate {
// Prepare db for logs // Prepare db for logs
blockHash := types.HashFromContext(ctx) hash, _ := k.GetBlockHashFromHeight(ctx, ctx.BlockHeight())
k.Prepare(ctx, ethHash, blockHash, k.TxCount) k.Prepare(ctx, ethHash, ethcmn.BytesToHash(hash), k.TxCount)
k.TxCount++ k.TxCount++
} }
config, found := k.GetChainConfig(ctx) config, found := k.GetChainConfig(ctx)
if !found { if !found {
metrics.ReportFuncError(k.svcTags)
return nil, types.ErrChainConfigNotFound return nil, types.ErrChainConfigNotFound
} }
executionResult, err := st.TransitionDb(ctx, config) executionResult, err := st.TransitionDb(ctx, config)
if err != nil { if err != nil {
if err.Error() == "execution reverted" && executionResult != nil {
// keep the execution result for revert reason
executionResult.Response.Reverted = true
metrics.ReportFuncError(k.svcTags)
if !st.Simulate {
blockHash, _ := k.GetBlockHashFromHeight(ctx, ctx.BlockHeight())
k.SetTxReceiptToHash(ctx, ethHash, &types.TxReceipt{
Hash: ethHash.Bytes(),
From: sender.Bytes(),
Data: msg.Data,
BlockHeight: uint64(ctx.BlockHeight()),
BlockHash: blockHash,
Result: &types.TxResult{
ContractAddress: executionResult.Response.ContractAddress,
Bloom: executionResult.Response.Bloom,
TxLogs: executionResult.Response.TxLogs,
Ret: executionResult.Response.Ret,
Reverted: executionResult.Response.Reverted,
GasUsed: executionResult.GasInfo.GasConsumed,
},
})
}
return executionResult.Response, nil
}
metrics.ReportFuncError(k.svcTags)
return nil, err return nil, err
} }
@ -86,28 +126,42 @@ func (k Keeper) EthereumTx(goCtx context.Context, msg *types.MsgEthereumTx) (*ty
k.Bloom.Or(k.Bloom, executionResult.Bloom) k.Bloom.Or(k.Bloom, executionResult.Bloom)
// update transaction logs in KVStore // update transaction logs in KVStore
err = k.SetLogs(ctx, ethcmn.BytesToHash(txHash), executionResult.Logs) err = k.SetLogs(ctx, ethHash, executionResult.Logs)
if err != nil { if err != nil {
panic(err) panic(err)
} }
}
// add metrics for the transaction blockHash, _ := k.GetBlockHashFromHeight(ctx, ctx.BlockHeight())
defer func() { k.SetTxReceiptToHash(ctx, ethHash, &types.TxReceipt{
if st.Amount.IsInt64() { Hash: ethHash.Bytes(),
telemetry.SetGaugeWithLabels( From: sender.Bytes(),
[]string{"tx", "msg", "ethereum"}, Data: msg.Data,
float32(st.Amount.Int64()), Index: uint64(st.Csdb.TxIndex()),
labels, BlockHeight: uint64(ctx.BlockHeight()),
) BlockHash: blockHash,
Result: &types.TxResult{
ContractAddress: executionResult.Response.ContractAddress,
Bloom: executionResult.Response.Bloom,
TxLogs: executionResult.Response.TxLogs,
Ret: executionResult.Response.Ret,
Reverted: executionResult.Response.Reverted,
GasUsed: executionResult.GasInfo.GasConsumed,
},
})
k.AddTxHashToBlock(ctx, ctx.BlockHeight(), ethHash)
for _, ethLog := range executionResult.Logs {
k.LogsCache[ethLog.Address] = append(k.LogsCache[ethLog.Address], ethLog)
}
} }
}()
// emit events // emit events
ctx.EventManager().EmitEvents(sdk.Events{ ctx.EventManager().EmitEvents(sdk.Events{
sdk.NewEvent( sdk.NewEvent(
types.EventTypeEthereumTx, types.EventTypeEthereumTx,
sdk.NewAttribute(sdk.AttributeKeyAmount, st.Amount.String()), sdk.NewAttribute(sdk.AttributeKeyAmount, st.Amount.String()),
sdk.NewAttribute(types.AttributeKeyTxHash, ethcmn.BytesToHash(txHash).Hex()),
), ),
sdk.NewEvent( sdk.NewEvent(
sdk.EventTypeMessage, sdk.EventTypeMessage,
@ -116,11 +170,209 @@ func (k Keeper) EthereumTx(goCtx context.Context, msg *types.MsgEthereumTx) (*ty
), ),
}) })
if msg.Data.Recipient != nil { if len(msg.Data.Recipient) > 0 {
ethAddr := ethcmn.BytesToAddress(msg.Data.Recipient)
ctx.EventManager().EmitEvent( ctx.EventManager().EmitEvent(
sdk.NewEvent( sdk.NewEvent(
types.EventTypeEthereumTx, types.EventTypeEthereumTx,
sdk.NewAttribute(types.AttributeKeyRecipient, msg.Data.Recipient.Address), sdk.NewAttribute(types.AttributeKeyRecipient, ethAddr.Hex()),
),
)
}
metrics.ReportFuncError(k.svcTags)
return executionResult.Response, nil
}
func (k *Keeper) SendInternalEthereumTx(
ctx sdk.Context,
payload []byte,
senderAddress common.Address,
recipientAddress common.Address,
) (*types.MsgEthereumTxResponse, error) {
accAddress := sdk.AccAddress(senderAddress.Bytes())
acc := k.accountKeeper.GetAccount(ctx, accAddress)
if acc == nil {
acc = k.accountKeeper.NewAccountWithAddress(ctx, accAddress)
k.accountKeeper.SetAccount(ctx, acc)
}
ethAccount, ok := acc.(*ethermint.EthAccount)
if !ok {
return nil, errors.New("could not cast account to EthAccount")
}
if err := ethAccount.SetSequence(ethAccount.GetSequence() + 1); err != nil {
return nil, errors.New("failed to set acc sequence")
}
k.accountKeeper.SetAccount(ctx, ethAccount)
res, err := k.InternalEthereumTx(sdk.WrapSDKContext(ctx), senderAddress, &types.TxData{
AccountNonce: ethAccount.GetSequence(),
Recipient: recipientAddress.Bytes(),
Amount: big.NewInt(0).Bytes(),
Price: big.NewInt(0).Bytes(),
GasLimit: 10000000, // TODO: don't hardcode, maybe set a limit?
Payload: payload,
})
if err != nil {
err = errors.Wrapf(err, "failed to execute InternalEthereumTx at contract %s", recipientAddress.Hex())
return nil, err
}
return res, nil
}
func (k *Keeper) InternalEthereumTx(
goCtx context.Context,
sender common.Address,
tx *types.TxData,
) (*types.MsgEthereumTxResponse, error) {
metrics.ReportFuncCall(k.svcTags)
doneFn := metrics.ReportFuncTiming(k.svcTags)
defer doneFn()
ctx := sdk.UnwrapSDKContext(goCtx)
// parse the chainID from a string to a base-10 integer
chainIDEpoch, err := ethermint.ParseChainID(ctx.ChainID())
if err != nil {
metrics.ReportFuncError(k.svcTags)
return nil, err
}
// true Ethereum tx hash based on its data
ethHash := (&types.MsgEthereumTx{
Data: tx,
}).RLPSignBytes(chainIDEpoch)
var recipient *ethcmn.Address
if len(tx.Recipient) > 0 {
addr := ethcmn.BytesToAddress(tx.Recipient)
recipient = &addr
}
st := &types.StateTransition{
AccountNonce: tx.AccountNonce,
Price: new(big.Int).SetBytes(tx.Price),
GasLimit: tx.GasLimit,
Recipient: recipient,
Amount: new(big.Int).SetBytes(tx.Amount),
Payload: tx.Payload,
Csdb: k.CommitStateDB.WithContext(ctx),
ChainID: chainIDEpoch,
TxHash: &ethHash,
Sender: sender,
Simulate: ctx.IsCheckTx(),
}
// since the txCount is used by the stateDB, and a simulated tx is run only on the node it's submitted to,
// then this will cause the txCount/stateDB of the node that ran the simulated tx to be different than the
// other nodes, causing a consensus error
if !st.Simulate {
// Prepare db for logs
hash, _ := k.GetBlockHashFromHeight(ctx, ctx.BlockHeight())
k.Prepare(ctx, ethHash, ethcmn.BytesToHash(hash), k.TxCount)
k.TxCount++
}
config, found := k.GetChainConfig(ctx)
if !found {
metrics.ReportFuncError(k.svcTags)
return nil, types.ErrChainConfigNotFound
}
executionResult, err := st.TransitionDb(ctx, config)
if err != nil {
if err.Error() == "execution reverted" && executionResult != nil {
// keep the execution result for revert reason
executionResult.Response.Reverted = true
metrics.ReportFuncError(k.svcTags)
if !st.Simulate {
blockHash, _ := k.GetBlockHashFromHeight(ctx, ctx.BlockHeight())
k.SetTxReceiptToHash(ctx, ethHash, &types.TxReceipt{
Hash: ethHash.Bytes(),
From: sender.Bytes(),
Data: tx,
BlockHeight: uint64(ctx.BlockHeight()),
BlockHash: blockHash,
Result: &types.TxResult{
ContractAddress: executionResult.Response.ContractAddress,
Bloom: executionResult.Response.Bloom,
TxLogs: executionResult.Response.TxLogs,
Ret: executionResult.Response.Ret,
Reverted: executionResult.Response.Reverted,
GasUsed: executionResult.GasInfo.GasConsumed,
},
})
}
return executionResult.Response, err
}
metrics.ReportFuncError(k.svcTags)
return nil, err
}
blockHash, _ := k.GetBlockHashFromHeight(ctx, ctx.BlockHeight())
k.SetTxReceiptToHash(ctx, ethHash, &types.TxReceipt{
Hash: ethHash.Bytes(),
From: sender.Bytes(),
Data: tx,
Index: uint64(st.Csdb.TxIndex()),
BlockHeight: uint64(ctx.BlockHeight()),
BlockHash: blockHash,
Result: &types.TxResult{
ContractAddress: executionResult.Response.ContractAddress,
Bloom: executionResult.Response.Bloom,
TxLogs: executionResult.Response.TxLogs,
Ret: executionResult.Response.Ret,
Reverted: executionResult.Response.Reverted,
GasUsed: executionResult.GasInfo.GasConsumed,
},
})
k.AddTxHashToBlock(ctx, ctx.BlockHeight(), ethHash)
if !st.Simulate {
// update block bloom filter
k.Bloom.Or(k.Bloom, executionResult.Bloom)
// update transaction logs in KVStore
err = k.SetLogs(ctx, ethHash, executionResult.Logs)
if err != nil {
panic(err)
}
for _, ethLog := range executionResult.Logs {
k.LogsCache[ethLog.Address] = append(k.LogsCache[ethLog.Address], ethLog)
}
}
// emit events
ctx.EventManager().EmitEvents(sdk.Events{
sdk.NewEvent(
types.EventTypeEthereumTx,
sdk.NewAttribute(sdk.AttributeKeyAmount, st.Amount.String()),
sdk.NewAttribute(types.AttributeKeyTxHash, ethHash.Hex()),
),
sdk.NewEvent(
sdk.EventTypeMessage,
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
sdk.NewAttribute(sdk.AttributeKeySender, sender.String()),
),
})
if len(tx.Recipient) > 0 {
ethAddr := ethcmn.BytesToAddress(tx.Recipient)
ctx.EventManager().EmitEvent(
sdk.NewEvent(
types.EventTypeEthereumTx,
sdk.NewAttribute(types.AttributeKeyRecipient, ethAddr.Hex()),
), ),
) )
} }

View File

@ -7,7 +7,7 @@ import (
func (suite *KeeperTestSuite) TestParams() { func (suite *KeeperTestSuite) TestParams() {
params := suite.app.EvmKeeper.GetParams(suite.ctx) params := suite.app.EvmKeeper.GetParams(suite.ctx)
suite.Require().Equal(types.DefaultParams(), params) suite.Require().Equal(types.DefaultParams(), params)
params.EvmDenom = "ara" params.EvmDenom = "inj"
suite.app.EvmKeeper.SetParams(suite.ctx, params) suite.app.EvmKeeper.SetParams(suite.ctx, params)
newParams := suite.app.EvmKeeper.GetParams(suite.ctx) newParams := suite.app.EvmKeeper.GetParams(suite.ctx)
suite.Require().Equal(newParams, params) suite.Require().Equal(newParams, params)

View File

@ -49,6 +49,11 @@ func (k *Keeper) SetCode(ctx sdk.Context, addr ethcmn.Address, code []byte) {
// SetLogs calls CommitStateDB.SetLogs using the passed in context // SetLogs calls CommitStateDB.SetLogs using the passed in context
func (k *Keeper) SetLogs(ctx sdk.Context, hash ethcmn.Hash, logs []*ethtypes.Log) error { func (k *Keeper) SetLogs(ctx sdk.Context, hash ethcmn.Hash, logs []*ethtypes.Log) error {
// TODO:@albert
// since SetLogs is only called for non-simulation mode, GasEstimation is quite not correct
// I suggest using ctx.ConsumeGas(XXX) where XXX is max of gas consume for set logs.
ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter())
return k.CommitStateDB.WithContext(ctx).SetLogs(hash, logs) return k.CommitStateDB.WithContext(ctx).SetLogs(hash, logs)
} }
@ -225,8 +230,8 @@ func (k *Keeper) Reset(ctx sdk.Context, root ethcmn.Hash) error {
} }
// Prepare calls CommitStateDB.Prepare using the passed in context // Prepare calls CommitStateDB.Prepare using the passed in context
func (k *Keeper) Prepare(ctx sdk.Context, thash ethcmn.Hash, txi int) { func (k *Keeper) Prepare(ctx sdk.Context, thash, bhash ethcmn.Hash, txi int) {
k.CommitStateDB.WithContext(ctx).Prepare(thash, txi) k.CommitStateDB.WithContext(ctx).Prepare(thash, bhash, txi)
} }
// CreateAccount calls CommitStateDB.CreateAccount using the passed in context // CreateAccount calls CommitStateDB.CreateAccount using the passed in context

View File

@ -18,7 +18,7 @@ import (
func (suite *KeeperTestSuite) TestBloomFilter() { func (suite *KeeperTestSuite) TestBloomFilter() {
// Prepare db for logs // Prepare db for logs
tHash := ethcmn.BytesToHash([]byte{0x1}) tHash := ethcmn.BytesToHash([]byte{0x1})
suite.app.EvmKeeper.Prepare(suite.ctx, tHash, 0) suite.app.EvmKeeper.Prepare(suite.ctx, tHash, ethcmn.Hash{}, 0)
contractAddress := ethcmn.BigToAddress(big.NewInt(1)) contractAddress := ethcmn.BigToAddress(big.NewInt(1))
log := ethtypes.Log{Address: contractAddress, Topics: []ethcmn.Hash{}} log := ethtypes.Log{Address: contractAddress, Topics: []ethcmn.Hash{}}
@ -230,7 +230,6 @@ func (suite *KeeperTestSuite) TestStateDB_Logs() {
suite.Require().Empty(dbLogs, tc.name) suite.Require().Empty(dbLogs, tc.name)
suite.app.EvmKeeper.AddLog(suite.ctx, tc.log) suite.app.EvmKeeper.AddLog(suite.ctx, tc.log)
tc.log.Index = 0 // reset index
suite.Require().Equal(logs, suite.app.EvmKeeper.AllLogs(suite.ctx), tc.name) suite.Require().Equal(logs, suite.app.EvmKeeper.AllLogs(suite.ctx), tc.name)
//resets state but checking to see if storekey still persists. //resets state but checking to see if storekey still persists.
@ -360,8 +359,7 @@ func (suite *KeeperTestSuite) TestSuiteDB_Prepare() {
bhash := ethcmn.BytesToHash([]byte("bhash")) bhash := ethcmn.BytesToHash([]byte("bhash"))
txi := 1 txi := 1
suite.app.EvmKeeper.Prepare(suite.ctx, thash, txi) suite.app.EvmKeeper.Prepare(suite.ctx, thash, bhash, txi)
suite.app.EvmKeeper.CommitStateDB.SetBlockHash(bhash)
suite.Require().Equal(txi, suite.app.EvmKeeper.TxIndex(suite.ctx)) suite.Require().Equal(txi, suite.app.EvmKeeper.TxIndex(suite.ctx))
suite.Require().Equal(bhash, suite.app.EvmKeeper.BlockHash(suite.ctx)) suite.Require().Equal(bhash, suite.app.EvmKeeper.BlockHash(suite.ctx))

View File

@ -57,17 +57,16 @@ func (AppModuleBasic) ValidateGenesis(cdc codec.JSONMarshaler, _ client.TxEncodi
// RegisterRESTRoutes performs a no-op as the EVM module doesn't expose REST // RegisterRESTRoutes performs a no-op as the EVM module doesn't expose REST
// endpoints // endpoints
func (AppModuleBasic) RegisterRESTRoutes(_ client.Context, _ *mux.Router) { func (AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Router) {
} }
// RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the evm module. func (b AppModuleBasic) RegisterGRPCGatewayRoutes(c client.Context, serveMux *runtime.ServeMux) {
func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { if err := types.RegisterQueryHandlerClient(context.Background(), serveMux, types.NewQueryClient(c)); err != nil {
if err := types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)); err != nil {
panic(err) panic(err)
} }
} }
// GetTxCmd returns nil as the evm module doesn't support transactions through the CLI. // GetTxCmd returns the root tx command for the evm module.
func (AppModuleBasic) GetTxCmd() *cobra.Command { func (AppModuleBasic) GetTxCmd() *cobra.Command {
return nil return nil
} }
@ -107,20 +106,23 @@ func (AppModule) Name() string {
return types.ModuleName return types.ModuleName
} }
// RegisterInvariants interface for registering invariants // RegisterInvariants interface for registering invariants. Performs a no-op
// as the evm module doesn't expose invariants.
func (am AppModule) RegisterInvariants(ir sdk.InvariantRegistry) { func (am AppModule) RegisterInvariants(ir sdk.InvariantRegistry) {
keeper.RegisterInvariants(ir, *am.keeper) // Invariats lead to performance degradation
//
// keeper.RegisterInvariants(ir, *am.keeper)
} }
// RegisterServices registers the evm module Msg and gRPC services. // RegisterQueryService registers a GRPC query service to respond to the
// module-specific GRPC queries.
func (am AppModule) RegisterServices(cfg module.Configurator) { func (am AppModule) RegisterServices(cfg module.Configurator) {
types.RegisterMsgServer(cfg.MsgServer(), am.keeper)
types.RegisterQueryServer(cfg.QueryServer(), am.keeper) types.RegisterQueryServer(cfg.QueryServer(), am.keeper)
} }
// Route returns the message routing key for the evm module. // Route returns the message routing key for the evm module.
func (am AppModule) Route() sdk.Route { func (am AppModule) Route() sdk.Route {
return sdk.NewRoute(types.RouterKey, NewHandler(*am.keeper)) return sdk.NewRoute(types.RouterKey, NewHandler(am.keeper))
} }
// QuerierRoute returns the evm module's querier route name. // QuerierRoute returns the evm module's querier route name.
@ -149,7 +151,8 @@ func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONMarshaler, data j
var genesisState types.GenesisState var genesisState types.GenesisState
cdc.MustUnmarshalJSON(data, &genesisState) cdc.MustUnmarshalJSON(data, &genesisState)
return InitGenesis(ctx, *am.keeper, am.ak, am.bk, genesisState) InitGenesis(ctx, *am.keeper, am.ak, am.bk, genesisState)
return []abci.ValidatorUpdate{}
} }
// ExportGenesis returns the exported genesis state as raw bytes for the evm // ExportGenesis returns the exported genesis state as raw bytes for the evm

View File

@ -28,12 +28,13 @@ func (cc ChainConfig) EthereumConfig(chainID *big.Int) *params.ChainConfig {
PetersburgBlock: getBlockValue(cc.PetersburgBlock), PetersburgBlock: getBlockValue(cc.PetersburgBlock),
IstanbulBlock: getBlockValue(cc.IstanbulBlock), IstanbulBlock: getBlockValue(cc.IstanbulBlock),
MuirGlacierBlock: getBlockValue(cc.MuirGlacierBlock), MuirGlacierBlock: getBlockValue(cc.MuirGlacierBlock),
//TODO(xlab): after upgrading ethereum to newer version, this should be set to YoloV2Block
YoloV2Block: getBlockValue(cc.YoloV2Block), YoloV2Block: getBlockValue(cc.YoloV2Block),
EWASMBlock: getBlockValue(cc.EWASMBlock), EWASMBlock: getBlockValue(cc.EWASMBlock),
} }
} }
// DefaultChainConfig returns default evm parameters. // DefaultChainConfig returns default evm parameters. Th
func DefaultChainConfig() ChainConfig { func DefaultChainConfig() ChainConfig {
return ChainConfig{ return ChainConfig{
HomesteadBlock: sdk.ZeroInt(), HomesteadBlock: sdk.ZeroInt(),
@ -46,8 +47,8 @@ func DefaultChainConfig() ChainConfig {
ByzantiumBlock: sdk.ZeroInt(), ByzantiumBlock: sdk.ZeroInt(),
ConstantinopleBlock: sdk.ZeroInt(), ConstantinopleBlock: sdk.ZeroInt(),
PetersburgBlock: sdk.ZeroInt(), PetersburgBlock: sdk.ZeroInt(),
IstanbulBlock: sdk.ZeroInt(), IstanbulBlock: sdk.NewInt(-1),
MuirGlacierBlock: sdk.ZeroInt(), MuirGlacierBlock: sdk.NewInt(-1),
YoloV2Block: sdk.NewInt(-1), YoloV2Block: sdk.NewInt(-1),
EWASMBlock: sdk.NewInt(-1), EWASMBlock: sdk.NewInt(-1),
} }
@ -125,13 +126,3 @@ func validateBlock(block sdk.Int) error {
return nil return nil
} }
// IsIstanbul returns whether the Istanbul version is enabled.
func (cc ChainConfig) IsIstanbul() bool {
return getBlockValue(cc.IstanbulBlock) != nil
}
// IsHomestead returns whether the Homestead version is enabled.
func (cc ChainConfig) IsHomestead() bool {
return getBlockValue(cc.HomesteadBlock) != nil
}

View File

@ -226,7 +226,7 @@ func TestChainConfigValidate(t *testing.T) {
} }
func TestChainConfig_String(t *testing.T) { func TestChainConfig_String(t *testing.T) {
configStr := `homestead_block:"0" dao_fork_block:"0" dao_fork_support:true eip150_block:"0" eip150_hash:"0x0000000000000000000000000000000000000000000000000000000000000000" eip155_block:"0" eip158_block:"0" byzantium_block:"0" constantinople_block:"0" petersburg_block:"0" istanbul_block:"-1" muir_glacier_block:"-1" yolo_v2_block:"-1" ewasm_block:"-1" `
config := DefaultChainConfig() config := DefaultChainConfig()
configStr := `homestead_block:"0" dao_fork_block:"0" dao_fork_support:true eip150_block:"0" eip150_hash:"0x0000000000000000000000000000000000000000000000000000000000000000" eip155_block:"0" eip158_block:"0" byzantium_block:"0" constantinople_block:"0" petersburg_block:"0" istanbul_block:"0" muir_glacier_block:"0" yolo_v2_block:"-1" ewasm_block:"-1" `
require.Equal(t, configStr, config.String()) require.Equal(t, configStr, config.String())
} }

Some files were not shown because too many files have changed in this diff Show More