From 9d49c4b9af6be1ef584331c1ff09a31061e5042f Mon Sep 17 00:00:00 2001 From: "M. J. Fromberger" Date: Thu, 21 Apr 2022 08:54:07 -0700 Subject: [PATCH 01/35] Add config samples from TM v26, v27, v28, v29. (#8384) --- scripts/confix/testdata/README.md | 52 +++++ scripts/confix/testdata/baseline.txt | 73 +++++++ scripts/confix/testdata/diff-26-27.txt | 0 scripts/confix/testdata/diff-27-28.txt | 3 + scripts/confix/testdata/diff-28-29.txt | 0 scripts/confix/testdata/diff-29-30.txt | 0 scripts/confix/testdata/v26-config.toml | 249 +++++++++++++++++++++++ scripts/confix/testdata/v27-config.toml | 249 +++++++++++++++++++++++ scripts/confix/testdata/v28-config.toml | 252 ++++++++++++++++++++++++ scripts/confix/testdata/v29-config.toml | 252 ++++++++++++++++++++++++ 10 files changed, 1130 insertions(+) create mode 100644 scripts/confix/testdata/README.md create mode 100644 scripts/confix/testdata/baseline.txt create mode 100644 scripts/confix/testdata/diff-26-27.txt create mode 100644 scripts/confix/testdata/diff-27-28.txt create mode 100644 scripts/confix/testdata/diff-28-29.txt create mode 100644 scripts/confix/testdata/diff-29-30.txt create mode 100644 scripts/confix/testdata/v26-config.toml create mode 100644 scripts/confix/testdata/v27-config.toml create mode 100644 scripts/confix/testdata/v28-config.toml create mode 100644 scripts/confix/testdata/v29-config.toml diff --git a/scripts/confix/testdata/README.md b/scripts/confix/testdata/README.md new file mode 100644 index 000000000..5bbfa795f --- /dev/null +++ b/scripts/confix/testdata/README.md @@ -0,0 +1,52 @@ +# Test data for `confix` and `condiff` + +The files in this directory are stock Tendermint configuration files generated +by the last point release of each version series from v0.26 to present, along +with diffs between consecutive versions. + +## Config Samples + +The files named `vXX-config.toml` were generated by checking out and building +the corresponding version of Tendermint v0.xx.y and initializing a new node in +an empty home directory. The resulting `config.toml` file was copied here. +The exact build instructions vary a bit, but a general repro looks like: + +```shell +# This example uses v0.31, substitute the version of your choice. +# Note that the branch names and tags may differ. +# Versions prior to v0.26 may not build. +git checkout v0.31.9 +git clean -fdx + +# Versions prior to v0.32 do not have Go module files. +# Those that do may need some dependencies manually updated. +go mod init github.com/tendermint/tendermint +go mod tidy +go get golang.org/x/sys + +# Once you sort out the dependencies, this should usually work. +make build + +# Confirm you go the version you expected, and generate the file. +./build/tendermint --home=tmhome version +./build/tendermint --home=tmhome init + +# Copy the file out. +cp ./tmhome/config/config.toml v31-config.toml +``` + +## Version Diffs + +The files named `diff-XX-YY.txt` were generated by using the `condiff` tool on +the config samples for versions v0.XX and v0.YY: + +```shell +go run ./scripts/confix/condiff -desnake vXX-config vYY-config.toml > diff-XX-YY.txt +``` + +The `baseline.txt` was computed in the same way, but using an empty starting +file so that we capture all the settings in the target: + +```shell +go run ./scripts/confix/condiff -desnake /dev/null v26-config.toml > baseline.txt +``` diff --git a/scripts/confix/testdata/baseline.txt b/scripts/confix/testdata/baseline.txt new file mode 100644 index 000000000..421343704 --- /dev/null +++ b/scripts/confix/testdata/baseline.txt @@ -0,0 +1,73 @@ ++M abci ++M db-backend ++M db-dir ++M fast-sync ++M filter-peers ++M genesis-file ++M log-format ++M log-level ++M moniker ++M node-key-file ++M priv-validator-file ++M priv-validator-laddr ++M prof-laddr ++M proxy-app ++S consensus ++M consensus.wal-file ++M consensus.timeout-propose ++M consensus.timeout-propose-delta ++M consensus.timeout-prevote ++M consensus.timeout-prevote-delta ++M consensus.timeout-precommit ++M consensus.timeout-precommit-delta ++M consensus.timeout-commit ++M consensus.skip-timeout-commit ++M consensus.create-empty-blocks ++M consensus.create-empty-blocks-interval ++M consensus.peer-gossip-sleep-duration ++M consensus.peer-query-maj23-sleep-duration ++M consensus.blocktime-iota ++S instrumentation ++M instrumentation.prometheus ++M instrumentation.prometheus-listen-addr ++M instrumentation.max-open-connections ++M instrumentation.namespace ++S mempool ++M mempool.recheck ++M mempool.broadcast ++M mempool.wal-dir ++M mempool.size ++M mempool.cache-size ++S p2p ++M p2p.laddr ++M p2p.external-address ++M p2p.seeds ++M p2p.persistent-peers ++M p2p.upnp ++M p2p.addr-book-file ++M p2p.addr-book-strict ++M p2p.max-num-inbound-peers ++M p2p.max-num-outbound-peers ++M p2p.flush-throttle-timeout ++M p2p.max-packet-msg-payload-size ++M p2p.send-rate ++M p2p.recv-rate ++M p2p.pex ++M p2p.seed-mode ++M p2p.private-peer-ids ++M p2p.allow-duplicate-ip ++M p2p.handshake-timeout ++M p2p.dial-timeout ++S rpc ++M rpc.laddr ++M rpc.cors-allowed-origins ++M rpc.cors-allowed-methods ++M rpc.cors-allowed-headers ++M rpc.grpc-laddr ++M rpc.grpc-max-open-connections ++M rpc.unsafe ++M rpc.max-open-connections ++S tx-index ++M tx-index.indexer ++M tx-index.index-tags ++M tx-index.index-all-tags diff --git a/scripts/confix/testdata/diff-26-27.txt b/scripts/confix/testdata/diff-26-27.txt new file mode 100644 index 000000000..e69de29bb diff --git a/scripts/confix/testdata/diff-27-28.txt b/scripts/confix/testdata/diff-27-28.txt new file mode 100644 index 000000000..c5c00449d --- /dev/null +++ b/scripts/confix/testdata/diff-27-28.txt @@ -0,0 +1,3 @@ +-M priv-validator-file ++M priv-validator-key-file ++M priv-validator-state-file diff --git a/scripts/confix/testdata/diff-28-29.txt b/scripts/confix/testdata/diff-28-29.txt new file mode 100644 index 000000000..e69de29bb diff --git a/scripts/confix/testdata/diff-29-30.txt b/scripts/confix/testdata/diff-29-30.txt new file mode 100644 index 000000000..e69de29bb diff --git a/scripts/confix/testdata/v26-config.toml b/scripts/confix/testdata/v26-config.toml new file mode 100644 index 000000000..a9237056b --- /dev/null +++ b/scripts/confix/testdata/v26-config.toml @@ -0,0 +1,249 @@ +# This is a TOML config file. +# For more information, see https://github.com/toml-lang/toml + +##### main base config options ##### + +# TCP or UNIX socket address of the ABCI application, +# or the name of an ABCI application compiled in with the Tendermint binary +proxy_app = "tcp://127.0.0.1:26658" + +# A custom human readable name for this node +moniker = "localhost" + +# If this node is many blocks behind the tip of the chain, FastSync +# allows them to catchup quickly by downloading blocks in parallel +# and verifying their commits +fast_sync = true + +# Database backend: leveldb | memdb | cleveldb +db_backend = "leveldb" + +# Database directory +db_dir = "data" + +# Output level for logging, including package level options +log_level = "main:info,state:info,*:error" + +# Output format: 'plain' (colored text) or 'json' +log_format = "plain" + +##### additional base config options ##### + +# Path to the JSON file containing the initial validator set and other meta data +genesis_file = "config/genesis.json" + +# Path to the JSON file containing the private key to use as a validator in the consensus protocol +priv_validator_file = "config/priv_validator.json" + +# TCP or UNIX socket address for Tendermint to listen on for +# connections from an external PrivValidator process +priv_validator_laddr = "" + +# Path to the JSON file containing the private key to use for node authentication in the p2p protocol +node_key_file = "config/node_key.json" + +# Mechanism to connect to the ABCI application: socket | grpc +abci = "socket" + +# TCP or UNIX socket address for the profiling server to listen on +prof_laddr = "" + +# If true, query the ABCI app on connecting to a new peer +# so the app can decide if we should keep the connection or not +filter_peers = false + +##### advanced configuration options ##### + +##### rpc server configuration options ##### +[rpc] + +# TCP or UNIX socket address for the RPC server to listen on +laddr = "tcp://0.0.0.0:26657" + +# A list of origins a cross-domain request can be executed from +# Default value '[]' disables cors support +# Use '["*"]' to allow any origin +cors_allowed_origins = "[]" + +# A list of methods the client is allowed to use with cross-domain requests +cors_allowed_methods = "[HEAD GET POST]" + +# A list of non simple headers the client is allowed to use with cross-domain requests +cors_allowed_headers = "[Origin Accept Content-Type X-Requested-With X-Server-Time]" + +# TCP or UNIX socket address for the gRPC server to listen on +# NOTE: This server only supports /broadcast_tx_commit +grpc_laddr = "" + +# Maximum number of simultaneous connections. +# Does not include RPC (HTTP&WebSocket) connections. See max_open_connections +# If you want to accept more significant number than the default, make sure +# you increase your OS limits. +# 0 - unlimited. +# Should be < {ulimit -Sn} - {MaxNumInboundPeers} - {MaxNumOutboundPeers} - {N of wal, db and other open files} +# 1024 - 40 - 10 - 50 = 924 = ~900 +grpc_max_open_connections = 900 + +# Activate unsafe RPC commands like /dial_seeds and /unsafe_flush_mempool +unsafe = false + +# Maximum number of simultaneous connections (including WebSocket). +# Does not include gRPC connections. See grpc_max_open_connections +# If you want to accept more significant number than the default, make sure +# you increase your OS limits. +# 0 - unlimited. +# Should be < {ulimit -Sn} - {MaxNumInboundPeers} - {MaxNumOutboundPeers} - {N of wal, db and other open files} +# 1024 - 40 - 10 - 50 = 924 = ~900 +max_open_connections = 900 + +##### peer to peer configuration options ##### +[p2p] + +# Address to listen for incoming connections +laddr = "tcp://0.0.0.0:26656" + +# Address to advertise to peers for them to dial +# If empty, will use the same port as the laddr, +# and will introspect on the listener or use UPnP +# to figure out the address. +external_address = "" + +# Comma separated list of seed nodes to connect to +seeds = "" + +# Comma separated list of nodes to keep persistent connections to +persistent_peers = "" + +# UPNP port forwarding +upnp = false + +# Path to address book +addr_book_file = "config/addrbook.json" + +# Set true for strict address routability rules +# Set false for private or local networks +addr_book_strict = true + +# Maximum number of inbound peers +max_num_inbound_peers = 40 + +# Maximum number of outbound peers to connect to, excluding persistent peers +max_num_outbound_peers = 10 + +# Time to wait before flushing messages out on the connection +flush_throttle_timeout = "100ms" + +# Maximum size of a message packet payload, in bytes +max_packet_msg_payload_size = 1024 + +# Rate at which packets can be sent, in bytes/second +send_rate = 5120000 + +# Rate at which packets can be received, in bytes/second +recv_rate = 5120000 + +# Set true to enable the peer-exchange reactor +pex = true + +# Seed mode, in which node constantly crawls the network and looks for +# peers. If another node asks it for addresses, it responds and disconnects. +# +# Does not work if the peer-exchange reactor is disabled. +seed_mode = false + +# Comma separated list of peer IDs to keep private (will not be gossiped to other peers) +private_peer_ids = "" + +# Toggle to disable guard against peers connecting from the same ip. +allow_duplicate_ip = true + +# Peer connection configuration. +handshake_timeout = "20s" +dial_timeout = "3s" + +##### mempool configuration options ##### +[mempool] + +recheck = true +broadcast = true +wal_dir = "" + +# size of the mempool +size = 5000 + +# size of the cache (used to filter transactions we saw earlier) +cache_size = 10000 + +##### consensus configuration options ##### +[consensus] + +wal_file = "data/cs.wal/wal" + +timeout_propose = "3s" +timeout_propose_delta = "500ms" +timeout_prevote = "1s" +timeout_prevote_delta = "500ms" +timeout_precommit = "1s" +timeout_precommit_delta = "500ms" +timeout_commit = "1s" + +# Make progress as soon as we have all the precommits (as if TimeoutCommit = 0) +skip_timeout_commit = false + +# EmptyBlocks mode and possible interval between empty blocks +create_empty_blocks = true +create_empty_blocks_interval = "0s" + +# Reactor sleep duration parameters +peer_gossip_sleep_duration = "100ms" +peer_query_maj23_sleep_duration = "2s" + +# Block time parameters. Corresponds to the minimum time increment between consecutive blocks. +blocktime_iota = "1s" + +##### transactions indexer configuration options ##### +[tx_index] + +# What indexer to use for transactions +# +# Options: +# 1) "null" (default) +# 2) "kv" - the simplest possible indexer, backed by key-value storage (defaults to levelDB; see DBBackend). +indexer = "kv" + +# Comma-separated list of tags to index (by default the only tag is "tx.hash") +# +# You can also index transactions by height by adding "tx.height" tag here. +# +# It's recommended to index only a subset of tags due to possible memory +# bloat. This is, of course, depends on the indexer's DB and the volume of +# transactions. +index_tags = "" + +# When set to true, tells indexer to index all tags (predefined tags: +# "tx.hash", "tx.height" and all tags from DeliverTx responses). +# +# Note this may be not desirable (see the comment above). IndexTags has a +# precedence over IndexAllTags (i.e. when given both, IndexTags will be +# indexed). +index_all_tags = false + +##### instrumentation configuration options ##### +[instrumentation] + +# When true, Prometheus metrics are served under /metrics on +# PrometheusListenAddr. +# Check out the documentation for the list of available metrics. +prometheus = false + +# Address to listen for Prometheus collector(s) connections +prometheus_listen_addr = ":26660" + +# Maximum number of simultaneous connections. +# If you want to accept more significant number than the default, make sure +# you increase your OS limits. +# 0 - unlimited. +max_open_connections = 3 + +# Instrumentation namespace +namespace = "tendermint" diff --git a/scripts/confix/testdata/v27-config.toml b/scripts/confix/testdata/v27-config.toml new file mode 100644 index 000000000..25e3b582f --- /dev/null +++ b/scripts/confix/testdata/v27-config.toml @@ -0,0 +1,249 @@ +# This is a TOML config file. +# For more information, see https://github.com/toml-lang/toml + +##### main base config options ##### + +# TCP or UNIX socket address of the ABCI application, +# or the name of an ABCI application compiled in with the Tendermint binary +proxy_app = "tcp://127.0.0.1:26658" + +# A custom human readable name for this node +moniker = "localhost" + +# If this node is many blocks behind the tip of the chain, FastSync +# allows them to catchup quickly by downloading blocks in parallel +# and verifying their commits +fast_sync = true + +# Database backend: leveldb | memdb | cleveldb +db_backend = "leveldb" + +# Database directory +db_dir = "data" + +# Output level for logging, including package level options +log_level = "main:info,state:info,*:error" + +# Output format: 'plain' (colored text) or 'json' +log_format = "plain" + +##### additional base config options ##### + +# Path to the JSON file containing the initial validator set and other meta data +genesis_file = "config/genesis.json" + +# Path to the JSON file containing the private key to use as a validator in the consensus protocol +priv_validator_file = "config/priv_validator.json" + +# TCP or UNIX socket address for Tendermint to listen on for +# connections from an external PrivValidator process +priv_validator_laddr = "" + +# Path to the JSON file containing the private key to use for node authentication in the p2p protocol +node_key_file = "config/node_key.json" + +# Mechanism to connect to the ABCI application: socket | grpc +abci = "socket" + +# TCP or UNIX socket address for the profiling server to listen on +prof_laddr = "" + +# If true, query the ABCI app on connecting to a new peer +# so the app can decide if we should keep the connection or not +filter_peers = false + +##### advanced configuration options ##### + +##### rpc server configuration options ##### +[rpc] + +# TCP or UNIX socket address for the RPC server to listen on +laddr = "tcp://0.0.0.0:26657" + +# A list of origins a cross-domain request can be executed from +# Default value '[]' disables cors support +# Use '["*"]' to allow any origin +cors_allowed_origins = [] + +# A list of methods the client is allowed to use with cross-domain requests +cors_allowed_methods = ["HEAD", "GET", "POST", ] + +# A list of non simple headers the client is allowed to use with cross-domain requests +cors_allowed_headers = ["Origin", "Accept", "Content-Type", "X-Requested-With", "X-Server-Time", ] + +# TCP or UNIX socket address for the gRPC server to listen on +# NOTE: This server only supports /broadcast_tx_commit +grpc_laddr = "" + +# Maximum number of simultaneous connections. +# Does not include RPC (HTTP&WebSocket) connections. See max_open_connections +# If you want to accept a larger number than the default, make sure +# you increase your OS limits. +# 0 - unlimited. +# Should be < {ulimit -Sn} - {MaxNumInboundPeers} - {MaxNumOutboundPeers} - {N of wal, db and other open files} +# 1024 - 40 - 10 - 50 = 924 = ~900 +grpc_max_open_connections = 900 + +# Activate unsafe RPC commands like /dial_seeds and /unsafe_flush_mempool +unsafe = false + +# Maximum number of simultaneous connections (including WebSocket). +# Does not include gRPC connections. See grpc_max_open_connections +# If you want to accept a larger number than the default, make sure +# you increase your OS limits. +# 0 - unlimited. +# Should be < {ulimit -Sn} - {MaxNumInboundPeers} - {MaxNumOutboundPeers} - {N of wal, db and other open files} +# 1024 - 40 - 10 - 50 = 924 = ~900 +max_open_connections = 900 + +##### peer to peer configuration options ##### +[p2p] + +# Address to listen for incoming connections +laddr = "tcp://0.0.0.0:26656" + +# Address to advertise to peers for them to dial +# If empty, will use the same port as the laddr, +# and will introspect on the listener or use UPnP +# to figure out the address. +external_address = "" + +# Comma separated list of seed nodes to connect to +seeds = "" + +# Comma separated list of nodes to keep persistent connections to +persistent_peers = "" + +# UPNP port forwarding +upnp = false + +# Path to address book +addr_book_file = "config/addrbook.json" + +# Set true for strict address routability rules +# Set false for private or local networks +addr_book_strict = true + +# Maximum number of inbound peers +max_num_inbound_peers = 40 + +# Maximum number of outbound peers to connect to, excluding persistent peers +max_num_outbound_peers = 10 + +# Time to wait before flushing messages out on the connection +flush_throttle_timeout = "100ms" + +# Maximum size of a message packet payload, in bytes +max_packet_msg_payload_size = 1024 + +# Rate at which packets can be sent, in bytes/second +send_rate = 5120000 + +# Rate at which packets can be received, in bytes/second +recv_rate = 5120000 + +# Set true to enable the peer-exchange reactor +pex = true + +# Seed mode, in which node constantly crawls the network and looks for +# peers. If another node asks it for addresses, it responds and disconnects. +# +# Does not work if the peer-exchange reactor is disabled. +seed_mode = false + +# Comma separated list of peer IDs to keep private (will not be gossiped to other peers) +private_peer_ids = "" + +# Toggle to disable guard against peers connecting from the same ip. +allow_duplicate_ip = true + +# Peer connection configuration. +handshake_timeout = "20s" +dial_timeout = "3s" + +##### mempool configuration options ##### +[mempool] + +recheck = true +broadcast = true +wal_dir = "" + +# size of the mempool +size = 5000 + +# size of the cache (used to filter transactions we saw earlier) +cache_size = 10000 + +##### consensus configuration options ##### +[consensus] + +wal_file = "data/cs.wal/wal" + +timeout_propose = "3s" +timeout_propose_delta = "500ms" +timeout_prevote = "1s" +timeout_prevote_delta = "500ms" +timeout_precommit = "1s" +timeout_precommit_delta = "500ms" +timeout_commit = "1s" + +# Make progress as soon as we have all the precommits (as if TimeoutCommit = 0) +skip_timeout_commit = false + +# EmptyBlocks mode and possible interval between empty blocks +create_empty_blocks = true +create_empty_blocks_interval = "0s" + +# Reactor sleep duration parameters +peer_gossip_sleep_duration = "100ms" +peer_query_maj23_sleep_duration = "2s" + +# Block time parameters. Corresponds to the minimum time increment between consecutive blocks. +blocktime_iota = "1s" + +##### transactions indexer configuration options ##### +[tx_index] + +# What indexer to use for transactions +# +# Options: +# 1) "null" +# 2) "kv" (default) - the simplest possible indexer, backed by key-value storage (defaults to levelDB; see DBBackend). +indexer = "kv" + +# Comma-separated list of tags to index (by default the only tag is "tx.hash") +# +# You can also index transactions by height by adding "tx.height" tag here. +# +# It's recommended to index only a subset of tags due to possible memory +# bloat. This is, of course, depends on the indexer's DB and the volume of +# transactions. +index_tags = "" + +# When set to true, tells indexer to index all tags (predefined tags: +# "tx.hash", "tx.height" and all tags from DeliverTx responses). +# +# Note this may be not desirable (see the comment above). IndexTags has a +# precedence over IndexAllTags (i.e. when given both, IndexTags will be +# indexed). +index_all_tags = false + +##### instrumentation configuration options ##### +[instrumentation] + +# When true, Prometheus metrics are served under /metrics on +# PrometheusListenAddr. +# Check out the documentation for the list of available metrics. +prometheus = false + +# Address to listen for Prometheus collector(s) connections +prometheus_listen_addr = ":26660" + +# Maximum number of simultaneous connections. +# If you want to accept a larger number than the default, make sure +# you increase your OS limits. +# 0 - unlimited. +max_open_connections = 3 + +# Instrumentation namespace +namespace = "tendermint" diff --git a/scripts/confix/testdata/v28-config.toml b/scripts/confix/testdata/v28-config.toml new file mode 100644 index 000000000..b4aaa5aae --- /dev/null +++ b/scripts/confix/testdata/v28-config.toml @@ -0,0 +1,252 @@ +# This is a TOML config file. +# For more information, see https://github.com/toml-lang/toml + +##### main base config options ##### + +# TCP or UNIX socket address of the ABCI application, +# or the name of an ABCI application compiled in with the Tendermint binary +proxy_app = "tcp://127.0.0.1:26658" + +# A custom human readable name for this node +moniker = "localhost" + +# If this node is many blocks behind the tip of the chain, FastSync +# allows them to catchup quickly by downloading blocks in parallel +# and verifying their commits +fast_sync = true + +# Database backend: leveldb | memdb | cleveldb +db_backend = "leveldb" + +# Database directory +db_dir = "data" + +# Output level for logging, including package level options +log_level = "main:info,state:info,*:error" + +# Output format: 'plain' (colored text) or 'json' +log_format = "plain" + +##### additional base config options ##### + +# Path to the JSON file containing the initial validator set and other meta data +genesis_file = "config/genesis.json" + +# Path to the JSON file containing the private key to use as a validator in the consensus protocol +priv_validator_key_file = "config/priv_validator_key.json" + +# Path to the JSON file containing the last sign state of a validator +priv_validator_state_file = "data/priv_validator_state.json" + +# TCP or UNIX socket address for Tendermint to listen on for +# connections from an external PrivValidator process +priv_validator_laddr = "" + +# Path to the JSON file containing the private key to use for node authentication in the p2p protocol +node_key_file = "config/node_key.json" + +# Mechanism to connect to the ABCI application: socket | grpc +abci = "socket" + +# TCP or UNIX socket address for the profiling server to listen on +prof_laddr = "" + +# If true, query the ABCI app on connecting to a new peer +# so the app can decide if we should keep the connection or not +filter_peers = false + +##### advanced configuration options ##### + +##### rpc server configuration options ##### +[rpc] + +# TCP or UNIX socket address for the RPC server to listen on +laddr = "tcp://0.0.0.0:26657" + +# A list of origins a cross-domain request can be executed from +# Default value '[]' disables cors support +# Use '["*"]' to allow any origin +cors_allowed_origins = [] + +# A list of methods the client is allowed to use with cross-domain requests +cors_allowed_methods = ["HEAD", "GET", "POST", ] + +# A list of non simple headers the client is allowed to use with cross-domain requests +cors_allowed_headers = ["Origin", "Accept", "Content-Type", "X-Requested-With", "X-Server-Time", ] + +# TCP or UNIX socket address for the gRPC server to listen on +# NOTE: This server only supports /broadcast_tx_commit +grpc_laddr = "" + +# Maximum number of simultaneous connections. +# Does not include RPC (HTTP&WebSocket) connections. See max_open_connections +# If you want to accept a larger number than the default, make sure +# you increase your OS limits. +# 0 - unlimited. +# Should be < {ulimit -Sn} - {MaxNumInboundPeers} - {MaxNumOutboundPeers} - {N of wal, db and other open files} +# 1024 - 40 - 10 - 50 = 924 = ~900 +grpc_max_open_connections = 900 + +# Activate unsafe RPC commands like /dial_seeds and /unsafe_flush_mempool +unsafe = false + +# Maximum number of simultaneous connections (including WebSocket). +# Does not include gRPC connections. See grpc_max_open_connections +# If you want to accept a larger number than the default, make sure +# you increase your OS limits. +# 0 - unlimited. +# Should be < {ulimit -Sn} - {MaxNumInboundPeers} - {MaxNumOutboundPeers} - {N of wal, db and other open files} +# 1024 - 40 - 10 - 50 = 924 = ~900 +max_open_connections = 900 + +##### peer to peer configuration options ##### +[p2p] + +# Address to listen for incoming connections +laddr = "tcp://0.0.0.0:26656" + +# Address to advertise to peers for them to dial +# If empty, will use the same port as the laddr, +# and will introspect on the listener or use UPnP +# to figure out the address. +external_address = "" + +# Comma separated list of seed nodes to connect to +seeds = "" + +# Comma separated list of nodes to keep persistent connections to +persistent_peers = "" + +# UPNP port forwarding +upnp = false + +# Path to address book +addr_book_file = "config/addrbook.json" + +# Set true for strict address routability rules +# Set false for private or local networks +addr_book_strict = true + +# Maximum number of inbound peers +max_num_inbound_peers = 40 + +# Maximum number of outbound peers to connect to, excluding persistent peers +max_num_outbound_peers = 10 + +# Time to wait before flushing messages out on the connection +flush_throttle_timeout = "100ms" + +# Maximum size of a message packet payload, in bytes +max_packet_msg_payload_size = 1024 + +# Rate at which packets can be sent, in bytes/second +send_rate = 5120000 + +# Rate at which packets can be received, in bytes/second +recv_rate = 5120000 + +# Set true to enable the peer-exchange reactor +pex = true + +# Seed mode, in which node constantly crawls the network and looks for +# peers. If another node asks it for addresses, it responds and disconnects. +# +# Does not work if the peer-exchange reactor is disabled. +seed_mode = false + +# Comma separated list of peer IDs to keep private (will not be gossiped to other peers) +private_peer_ids = "" + +# Toggle to disable guard against peers connecting from the same ip. +allow_duplicate_ip = false + +# Peer connection configuration. +handshake_timeout = "20s" +dial_timeout = "3s" + +##### mempool configuration options ##### +[mempool] + +recheck = true +broadcast = true +wal_dir = "" + +# size of the mempool +size = 5000 + +# size of the cache (used to filter transactions we saw earlier) +cache_size = 10000 + +##### consensus configuration options ##### +[consensus] + +wal_file = "data/cs.wal/wal" + +timeout_propose = "3s" +timeout_propose_delta = "500ms" +timeout_prevote = "1s" +timeout_prevote_delta = "500ms" +timeout_precommit = "1s" +timeout_precommit_delta = "500ms" +timeout_commit = "1s" + +# Make progress as soon as we have all the precommits (as if TimeoutCommit = 0) +skip_timeout_commit = false + +# EmptyBlocks mode and possible interval between empty blocks +create_empty_blocks = true +create_empty_blocks_interval = "0s" + +# Reactor sleep duration parameters +peer_gossip_sleep_duration = "100ms" +peer_query_maj23_sleep_duration = "2s" + +# Block time parameters. Corresponds to the minimum time increment between consecutive blocks. +blocktime_iota = "1s" + +##### transactions indexer configuration options ##### +[tx_index] + +# What indexer to use for transactions +# +# Options: +# 1) "null" +# 2) "kv" (default) - the simplest possible indexer, backed by key-value storage (defaults to levelDB; see DBBackend). +indexer = "kv" + +# Comma-separated list of tags to index (by default the only tag is "tx.hash") +# +# You can also index transactions by height by adding "tx.height" tag here. +# +# It's recommended to index only a subset of tags due to possible memory +# bloat. This is, of course, depends on the indexer's DB and the volume of +# transactions. +index_tags = "" + +# When set to true, tells indexer to index all tags (predefined tags: +# "tx.hash", "tx.height" and all tags from DeliverTx responses). +# +# Note this may be not desirable (see the comment above). IndexTags has a +# precedence over IndexAllTags (i.e. when given both, IndexTags will be +# indexed). +index_all_tags = false + +##### instrumentation configuration options ##### +[instrumentation] + +# When true, Prometheus metrics are served under /metrics on +# PrometheusListenAddr. +# Check out the documentation for the list of available metrics. +prometheus = false + +# Address to listen for Prometheus collector(s) connections +prometheus_listen_addr = ":26660" + +# Maximum number of simultaneous connections. +# If you want to accept a larger number than the default, make sure +# you increase your OS limits. +# 0 - unlimited. +max_open_connections = 3 + +# Instrumentation namespace +namespace = "tendermint" diff --git a/scripts/confix/testdata/v29-config.toml b/scripts/confix/testdata/v29-config.toml new file mode 100644 index 000000000..b4aaa5aae --- /dev/null +++ b/scripts/confix/testdata/v29-config.toml @@ -0,0 +1,252 @@ +# This is a TOML config file. +# For more information, see https://github.com/toml-lang/toml + +##### main base config options ##### + +# TCP or UNIX socket address of the ABCI application, +# or the name of an ABCI application compiled in with the Tendermint binary +proxy_app = "tcp://127.0.0.1:26658" + +# A custom human readable name for this node +moniker = "localhost" + +# If this node is many blocks behind the tip of the chain, FastSync +# allows them to catchup quickly by downloading blocks in parallel +# and verifying their commits +fast_sync = true + +# Database backend: leveldb | memdb | cleveldb +db_backend = "leveldb" + +# Database directory +db_dir = "data" + +# Output level for logging, including package level options +log_level = "main:info,state:info,*:error" + +# Output format: 'plain' (colored text) or 'json' +log_format = "plain" + +##### additional base config options ##### + +# Path to the JSON file containing the initial validator set and other meta data +genesis_file = "config/genesis.json" + +# Path to the JSON file containing the private key to use as a validator in the consensus protocol +priv_validator_key_file = "config/priv_validator_key.json" + +# Path to the JSON file containing the last sign state of a validator +priv_validator_state_file = "data/priv_validator_state.json" + +# TCP or UNIX socket address for Tendermint to listen on for +# connections from an external PrivValidator process +priv_validator_laddr = "" + +# Path to the JSON file containing the private key to use for node authentication in the p2p protocol +node_key_file = "config/node_key.json" + +# Mechanism to connect to the ABCI application: socket | grpc +abci = "socket" + +# TCP or UNIX socket address for the profiling server to listen on +prof_laddr = "" + +# If true, query the ABCI app on connecting to a new peer +# so the app can decide if we should keep the connection or not +filter_peers = false + +##### advanced configuration options ##### + +##### rpc server configuration options ##### +[rpc] + +# TCP or UNIX socket address for the RPC server to listen on +laddr = "tcp://0.0.0.0:26657" + +# A list of origins a cross-domain request can be executed from +# Default value '[]' disables cors support +# Use '["*"]' to allow any origin +cors_allowed_origins = [] + +# A list of methods the client is allowed to use with cross-domain requests +cors_allowed_methods = ["HEAD", "GET", "POST", ] + +# A list of non simple headers the client is allowed to use with cross-domain requests +cors_allowed_headers = ["Origin", "Accept", "Content-Type", "X-Requested-With", "X-Server-Time", ] + +# TCP or UNIX socket address for the gRPC server to listen on +# NOTE: This server only supports /broadcast_tx_commit +grpc_laddr = "" + +# Maximum number of simultaneous connections. +# Does not include RPC (HTTP&WebSocket) connections. See max_open_connections +# If you want to accept a larger number than the default, make sure +# you increase your OS limits. +# 0 - unlimited. +# Should be < {ulimit -Sn} - {MaxNumInboundPeers} - {MaxNumOutboundPeers} - {N of wal, db and other open files} +# 1024 - 40 - 10 - 50 = 924 = ~900 +grpc_max_open_connections = 900 + +# Activate unsafe RPC commands like /dial_seeds and /unsafe_flush_mempool +unsafe = false + +# Maximum number of simultaneous connections (including WebSocket). +# Does not include gRPC connections. See grpc_max_open_connections +# If you want to accept a larger number than the default, make sure +# you increase your OS limits. +# 0 - unlimited. +# Should be < {ulimit -Sn} - {MaxNumInboundPeers} - {MaxNumOutboundPeers} - {N of wal, db and other open files} +# 1024 - 40 - 10 - 50 = 924 = ~900 +max_open_connections = 900 + +##### peer to peer configuration options ##### +[p2p] + +# Address to listen for incoming connections +laddr = "tcp://0.0.0.0:26656" + +# Address to advertise to peers for them to dial +# If empty, will use the same port as the laddr, +# and will introspect on the listener or use UPnP +# to figure out the address. +external_address = "" + +# Comma separated list of seed nodes to connect to +seeds = "" + +# Comma separated list of nodes to keep persistent connections to +persistent_peers = "" + +# UPNP port forwarding +upnp = false + +# Path to address book +addr_book_file = "config/addrbook.json" + +# Set true for strict address routability rules +# Set false for private or local networks +addr_book_strict = true + +# Maximum number of inbound peers +max_num_inbound_peers = 40 + +# Maximum number of outbound peers to connect to, excluding persistent peers +max_num_outbound_peers = 10 + +# Time to wait before flushing messages out on the connection +flush_throttle_timeout = "100ms" + +# Maximum size of a message packet payload, in bytes +max_packet_msg_payload_size = 1024 + +# Rate at which packets can be sent, in bytes/second +send_rate = 5120000 + +# Rate at which packets can be received, in bytes/second +recv_rate = 5120000 + +# Set true to enable the peer-exchange reactor +pex = true + +# Seed mode, in which node constantly crawls the network and looks for +# peers. If another node asks it for addresses, it responds and disconnects. +# +# Does not work if the peer-exchange reactor is disabled. +seed_mode = false + +# Comma separated list of peer IDs to keep private (will not be gossiped to other peers) +private_peer_ids = "" + +# Toggle to disable guard against peers connecting from the same ip. +allow_duplicate_ip = false + +# Peer connection configuration. +handshake_timeout = "20s" +dial_timeout = "3s" + +##### mempool configuration options ##### +[mempool] + +recheck = true +broadcast = true +wal_dir = "" + +# size of the mempool +size = 5000 + +# size of the cache (used to filter transactions we saw earlier) +cache_size = 10000 + +##### consensus configuration options ##### +[consensus] + +wal_file = "data/cs.wal/wal" + +timeout_propose = "3s" +timeout_propose_delta = "500ms" +timeout_prevote = "1s" +timeout_prevote_delta = "500ms" +timeout_precommit = "1s" +timeout_precommit_delta = "500ms" +timeout_commit = "1s" + +# Make progress as soon as we have all the precommits (as if TimeoutCommit = 0) +skip_timeout_commit = false + +# EmptyBlocks mode and possible interval between empty blocks +create_empty_blocks = true +create_empty_blocks_interval = "0s" + +# Reactor sleep duration parameters +peer_gossip_sleep_duration = "100ms" +peer_query_maj23_sleep_duration = "2s" + +# Block time parameters. Corresponds to the minimum time increment between consecutive blocks. +blocktime_iota = "1s" + +##### transactions indexer configuration options ##### +[tx_index] + +# What indexer to use for transactions +# +# Options: +# 1) "null" +# 2) "kv" (default) - the simplest possible indexer, backed by key-value storage (defaults to levelDB; see DBBackend). +indexer = "kv" + +# Comma-separated list of tags to index (by default the only tag is "tx.hash") +# +# You can also index transactions by height by adding "tx.height" tag here. +# +# It's recommended to index only a subset of tags due to possible memory +# bloat. This is, of course, depends on the indexer's DB and the volume of +# transactions. +index_tags = "" + +# When set to true, tells indexer to index all tags (predefined tags: +# "tx.hash", "tx.height" and all tags from DeliverTx responses). +# +# Note this may be not desirable (see the comment above). IndexTags has a +# precedence over IndexAllTags (i.e. when given both, IndexTags will be +# indexed). +index_all_tags = false + +##### instrumentation configuration options ##### +[instrumentation] + +# When true, Prometheus metrics are served under /metrics on +# PrometheusListenAddr. +# Check out the documentation for the list of available metrics. +prometheus = false + +# Address to listen for Prometheus collector(s) connections +prometheus_listen_addr = ":26660" + +# Maximum number of simultaneous connections. +# If you want to accept a larger number than the default, make sure +# you increase your OS limits. +# 0 - unlimited. +max_open_connections = 3 + +# Instrumentation namespace +namespace = "tendermint" From f0db0ff26010d1192b5bd6a257d1dbbf196eff61 Mon Sep 17 00:00:00 2001 From: Sam Kleinman Date: Thu, 21 Apr 2022 12:21:11 -0400 Subject: [PATCH 02/35] abci: streamline grpc application construction (#8383) In my mind this is "don't make grpc any weirder than it has to be." We definitely don't need to export this type: if you're using gRPC for ABCI you *probably* don't want to also depend on the huge swath of the code that The ideal case is you generate the proto yourself, standup a gRPC service on your own (presumably because your application has other gRPC services that you want to expose,) and then your application doesn't need to interact with the types package at all. This is definitely the case for anyone who uses gRPC and doesn't use Go (which is likely the predominant use case.) If you're using Go, and want to use tendermint's service runner for running your gRPC service, you can, but at this point (as before,) you're already importing the `types` package (and you were before,) I've just eliminated an intermediate type that you shouldn't need to think about. Reviewers: I think the change is pretty rote, but the logic/user-story above would definitely be better for being validated by someone other than me. :) --- abci/example/example_test.go | 4 +- abci/example/kvstore/kvstore_test.go | 3 +- abci/server/grpc_server.go | 91 +++++++++++++++++++++++- abci/server/server.go | 2 +- abci/types/application.go | 102 --------------------------- 5 files changed, 92 insertions(+), 110 deletions(-) diff --git a/abci/example/example_test.go b/abci/example/example_test.go index 9d9d1548f..6da090e9d 100644 --- a/abci/example/example_test.go +++ b/abci/example/example_test.go @@ -53,7 +53,7 @@ func TestGRPC(t *testing.T) { logger := log.NewNopLogger() t.Log("### Testing GRPC") - testGRPCSync(ctx, t, logger, types.NewGRPCApplication(types.NewBaseApplication())) + testGRPCSync(ctx, t, logger, types.NewBaseApplication()) } func testBulk(ctx context.Context, t *testing.T, logger log.Logger, app types.Application) { @@ -101,7 +101,7 @@ func dialerFunc(ctx context.Context, addr string) (net.Conn, error) { return tmnet.Connect(addr) } -func testGRPCSync(ctx context.Context, t *testing.T, logger log.Logger, app types.ABCIApplicationServer) { +func testGRPCSync(ctx context.Context, t *testing.T, logger log.Logger, app types.Application) { t.Helper() numDeliverTxs := 680000 socketFile := fmt.Sprintf("/tmp/test-%08x.sock", rand.Int31n(1<<30)) diff --git a/abci/example/kvstore/kvstore_test.go b/abci/example/kvstore/kvstore_test.go index 0b62bbc61..482e3d691 100644 --- a/abci/example/kvstore/kvstore_test.go +++ b/abci/example/kvstore/kvstore_test.go @@ -260,8 +260,7 @@ func makeGRPCClientServer( // Start the listener socket := fmt.Sprintf("unix://%s.sock", name) - gapp := types.NewGRPCApplication(app) - server := abciserver.NewGRPCServer(logger.With("module", "abci-server"), socket, gapp) + server := abciserver.NewGRPCServer(logger.With("module", "abci-server"), socket, app) if err := server.Start(ctx); err != nil { cancel() diff --git a/abci/server/grpc_server.go b/abci/server/grpc_server.go index c1446d17a..f3d454435 100644 --- a/abci/server/grpc_server.go +++ b/abci/server/grpc_server.go @@ -20,11 +20,11 @@ type GRPCServer struct { addr string server *grpc.Server - app types.ABCIApplicationServer + app types.Application } // NewGRPCServer returns a new gRPC ABCI server -func NewGRPCServer(logger log.Logger, protoAddr string, app types.ABCIApplicationServer) service.Service { +func NewGRPCServer(logger log.Logger, protoAddr string, app types.Application) service.Service { proto, addr := tmnet.ProtocolAndAddress(protoAddr) s := &GRPCServer{ logger: logger, @@ -44,7 +44,7 @@ func (s *GRPCServer) OnStart(ctx context.Context) error { } s.server = grpc.NewServer() - types.RegisterABCIApplicationServer(s.server, s.app) + types.RegisterABCIApplicationServer(s.server, &gRPCApplication{app: s.app}) s.logger.Info("Listening", "proto", s.proto, "addr", s.addr) go func() { @@ -62,3 +62,88 @@ func (s *GRPCServer) OnStart(ctx context.Context) error { // OnStop stops the gRPC server. func (s *GRPCServer) OnStop() { s.server.Stop() } + +//------------------------------------------------------- + +// gRPCApplication is a gRPC shim for Application +type gRPCApplication struct { + app types.Application +} + +func (app *gRPCApplication) Echo(_ context.Context, req *types.RequestEcho) (*types.ResponseEcho, error) { + return &types.ResponseEcho{Message: req.Message}, nil +} + +func (app *gRPCApplication) Flush(_ context.Context, req *types.RequestFlush) (*types.ResponseFlush, error) { + return &types.ResponseFlush{}, nil +} + +func (app *gRPCApplication) Info(_ context.Context, req *types.RequestInfo) (*types.ResponseInfo, error) { + res := app.app.Info(*req) + return &res, nil +} + +func (app *gRPCApplication) CheckTx(_ context.Context, req *types.RequestCheckTx) (*types.ResponseCheckTx, error) { + res := app.app.CheckTx(*req) + return &res, nil +} + +func (app *gRPCApplication) Query(_ context.Context, req *types.RequestQuery) (*types.ResponseQuery, error) { + res := app.app.Query(*req) + return &res, nil +} + +func (app *gRPCApplication) Commit(_ context.Context, req *types.RequestCommit) (*types.ResponseCommit, error) { + res := app.app.Commit() + return &res, nil +} + +func (app *gRPCApplication) InitChain(_ context.Context, req *types.RequestInitChain) (*types.ResponseInitChain, error) { + res := app.app.InitChain(*req) + return &res, nil +} + +func (app *gRPCApplication) ListSnapshots(_ context.Context, req *types.RequestListSnapshots) (*types.ResponseListSnapshots, error) { + res := app.app.ListSnapshots(*req) + return &res, nil +} + +func (app *gRPCApplication) OfferSnapshot(_ context.Context, req *types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { + res := app.app.OfferSnapshot(*req) + return &res, nil +} + +func (app *gRPCApplication) LoadSnapshotChunk(_ context.Context, req *types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) { + res := app.app.LoadSnapshotChunk(*req) + return &res, nil +} + +func (app *gRPCApplication) ApplySnapshotChunk(_ context.Context, req *types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { + res := app.app.ApplySnapshotChunk(*req) + return &res, nil +} + +func (app *gRPCApplication) ExtendVote(_ context.Context, req *types.RequestExtendVote) (*types.ResponseExtendVote, error) { + res := app.app.ExtendVote(*req) + return &res, nil +} + +func (app *gRPCApplication) VerifyVoteExtension(_ context.Context, req *types.RequestVerifyVoteExtension) (*types.ResponseVerifyVoteExtension, error) { + res := app.app.VerifyVoteExtension(*req) + return &res, nil +} + +func (app *gRPCApplication) PrepareProposal(_ context.Context, req *types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) { + res := app.app.PrepareProposal(*req) + return &res, nil +} + +func (app *gRPCApplication) ProcessProposal(_ context.Context, req *types.RequestProcessProposal) (*types.ResponseProcessProposal, error) { + res := app.app.ProcessProposal(*req) + return &res, nil +} + +func (app *gRPCApplication) FinalizeBlock(_ context.Context, req *types.RequestFinalizeBlock) (*types.ResponseFinalizeBlock, error) { + res := app.app.FinalizeBlock(*req) + return &res, nil +} diff --git a/abci/server/server.go b/abci/server/server.go index 2a6d50fd2..0e0173ca6 100644 --- a/abci/server/server.go +++ b/abci/server/server.go @@ -23,7 +23,7 @@ func NewServer(logger log.Logger, protoAddr, transport string, app types.Applica case "socket": s = NewSocketServer(logger, protoAddr, app) case "grpc": - s = NewGRPCServer(logger, protoAddr, types.NewGRPCApplication(app)) + s = NewGRPCServer(logger, protoAddr, app) default: err = fmt.Errorf("unknown server type %s", transport) } diff --git a/abci/types/application.go b/abci/types/application.go index 959311e3b..067c0cdba 100644 --- a/abci/types/application.go +++ b/abci/types/application.go @@ -1,9 +1,5 @@ package types -import ( - "context" -) - //go:generate ../../scripts/mockery_generate.sh Application // Application is an interface that enables any finite, deterministic state machine // to be driven by a blockchain-based replication engine via the ABCI. @@ -123,101 +119,3 @@ func (BaseApplication) FinalizeBlock(req RequestFinalizeBlock) ResponseFinalizeB TxResults: txs, } } - -//------------------------------------------------------- - -// GRPCApplication is a GRPC wrapper for Application -type GRPCApplication struct { - app Application -} - -func NewGRPCApplication(app Application) *GRPCApplication { - return &GRPCApplication{app} -} - -func (app *GRPCApplication) Echo(ctx context.Context, req *RequestEcho) (*ResponseEcho, error) { - return &ResponseEcho{Message: req.Message}, nil -} - -func (app *GRPCApplication) Flush(ctx context.Context, req *RequestFlush) (*ResponseFlush, error) { - return &ResponseFlush{}, nil -} - -func (app *GRPCApplication) Info(ctx context.Context, req *RequestInfo) (*ResponseInfo, error) { - res := app.app.Info(*req) - return &res, nil -} - -func (app *GRPCApplication) CheckTx(ctx context.Context, req *RequestCheckTx) (*ResponseCheckTx, error) { - res := app.app.CheckTx(*req) - return &res, nil -} - -func (app *GRPCApplication) Query(ctx context.Context, req *RequestQuery) (*ResponseQuery, error) { - res := app.app.Query(*req) - return &res, nil -} - -func (app *GRPCApplication) Commit(ctx context.Context, req *RequestCommit) (*ResponseCommit, error) { - res := app.app.Commit() - return &res, nil -} - -func (app *GRPCApplication) InitChain(ctx context.Context, req *RequestInitChain) (*ResponseInitChain, error) { - res := app.app.InitChain(*req) - return &res, nil -} - -func (app *GRPCApplication) ListSnapshots( - ctx context.Context, req *RequestListSnapshots) (*ResponseListSnapshots, error) { - res := app.app.ListSnapshots(*req) - return &res, nil -} - -func (app *GRPCApplication) OfferSnapshot( - ctx context.Context, req *RequestOfferSnapshot) (*ResponseOfferSnapshot, error) { - res := app.app.OfferSnapshot(*req) - return &res, nil -} - -func (app *GRPCApplication) LoadSnapshotChunk( - ctx context.Context, req *RequestLoadSnapshotChunk) (*ResponseLoadSnapshotChunk, error) { - res := app.app.LoadSnapshotChunk(*req) - return &res, nil -} - -func (app *GRPCApplication) ApplySnapshotChunk( - ctx context.Context, req *RequestApplySnapshotChunk) (*ResponseApplySnapshotChunk, error) { - res := app.app.ApplySnapshotChunk(*req) - return &res, nil -} - -func (app *GRPCApplication) ExtendVote( - ctx context.Context, req *RequestExtendVote) (*ResponseExtendVote, error) { - res := app.app.ExtendVote(*req) - return &res, nil -} - -func (app *GRPCApplication) VerifyVoteExtension( - ctx context.Context, req *RequestVerifyVoteExtension) (*ResponseVerifyVoteExtension, error) { - res := app.app.VerifyVoteExtension(*req) - return &res, nil -} - -func (app *GRPCApplication) PrepareProposal( - ctx context.Context, req *RequestPrepareProposal) (*ResponsePrepareProposal, error) { - res := app.app.PrepareProposal(*req) - return &res, nil -} - -func (app *GRPCApplication) ProcessProposal( - ctx context.Context, req *RequestProcessProposal) (*ResponseProcessProposal, error) { - res := app.app.ProcessProposal(*req) - return &res, nil -} - -func (app *GRPCApplication) FinalizeBlock( - ctx context.Context, req *RequestFinalizeBlock) (*ResponseFinalizeBlock, error) { - res := app.app.FinalizeBlock(*req) - return &res, nil -} From ef314708e74c64bfc8fb40f677ed5493c67186c0 Mon Sep 17 00:00:00 2001 From: "M. J. Fromberger" Date: Thu, 21 Apr 2022 10:08:47 -0700 Subject: [PATCH 03/35] RFC 019: Configuration File Versioning (#8379) This RFC discusses issues in how we migrate configuration data across Tendermint versions, and some options for how to improve the experience for node operators in the future. --- docs/rfc/README.md | 1 + docs/rfc/rfc-019-config-version.md | 400 +++++++++++++++++++++++++++++ 2 files changed, 401 insertions(+) create mode 100644 docs/rfc/rfc-019-config-version.md diff --git a/docs/rfc/README.md b/docs/rfc/README.md index b5c42ea85..f2ad6ad69 100644 --- a/docs/rfc/README.md +++ b/docs/rfc/README.md @@ -53,5 +53,6 @@ sections. - [RFC-013: ABCI++](./rfc-013-abci++.md) - [RFC-014: Semantic Versioning](./rfc-014-semantic-versioning.md) - [RFC-015: ABCI++ Tx Mutation](./rfc-015-abci++-tx-mutation.md) +- [RFC-019: Configuration File Versioning](./rfc-019-config-version.md) diff --git a/docs/rfc/rfc-019-config-version.md b/docs/rfc/rfc-019-config-version.md new file mode 100644 index 000000000..3dfd7840b --- /dev/null +++ b/docs/rfc/rfc-019-config-version.md @@ -0,0 +1,400 @@ +# RFC 019: Configuration File Versioning + +## Changelog + +- 19-Apr-2022: Initial draft (@creachadair) +- 20-Apr-2022: Updates from review feedback (@creachadair) + +## Abstract + +Updating configuration settings is an essential part of upgrading an existing +node to a new version of the Tendermint software. Unfortunately, it is also +currently a very manual process. This document discusses some of the history of +changes to the config format, actions we've taken to improve the tooling for +configuration upgrades, and additional steps we may want to consider. + +## Background + +A Tendermint node reads configuration settings at startup from a TOML formatted +text file, typically named `config.toml`. The contents of this file are defined +by the [`github.com/tendermint/tendermint/config`][config-pkg]. + +Although many settings in this file remain valid from one version of Tendermint +to the next, new versions of Tendermint often add, update, and remove settings. +These changes often require manual intervention by operators who are upgrading +their nodes. + +I propose we should provide better tools and documentation to help operators +make configuration changes correctly during version upgrades. Ideally, as much +as possible of any configuration file update should be automated, and where +that is not possible or practical, we should provide clear, explicit directions +for what steps need to be taken manually. Moreover, when the node discovers +incorrect or invalid configuration, we should improve the diagnostics it emits +so that the operator can quickly and easily find the relevant documentation, +without having to grep through source code. + +## Discussion + +By convention, we are supposed to document required changes to the config file +in the `UPGRADING.md` file for the release that introduces them. Although we +have mostly done this, the level of detail in the upgrading instructions is +often insufficient for an operator to correctly update their file. + +The updates vary widely in complexity: Operators may need to add new required +settings, update obsolete values for existing settings, move or rename existing +settings within the file, or remove obsolete settings (which are thus invalid). +Here are a few examples of each of these cases: + +- **New required settings:** Tendermint v0.35 added a new top-level `mode` + setting that determines whether a node runs as a validator, a full node, or a + seed node. The default value is `"full"`, which means the operator of a + validator must manually add `mode = "validator"` (or set the `--mode` flag on + the command line) for their node to come up in the correct mode. + +- **Updated obsolete values:** Tendermint v0.35 removed support for versions + `"v1"` and `"v2"` of the blocksync (formerly "fastsync") protocol, requiring + any node using either of those values to update to `"v0"`. + +- **Moved/renamed settings:** Version v0.34 moved the top-level `pprof_laddr` + setting under the `[rpc]` section. + + Version v0.35 renamed every setting in the file from `snake_case` to + `kebab-case`, moved the top-level `fast_sync` setting into the `[blocksync]` + section as (itself renamed from `[fastsync]`), and moved all the top-level + `priv-validator-*` settings under a new `[priv-validator]` section with their + prefix trimmed off. + +- **Removed obsolete settings:** Version v0.34 removed the `index_all_keys` and + `index_keys` settings from the `[tx_index]` section; version v0.35 removed + the `wal-dir` setting from the `[mempool]` section, and version v0.36 removed + the `[blocksync]` section entirely. + +While many of these changes are mentioned in the config section of the upgrade +instructions, some are not mentioned at all, or are hidden in other parts of +the doc. For instance, the v0.34 `pprof_laddr` change was documented only as an +RPC flag change. (A savvy reader might realize that the flag `--rpc.pprof_laddr` +implies a corresponding config section, but it omits the related detail that +there was a top-level setting that's been renamed). The lesson here is not +that the docs are bad, but to point out that prose is not the most efficient +format to convey detailed changes like this. The upgrading instructions are +still valuable for the human reader to understand what to expect. + +### Concrete Steps + +As part of the v0.36 development cycle, we spent some time reverse-engineering +the configuration changes since the v0.34 release and built an experimental +command-line tool called [`confix`][confix], whose job it is to automatically +update the settings in a `config.toml` file to the latest version. We also +backported a version of this tool into the v0.35.x branch at release v0.35.4. + +This tool should work fine for configuration files created by Tendermint v0.34 +and later, but does not (yet) know how to handle changes from prior versions of +Tendermint. Part of the difficulty for older versions is simply logistical: To +figure out which changes to apply, we need to understand something about the +version that made the file, as well as the version we're converting it to. + +> **Discussion point:** In the future we might want to consider incorporating +> this into the node CLI directly, but we're keeping it separate for now until +> we can get some feedback from operators. + +For the experiment, we handled this by carefully searching the history of +config format changes for shibboleths to bound the version: For example, the +`[fastsync]` section was added in Tendermint v0.32 and renamed `[blocksync]` in +Tendermint v0.35. So if we see a `[fastsync]` section, we have some confidence +that the file was created by v0.32, v0.33, or v0.34. + +But such signals are delicate: The `[blocksync]` section was removed in v0.36, +so if we do not find `[fastsync]`, we cannot conclude from that alone that the +file is from v0.31 or earlier -- we have to look for corroborating details. +While such "sniffing" tactics are fine for an experiment, they aren't as robust +as we might like. + +This is especially relevant for configuration files that may have already been +manually upgraded across several versions by the time we are asked to update +them again. Another related concern is that we'd like to make sure conversion +is idempotent, so that it would be safe to rerun the tool over an +already-converted file without breaking anything. + +### Config Versioning + +One obvious tactic we could use for future releases is add a version marker to +the config file. This would give tools like `confix` (and the node itself) a +way to calibrate their expectations. Rather than being a version for the file +itself, however, this version marker would indicate which version of Tendermint +is needed to read the file. + +Provisionally, this might look something like: + +```toml +# THe minimum version of Tendermint compatible with the contents of +# this configuration file. +config-version = 'v0.35' +``` + +When initializing a new node, Tendermint would populate this field with its own +version (e.g., `v0.36`). When conducting an upgrade, tools like `confix` can +then use this to decide which conversions are valid, and then update the value +accordingly. After converting a file marked `'v0.35'` to`'v0.37'`, the +conversion tool sets the file's `config-version` to reflect its compatibility. + +> **Discussion point:** This example presumes we would keep config files +> compatible within a given release cycle, e.g., all of v0.36.x. We could also +> use patch numbers here, if we think there's some reason to permit changes +> that would require config file edits at that granularity. I don't think we +> should, but that's a design question to consider. + +Upon seeing an up-to-date version marker, the conversion tool can simply exit +with a diagnostic like "this file is already up-to-date", rather than sniffing +the keyspace and potentially introducing errors. In addition, this would let a +tool detect config files that are _newer_ than the one it understands, and +issue a safe diagnostic rather than doing something wrong. Plus, besides +avoiding potentially unsafe conversions, this would also serve as +human-readable documentation that the file is up-to-date for a given version. + +Adding a config version would not address the problem of how to convert files +created by older versions of Tendermint, but it would at least help us build +more robust config tooling going forward. + +### Stability and Change + +In light of the discussion so far, it is natural to examine why we make so many +changes to the configuration file from one version to the next, and whether we +could reduce friction by being more conservative about what we make +configurable, what config changes we make over time, and how we roll them out. + +Some changes, like renaming everything from snake case to kebab case, are +entirely gratuitous. We could safely agree not to make those kinds of changes. +Apart from that obvious case, however, many other configuration settings +provide value to node operators in cases where there is no simple, universal +setting that matches every application. + +Taking a high-level view, there are several broad reasons why we might want to +make changes to configuration settings: + +- **Lessons learned:** Configuration settings are a good way to try things out + in production, before making more invasive changes to the consensus protocol. + + For example, up until Tendermint v0.35, consensus timeouts were specified as + per-node configuration settings (e.g., `timeout-precommit` et al.). This + allowed operators to tune these values for the needs of their network, but + had the downside that individually-misconfigured nodes could stall consensus. + + Based on that experience, these timeouts have been deprecated in Tendermint + v0.36 and converted to consensus parameters, to be consistent across all + nodes in the network. + +- **Migration & experimentation:** Introducing new features and updating old + features can complicate migration for existing users of the software. + Temporary or "experimental" configuration settings can be a valuable way to + mitigate that friction. + + For example, Tendermint v0.36 introduces a new RPC event subscription + endpoint (see [ADR 075][adr075]) that will eventually replace the existing + webwocket-based interface. To give users time to migrate, v0.36 adds an + `experimental-disable-websocket` setting, defaulted to `false`, that allows + operators to selectively disable the websocket API for testing purposes + during the conversion. This setting is designed to be removed in v0.37, when + the old interface is no longer supported. + +- **Ongoing maintenance:** Sometimes configuration settings become obsolete, + and the cost of removing them trades off against the potential risks of + leaving a non-functional or deprecated knob hooked up indefinitely. + + For example, Tendermint v0.35 deprecated two alternate implementations of the + blocksync protocol, one of which was deleted entirely (`v1`) and one of which + was scheduled for removal (`v2`). The `blocksync.version` setting, which had + been added as a migration aid, became obsolete and needed to be updated. + + Despite our best intentions, sometimes engineering designs do not work out. + It's just as important to leave room to back out of changes we have since + reconsidered, as it is to support migrations forward onto new and improved + code. + +- **Clarity and legibility:** Besides configuring the software, another + important purpose of a config file is to document intent for the humans who + operate and maintain the software. Operators need adjust settings to keep the + node running, and developers need to know what options were in use when + something goes wrong so they can diagnose and fix bugs. The legibility of a + config file as a _human_ artifact is also thus important. + + For example, Tendermint v0.35 moved settings related to validator private + keys from the top-level section of the configuration file to their own + designated `[priv-validator]` section. Although this change did not make any + difference to the meaning of those settings, it made the organization of the + file easier to understand, and allowed the names of the individual settings + to be simplified (e.g., `priv-validator-key-file` became simply `key-file` in + the new section). + + Although such changes are "gratuitous" with respect to the software, there is + often value in making things more legible for the humans. While there is no + simple rule to define the line, the Potter Stewart principle can be used with + due care. + +Keeping these examples in mind, we can and should take reasonable steps to +avoid churn in the configuration file across versions where we can. However, we +must also accept that part of the reason for _having_ a config file is to allow +us flexibility elsewhere in the design. On that basis, we should not attempt +to be too dogmatic about config changes either. Unlike changes in the block +protocol, for example, which affect every user of every network that adopts +them, config changes are relatively self-contained. + +There are few guiding principles I think we can use to strike a sensible +balance: + +1. **No gratuitous changes.** Aesthetic changes that do not enhance legibility, + avert confusion, or clarity documentation, should be entirely avoided. + +2. **Prefer mechanical changes.** Whenever it is practical, change settings in + a way that can be updated by a tool without operator judgement. This implies + finding safe, universal defaults for new settings, and not changing the + default values of existing settings. + + Even if that means we have to make multiple changes (e.g., add a new setting + in the current version, deprecate the old one, and remove the old one in the + next version) it's preferable if we can mechanize each step. + +3. **Clearly signal intent.** When adding temporary or experimental settings, + they should be clearly named and documented as such. Use long names and + suggestive prefixes (e.g., `experimental-*`) so that they stand out when + read in the config file or printed in logs. + + Relatedly, using temporary or experimental settings should cause the + software to emit diagnostic logs at runtime. These log messages should be + easy to grep for, and should contain pointers to more complete documentation + (say, issue numbers or URLs) that the operator can read, as well as a hint + about when the setting is expected to become invalid. For example: + + ``` + WARNING: Websocket RPC access is deprecated and will be removed in + Tendermint v0.37. See https://tinyurl.com/adr075 for more information. + ``` + +4. **Consider both directions.** When adding a configuration setting, take some + time during the implementation process to think about how the setting could + be removed, as well as how it will be rolled out. This applies even for + settings we imagine should be permanent. Experience may cause is to rethink + our original design intent more broadly than we expected. + + This does not mean we have to spend a long time picking nits over the design + of every setting; merely that we should convince ourselves we _could_ undo + it without making too big a mess later. Even a little extra effort up front + can sometimes save a lot. + +## References + +- [Tendermint `config` package][config-pkg] +- [`confix` command-line tool][confix] +- [`condiff` command-line tool][condiff] +- [Configuration update plan][plan] +- [ADR 075: RPC Event Subscription Interface][adr075] + +[config-pkg]: https://godoc.org/github.com/tendermint/tendermint/config +[confix]: https://github.com/tendermint/tendermint/blob/master/scripts/confix +[condiff]: https://github.com/tendermint/tendermint/blob/master/scripts/confix/condiff +[plan]: https://github.com/tendermint/tendermint/blob/master/scripts/confix/plan.go +[testdata]: https://github.com/tendermint/tendermint/blob/master/scripts/confix/testdata +[adr075]: https://github.com/tendermint/tendermint/blob/master/docs/architecture/adr-075-rpc-subscription.md + +## Appendix: Research Notes + +Discovering when various configuration settings were added, updated, and +removed turns out to be surprisingly tedious. To solve this puzzle, we had to +answer the following questions: + +1. What changes were made between v0.x and v0.y? This is further complicated by + cases where we have backported config changes into the middle of an earlier + release cycle (e.g., `psql-conn` from v0.35.x into v0.34.13). + +2. When during the development cycle were those changes made? This allows us to + recognize features that were backported into a previous release. + +3. What were the default values of the changed settings, and did they change at + all during or across the release boundary? + +Each step of the [configuration update plan][plan] is commented with a link to +one or more PRs where that change was made. The sections below discuss how we +found these references. + +### Tracking Changes Across Releases + +To figure out what changed between two releases, we built a tool called +[`condiff`][condiff], which performs a "keyspace" diff of two TOML documents. +This diff respects the structure of the TOML file, but ignores comments, blank +lines, and configuration values, so that we can see what was added and removed. + +To use it, run: + +```shell +go run ./scripts/confix/condiff old.toml new.toml +``` + +This tool works on any TOML documents, but for our purposes we needed +Tendermint `config.toml` files. The easiest way to get these is to build the +node binary for your version of interest, run `tendermint init` on a clean home +directory, and copy the generated config file out. The [`testdata`][testdata] +directory for the `confix` tool has configs generated from the heads of each +release branch from v0.31 through v0.35. + +If you want to reproduce this yourself, it looks something like this: + +```shell +# Example for Tendermint v0.32. +git checkout --track origin/v0.32.x +go get golang.org/x/sys/unix +go mod tidy +make build +rm -fr -- tmhome +./build/tendermint --home=tmhome init +cp tmhome/config/config.toml config-v32.toml +``` + +Be advised that the further back you go, the more idiosyncrasies you will +encounter. For example, Tendermint v0.31 and earlier predate Go modules (v0.31 +used dep), and lack backport branches. And you may need to do some editing of +Makefile rules once you get back into the 20s. + +Note that when diffing config files across the v0.34/v0.35 gap, the swap from +`snake_case` to `kebab-case` makes it look like everything changed. The +`condiff` tool has a `-desnake` flag that normalizes all the keys to kebab case +in both inputs before comparison. + +### Locating Additions and Deletions + +To figure out when a configuration setting was added or removed, your tool of +choice is `git bisect`. The only tricky part is finding the endpoints for the +search. If the transition happened within a release, you can use that +release's backport branch as the endpoint (if it has one, e.g., `v0.35.x`). + +However, the start point can be more problematic. The backport branches are not +ancestors of `master` or of each other, which means you need to find some point +in history _prior_ to the change but still attached to the mainline. For recent +releases there is a dev root (e.g., `v0.35.0-dev`, `v0.34.0-dev1`, etc.). These +are not named consistently, but you can usually grep the output of `git tag` to +find them. + +In the worst case you could try starting from the root commit of the repo, but +that turns out not to work in all cases. We've done some branching shenanigans +over the years that mean the root is not a direct ancestor of all our release +branches. When you find this you will probably swear a lot. I did. + +Once you have a start and end point (say, `v0.35.0-dev` and `master`), you can +bisect in the usual way. I use `git grep` on the `config` directory to check +whether the case I am looking for is present. For example, to find when the +`[fastsync]` section was removed: + +```shell +# Setup: +git checkout master +git bisect start +git bisect bad # it's not present on tip of master. +git bisect good v0.34.0-dev1 # it was present at the start of v0.34. +``` + +```shell +# Now repeat this until it gives you a specific commit: +if git grep -q '\[fastsync\]' config ; then git bisect good ; else git bisect bad ; fi +``` + +The above example finds where a config was removed: To find where a setting was +added, do the same thing except reverse the sense of the test (`if ! git grep -q +...`). From 383f9ea1809ec178510ca13afbf387818c4eba79 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 Apr 2022 12:22:20 +0000 Subject: [PATCH 04/35] build(deps): Bump github.com/creachadair/tomledit from 0.0.16 to 0.0.18 (#8392) Bumps [github.com/creachadair/tomledit](https://github.com/creachadair/tomledit) from 0.0.16 to 0.0.18.
Commits
  • 5802e26 Release v0.0.18
  • 3c9daf1 document that we don't validate
  • da8c938 Remove non-applicable test cases.
  • ac4210b parser: ensure unclosed arrays are not treated as empty
  • f98f82f parser: ensure array separators are present
  • ea1671e scanner: clean up some issues in escape and space handling
  • 8168589 scanner: filter bad commas in numeric literals
  • 83189e2 scanner: fix some issues in multiline string recognition
  • bdc8e22 scanner: allow space separators in date-time strings
  • 1ab2c8d Add compliance tests.
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/creachadair/tomledit&package-manager=go_modules&previous-version=0.0.16&new-version=0.0.18)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 4dba71354..0fc3529af 100644 --- a/go.mod +++ b/go.mod @@ -75,7 +75,7 @@ require ( github.com/charithe/durationcheck v0.0.9 // indirect github.com/chavacava/garif v0.0.0-20210405164556-e8a0a408d6af // indirect github.com/containerd/continuity v0.2.1 // indirect - github.com/creachadair/tomledit v0.0.16 + github.com/creachadair/tomledit v0.0.18 github.com/daixiang0/gci v0.3.3 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/denis-tingaikin/go-header v0.4.3 // indirect diff --git a/go.sum b/go.sum index 718795458..23a85fcef 100644 --- a/go.sum +++ b/go.sum @@ -229,8 +229,8 @@ github.com/creachadair/atomicfile v0.2.5 h1:wkOlpsjyJOvJ3Hd8juHKdirJnCSIPacvtY21 github.com/creachadair/atomicfile v0.2.5/go.mod h1:BRq8Une6ckFneYXZQ+kO7p1ZZP3I2fzVzf28JxrIkBc= github.com/creachadair/taskgroup v0.3.2 h1:zlfutDS+5XG40AOxcHDSThxKzns8Tnr9jnr6VqkYlkM= github.com/creachadair/taskgroup v0.3.2/go.mod h1:wieWwecHVzsidg2CsUnFinW1faVN4+kq+TDlRJQ0Wbk= -github.com/creachadair/tomledit v0.0.16 h1:PDNxgDjeeiNk1cyFfliIVQmagh1jPbDMabOw9yfSKLk= -github.com/creachadair/tomledit v0.0.16/go.mod h1:gvtfnSZLa+YNQD28vaPq0Nk12bRxEhmUdBzAWn+EGF4= +github.com/creachadair/tomledit v0.0.18 h1:gleeCnEgMPYcaBz5KN/1CN9yycF5n6Q2py7Ahu6yc7A= +github.com/creachadair/tomledit v0.0.18/go.mod h1:gvtfnSZLa+YNQD28vaPq0Nk12bRxEhmUdBzAWn+EGF4= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= From 6970c9177b8a2d4f2c2e3c06fd02568931088722 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 Apr 2022 05:55:33 -0700 Subject: [PATCH 05/35] build(deps): Bump github.com/vektra/mockery/v2 from 2.11.0 to 2.12.0 (#8393) --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 0fc3529af..cb6e322d2 100644 --- a/go.mod +++ b/go.mod @@ -42,7 +42,7 @@ require ( github.com/creachadair/taskgroup v0.3.2 github.com/golangci/golangci-lint v1.45.2 github.com/google/go-cmp v0.5.7 - github.com/vektra/mockery/v2 v2.11.0 + github.com/vektra/mockery/v2 v2.12.0 gotest.tools v2.2.0+incompatible ) diff --git a/go.sum b/go.sum index 23a85fcef..9a11ff196 100644 --- a/go.sum +++ b/go.sum @@ -1055,8 +1055,8 @@ github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyC github.com/valyala/fasthttp v1.30.0/go.mod h1:2rsYD01CKFrjjsvFxx75KlEUNpWNBY9JWD3K/7o2Cus= github.com/valyala/quicktemplate v1.7.0/go.mod h1:sqKJnoaOF88V07vkO+9FL8fb9uZg/VPSJnLYn+LmLk8= github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= -github.com/vektra/mockery/v2 v2.11.0 h1:9NkC3urGvJS9B0ve5aTbFjksbO9f/u5cZFgCTVJ30jg= -github.com/vektra/mockery/v2 v2.11.0/go.mod h1:8vf4KDDUptfkyypzdHLuE7OE2xA7Gdt60WgIS8PgD+U= +github.com/vektra/mockery/v2 v2.12.0 h1:g3lq1ni5swlT9y6jYBx/CITVpwg3vsWrhKIuIweAxYI= +github.com/vektra/mockery/v2 v2.12.0/go.mod h1:8vf4KDDUptfkyypzdHLuE7OE2xA7Gdt60WgIS8PgD+U= github.com/viki-org/dnscache v0.0.0-20130720023526-c70c1f23c5d8/go.mod h1:dniwbG03GafCjFohMDmz6Zc6oCuiqgH6tGNyXTkHzXE= github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= From 8345dc4f7c2a1e6bb4cb6de95d90da09a25eb38f Mon Sep 17 00:00:00 2001 From: Sam Kleinman Date: Fri, 22 Apr 2022 10:58:01 -0400 Subject: [PATCH 06/35] abci: application type should take contexts (#8388) --- abci/client/local_client.go | 52 +++--- abci/client/mocks/client.go | 11 ++ abci/example/kvstore/helpers.go | 5 +- abci/example/kvstore/kvstore.go | 17 +- abci/example/kvstore/kvstore_test.go | 62 +++---- abci/example/kvstore/persistent_kvstore.go | 6 +- abci/server/grpc_server.go | 56 +++---- abci/server/socket_server.go | 38 ++--- abci/types/application.go | 58 +++---- abci/types/mocks/application.go | 153 ++++++++++-------- abci/types/mocks/base.go | 86 +++++----- internal/consensus/byzantine_test.go | 2 +- internal/consensus/common_test.go | 11 +- internal/consensus/mempool_test.go | 18 +-- internal/consensus/mocks/cons_sync_reactor.go | 11 ++ internal/consensus/reactor_test.go | 2 +- internal/consensus/replay_stubs.go | 4 +- internal/consensus/replay_test.go | 10 +- internal/consensus/state_test.go | 59 ++++--- internal/evidence/mocks/block_store.go | 12 ++ internal/mempool/mempool_test.go | 2 +- internal/mempool/mocks/mempool.go | 11 ++ internal/p2p/mocks/connection.go | 11 ++ internal/p2p/mocks/transport.go | 11 ++ internal/state/execution_test.go | 14 +- internal/state/helpers_test.go | 12 +- internal/state/indexer/mocks/event_sink.go | 11 ++ internal/state/mocks/block_store.go | 11 ++ internal/state/mocks/evidence_pool.go | 11 ++ internal/state/mocks/store.go | 11 ++ internal/statesync/mocks/state_provider.go | 11 ++ libs/time/mocks/source.go | 13 +- light/provider/mocks/provider.go | 11 ++ light/rpc/mocks/light_client.go | 11 ++ rpc/client/mock/abci.go | 34 ++-- rpc/client/mock/abci_test.go | 2 +- rpc/client/mocks/client.go | 11 ++ test/e2e/app/app.go | 29 ++-- 38 files changed, 543 insertions(+), 357 deletions(-) diff --git a/abci/client/local_client.go b/abci/client/local_client.go index 938ed2ab6..b7bc65b23 100644 --- a/abci/client/local_client.go +++ b/abci/client/local_client.go @@ -44,71 +44,71 @@ func (app *localClient) Echo(_ context.Context, msg string) (*types.ResponseEcho } func (app *localClient) Info(ctx context.Context, req types.RequestInfo) (*types.ResponseInfo, error) { - res := app.Application.Info(req) + res := app.Application.Info(ctx, req) return &res, nil } -func (app *localClient) CheckTx(_ context.Context, req types.RequestCheckTx) (*types.ResponseCheckTx, error) { - res := app.Application.CheckTx(req) +func (app *localClient) CheckTx(ctx context.Context, req types.RequestCheckTx) (*types.ResponseCheckTx, error) { + res := app.Application.CheckTx(ctx, req) return &res, nil } -func (app *localClient) Query(_ context.Context, req types.RequestQuery) (*types.ResponseQuery, error) { - res := app.Application.Query(req) +func (app *localClient) Query(ctx context.Context, req types.RequestQuery) (*types.ResponseQuery, error) { + res := app.Application.Query(ctx, req) return &res, nil } func (app *localClient) Commit(ctx context.Context) (*types.ResponseCommit, error) { - res := app.Application.Commit() + res := app.Application.Commit(ctx) return &res, nil } -func (app *localClient) InitChain(_ context.Context, req types.RequestInitChain) (*types.ResponseInitChain, error) { - res := app.Application.InitChain(req) +func (app *localClient) InitChain(ctx context.Context, req types.RequestInitChain) (*types.ResponseInitChain, error) { + res := app.Application.InitChain(ctx, req) return &res, nil } -func (app *localClient) ListSnapshots(_ context.Context, req types.RequestListSnapshots) (*types.ResponseListSnapshots, error) { - res := app.Application.ListSnapshots(req) +func (app *localClient) ListSnapshots(ctx context.Context, req types.RequestListSnapshots) (*types.ResponseListSnapshots, error) { + res := app.Application.ListSnapshots(ctx, req) return &res, nil } -func (app *localClient) OfferSnapshot(_ context.Context, req types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { - res := app.Application.OfferSnapshot(req) +func (app *localClient) OfferSnapshot(ctx context.Context, req types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { + res := app.Application.OfferSnapshot(ctx, req) return &res, nil } -func (app *localClient) LoadSnapshotChunk(_ context.Context, req types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) { - res := app.Application.LoadSnapshotChunk(req) +func (app *localClient) LoadSnapshotChunk(ctx context.Context, req types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) { + res := app.Application.LoadSnapshotChunk(ctx, req) return &res, nil } -func (app *localClient) ApplySnapshotChunk(_ context.Context, req types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { - res := app.Application.ApplySnapshotChunk(req) +func (app *localClient) ApplySnapshotChunk(ctx context.Context, req types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { + res := app.Application.ApplySnapshotChunk(ctx, req) return &res, nil } -func (app *localClient) PrepareProposal(_ context.Context, req types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) { - res := app.Application.PrepareProposal(req) +func (app *localClient) PrepareProposal(ctx context.Context, req types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) { + res := app.Application.PrepareProposal(ctx, req) return &res, nil } -func (app *localClient) ProcessProposal(_ context.Context, req types.RequestProcessProposal) (*types.ResponseProcessProposal, error) { - res := app.Application.ProcessProposal(req) +func (app *localClient) ProcessProposal(ctx context.Context, req types.RequestProcessProposal) (*types.ResponseProcessProposal, error) { + res := app.Application.ProcessProposal(ctx, req) return &res, nil } -func (app *localClient) ExtendVote(_ context.Context, req types.RequestExtendVote) (*types.ResponseExtendVote, error) { - res := app.Application.ExtendVote(req) +func (app *localClient) ExtendVote(ctx context.Context, req types.RequestExtendVote) (*types.ResponseExtendVote, error) { + res := app.Application.ExtendVote(ctx, req) return &res, nil } -func (app *localClient) VerifyVoteExtension(_ context.Context, req types.RequestVerifyVoteExtension) (*types.ResponseVerifyVoteExtension, error) { - res := app.Application.VerifyVoteExtension(req) +func (app *localClient) VerifyVoteExtension(ctx context.Context, req types.RequestVerifyVoteExtension) (*types.ResponseVerifyVoteExtension, error) { + res := app.Application.VerifyVoteExtension(ctx, req) return &res, nil } -func (app *localClient) FinalizeBlock(_ context.Context, req types.RequestFinalizeBlock) (*types.ResponseFinalizeBlock, error) { - res := app.Application.FinalizeBlock(req) +func (app *localClient) FinalizeBlock(ctx context.Context, req types.RequestFinalizeBlock) (*types.ResponseFinalizeBlock, error) { + res := app.Application.FinalizeBlock(ctx, req) return &res, nil } diff --git a/abci/client/mocks/client.go b/abci/client/mocks/client.go index 37df53979..365f45a94 100644 --- a/abci/client/mocks/client.go +++ b/abci/client/mocks/client.go @@ -4,8 +4,10 @@ package mocks import ( context "context" + testing "testing" mock "github.com/stretchr/testify/mock" + types "github.com/tendermint/tendermint/abci/types" ) @@ -419,3 +421,12 @@ func (_m *Client) VerifyVoteExtension(_a0 context.Context, _a1 types.RequestVeri func (_m *Client) Wait() { _m.Called() } + +// NewClient creates a new instance of Client. It also registers a cleanup function to assert the mocks expectations. +func NewClient(t testing.TB) *Client { + mock := &Client{} + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/abci/example/kvstore/helpers.go b/abci/example/kvstore/helpers.go index 38bb42ea8..d0428cceb 100644 --- a/abci/example/kvstore/helpers.go +++ b/abci/example/kvstore/helpers.go @@ -1,6 +1,7 @@ package kvstore import ( + "context" mrand "math/rand" "github.com/tendermint/tendermint/abci/types" @@ -32,8 +33,8 @@ func RandVals(cnt int) []types.ValidatorUpdate { // InitKVStore initializes the kvstore app with some data, // which allows tests to pass and is fine as long as you // don't make any tx that modify the validator state -func InitKVStore(app *PersistentKVStoreApplication) { - app.InitChain(types.RequestInitChain{ +func InitKVStore(ctx context.Context, app *PersistentKVStoreApplication) { + app.InitChain(ctx, types.RequestInitChain{ Validators: RandVals(1), }) } diff --git a/abci/example/kvstore/kvstore.go b/abci/example/kvstore/kvstore.go index 045e872d4..4c31cee34 100644 --- a/abci/example/kvstore/kvstore.go +++ b/abci/example/kvstore/kvstore.go @@ -2,6 +2,7 @@ package kvstore import ( "bytes" + "context" "encoding/base64" "encoding/binary" "encoding/json" @@ -90,7 +91,7 @@ func NewApplication() *Application { } } -func (app *Application) InitChain(req types.RequestInitChain) types.ResponseInitChain { +func (app *Application) InitChain(_ context.Context, req types.RequestInitChain) types.ResponseInitChain { app.mu.Lock() defer app.mu.Unlock() @@ -104,7 +105,7 @@ func (app *Application) InitChain(req types.RequestInitChain) types.ResponseInit return types.ResponseInitChain{} } -func (app *Application) Info(req types.RequestInfo) types.ResponseInfo { +func (app *Application) Info(_ context.Context, req types.RequestInfo) types.ResponseInfo { app.mu.Lock() defer app.mu.Unlock() return types.ResponseInfo{ @@ -166,7 +167,7 @@ func (app *Application) Close() error { return app.state.db.Close() } -func (app *Application) FinalizeBlock(req types.RequestFinalizeBlock) types.ResponseFinalizeBlock { +func (app *Application) FinalizeBlock(_ context.Context, req types.RequestFinalizeBlock) types.ResponseFinalizeBlock { app.mu.Lock() defer app.mu.Unlock() @@ -198,11 +199,11 @@ func (app *Application) FinalizeBlock(req types.RequestFinalizeBlock) types.Resp return types.ResponseFinalizeBlock{TxResults: respTxs, ValidatorUpdates: app.ValUpdates} } -func (*Application) CheckTx(req types.RequestCheckTx) types.ResponseCheckTx { +func (*Application) CheckTx(_ context.Context, req types.RequestCheckTx) types.ResponseCheckTx { return types.ResponseCheckTx{Code: code.CodeTypeOK, GasWanted: 1} } -func (app *Application) Commit() types.ResponseCommit { +func (app *Application) Commit(_ context.Context) types.ResponseCommit { app.mu.Lock() defer app.mu.Unlock() @@ -221,7 +222,7 @@ func (app *Application) Commit() types.ResponseCommit { } // Returns an associated value or nil if missing. -func (app *Application) Query(reqQuery types.RequestQuery) types.ResponseQuery { +func (app *Application) Query(_ context.Context, reqQuery types.RequestQuery) types.ResponseQuery { app.mu.Lock() defer app.mu.Unlock() @@ -280,7 +281,7 @@ func (app *Application) Query(reqQuery types.RequestQuery) types.ResponseQuery { return resQuery } -func (app *Application) PrepareProposal(req types.RequestPrepareProposal) types.ResponsePrepareProposal { +func (app *Application) PrepareProposal(_ context.Context, req types.RequestPrepareProposal) types.ResponsePrepareProposal { app.mu.Lock() defer app.mu.Unlock() @@ -289,7 +290,7 @@ func (app *Application) PrepareProposal(req types.RequestPrepareProposal) types. } } -func (*Application) ProcessProposal(req types.RequestProcessProposal) types.ResponseProcessProposal { +func (*Application) ProcessProposal(_ context.Context, req types.RequestProcessProposal) types.ResponseProcessProposal { for _, tx := range req.Txs { if len(tx) == 0 { return types.ResponseProcessProposal{Status: types.ResponseProcessProposal_REJECT} diff --git a/abci/example/kvstore/kvstore_test.go b/abci/example/kvstore/kvstore_test.go index 482e3d691..5bd9907ae 100644 --- a/abci/example/kvstore/kvstore_test.go +++ b/abci/example/kvstore/kvstore_test.go @@ -23,23 +23,23 @@ const ( testValue = "def" ) -func testKVStore(t *testing.T, app types.Application, tx []byte, key, value string) { +func testKVStore(ctx context.Context, t *testing.T, app types.Application, tx []byte, key, value string) { req := types.RequestFinalizeBlock{Txs: [][]byte{tx}} - ar := app.FinalizeBlock(req) + ar := app.FinalizeBlock(ctx, req) require.Equal(t, 1, len(ar.TxResults)) require.False(t, ar.TxResults[0].IsErr()) // repeating tx doesn't raise error - ar = app.FinalizeBlock(req) + ar = app.FinalizeBlock(ctx, req) require.Equal(t, 1, len(ar.TxResults)) require.False(t, ar.TxResults[0].IsErr()) // commit - app.Commit() + app.Commit(ctx) - info := app.Info(types.RequestInfo{}) + info := app.Info(ctx, types.RequestInfo{}) require.NotZero(t, info.LastBlockHeight) // make sure query is fine - resQuery := app.Query(types.RequestQuery{ + resQuery := app.Query(ctx, types.RequestQuery{ Path: "/store", Data: []byte(key), }) @@ -49,7 +49,7 @@ func testKVStore(t *testing.T, app types.Application, tx []byte, key, value stri require.EqualValues(t, info.LastBlockHeight, resQuery.Height) // make sure proof is fine - resQuery = app.Query(types.RequestQuery{ + resQuery = app.Query(ctx, types.RequestQuery{ Path: "/store", Data: []byte(key), Prove: true, @@ -61,18 +61,24 @@ func testKVStore(t *testing.T, app types.Application, tx []byte, key, value stri } func TestKVStoreKV(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + kvstore := NewApplication() key := testKey value := key tx := []byte(key) - testKVStore(t, kvstore, tx, key, value) + testKVStore(ctx, t, kvstore, tx, key, value) value = testValue tx = []byte(key + "=" + value) - testKVStore(t, kvstore, tx, key, value) + testKVStore(ctx, t, kvstore, tx, key, value) } func TestPersistentKVStoreKV(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + dir := t.TempDir() logger := log.NewNopLogger() @@ -80,22 +86,24 @@ func TestPersistentKVStoreKV(t *testing.T) { key := testKey value := key tx := []byte(key) - testKVStore(t, kvstore, tx, key, value) + testKVStore(ctx, t, kvstore, tx, key, value) value = testValue tx = []byte(key + "=" + value) - testKVStore(t, kvstore, tx, key, value) + testKVStore(ctx, t, kvstore, tx, key, value) } func TestPersistentKVStoreInfo(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() dir := t.TempDir() logger := log.NewNopLogger() kvstore := NewPersistentKVStoreApplication(logger, dir) - InitKVStore(kvstore) + InitKVStore(ctx, kvstore) height := int64(0) - resInfo := kvstore.Info(types.RequestInfo{}) + resInfo := kvstore.Info(ctx, types.RequestInfo{}) if resInfo.LastBlockHeight != height { t.Fatalf("expected height of %d, got %d", height, resInfo.LastBlockHeight) } @@ -103,10 +111,10 @@ func TestPersistentKVStoreInfo(t *testing.T) { // make and apply block height = int64(1) hash := []byte("foo") - kvstore.FinalizeBlock(types.RequestFinalizeBlock{Hash: hash, Height: height}) - kvstore.Commit() + kvstore.FinalizeBlock(ctx, types.RequestFinalizeBlock{Hash: hash, Height: height}) + kvstore.Commit(ctx) - resInfo = kvstore.Info(types.RequestInfo{}) + resInfo = kvstore.Info(ctx, types.RequestInfo{}) if resInfo.LastBlockHeight != height { t.Fatalf("expected height of %d, got %d", height, resInfo.LastBlockHeight) } @@ -115,6 +123,9 @@ func TestPersistentKVStoreInfo(t *testing.T) { // add a validator, remove a validator, update a validator func TestValUpdates(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + kvstore := NewApplication() // init with some validators @@ -122,7 +133,7 @@ func TestValUpdates(t *testing.T) { nInit := 5 vals := RandVals(total) // initialize with the first nInit - kvstore.InitChain(types.RequestInitChain{ + kvstore.InitChain(ctx, types.RequestInitChain{ Validators: vals[:nInit], }) @@ -137,7 +148,7 @@ func TestValUpdates(t *testing.T) { tx1 := MakeValSetChangeTx(v1.PubKey, v1.Power) tx2 := MakeValSetChangeTx(v2.PubKey, v2.Power) - makeApplyBlock(t, kvstore, 1, diff, tx1, tx2) + makeApplyBlock(ctx, t, kvstore, 1, diff, tx1, tx2) vals1, vals2 = vals[:nInit+2], kvstore.Validators() valsEqual(t, vals1, vals2) @@ -152,7 +163,7 @@ func TestValUpdates(t *testing.T) { tx2 = MakeValSetChangeTx(v2.PubKey, v2.Power) tx3 := MakeValSetChangeTx(v3.PubKey, v3.Power) - makeApplyBlock(t, kvstore, 2, diff, tx1, tx2, tx3) + makeApplyBlock(ctx, t, kvstore, 2, diff, tx1, tx2, tx3) vals1 = append(vals[:nInit-2], vals[nInit+1]) // nolint: gocritic vals2 = kvstore.Validators() @@ -168,7 +179,7 @@ func TestValUpdates(t *testing.T) { diff = []types.ValidatorUpdate{v1} tx1 = MakeValSetChangeTx(v1.PubKey, v1.Power) - makeApplyBlock(t, kvstore, 3, diff, tx1) + makeApplyBlock(ctx, t, kvstore, 3, diff, tx1) vals1 = append([]types.ValidatorUpdate{v1}, vals1[1:]...) vals2 = kvstore.Validators() @@ -176,22 +187,17 @@ func TestValUpdates(t *testing.T) { } -func makeApplyBlock( - t *testing.T, - kvstore types.Application, - heightInt int, - diff []types.ValidatorUpdate, - txs ...[]byte) { +func makeApplyBlock(ctx context.Context, t *testing.T, kvstore types.Application, heightInt int, diff []types.ValidatorUpdate, txs ...[]byte) { // make and apply block height := int64(heightInt) hash := []byte("foo") - resFinalizeBlock := kvstore.FinalizeBlock(types.RequestFinalizeBlock{ + resFinalizeBlock := kvstore.FinalizeBlock(ctx, types.RequestFinalizeBlock{ Hash: hash, Height: height, Txs: txs, }) - kvstore.Commit() + kvstore.Commit(ctx) valsEqual(t, diff, resFinalizeBlock.ValidatorUpdates) diff --git a/abci/example/kvstore/persistent_kvstore.go b/abci/example/kvstore/persistent_kvstore.go index e908ea98f..aec915e11 100644 --- a/abci/example/kvstore/persistent_kvstore.go +++ b/abci/example/kvstore/persistent_kvstore.go @@ -1,6 +1,8 @@ package kvstore import ( + "context" + dbm "github.com/tendermint/tm-db" "github.com/tendermint/tendermint/abci/types" @@ -35,10 +37,10 @@ func NewPersistentKVStoreApplication(logger log.Logger, dbDir string) *Persisten } } -func (app *PersistentKVStoreApplication) OfferSnapshot(req types.RequestOfferSnapshot) types.ResponseOfferSnapshot { +func (app *PersistentKVStoreApplication) OfferSnapshot(_ context.Context, req types.RequestOfferSnapshot) types.ResponseOfferSnapshot { return types.ResponseOfferSnapshot{Result: types.ResponseOfferSnapshot_ABORT} } -func (app *PersistentKVStoreApplication) ApplySnapshotChunk(req types.RequestApplySnapshotChunk) types.ResponseApplySnapshotChunk { +func (app *PersistentKVStoreApplication) ApplySnapshotChunk(_ context.Context, req types.RequestApplySnapshotChunk) types.ResponseApplySnapshotChunk { return types.ResponseApplySnapshotChunk{Result: types.ResponseApplySnapshotChunk_ABORT} } diff --git a/abci/server/grpc_server.go b/abci/server/grpc_server.go index f3d454435..dd5bdcb69 100644 --- a/abci/server/grpc_server.go +++ b/abci/server/grpc_server.go @@ -78,72 +78,72 @@ func (app *gRPCApplication) Flush(_ context.Context, req *types.RequestFlush) (* return &types.ResponseFlush{}, nil } -func (app *gRPCApplication) Info(_ context.Context, req *types.RequestInfo) (*types.ResponseInfo, error) { - res := app.app.Info(*req) +func (app *gRPCApplication) Info(ctx context.Context, req *types.RequestInfo) (*types.ResponseInfo, error) { + res := app.app.Info(ctx, *req) return &res, nil } -func (app *gRPCApplication) CheckTx(_ context.Context, req *types.RequestCheckTx) (*types.ResponseCheckTx, error) { - res := app.app.CheckTx(*req) +func (app *gRPCApplication) CheckTx(ctx context.Context, req *types.RequestCheckTx) (*types.ResponseCheckTx, error) { + res := app.app.CheckTx(ctx, *req) return &res, nil } -func (app *gRPCApplication) Query(_ context.Context, req *types.RequestQuery) (*types.ResponseQuery, error) { - res := app.app.Query(*req) +func (app *gRPCApplication) Query(ctx context.Context, req *types.RequestQuery) (*types.ResponseQuery, error) { + res := app.app.Query(ctx, *req) return &res, nil } -func (app *gRPCApplication) Commit(_ context.Context, req *types.RequestCommit) (*types.ResponseCommit, error) { - res := app.app.Commit() +func (app *gRPCApplication) Commit(ctx context.Context, req *types.RequestCommit) (*types.ResponseCommit, error) { + res := app.app.Commit(ctx) return &res, nil } -func (app *gRPCApplication) InitChain(_ context.Context, req *types.RequestInitChain) (*types.ResponseInitChain, error) { - res := app.app.InitChain(*req) +func (app *gRPCApplication) InitChain(ctx context.Context, req *types.RequestInitChain) (*types.ResponseInitChain, error) { + res := app.app.InitChain(ctx, *req) return &res, nil } -func (app *gRPCApplication) ListSnapshots(_ context.Context, req *types.RequestListSnapshots) (*types.ResponseListSnapshots, error) { - res := app.app.ListSnapshots(*req) +func (app *gRPCApplication) ListSnapshots(ctx context.Context, req *types.RequestListSnapshots) (*types.ResponseListSnapshots, error) { + res := app.app.ListSnapshots(ctx, *req) return &res, nil } -func (app *gRPCApplication) OfferSnapshot(_ context.Context, req *types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { - res := app.app.OfferSnapshot(*req) +func (app *gRPCApplication) OfferSnapshot(ctx context.Context, req *types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { + res := app.app.OfferSnapshot(ctx, *req) return &res, nil } -func (app *gRPCApplication) LoadSnapshotChunk(_ context.Context, req *types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) { - res := app.app.LoadSnapshotChunk(*req) +func (app *gRPCApplication) LoadSnapshotChunk(ctx context.Context, req *types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) { + res := app.app.LoadSnapshotChunk(ctx, *req) return &res, nil } -func (app *gRPCApplication) ApplySnapshotChunk(_ context.Context, req *types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { - res := app.app.ApplySnapshotChunk(*req) +func (app *gRPCApplication) ApplySnapshotChunk(ctx context.Context, req *types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { + res := app.app.ApplySnapshotChunk(ctx, *req) return &res, nil } -func (app *gRPCApplication) ExtendVote(_ context.Context, req *types.RequestExtendVote) (*types.ResponseExtendVote, error) { - res := app.app.ExtendVote(*req) +func (app *gRPCApplication) ExtendVote(ctx context.Context, req *types.RequestExtendVote) (*types.ResponseExtendVote, error) { + res := app.app.ExtendVote(ctx, *req) return &res, nil } -func (app *gRPCApplication) VerifyVoteExtension(_ context.Context, req *types.RequestVerifyVoteExtension) (*types.ResponseVerifyVoteExtension, error) { - res := app.app.VerifyVoteExtension(*req) +func (app *gRPCApplication) VerifyVoteExtension(ctx context.Context, req *types.RequestVerifyVoteExtension) (*types.ResponseVerifyVoteExtension, error) { + res := app.app.VerifyVoteExtension(ctx, *req) return &res, nil } -func (app *gRPCApplication) PrepareProposal(_ context.Context, req *types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) { - res := app.app.PrepareProposal(*req) +func (app *gRPCApplication) PrepareProposal(ctx context.Context, req *types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) { + res := app.app.PrepareProposal(ctx, *req) return &res, nil } -func (app *gRPCApplication) ProcessProposal(_ context.Context, req *types.RequestProcessProposal) (*types.ResponseProcessProposal, error) { - res := app.app.ProcessProposal(*req) +func (app *gRPCApplication) ProcessProposal(ctx context.Context, req *types.RequestProcessProposal) (*types.ResponseProcessProposal, error) { + res := app.app.ProcessProposal(ctx, *req) return &res, nil } -func (app *gRPCApplication) FinalizeBlock(_ context.Context, req *types.RequestFinalizeBlock) (*types.ResponseFinalizeBlock, error) { - res := app.app.FinalizeBlock(*req) +func (app *gRPCApplication) FinalizeBlock(ctx context.Context, req *types.RequestFinalizeBlock) (*types.ResponseFinalizeBlock, error) { + res := app.app.FinalizeBlock(ctx, *req) return &res, nil } diff --git a/abci/server/socket_server.go b/abci/server/socket_server.go index 72dd1221c..bf3dbdf09 100644 --- a/abci/server/socket_server.go +++ b/abci/server/socket_server.go @@ -159,11 +159,7 @@ func (s *SocketServer) acceptConnectionsRoutine(ctx context.Context) { } // Read requests from conn and deal with them -func (s *SocketServer) handleRequests( - ctx context.Context, - closer func(error), - conn io.Reader, - responses chan<- *types.Response, +func (s *SocketServer) handleRequests(ctx context.Context, closer func(error), conn io.Reader, responses chan<- *types.Response, ) { var bufReader = bufio.NewReader(conn) @@ -184,7 +180,7 @@ func (s *SocketServer) handleRequests( return } - resp := s.processRequest(req) + resp := s.processRequest(ctx, req) select { case <-ctx.Done(): closer(ctx.Err()) @@ -194,40 +190,40 @@ func (s *SocketServer) handleRequests( } } -func (s *SocketServer) processRequest(req *types.Request) *types.Response { +func (s *SocketServer) processRequest(ctx context.Context, req *types.Request) *types.Response { switch r := req.Value.(type) { case *types.Request_Echo: return types.ToResponseEcho(r.Echo.Message) case *types.Request_Flush: return types.ToResponseFlush() case *types.Request_Info: - return types.ToResponseInfo(s.app.Info(*r.Info)) + return types.ToResponseInfo(s.app.Info(ctx, *r.Info)) case *types.Request_CheckTx: - return types.ToResponseCheckTx(s.app.CheckTx(*r.CheckTx)) + return types.ToResponseCheckTx(s.app.CheckTx(ctx, *r.CheckTx)) case *types.Request_Commit: - return types.ToResponseCommit(s.app.Commit()) + return types.ToResponseCommit(s.app.Commit(ctx)) case *types.Request_Query: - return types.ToResponseQuery(s.app.Query(*r.Query)) + return types.ToResponseQuery(s.app.Query(ctx, *r.Query)) case *types.Request_InitChain: - return types.ToResponseInitChain(s.app.InitChain(*r.InitChain)) + return types.ToResponseInitChain(s.app.InitChain(ctx, *r.InitChain)) case *types.Request_ListSnapshots: - return types.ToResponseListSnapshots(s.app.ListSnapshots(*r.ListSnapshots)) + return types.ToResponseListSnapshots(s.app.ListSnapshots(ctx, *r.ListSnapshots)) case *types.Request_OfferSnapshot: - return types.ToResponseOfferSnapshot(s.app.OfferSnapshot(*r.OfferSnapshot)) + return types.ToResponseOfferSnapshot(s.app.OfferSnapshot(ctx, *r.OfferSnapshot)) case *types.Request_PrepareProposal: - return types.ToResponsePrepareProposal(s.app.PrepareProposal(*r.PrepareProposal)) + return types.ToResponsePrepareProposal(s.app.PrepareProposal(ctx, *r.PrepareProposal)) case *types.Request_ProcessProposal: - return types.ToResponseProcessProposal(s.app.ProcessProposal(*r.ProcessProposal)) + return types.ToResponseProcessProposal(s.app.ProcessProposal(ctx, *r.ProcessProposal)) case *types.Request_LoadSnapshotChunk: - return types.ToResponseLoadSnapshotChunk(s.app.LoadSnapshotChunk(*r.LoadSnapshotChunk)) + return types.ToResponseLoadSnapshotChunk(s.app.LoadSnapshotChunk(ctx, *r.LoadSnapshotChunk)) case *types.Request_ApplySnapshotChunk: - return types.ToResponseApplySnapshotChunk(s.app.ApplySnapshotChunk(*r.ApplySnapshotChunk)) + return types.ToResponseApplySnapshotChunk(s.app.ApplySnapshotChunk(ctx, *r.ApplySnapshotChunk)) case *types.Request_ExtendVote: - return types.ToResponseExtendVote(s.app.ExtendVote(*r.ExtendVote)) + return types.ToResponseExtendVote(s.app.ExtendVote(ctx, *r.ExtendVote)) case *types.Request_VerifyVoteExtension: - return types.ToResponseVerifyVoteExtension(s.app.VerifyVoteExtension(*r.VerifyVoteExtension)) + return types.ToResponseVerifyVoteExtension(s.app.VerifyVoteExtension(ctx, *r.VerifyVoteExtension)) case *types.Request_FinalizeBlock: - return types.ToResponseFinalizeBlock(s.app.FinalizeBlock(*r.FinalizeBlock)) + return types.ToResponseFinalizeBlock(s.app.FinalizeBlock(ctx, *r.FinalizeBlock)) default: return types.ToResponseException("Unknown request") } diff --git a/abci/types/application.go b/abci/types/application.go index 067c0cdba..c8ac12f87 100644 --- a/abci/types/application.go +++ b/abci/types/application.go @@ -1,5 +1,7 @@ package types +import "context" + //go:generate ../../scripts/mockery_generate.sh Application // Application is an interface that enables any finite, deterministic state machine // to be driven by a blockchain-based replication engine via the ABCI. @@ -7,30 +9,30 @@ package types // except CheckTx/DeliverTx, which take `tx []byte`, and `Commit`, which takes nothing. type Application interface { // Info/Query Connection - Info(RequestInfo) ResponseInfo // Return application info - Query(RequestQuery) ResponseQuery // Query for state + Info(context.Context, RequestInfo) ResponseInfo // Return application info + Query(context.Context, RequestQuery) ResponseQuery // Query for state // Mempool Connection - CheckTx(RequestCheckTx) ResponseCheckTx // Validate a tx for the mempool + CheckTx(context.Context, RequestCheckTx) ResponseCheckTx // Validate a tx for the mempool // Consensus Connection - InitChain(RequestInitChain) ResponseInitChain // Initialize blockchain w validators/other info from TendermintCore - PrepareProposal(RequestPrepareProposal) ResponsePrepareProposal - ProcessProposal(RequestProcessProposal) ResponseProcessProposal + InitChain(context.Context, RequestInitChain) ResponseInitChain // Initialize blockchain w validators/other info from TendermintCore + PrepareProposal(context.Context, RequestPrepareProposal) ResponsePrepareProposal + ProcessProposal(context.Context, RequestProcessProposal) ResponseProcessProposal // Commit the state and return the application Merkle root hash - Commit() ResponseCommit + Commit(context.Context) ResponseCommit // Create application specific vote extension - ExtendVote(RequestExtendVote) ResponseExtendVote + ExtendVote(context.Context, RequestExtendVote) ResponseExtendVote // Verify application's vote extension data - VerifyVoteExtension(RequestVerifyVoteExtension) ResponseVerifyVoteExtension + VerifyVoteExtension(context.Context, RequestVerifyVoteExtension) ResponseVerifyVoteExtension // Deliver the decided block with its txs to the Application - FinalizeBlock(RequestFinalizeBlock) ResponseFinalizeBlock + FinalizeBlock(context.Context, RequestFinalizeBlock) ResponseFinalizeBlock // State Sync Connection - ListSnapshots(RequestListSnapshots) ResponseListSnapshots // List available snapshots - OfferSnapshot(RequestOfferSnapshot) ResponseOfferSnapshot // Offer a snapshot to the application - LoadSnapshotChunk(RequestLoadSnapshotChunk) ResponseLoadSnapshotChunk // Load a snapshot chunk - ApplySnapshotChunk(RequestApplySnapshotChunk) ResponseApplySnapshotChunk // Apply a shapshot chunk + ListSnapshots(context.Context, RequestListSnapshots) ResponseListSnapshots // List available snapshots + OfferSnapshot(context.Context, RequestOfferSnapshot) ResponseOfferSnapshot // Offer a snapshot to the application + LoadSnapshotChunk(context.Context, RequestLoadSnapshotChunk) ResponseLoadSnapshotChunk // Load a snapshot chunk + ApplySnapshotChunk(context.Context, RequestApplySnapshotChunk) ResponseApplySnapshotChunk // Apply a shapshot chunk } //------------------------------------------------------- @@ -44,53 +46,53 @@ func NewBaseApplication() *BaseApplication { return &BaseApplication{} } -func (BaseApplication) Info(req RequestInfo) ResponseInfo { +func (BaseApplication) Info(_ context.Context, req RequestInfo) ResponseInfo { return ResponseInfo{} } -func (BaseApplication) CheckTx(req RequestCheckTx) ResponseCheckTx { +func (BaseApplication) CheckTx(_ context.Context, req RequestCheckTx) ResponseCheckTx { return ResponseCheckTx{Code: CodeTypeOK} } -func (BaseApplication) Commit() ResponseCommit { +func (BaseApplication) Commit(_ context.Context) ResponseCommit { return ResponseCommit{} } -func (BaseApplication) ExtendVote(req RequestExtendVote) ResponseExtendVote { +func (BaseApplication) ExtendVote(_ context.Context, req RequestExtendVote) ResponseExtendVote { return ResponseExtendVote{} } -func (BaseApplication) VerifyVoteExtension(req RequestVerifyVoteExtension) ResponseVerifyVoteExtension { +func (BaseApplication) VerifyVoteExtension(_ context.Context, req RequestVerifyVoteExtension) ResponseVerifyVoteExtension { return ResponseVerifyVoteExtension{ Status: ResponseVerifyVoteExtension_ACCEPT, } } -func (BaseApplication) Query(req RequestQuery) ResponseQuery { +func (BaseApplication) Query(_ context.Context, req RequestQuery) ResponseQuery { return ResponseQuery{Code: CodeTypeOK} } -func (BaseApplication) InitChain(req RequestInitChain) ResponseInitChain { +func (BaseApplication) InitChain(_ context.Context, req RequestInitChain) ResponseInitChain { return ResponseInitChain{} } -func (BaseApplication) ListSnapshots(req RequestListSnapshots) ResponseListSnapshots { +func (BaseApplication) ListSnapshots(_ context.Context, req RequestListSnapshots) ResponseListSnapshots { return ResponseListSnapshots{} } -func (BaseApplication) OfferSnapshot(req RequestOfferSnapshot) ResponseOfferSnapshot { +func (BaseApplication) OfferSnapshot(_ context.Context, req RequestOfferSnapshot) ResponseOfferSnapshot { return ResponseOfferSnapshot{} } -func (BaseApplication) LoadSnapshotChunk(req RequestLoadSnapshotChunk) ResponseLoadSnapshotChunk { +func (BaseApplication) LoadSnapshotChunk(_ context.Context, _ RequestLoadSnapshotChunk) ResponseLoadSnapshotChunk { return ResponseLoadSnapshotChunk{} } -func (BaseApplication) ApplySnapshotChunk(req RequestApplySnapshotChunk) ResponseApplySnapshotChunk { +func (BaseApplication) ApplySnapshotChunk(_ context.Context, req RequestApplySnapshotChunk) ResponseApplySnapshotChunk { return ResponseApplySnapshotChunk{} } -func (BaseApplication) PrepareProposal(req RequestPrepareProposal) ResponsePrepareProposal { +func (BaseApplication) PrepareProposal(_ context.Context, req RequestPrepareProposal) ResponsePrepareProposal { trs := make([]*TxRecord, 0, len(req.Txs)) var totalBytes int64 for _, tx := range req.Txs { @@ -106,11 +108,11 @@ func (BaseApplication) PrepareProposal(req RequestPrepareProposal) ResponsePrepa return ResponsePrepareProposal{TxRecords: trs} } -func (BaseApplication) ProcessProposal(req RequestProcessProposal) ResponseProcessProposal { +func (BaseApplication) ProcessProposal(_ context.Context, req RequestProcessProposal) ResponseProcessProposal { return ResponseProcessProposal{Status: ResponseProcessProposal_ACCEPT} } -func (BaseApplication) FinalizeBlock(req RequestFinalizeBlock) ResponseFinalizeBlock { +func (BaseApplication) FinalizeBlock(_ context.Context, req RequestFinalizeBlock) ResponseFinalizeBlock { txs := make([]*ExecTxResult, len(req.Txs)) for i := range req.Txs { txs[i] = &ExecTxResult{Code: CodeTypeOK} diff --git a/abci/types/mocks/application.go b/abci/types/mocks/application.go index 30bf0f84c..4137f5f93 100644 --- a/abci/types/mocks/application.go +++ b/abci/types/mocks/application.go @@ -3,7 +3,11 @@ package mocks import ( + context "context" + testing "testing" + mock "github.com/stretchr/testify/mock" + types "github.com/tendermint/tendermint/abci/types" ) @@ -12,13 +16,13 @@ type Application struct { mock.Mock } -// ApplySnapshotChunk provides a mock function with given fields: _a0 -func (_m *Application) ApplySnapshotChunk(_a0 types.RequestApplySnapshotChunk) types.ResponseApplySnapshotChunk { - ret := _m.Called(_a0) +// ApplySnapshotChunk provides a mock function with given fields: _a0, _a1 +func (_m *Application) ApplySnapshotChunk(_a0 context.Context, _a1 types.RequestApplySnapshotChunk) types.ResponseApplySnapshotChunk { + ret := _m.Called(_a0, _a1) var r0 types.ResponseApplySnapshotChunk - if rf, ok := ret.Get(0).(func(types.RequestApplySnapshotChunk) types.ResponseApplySnapshotChunk); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, types.RequestApplySnapshotChunk) types.ResponseApplySnapshotChunk); ok { + r0 = rf(_a0, _a1) } else { r0 = ret.Get(0).(types.ResponseApplySnapshotChunk) } @@ -26,13 +30,13 @@ func (_m *Application) ApplySnapshotChunk(_a0 types.RequestApplySnapshotChunk) t return r0 } -// CheckTx provides a mock function with given fields: _a0 -func (_m *Application) CheckTx(_a0 types.RequestCheckTx) types.ResponseCheckTx { - ret := _m.Called(_a0) +// CheckTx provides a mock function with given fields: _a0, _a1 +func (_m *Application) CheckTx(_a0 context.Context, _a1 types.RequestCheckTx) types.ResponseCheckTx { + ret := _m.Called(_a0, _a1) var r0 types.ResponseCheckTx - if rf, ok := ret.Get(0).(func(types.RequestCheckTx) types.ResponseCheckTx); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, types.RequestCheckTx) types.ResponseCheckTx); ok { + r0 = rf(_a0, _a1) } else { r0 = ret.Get(0).(types.ResponseCheckTx) } @@ -40,13 +44,13 @@ func (_m *Application) CheckTx(_a0 types.RequestCheckTx) types.ResponseCheckTx { return r0 } -// Commit provides a mock function with given fields: -func (_m *Application) Commit() types.ResponseCommit { - ret := _m.Called() +// Commit provides a mock function with given fields: _a0 +func (_m *Application) Commit(_a0 context.Context) types.ResponseCommit { + ret := _m.Called(_a0) var r0 types.ResponseCommit - if rf, ok := ret.Get(0).(func() types.ResponseCommit); ok { - r0 = rf() + if rf, ok := ret.Get(0).(func(context.Context) types.ResponseCommit); ok { + r0 = rf(_a0) } else { r0 = ret.Get(0).(types.ResponseCommit) } @@ -54,13 +58,13 @@ func (_m *Application) Commit() types.ResponseCommit { return r0 } -// ExtendVote provides a mock function with given fields: _a0 -func (_m *Application) ExtendVote(_a0 types.RequestExtendVote) types.ResponseExtendVote { - ret := _m.Called(_a0) +// ExtendVote provides a mock function with given fields: _a0, _a1 +func (_m *Application) ExtendVote(_a0 context.Context, _a1 types.RequestExtendVote) types.ResponseExtendVote { + ret := _m.Called(_a0, _a1) var r0 types.ResponseExtendVote - if rf, ok := ret.Get(0).(func(types.RequestExtendVote) types.ResponseExtendVote); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, types.RequestExtendVote) types.ResponseExtendVote); ok { + r0 = rf(_a0, _a1) } else { r0 = ret.Get(0).(types.ResponseExtendVote) } @@ -68,13 +72,13 @@ func (_m *Application) ExtendVote(_a0 types.RequestExtendVote) types.ResponseExt return r0 } -// FinalizeBlock provides a mock function with given fields: _a0 -func (_m *Application) FinalizeBlock(_a0 types.RequestFinalizeBlock) types.ResponseFinalizeBlock { - ret := _m.Called(_a0) +// FinalizeBlock provides a mock function with given fields: _a0, _a1 +func (_m *Application) FinalizeBlock(_a0 context.Context, _a1 types.RequestFinalizeBlock) types.ResponseFinalizeBlock { + ret := _m.Called(_a0, _a1) var r0 types.ResponseFinalizeBlock - if rf, ok := ret.Get(0).(func(types.RequestFinalizeBlock) types.ResponseFinalizeBlock); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, types.RequestFinalizeBlock) types.ResponseFinalizeBlock); ok { + r0 = rf(_a0, _a1) } else { r0 = ret.Get(0).(types.ResponseFinalizeBlock) } @@ -82,13 +86,13 @@ func (_m *Application) FinalizeBlock(_a0 types.RequestFinalizeBlock) types.Respo return r0 } -// Info provides a mock function with given fields: _a0 -func (_m *Application) Info(_a0 types.RequestInfo) types.ResponseInfo { - ret := _m.Called(_a0) +// Info provides a mock function with given fields: _a0, _a1 +func (_m *Application) Info(_a0 context.Context, _a1 types.RequestInfo) types.ResponseInfo { + ret := _m.Called(_a0, _a1) var r0 types.ResponseInfo - if rf, ok := ret.Get(0).(func(types.RequestInfo) types.ResponseInfo); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, types.RequestInfo) types.ResponseInfo); ok { + r0 = rf(_a0, _a1) } else { r0 = ret.Get(0).(types.ResponseInfo) } @@ -96,13 +100,13 @@ func (_m *Application) Info(_a0 types.RequestInfo) types.ResponseInfo { return r0 } -// InitChain provides a mock function with given fields: _a0 -func (_m *Application) InitChain(_a0 types.RequestInitChain) types.ResponseInitChain { - ret := _m.Called(_a0) +// InitChain provides a mock function with given fields: _a0, _a1 +func (_m *Application) InitChain(_a0 context.Context, _a1 types.RequestInitChain) types.ResponseInitChain { + ret := _m.Called(_a0, _a1) var r0 types.ResponseInitChain - if rf, ok := ret.Get(0).(func(types.RequestInitChain) types.ResponseInitChain); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, types.RequestInitChain) types.ResponseInitChain); ok { + r0 = rf(_a0, _a1) } else { r0 = ret.Get(0).(types.ResponseInitChain) } @@ -110,13 +114,13 @@ func (_m *Application) InitChain(_a0 types.RequestInitChain) types.ResponseInitC return r0 } -// ListSnapshots provides a mock function with given fields: _a0 -func (_m *Application) ListSnapshots(_a0 types.RequestListSnapshots) types.ResponseListSnapshots { - ret := _m.Called(_a0) +// ListSnapshots provides a mock function with given fields: _a0, _a1 +func (_m *Application) ListSnapshots(_a0 context.Context, _a1 types.RequestListSnapshots) types.ResponseListSnapshots { + ret := _m.Called(_a0, _a1) var r0 types.ResponseListSnapshots - if rf, ok := ret.Get(0).(func(types.RequestListSnapshots) types.ResponseListSnapshots); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, types.RequestListSnapshots) types.ResponseListSnapshots); ok { + r0 = rf(_a0, _a1) } else { r0 = ret.Get(0).(types.ResponseListSnapshots) } @@ -124,13 +128,13 @@ func (_m *Application) ListSnapshots(_a0 types.RequestListSnapshots) types.Respo return r0 } -// LoadSnapshotChunk provides a mock function with given fields: _a0 -func (_m *Application) LoadSnapshotChunk(_a0 types.RequestLoadSnapshotChunk) types.ResponseLoadSnapshotChunk { - ret := _m.Called(_a0) +// LoadSnapshotChunk provides a mock function with given fields: _a0, _a1 +func (_m *Application) LoadSnapshotChunk(_a0 context.Context, _a1 types.RequestLoadSnapshotChunk) types.ResponseLoadSnapshotChunk { + ret := _m.Called(_a0, _a1) var r0 types.ResponseLoadSnapshotChunk - if rf, ok := ret.Get(0).(func(types.RequestLoadSnapshotChunk) types.ResponseLoadSnapshotChunk); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, types.RequestLoadSnapshotChunk) types.ResponseLoadSnapshotChunk); ok { + r0 = rf(_a0, _a1) } else { r0 = ret.Get(0).(types.ResponseLoadSnapshotChunk) } @@ -138,13 +142,13 @@ func (_m *Application) LoadSnapshotChunk(_a0 types.RequestLoadSnapshotChunk) typ return r0 } -// OfferSnapshot provides a mock function with given fields: _a0 -func (_m *Application) OfferSnapshot(_a0 types.RequestOfferSnapshot) types.ResponseOfferSnapshot { - ret := _m.Called(_a0) +// OfferSnapshot provides a mock function with given fields: _a0, _a1 +func (_m *Application) OfferSnapshot(_a0 context.Context, _a1 types.RequestOfferSnapshot) types.ResponseOfferSnapshot { + ret := _m.Called(_a0, _a1) var r0 types.ResponseOfferSnapshot - if rf, ok := ret.Get(0).(func(types.RequestOfferSnapshot) types.ResponseOfferSnapshot); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, types.RequestOfferSnapshot) types.ResponseOfferSnapshot); ok { + r0 = rf(_a0, _a1) } else { r0 = ret.Get(0).(types.ResponseOfferSnapshot) } @@ -152,13 +156,13 @@ func (_m *Application) OfferSnapshot(_a0 types.RequestOfferSnapshot) types.Respo return r0 } -// PrepareProposal provides a mock function with given fields: _a0 -func (_m *Application) PrepareProposal(_a0 types.RequestPrepareProposal) types.ResponsePrepareProposal { - ret := _m.Called(_a0) +// PrepareProposal provides a mock function with given fields: _a0, _a1 +func (_m *Application) PrepareProposal(_a0 context.Context, _a1 types.RequestPrepareProposal) types.ResponsePrepareProposal { + ret := _m.Called(_a0, _a1) var r0 types.ResponsePrepareProposal - if rf, ok := ret.Get(0).(func(types.RequestPrepareProposal) types.ResponsePrepareProposal); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, types.RequestPrepareProposal) types.ResponsePrepareProposal); ok { + r0 = rf(_a0, _a1) } else { r0 = ret.Get(0).(types.ResponsePrepareProposal) } @@ -166,13 +170,13 @@ func (_m *Application) PrepareProposal(_a0 types.RequestPrepareProposal) types.R return r0 } -// ProcessProposal provides a mock function with given fields: _a0 -func (_m *Application) ProcessProposal(_a0 types.RequestProcessProposal) types.ResponseProcessProposal { - ret := _m.Called(_a0) +// ProcessProposal provides a mock function with given fields: _a0, _a1 +func (_m *Application) ProcessProposal(_a0 context.Context, _a1 types.RequestProcessProposal) types.ResponseProcessProposal { + ret := _m.Called(_a0, _a1) var r0 types.ResponseProcessProposal - if rf, ok := ret.Get(0).(func(types.RequestProcessProposal) types.ResponseProcessProposal); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, types.RequestProcessProposal) types.ResponseProcessProposal); ok { + r0 = rf(_a0, _a1) } else { r0 = ret.Get(0).(types.ResponseProcessProposal) } @@ -180,13 +184,13 @@ func (_m *Application) ProcessProposal(_a0 types.RequestProcessProposal) types.R return r0 } -// Query provides a mock function with given fields: _a0 -func (_m *Application) Query(_a0 types.RequestQuery) types.ResponseQuery { - ret := _m.Called(_a0) +// Query provides a mock function with given fields: _a0, _a1 +func (_m *Application) Query(_a0 context.Context, _a1 types.RequestQuery) types.ResponseQuery { + ret := _m.Called(_a0, _a1) var r0 types.ResponseQuery - if rf, ok := ret.Get(0).(func(types.RequestQuery) types.ResponseQuery); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, types.RequestQuery) types.ResponseQuery); ok { + r0 = rf(_a0, _a1) } else { r0 = ret.Get(0).(types.ResponseQuery) } @@ -194,16 +198,25 @@ func (_m *Application) Query(_a0 types.RequestQuery) types.ResponseQuery { return r0 } -// VerifyVoteExtension provides a mock function with given fields: _a0 -func (_m *Application) VerifyVoteExtension(_a0 types.RequestVerifyVoteExtension) types.ResponseVerifyVoteExtension { - ret := _m.Called(_a0) +// VerifyVoteExtension provides a mock function with given fields: _a0, _a1 +func (_m *Application) VerifyVoteExtension(_a0 context.Context, _a1 types.RequestVerifyVoteExtension) types.ResponseVerifyVoteExtension { + ret := _m.Called(_a0, _a1) var r0 types.ResponseVerifyVoteExtension - if rf, ok := ret.Get(0).(func(types.RequestVerifyVoteExtension) types.ResponseVerifyVoteExtension); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, types.RequestVerifyVoteExtension) types.ResponseVerifyVoteExtension); ok { + r0 = rf(_a0, _a1) } else { r0 = ret.Get(0).(types.ResponseVerifyVoteExtension) } return r0 } + +// NewApplication creates a new instance of Application. It also registers a cleanup function to assert the mocks expectations. +func NewApplication(t testing.TB) *Application { + mock := &Application{} + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/abci/types/mocks/base.go b/abci/types/mocks/base.go index fe0516e26..da14fb8fe 100644 --- a/abci/types/mocks/base.go +++ b/abci/types/mocks/base.go @@ -1,6 +1,8 @@ package mocks import ( + context "context" + types "github.com/tendermint/tendermint/abci/types" ) @@ -25,151 +27,151 @@ func NewBaseMock() BaseMock { // Info/Query Connection // Return application info -func (m BaseMock) Info(input types.RequestInfo) (ret types.ResponseInfo) { +func (m BaseMock) Info(ctx context.Context, input types.RequestInfo) (ret types.ResponseInfo) { defer func() { if r := recover(); r != nil { - ret = m.base.Info(input) + ret = m.base.Info(ctx, input) } }() - ret = m.Application.Info(input) + ret = m.Application.Info(ctx, input) return ret } -func (m BaseMock) Query(input types.RequestQuery) (ret types.ResponseQuery) { +func (m BaseMock) Query(ctx context.Context, input types.RequestQuery) (ret types.ResponseQuery) { defer func() { if r := recover(); r != nil { - ret = m.base.Query(input) + ret = m.base.Query(ctx, input) } }() - ret = m.Application.Query(input) + ret = m.Application.Query(ctx, input) return ret } // Mempool Connection // Validate a tx for the mempool -func (m BaseMock) CheckTx(input types.RequestCheckTx) (ret types.ResponseCheckTx) { +func (m BaseMock) CheckTx(ctx context.Context, input types.RequestCheckTx) (ret types.ResponseCheckTx) { defer func() { if r := recover(); r != nil { - ret = m.base.CheckTx(input) + ret = m.base.CheckTx(ctx, input) } }() - ret = m.Application.CheckTx(input) + ret = m.Application.CheckTx(ctx, input) return ret } // Consensus Connection // Initialize blockchain w validators/other info from TendermintCore -func (m BaseMock) InitChain(input types.RequestInitChain) (ret types.ResponseInitChain) { +func (m BaseMock) InitChain(ctx context.Context, input types.RequestInitChain) (ret types.ResponseInitChain) { defer func() { if r := recover(); r != nil { - ret = m.base.InitChain(input) + ret = m.base.InitChain(ctx, input) } }() - ret = m.Application.InitChain(input) + ret = m.Application.InitChain(ctx, input) return ret } -func (m BaseMock) PrepareProposal(input types.RequestPrepareProposal) (ret types.ResponsePrepareProposal) { +func (m BaseMock) PrepareProposal(ctx context.Context, input types.RequestPrepareProposal) (ret types.ResponsePrepareProposal) { defer func() { if r := recover(); r != nil { - ret = m.base.PrepareProposal(input) + ret = m.base.PrepareProposal(ctx, input) } }() - ret = m.Application.PrepareProposal(input) + ret = m.Application.PrepareProposal(ctx, input) return ret } -func (m BaseMock) ProcessProposal(input types.RequestProcessProposal) (ret types.ResponseProcessProposal) { +func (m BaseMock) ProcessProposal(ctx context.Context, input types.RequestProcessProposal) (ret types.ResponseProcessProposal) { defer func() { if r := recover(); r != nil { - ret = m.base.ProcessProposal(input) + ret = m.base.ProcessProposal(ctx, input) } }() - ret = m.Application.ProcessProposal(input) + ret = m.Application.ProcessProposal(ctx, input) return ret } // Commit the state and return the application Merkle root hash -func (m BaseMock) Commit() (ret types.ResponseCommit) { +func (m BaseMock) Commit(ctx context.Context) (ret types.ResponseCommit) { defer func() { if r := recover(); r != nil { - ret = m.base.Commit() + ret = m.base.Commit(ctx) } }() - ret = m.Application.Commit() + ret = m.Application.Commit(ctx) return ret } // Create application specific vote extension -func (m BaseMock) ExtendVote(input types.RequestExtendVote) (ret types.ResponseExtendVote) { +func (m BaseMock) ExtendVote(ctx context.Context, input types.RequestExtendVote) (ret types.ResponseExtendVote) { defer func() { if r := recover(); r != nil { - ret = m.base.ExtendVote(input) + ret = m.base.ExtendVote(ctx, input) } }() - ret = m.Application.ExtendVote(input) + ret = m.Application.ExtendVote(ctx, input) return ret } // Verify application's vote extension data -func (m BaseMock) VerifyVoteExtension(input types.RequestVerifyVoteExtension) (ret types.ResponseVerifyVoteExtension) { +func (m BaseMock) VerifyVoteExtension(ctx context.Context, input types.RequestVerifyVoteExtension) (ret types.ResponseVerifyVoteExtension) { defer func() { if r := recover(); r != nil { - ret = m.base.VerifyVoteExtension(input) + ret = m.base.VerifyVoteExtension(ctx, input) } }() - ret = m.Application.VerifyVoteExtension(input) + ret = m.Application.VerifyVoteExtension(ctx, input) return ret } // State Sync Connection // List available snapshots -func (m BaseMock) ListSnapshots(input types.RequestListSnapshots) (ret types.ResponseListSnapshots) { +func (m BaseMock) ListSnapshots(ctx context.Context, input types.RequestListSnapshots) (ret types.ResponseListSnapshots) { defer func() { if r := recover(); r != nil { - ret = m.base.ListSnapshots(input) + ret = m.base.ListSnapshots(ctx, input) } }() - ret = m.Application.ListSnapshots(input) + ret = m.Application.ListSnapshots(ctx, input) return ret } -func (m BaseMock) OfferSnapshot(input types.RequestOfferSnapshot) (ret types.ResponseOfferSnapshot) { +func (m BaseMock) OfferSnapshot(ctx context.Context, input types.RequestOfferSnapshot) (ret types.ResponseOfferSnapshot) { defer func() { if r := recover(); r != nil { - ret = m.base.OfferSnapshot(input) + ret = m.base.OfferSnapshot(ctx, input) } }() - ret = m.Application.OfferSnapshot(input) + ret = m.Application.OfferSnapshot(ctx, input) return ret } -func (m BaseMock) LoadSnapshotChunk(input types.RequestLoadSnapshotChunk) (ret types.ResponseLoadSnapshotChunk) { +func (m BaseMock) LoadSnapshotChunk(ctx context.Context, input types.RequestLoadSnapshotChunk) (ret types.ResponseLoadSnapshotChunk) { defer func() { if r := recover(); r != nil { - ret = m.base.LoadSnapshotChunk(input) + ret = m.base.LoadSnapshotChunk(ctx, input) } }() - ret = m.Application.LoadSnapshotChunk(input) + ret = m.Application.LoadSnapshotChunk(ctx, input) return ret } -func (m BaseMock) ApplySnapshotChunk(input types.RequestApplySnapshotChunk) (ret types.ResponseApplySnapshotChunk) { +func (m BaseMock) ApplySnapshotChunk(ctx context.Context, input types.RequestApplySnapshotChunk) (ret types.ResponseApplySnapshotChunk) { defer func() { if r := recover(); r != nil { - ret = m.base.ApplySnapshotChunk(input) + ret = m.base.ApplySnapshotChunk(ctx, input) } }() - ret = m.Application.ApplySnapshotChunk(input) + ret = m.Application.ApplySnapshotChunk(ctx, input) return ret } -func (m BaseMock) FinalizeBlock(input types.RequestFinalizeBlock) (ret types.ResponseFinalizeBlock) { +func (m BaseMock) FinalizeBlock(ctx context.Context, input types.RequestFinalizeBlock) (ret types.ResponseFinalizeBlock) { defer func() { if r := recover(); r != nil { - ret = m.base.FinalizeBlock(input) + ret = m.base.FinalizeBlock(ctx, input) } }() - ret = m.Application.FinalizeBlock(input) + ret = m.Application.FinalizeBlock(ctx, input) return ret } diff --git a/internal/consensus/byzantine_test.go b/internal/consensus/byzantine_test.go index 2093a4aec..d6287d6f1 100644 --- a/internal/consensus/byzantine_test.go +++ b/internal/consensus/byzantine_test.go @@ -68,7 +68,7 @@ func TestByzantinePrevoteEquivocation(t *testing.T) { ensureDir(t, path.Dir(thisConfig.Consensus.WalFile()), 0700) // dir for wal app := kvstore.NewApplication() vals := types.TM2PB.ValidatorUpdates(state.Validators) - app.InitChain(abci.RequestInitChain{Validators: vals}) + app.InitChain(ctx, abci.RequestInitChain{Validators: vals}) blockDB := dbm.NewMemDB() blockStore := store.NewBlockStore(blockDB) diff --git a/internal/consensus/common_test.go b/internal/consensus/common_test.go index 8a19ef85a..67386e65d 100644 --- a/internal/consensus/common_test.go +++ b/internal/consensus/common_test.go @@ -12,6 +12,7 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" dbm "github.com/tendermint/tm-db" @@ -730,9 +731,9 @@ func ensureVoteMatch(t *testing.T, voteCh <-chan tmpubsub.Message, height int64, msg.Data()) vote := voteEvent.Vote - require.Equal(t, height, vote.Height, "expected height %d, but got %d", height, vote.Height) - require.Equal(t, round, vote.Round, "expected round %d, but got %d", round, vote.Round) - require.Equal(t, voteType, vote.Type, "expected type %s, but got %s", voteType, vote.Type) + assert.Equal(t, height, vote.Height, "expected height %d, but got %d", height, vote.Height) + assert.Equal(t, round, vote.Round, "expected round %d, but got %d", round, vote.Round) + assert.Equal(t, voteType, vote.Type, "expected type %s, but got %s", voteType, vote.Type) if hash == nil { require.Nil(t, vote.BlockID.Hash, "Expected prevote to be for nil, got %X", vote.BlockID.Hash) } else { @@ -820,7 +821,7 @@ func makeConsensusState( closeFuncs = append(closeFuncs, app.Close) vals := types.TM2PB.ValidatorUpdates(state.Validators) - app.InitChain(abci.RequestInitChain{Validators: vals}) + app.InitChain(ctx, abci.RequestInitChain{Validators: vals}) l := logger.With("validator", i, "module", "consensus") css[i] = newStateWithConfigAndBlockStore(ctx, t, l, thisConfig, state, privVals[i], app, blockStore) @@ -891,7 +892,7 @@ func randConsensusNetWithPeers( case *kvstore.Application: state.Version.Consensus.App = kvstore.ProtocolVersion } - app.InitChain(abci.RequestInitChain{Validators: vals}) + app.InitChain(ctx, abci.RequestInitChain{Validators: vals}) // sm.SaveState(stateDB,state) //height 1's validatorsInfo already saved in LoadStateFromDBOrGenesisDoc above css[i] = newStateWithConfig(ctx, t, logger.With("validator", i, "module", "consensus"), thisConfig, state, privVal, app) diff --git a/internal/consensus/mempool_test.go b/internal/consensus/mempool_test.go index ab7a2baf3..3111dbb52 100644 --- a/internal/consensus/mempool_test.go +++ b/internal/consensus/mempool_test.go @@ -199,10 +199,10 @@ func TestMempoolRmBadTx(t *testing.T) { txBytes := make([]byte, 8) binary.BigEndian.PutUint64(txBytes, uint64(0)) - resFinalize := app.FinalizeBlock(abci.RequestFinalizeBlock{Txs: [][]byte{txBytes}}) + resFinalize := app.FinalizeBlock(ctx, abci.RequestFinalizeBlock{Txs: [][]byte{txBytes}}) assert.False(t, resFinalize.TxResults[0].IsErr(), fmt.Sprintf("expected no error. got %v", resFinalize)) - resCommit := app.Commit() + resCommit := app.Commit(ctx) assert.True(t, len(resCommit.Data) > 0) emptyMempoolCh := make(chan struct{}) @@ -267,11 +267,11 @@ func NewCounterApplication() *CounterApplication { return &CounterApplication{} } -func (app *CounterApplication) Info(req abci.RequestInfo) abci.ResponseInfo { +func (app *CounterApplication) Info(_ context.Context, req abci.RequestInfo) abci.ResponseInfo { return abci.ResponseInfo{Data: fmt.Sprintf("txs:%v", app.txCount)} } -func (app *CounterApplication) FinalizeBlock(req abci.RequestFinalizeBlock) abci.ResponseFinalizeBlock { +func (app *CounterApplication) FinalizeBlock(_ context.Context, req abci.RequestFinalizeBlock) abci.ResponseFinalizeBlock { respTxs := make([]*abci.ExecTxResult, len(req.Txs)) for i, tx := range req.Txs { txValue := txAsUint64(tx) @@ -288,7 +288,7 @@ func (app *CounterApplication) FinalizeBlock(req abci.RequestFinalizeBlock) abci return abci.ResponseFinalizeBlock{TxResults: respTxs} } -func (app *CounterApplication) CheckTx(req abci.RequestCheckTx) abci.ResponseCheckTx { +func (app *CounterApplication) CheckTx(_ context.Context, req abci.RequestCheckTx) abci.ResponseCheckTx { txValue := txAsUint64(req.Tx) if txValue != uint64(app.mempoolTxCount) { return abci.ResponseCheckTx{ @@ -305,7 +305,7 @@ func txAsUint64(tx []byte) uint64 { return binary.BigEndian.Uint64(tx8) } -func (app *CounterApplication) Commit() abci.ResponseCommit { +func (app *CounterApplication) Commit(context.Context) abci.ResponseCommit { app.mempoolTxCount = app.txCount if app.txCount == 0 { return abci.ResponseCommit{} @@ -315,8 +315,7 @@ func (app *CounterApplication) Commit() abci.ResponseCommit { return abci.ResponseCommit{Data: hash} } -func (app *CounterApplication) PrepareProposal( - req abci.RequestPrepareProposal) abci.ResponsePrepareProposal { +func (app *CounterApplication) PrepareProposal(_ context.Context, req abci.RequestPrepareProposal) abci.ResponsePrepareProposal { trs := make([]*abci.TxRecord, 0, len(req.Txs)) var totalBytes int64 @@ -333,7 +332,6 @@ func (app *CounterApplication) PrepareProposal( return abci.ResponsePrepareProposal{TxRecords: trs} } -func (app *CounterApplication) ProcessProposal( - req abci.RequestProcessProposal) abci.ResponseProcessProposal { +func (app *CounterApplication) ProcessProposal(_ context.Context, req abci.RequestProcessProposal) abci.ResponseProcessProposal { return abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT} } diff --git a/internal/consensus/mocks/cons_sync_reactor.go b/internal/consensus/mocks/cons_sync_reactor.go index 5ac592f0d..801713414 100644 --- a/internal/consensus/mocks/cons_sync_reactor.go +++ b/internal/consensus/mocks/cons_sync_reactor.go @@ -3,6 +3,8 @@ package mocks import ( + testing "testing" + mock "github.com/stretchr/testify/mock" state "github.com/tendermint/tendermint/internal/state" ) @@ -26,3 +28,12 @@ func (_m *ConsSyncReactor) SetStateSyncingMetrics(_a0 float64) { func (_m *ConsSyncReactor) SwitchToConsensus(_a0 state.State, _a1 bool) { _m.Called(_a0, _a1) } + +// NewConsSyncReactor creates a new instance of ConsSyncReactor. It also registers a cleanup function to assert the mocks expectations. +func NewConsSyncReactor(t testing.TB) *ConsSyncReactor { + mock := &ConsSyncReactor{} + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/internal/consensus/reactor_test.go b/internal/consensus/reactor_test.go index 6a92b984f..2d4e6f61a 100644 --- a/internal/consensus/reactor_test.go +++ b/internal/consensus/reactor_test.go @@ -466,7 +466,7 @@ func TestReactorWithEvidence(t *testing.T) { app := kvstore.NewApplication() vals := types.TM2PB.ValidatorUpdates(state.Validators) - app.InitChain(abci.RequestInitChain{Validators: vals}) + app.InitChain(ctx, abci.RequestInitChain{Validators: vals}) pv := privVals[i] blockDB := dbm.NewMemDB() diff --git a/internal/consensus/replay_stubs.go b/internal/consensus/replay_stubs.go index e8f5cbc4b..141389caa 100644 --- a/internal/consensus/replay_stubs.go +++ b/internal/consensus/replay_stubs.go @@ -75,7 +75,7 @@ type mockProxyApp struct { abciResponses *tmstate.ABCIResponses } -func (mock *mockProxyApp) FinalizeBlock(req abci.RequestFinalizeBlock) abci.ResponseFinalizeBlock { +func (mock *mockProxyApp) FinalizeBlock(_ context.Context, req abci.RequestFinalizeBlock) abci.ResponseFinalizeBlock { r := mock.abciResponses.FinalizeBlock mock.txCount++ if r == nil { @@ -84,6 +84,6 @@ func (mock *mockProxyApp) FinalizeBlock(req abci.RequestFinalizeBlock) abci.Resp return *r } -func (mock *mockProxyApp) Commit() abci.ResponseCommit { +func (mock *mockProxyApp) Commit(context.Context) abci.ResponseCommit { return abci.ResponseCommit{Data: mock.appHash} } diff --git a/internal/consensus/replay_test.go b/internal/consensus/replay_test.go index 6d9e82a05..436a7c745 100644 --- a/internal/consensus/replay_test.go +++ b/internal/consensus/replay_test.go @@ -118,9 +118,6 @@ func sendTxs(ctx context.Context, t *testing.T, cs *State) { // TestWALCrash uses crashing WAL to test we can recover from any WAL failure. func TestWALCrash(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - testCases := []struct { name string initFn func(dbm.DB, *State, context.Context) @@ -139,6 +136,9 @@ func TestWALCrash(t *testing.T) { for _, tc := range testCases { tc := tc t.Run(tc.name, func(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + consensusReplayConfig, err := ResetConfig(t.TempDir(), tc.name) require.NoError(t, err) crashWALandCheckLiveness(ctx, t, consensusReplayConfig, tc.initFn, tc.heightToStop) @@ -1017,7 +1017,7 @@ type badApp struct { onlyLastHashIsWrong bool } -func (app *badApp) Commit() abci.ResponseCommit { +func (app *badApp) Commit(context.Context) abci.ResponseCommit { app.height++ if app.onlyLastHashIsWrong { if app.height == app.numBlocks { @@ -1275,7 +1275,7 @@ type initChainApp struct { vals []abci.ValidatorUpdate } -func (ica *initChainApp) InitChain(req abci.RequestInitChain) abci.ResponseInitChain { +func (ica *initChainApp) InitChain(_ context.Context, req abci.RequestInitChain) abci.ResponseInitChain { return abci.ResponseInitChain{ Validators: ica.vals, } diff --git a/internal/consensus/state_test.go b/internal/consensus/state_test.go index 345b65f56..6ddadd426 100644 --- a/internal/consensus/state_test.go +++ b/internal/consensus/state_test.go @@ -1917,7 +1917,8 @@ func TestProcessProposalAccept(t *testing.T) { if testCase.accept { status = abci.ResponseProcessProposal_ACCEPT } - m.On("ProcessProposal", mock.Anything).Return(abci.ResponseProcessProposal{Status: status}) + m.On("ProcessProposal", mock.Anything, mock.Anything).Return(abci.ResponseProcessProposal{Status: status}) + m.On("PrepareProposal", mock.Anything, mock.Anything).Return(abci.ResponsePrepareProposal{}) cs1, _ := makeState(ctx, t, makeStateArgs{config: config, application: m}) height, round := cs1.Height, cs1.Round @@ -1965,11 +1966,14 @@ func TestFinalizeBlockCalled(t *testing.T) { defer cancel() m := abcimocks.NewBaseMock() - m.On("ProcessProposal", mock.Anything).Return(abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT}) - m.On("VerifyVoteExtension", mock.Anything).Return(abci.ResponseVerifyVoteExtension{ + m.On("ProcessProposal", mock.Anything, mock.Anything).Return(abci.ResponseProcessProposal{ + Status: abci.ResponseProcessProposal_ACCEPT, + }) + m.On("PrepareProposal", mock.Anything, mock.Anything).Return(abci.ResponsePrepareProposal{}) + m.On("VerifyVoteExtension", mock.Anything, mock.Anything).Return(abci.ResponseVerifyVoteExtension{ Status: abci.ResponseVerifyVoteExtension_ACCEPT, }) - m.On("FinalizeBlock", mock.Anything).Return(abci.ResponseFinalizeBlock{}).Maybe() + m.On("FinalizeBlock", mock.Anything, mock.Anything).Return(abci.ResponseFinalizeBlock{}).Maybe() cs1, vss := makeState(ctx, t, makeStateArgs{config: config, application: m}) height, round := cs1.Height, cs1.Round @@ -2007,9 +2011,9 @@ func TestFinalizeBlockCalled(t *testing.T) { m.AssertExpectations(t) if !testCase.expectCalled { - m.AssertNotCalled(t, "FinalizeBlock", mock.Anything) + m.AssertNotCalled(t, "FinalizeBlock", ctx, mock.Anything) } else { - m.AssertCalled(t, "FinalizeBlock", mock.Anything) + m.AssertCalled(t, "FinalizeBlock", ctx, mock.Anything) } }) } @@ -2023,14 +2027,15 @@ func TestExtendVoteCalled(t *testing.T) { defer cancel() m := abcimocks.NewBaseMock() - m.On("ProcessProposal", mock.Anything).Return(abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT}) - m.On("ExtendVote", mock.Anything).Return(abci.ResponseExtendVote{ + m.On("ProcessProposal", mock.Anything, mock.Anything).Return(abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT}) + m.On("PrepareProposal", mock.Anything, mock.Anything).Return(abci.ResponsePrepareProposal{}) + m.On("ExtendVote", mock.Anything, mock.Anything).Return(abci.ResponseExtendVote{ VoteExtension: []byte("extension"), }) - m.On("VerifyVoteExtension", mock.Anything).Return(abci.ResponseVerifyVoteExtension{ + m.On("VerifyVoteExtension", mock.Anything, mock.Anything).Return(abci.ResponseVerifyVoteExtension{ Status: abci.ResponseVerifyVoteExtension_ACCEPT, }) - m.On("FinalizeBlock", mock.Anything).Return(abci.ResponseFinalizeBlock{}).Maybe() + m.On("FinalizeBlock", mock.Anything, mock.Anything).Return(abci.ResponseFinalizeBlock{}).Maybe() cs1, vss := makeState(ctx, t, makeStateArgs{config: config, application: m}) height, round := cs1.Height, cs1.Round @@ -2045,7 +2050,7 @@ func TestExtendVoteCalled(t *testing.T) { ensureNewRound(t, newRoundCh, height, round) ensureNewProposal(t, proposalCh, height, round) - m.AssertNotCalled(t, "ExtendVote", mock.Anything) + m.AssertNotCalled(t, "ExtendVote", mock.Anything, mock.Anything) rs := cs1.GetRoundState() @@ -2058,12 +2063,12 @@ func TestExtendVoteCalled(t *testing.T) { ensurePrecommit(t, voteCh, height, round) - m.AssertCalled(t, "ExtendVote", abci.RequestExtendVote{ + m.AssertCalled(t, "ExtendVote", ctx, abci.RequestExtendVote{ Height: height, Hash: blockID.Hash, }) - m.AssertCalled(t, "VerifyVoteExtension", abci.RequestVerifyVoteExtension{ + m.AssertCalled(t, "VerifyVoteExtension", ctx, abci.RequestVerifyVoteExtension{ Hash: blockID.Hash, ValidatorAddress: addr, Height: height, @@ -2080,7 +2085,7 @@ func TestExtendVoteCalled(t *testing.T) { pv, err := pv.GetPubKey(ctx) require.NoError(t, err) addr := pv.Address() - m.AssertCalled(t, "VerifyVoteExtension", abci.RequestVerifyVoteExtension{ + m.AssertCalled(t, "VerifyVoteExtension", ctx, abci.RequestVerifyVoteExtension{ Hash: blockID.Hash, ValidatorAddress: addr, Height: height, @@ -2098,14 +2103,15 @@ func TestVerifyVoteExtensionNotCalledOnAbsentPrecommit(t *testing.T) { defer cancel() m := abcimocks.NewBaseMock() - m.On("ProcessProposal", mock.Anything).Return(abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT}) - m.On("ExtendVote", mock.Anything).Return(abci.ResponseExtendVote{ + m.On("ProcessProposal", mock.Anything, mock.Anything).Return(abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT}) + m.On("PrepareProposal", mock.Anything, mock.Anything).Return(abci.ResponsePrepareProposal{}) + m.On("ExtendVote", mock.Anything, mock.Anything).Return(abci.ResponseExtendVote{ VoteExtension: []byte("extension"), }) - m.On("VerifyVoteExtension", mock.Anything).Return(abci.ResponseVerifyVoteExtension{ + m.On("VerifyVoteExtension", mock.Anything, mock.Anything).Return(abci.ResponseVerifyVoteExtension{ Status: abci.ResponseVerifyVoteExtension_ACCEPT, }) - m.On("FinalizeBlock", mock.Anything).Return(abci.ResponseFinalizeBlock{}).Maybe() + m.On("FinalizeBlock", mock.Anything, mock.Anything).Return(abci.ResponseFinalizeBlock{}).Maybe() cs1, vss := makeState(ctx, t, makeStateArgs{config: config, application: m}) height, round := cs1.Height, cs1.Round @@ -2130,12 +2136,12 @@ func TestVerifyVoteExtensionNotCalledOnAbsentPrecommit(t *testing.T) { ensurePrecommit(t, voteCh, height, round) - m.AssertCalled(t, "ExtendVote", abci.RequestExtendVote{ + m.AssertCalled(t, "ExtendVote", mock.Anything, abci.RequestExtendVote{ Height: height, Hash: blockID.Hash, }) - m.AssertCalled(t, "VerifyVoteExtension", abci.RequestVerifyVoteExtension{ + m.AssertCalled(t, "VerifyVoteExtension", mock.Anything, abci.RequestVerifyVoteExtension{ Hash: blockID.Hash, ValidatorAddress: addr, Height: height, @@ -2152,7 +2158,7 @@ func TestVerifyVoteExtensionNotCalledOnAbsentPrecommit(t *testing.T) { require.NoError(t, err) addr = pv.Address() - m.AssertNotCalled(t, "VerifyVoteExtension", abci.RequestVerifyVoteExtension{ + m.AssertNotCalled(t, "VerifyVoteExtension", ctx, abci.RequestVerifyVoteExtension{ Hash: blockID.Hash, ValidatorAddress: addr, Height: height, @@ -2168,10 +2174,11 @@ func TestVerifyVoteExtensionNotCalledOnAbsentPrecommit(t *testing.T) { // is the proposer again and ensures that the mock application receives the set of // vote extensions from the previous consensus instance. func TestPrepareProposalReceivesVoteExtensions(t *testing.T) { - config := configSetup(t) ctx, cancel := context.WithCancel(context.Background()) defer cancel() + config := configSetup(t) + // create a list of vote extensions, one for each validator. voteExtensions := [][]byte{ []byte("extension 0"), @@ -2181,10 +2188,12 @@ func TestPrepareProposalReceivesVoteExtensions(t *testing.T) { } m := abcimocks.NewBaseMock() - m.On("ExtendVote", mock.Anything).Return(abci.ResponseExtendVote{ + m.On("ExtendVote", mock.Anything, mock.Anything).Return(abci.ResponseExtendVote{ VoteExtension: voteExtensions[0], }) - m.On("PrepareProposal", mock.Anything).Return(abci.ResponsePrepareProposal{}).Once() + m.On("PrepareProposal", mock.Anything, mock.Anything).Return(abci.ResponsePrepareProposal{}).Once() + m.On("ProcessProposal", mock.Anything, mock.Anything).Return(abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT}).Once() + m.On("VerifyVoteExtension", mock.Anything, mock.Anything).Return(abci.ResponseVerifyVoteExtension{Status: abci.ResponseVerifyVoteExtension_ACCEPT}) cs1, vss := makeState(ctx, t, makeStateArgs{config: config, application: m}) height, round := cs1.Height, cs1.Round @@ -2228,7 +2237,7 @@ func TestPrepareProposalReceivesVoteExtensions(t *testing.T) { // capture the prepare proposal request. rpp := abci.RequestPrepareProposal{} - m.On("PrepareProposal", mock.MatchedBy(func(r abci.RequestPrepareProposal) bool { + m.On("PrepareProposal", mock.Anything, mock.MatchedBy(func(r abci.RequestPrepareProposal) bool { rpp = r return true })).Return(abci.ResponsePrepareProposal{}) diff --git a/internal/evidence/mocks/block_store.go b/internal/evidence/mocks/block_store.go index ef3346b2a..77745b15a 100644 --- a/internal/evidence/mocks/block_store.go +++ b/internal/evidence/mocks/block_store.go @@ -3,7 +3,10 @@ package mocks import ( + testing "testing" + mock "github.com/stretchr/testify/mock" + types "github.com/tendermint/tendermint/types" ) @@ -57,3 +60,12 @@ func (_m *BlockStore) LoadBlockMeta(height int64) *types.BlockMeta { return r0 } + +// NewBlockStore creates a new instance of BlockStore. It also registers a cleanup function to assert the mocks expectations. +func NewBlockStore(t testing.TB) *BlockStore { + mock := &BlockStore{} + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/internal/mempool/mempool_test.go b/internal/mempool/mempool_test.go index a20e793c3..5d6ba6825 100644 --- a/internal/mempool/mempool_test.go +++ b/internal/mempool/mempool_test.go @@ -36,7 +36,7 @@ type testTx struct { priority int64 } -func (app *application) CheckTx(req abci.RequestCheckTx) abci.ResponseCheckTx { +func (app *application) CheckTx(_ context.Context, req abci.RequestCheckTx) abci.ResponseCheckTx { var ( priority int64 sender string diff --git a/internal/mempool/mocks/mempool.go b/internal/mempool/mocks/mempool.go index d4cdfabd7..48017c6d2 100644 --- a/internal/mempool/mocks/mempool.go +++ b/internal/mempool/mocks/mempool.go @@ -11,6 +11,8 @@ import ( mock "github.com/stretchr/testify/mock" + testing "testing" + types "github.com/tendermint/tendermint/types" ) @@ -170,3 +172,12 @@ func (_m *Mempool) Update(ctx context.Context, blockHeight int64, blockTxs types return r0 } + +// NewMempool creates a new instance of Mempool. It also registers a cleanup function to assert the mocks expectations. +func NewMempool(t testing.TB) *Mempool { + mock := &Mempool{} + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/internal/p2p/mocks/connection.go b/internal/p2p/mocks/connection.go index 576fb2386..bb9390ddb 100644 --- a/internal/p2p/mocks/connection.go +++ b/internal/p2p/mocks/connection.go @@ -13,6 +13,8 @@ import ( p2p "github.com/tendermint/tendermint/internal/p2p" + testing "testing" + types "github.com/tendermint/tendermint/types" ) @@ -150,3 +152,12 @@ func (_m *Connection) String() string { return r0 } + +// NewConnection creates a new instance of Connection. It also registers a cleanup function to assert the mocks expectations. +func NewConnection(t testing.TB) *Connection { + mock := &Connection{} + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/internal/p2p/mocks/transport.go b/internal/p2p/mocks/transport.go index b17290118..6ca4146df 100644 --- a/internal/p2p/mocks/transport.go +++ b/internal/p2p/mocks/transport.go @@ -10,6 +10,8 @@ import ( mock "github.com/stretchr/testify/mock" p2p "github.com/tendermint/tendermint/internal/p2p" + + testing "testing" ) // Transport is an autogenerated mock type for the Transport type @@ -141,3 +143,12 @@ func (_m *Transport) String() string { return r0 } + +// NewTransport creates a new instance of Transport. It also registers a cleanup function to assert the mocks expectations. +func NewTransport(t testing.TB) *Transport { + mock := &Transport{} + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/internal/state/execution_test.go b/internal/state/execution_test.go index dcbe01ef3..c6caa4272 100644 --- a/internal/state/execution_test.go +++ b/internal/state/execution_test.go @@ -343,12 +343,12 @@ func TestProcessProposal(t *testing.T) { ProposerAddress: block1.ProposerAddress, } - app.On("ProcessProposal", mock.Anything).Return(abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT}) + app.On("ProcessProposal", mock.Anything, mock.Anything).Return(abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT}) acceptBlock, err := blockExec.ProcessProposal(ctx, block1, state) require.NoError(t, err) require.True(t, acceptBlock) app.AssertExpectations(t) - app.AssertCalled(t, "ProcessProposal", expectedRpp) + app.AssertCalled(t, "ProcessProposal", ctx, expectedRpp) } func TestValidateValidatorUpdates(t *testing.T) { @@ -691,7 +691,7 @@ func TestPrepareProposalErrorOnNonExistingRemoved(t *testing.T) { }, }, } - app.On("PrepareProposal", mock.Anything).Return(rpp) + app.On("PrepareProposal", mock.Anything, mock.Anything).Return(rpp) cc := abciclient.NewLocalClient(logger, app) proxyApp := proxy.New(cc, logger, proxy.NopMetrics()) @@ -745,7 +745,7 @@ func TestPrepareProposalRemoveTxs(t *testing.T) { mp.On("RemoveTxByKey", mock.Anything).Return(nil).Twice() app := abcimocks.NewBaseMock() - app.On("PrepareProposal", mock.Anything).Return(abci.ResponsePrepareProposal{ + app.On("PrepareProposal", mock.Anything, mock.Anything).Return(abci.ResponsePrepareProposal{ TxRecords: trs, }) @@ -804,7 +804,7 @@ func TestPrepareProposalAddedTxsIncluded(t *testing.T) { trs[1].Action = abci.TxRecord_ADDED app := abcimocks.NewBaseMock() - app.On("PrepareProposal", mock.Anything).Return(abci.ResponsePrepareProposal{ + app.On("PrepareProposal", mock.Anything, mock.Anything).Return(abci.ResponsePrepareProposal{ TxRecords: trs, }) @@ -860,7 +860,7 @@ func TestPrepareProposalReorderTxs(t *testing.T) { trs = append(trs[len(trs)/2:], trs[:len(trs)/2]...) app := abcimocks.NewBaseMock() - app.On("PrepareProposal", mock.Anything).Return(abci.ResponsePrepareProposal{ + app.On("PrepareProposal", mock.Anything, mock.Anything).Return(abci.ResponsePrepareProposal{ TxRecords: trs, }) @@ -920,7 +920,7 @@ func TestPrepareProposalErrorOnTooManyTxs(t *testing.T) { trs := txsToTxRecords(types.Txs(txs)) app := abcimocks.NewBaseMock() - app.On("PrepareProposal", mock.Anything).Return(abci.ResponsePrepareProposal{ + app.On("PrepareProposal", mock.Anything, mock.Anything).Return(abci.ResponsePrepareProposal{ TxRecords: trs, }) diff --git a/internal/state/helpers_test.go b/internal/state/helpers_test.go index c3c143462..e59c4c4d8 100644 --- a/internal/state/helpers_test.go +++ b/internal/state/helpers_test.go @@ -278,11 +278,11 @@ type testApp struct { var _ abci.Application = (*testApp)(nil) -func (app *testApp) Info(req abci.RequestInfo) (resInfo abci.ResponseInfo) { +func (app *testApp) Info(_ context.Context, req abci.RequestInfo) (resInfo abci.ResponseInfo) { return abci.ResponseInfo{} } -func (app *testApp) FinalizeBlock(req abci.RequestFinalizeBlock) abci.ResponseFinalizeBlock { +func (app *testApp) FinalizeBlock(_ context.Context, req abci.RequestFinalizeBlock) abci.ResponseFinalizeBlock { app.CommitVotes = req.DecidedLastCommit.Votes app.ByzantineValidators = req.ByzantineValidators @@ -307,19 +307,19 @@ func (app *testApp) FinalizeBlock(req abci.RequestFinalizeBlock) abci.ResponseFi } } -func (app *testApp) CheckTx(req abci.RequestCheckTx) abci.ResponseCheckTx { +func (app *testApp) CheckTx(_ context.Context, req abci.RequestCheckTx) abci.ResponseCheckTx { return abci.ResponseCheckTx{} } -func (app *testApp) Commit() abci.ResponseCommit { +func (app *testApp) Commit(context.Context) abci.ResponseCommit { return abci.ResponseCommit{RetainHeight: 1} } -func (app *testApp) Query(reqQuery abci.RequestQuery) (resQuery abci.ResponseQuery) { +func (app *testApp) Query(_ context.Context, req abci.RequestQuery) (resQuery abci.ResponseQuery) { return } -func (app *testApp) ProcessProposal(req abci.RequestProcessProposal) abci.ResponseProcessProposal { +func (app *testApp) ProcessProposal(_ context.Context, req abci.RequestProcessProposal) abci.ResponseProcessProposal { for _, tx := range req.Txs { if len(tx) == 0 { return abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_REJECT} diff --git a/internal/state/indexer/mocks/event_sink.go b/internal/state/indexer/mocks/event_sink.go index d5555a417..0daffbaf8 100644 --- a/internal/state/indexer/mocks/event_sink.go +++ b/internal/state/indexer/mocks/event_sink.go @@ -12,6 +12,8 @@ import ( tenderminttypes "github.com/tendermint/tendermint/types" + testing "testing" + types "github.com/tendermint/tendermint/abci/types" ) @@ -165,3 +167,12 @@ func (_m *EventSink) Type() indexer.EventSinkType { return r0 } + +// NewEventSink creates a new instance of EventSink. It also registers a cleanup function to assert the mocks expectations. +func NewEventSink(t testing.TB) *EventSink { + mock := &EventSink{} + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/internal/state/mocks/block_store.go b/internal/state/mocks/block_store.go index 563183437..7d7bbcf19 100644 --- a/internal/state/mocks/block_store.go +++ b/internal/state/mocks/block_store.go @@ -5,6 +5,8 @@ package mocks import ( mock "github.com/stretchr/testify/mock" + testing "testing" + types "github.com/tendermint/tendermint/types" ) @@ -208,3 +210,12 @@ func (_m *BlockStore) Size() int64 { return r0 } + +// NewBlockStore creates a new instance of BlockStore. It also registers a cleanup function to assert the mocks expectations. +func NewBlockStore(t testing.TB) *BlockStore { + mock := &BlockStore{} + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/internal/state/mocks/evidence_pool.go b/internal/state/mocks/evidence_pool.go index 04e8be7bc..1d081b3b8 100644 --- a/internal/state/mocks/evidence_pool.go +++ b/internal/state/mocks/evidence_pool.go @@ -8,6 +8,8 @@ import ( mock "github.com/stretchr/testify/mock" state "github.com/tendermint/tendermint/internal/state" + testing "testing" + types "github.com/tendermint/tendermint/types" ) @@ -71,3 +73,12 @@ func (_m *EvidencePool) PendingEvidence(maxBytes int64) ([]types.Evidence, int64 func (_m *EvidencePool) Update(_a0 context.Context, _a1 state.State, _a2 types.EvidenceList) { _m.Called(_a0, _a1, _a2) } + +// NewEvidencePool creates a new instance of EvidencePool. It also registers a cleanup function to assert the mocks expectations. +func NewEvidencePool(t testing.TB) *EvidencePool { + mock := &EvidencePool{} + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/internal/state/mocks/store.go b/internal/state/mocks/store.go index 02c69d3e0..3ef8a3ebb 100644 --- a/internal/state/mocks/store.go +++ b/internal/state/mocks/store.go @@ -7,6 +7,8 @@ import ( state "github.com/tendermint/tendermint/internal/state" tendermintstate "github.com/tendermint/tendermint/proto/tendermint/state" + testing "testing" + types "github.com/tendermint/tendermint/types" ) @@ -186,3 +188,12 @@ func (_m *Store) SaveValidatorSets(_a0 int64, _a1 int64, _a2 *types.ValidatorSet return r0 } + +// NewStore creates a new instance of Store. It also registers a cleanup function to assert the mocks expectations. +func NewStore(t testing.TB) *Store { + mock := &Store{} + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/internal/statesync/mocks/state_provider.go b/internal/statesync/mocks/state_provider.go index b8d681631..83287aa2f 100644 --- a/internal/statesync/mocks/state_provider.go +++ b/internal/statesync/mocks/state_provider.go @@ -8,6 +8,8 @@ import ( mock "github.com/stretchr/testify/mock" state "github.com/tendermint/tendermint/internal/state" + testing "testing" + types "github.com/tendermint/tendermint/types" ) @@ -82,3 +84,12 @@ func (_m *StateProvider) State(ctx context.Context, height uint64) (state.State, return r0, r1 } + +// NewStateProvider creates a new instance of StateProvider. It also registers a cleanup function to assert the mocks expectations. +func NewStateProvider(t testing.TB) *StateProvider { + mock := &StateProvider{} + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/libs/time/mocks/source.go b/libs/time/mocks/source.go index a8e49b314..0872db5e3 100644 --- a/libs/time/mocks/source.go +++ b/libs/time/mocks/source.go @@ -3,9 +3,11 @@ package mocks import ( - time "time" + testing "testing" mock "github.com/stretchr/testify/mock" + + time "time" ) // Source is an autogenerated mock type for the Source type @@ -26,3 +28,12 @@ func (_m *Source) Now() time.Time { return r0 } + +// NewSource creates a new instance of Source. It also registers a cleanup function to assert the mocks expectations. +func NewSource(t testing.TB) *Source { + mock := &Source{} + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/light/provider/mocks/provider.go b/light/provider/mocks/provider.go index 1b4e583de..fe0fbade5 100644 --- a/light/provider/mocks/provider.go +++ b/light/provider/mocks/provider.go @@ -7,6 +7,8 @@ import ( mock "github.com/stretchr/testify/mock" + testing "testing" + types "github.com/tendermint/tendermint/types" ) @@ -65,3 +67,12 @@ func (_m *Provider) ReportEvidence(_a0 context.Context, _a1 types.Evidence) erro return r0 } + +// NewProvider creates a new instance of Provider. It also registers a cleanup function to assert the mocks expectations. +func NewProvider(t testing.TB) *Provider { + mock := &Provider{} + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/light/rpc/mocks/light_client.go b/light/rpc/mocks/light_client.go index 347d14707..4ca1c1dce 100644 --- a/light/rpc/mocks/light_client.go +++ b/light/rpc/mocks/light_client.go @@ -7,6 +7,8 @@ import ( mock "github.com/stretchr/testify/mock" + testing "testing" + time "time" types "github.com/tendermint/tendermint/types" @@ -115,3 +117,12 @@ func (_m *LightClient) VerifyLightBlockAtHeight(ctx context.Context, height int6 return r0, r1 } + +// NewLightClient creates a new instance of LightClient. It also registers a cleanup function to assert the mocks expectations. +func NewLightClient(t testing.TB) *LightClient { + mock := &LightClient{} + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/rpc/client/mock/abci.go b/rpc/client/mock/abci.go index 8c652444b..ce751717d 100644 --- a/rpc/client/mock/abci.go +++ b/rpc/client/mock/abci.go @@ -25,19 +25,15 @@ var ( ) func (a ABCIApp) ABCIInfo(ctx context.Context) (*coretypes.ResultABCIInfo, error) { - return &coretypes.ResultABCIInfo{Response: a.App.Info(proxy.RequestInfo)}, nil + return &coretypes.ResultABCIInfo{Response: a.App.Info(ctx, proxy.RequestInfo)}, nil } func (a ABCIApp) ABCIQuery(ctx context.Context, path string, data bytes.HexBytes) (*coretypes.ResultABCIQuery, error) { return a.ABCIQueryWithOptions(ctx, path, data, client.DefaultABCIQueryOptions) } -func (a ABCIApp) ABCIQueryWithOptions( - ctx context.Context, - path string, - data bytes.HexBytes, - opts client.ABCIQueryOptions) (*coretypes.ResultABCIQuery, error) { - q := a.App.Query(abci.RequestQuery{ +func (a ABCIApp) ABCIQueryWithOptions(ctx context.Context, path string, data bytes.HexBytes, opts client.ABCIQueryOptions) (*coretypes.ResultABCIQuery, error) { + q := a.App.Query(ctx, abci.RequestQuery{ Data: data, Path: path, Height: opts.Height, @@ -51,21 +47,21 @@ func (a ABCIApp) ABCIQueryWithOptions( // TODO: Make it wait for a commit and set res.Height appropriately. func (a ABCIApp) BroadcastTxCommit(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTxCommit, error) { res := coretypes.ResultBroadcastTxCommit{} - res.CheckTx = a.App.CheckTx(abci.RequestCheckTx{Tx: tx}) + res.CheckTx = a.App.CheckTx(ctx, abci.RequestCheckTx{Tx: tx}) if res.CheckTx.IsErr() { return &res, nil } - fb := a.App.FinalizeBlock(abci.RequestFinalizeBlock{Txs: [][]byte{tx}}) + fb := a.App.FinalizeBlock(ctx, abci.RequestFinalizeBlock{Txs: [][]byte{tx}}) res.TxResult = *fb.TxResults[0] res.Height = -1 // TODO return &res, nil } func (a ABCIApp) BroadcastTxAsync(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTx, error) { - c := a.App.CheckTx(abci.RequestCheckTx{Tx: tx}) + c := a.App.CheckTx(ctx, abci.RequestCheckTx{Tx: tx}) // and this gets written in a background thread... if !c.IsErr() { - go func() { a.App.FinalizeBlock(abci.RequestFinalizeBlock{Txs: [][]byte{tx}}) }() + go func() { a.App.FinalizeBlock(ctx, abci.RequestFinalizeBlock{Txs: [][]byte{tx}}) }() } return &coretypes.ResultBroadcastTx{ Code: c.Code, @@ -77,10 +73,10 @@ func (a ABCIApp) BroadcastTxAsync(ctx context.Context, tx types.Tx) (*coretypes. } func (a ABCIApp) BroadcastTxSync(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTx, error) { - c := a.App.CheckTx(abci.RequestCheckTx{Tx: tx}) + c := a.App.CheckTx(ctx, abci.RequestCheckTx{Tx: tx}) // and this gets written in a background thread... if !c.IsErr() { - go func() { a.App.FinalizeBlock(abci.RequestFinalizeBlock{Txs: [][]byte{tx}}) }() + go func() { a.App.FinalizeBlock(ctx, abci.RequestFinalizeBlock{Txs: [][]byte{tx}}) }() } return &coretypes.ResultBroadcastTx{ Code: c.Code, @@ -113,11 +109,7 @@ func (m ABCIMock) ABCIQuery(ctx context.Context, path string, data bytes.HexByte return m.ABCIQueryWithOptions(ctx, path, data, client.DefaultABCIQueryOptions) } -func (m ABCIMock) ABCIQueryWithOptions( - ctx context.Context, - path string, - data bytes.HexBytes, - opts client.ABCIQueryOptions) (*coretypes.ResultABCIQuery, error) { +func (m ABCIMock) ABCIQueryWithOptions(ctx context.Context, path string, data bytes.HexBytes, opts client.ABCIQueryOptions) (*coretypes.ResultABCIQuery, error) { res, err := m.Query.GetResponse(QueryArgs{path, data, opts.Height, opts.Prove}) if err != nil { return nil, err @@ -185,11 +177,7 @@ func (r *ABCIRecorder) ABCIInfo(ctx context.Context) (*coretypes.ResultABCIInfo, return res, err } -func (r *ABCIRecorder) ABCIQuery( - ctx context.Context, - path string, - data bytes.HexBytes, -) (*coretypes.ResultABCIQuery, error) { +func (r *ABCIRecorder) ABCIQuery(ctx context.Context, path string, data bytes.HexBytes) (*coretypes.ResultABCIQuery, error) { return r.ABCIQueryWithOptions(ctx, path, data, client.DefaultABCIQueryOptions) } diff --git a/rpc/client/mock/abci_test.go b/rpc/client/mock/abci_test.go index 489133a5b..aa117f058 100644 --- a/rpc/client/mock/abci_test.go +++ b/rpc/client/mock/abci_test.go @@ -185,7 +185,7 @@ func TestABCIApp(t *testing.T) { // commit // TODO: This may not be necessary in the future if res.Height == -1 { - m.App.Commit() + m.App.Commit(ctx) } // check the key diff --git a/rpc/client/mocks/client.go b/rpc/client/mocks/client.go index d9049ea44..d8cbd560d 100644 --- a/rpc/client/mocks/client.go +++ b/rpc/client/mocks/client.go @@ -12,6 +12,8 @@ import ( mock "github.com/stretchr/testify/mock" + testing "testing" + types "github.com/tendermint/tendermint/types" ) @@ -795,3 +797,12 @@ func (_m *Client) Validators(ctx context.Context, height *int64, page *int, perP return r0, r1 } + +// NewClient creates a new instance of Client. It also registers a cleanup function to assert the mocks expectations. +func NewClient(t testing.TB) *Client { + mock := &Client{} + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/test/e2e/app/app.go b/test/e2e/app/app.go index 797c3b99c..d4412c15c 100644 --- a/test/e2e/app/app.go +++ b/test/e2e/app/app.go @@ -2,6 +2,7 @@ package app import ( "bytes" + "context" "encoding/base64" "encoding/binary" "errors" @@ -113,7 +114,7 @@ func NewApplication(cfg *Config) (*Application, error) { } // Info implements ABCI. -func (app *Application) Info(req abci.RequestInfo) abci.ResponseInfo { +func (app *Application) Info(_ context.Context, req abci.RequestInfo) abci.ResponseInfo { app.mu.Lock() defer app.mu.Unlock() @@ -126,7 +127,7 @@ func (app *Application) Info(req abci.RequestInfo) abci.ResponseInfo { } // Info implements ABCI. -func (app *Application) InitChain(req abci.RequestInitChain) abci.ResponseInitChain { +func (app *Application) InitChain(_ context.Context, req abci.RequestInitChain) abci.ResponseInitChain { app.mu.Lock() defer app.mu.Unlock() @@ -153,7 +154,7 @@ func (app *Application) InitChain(req abci.RequestInitChain) abci.ResponseInitCh } // CheckTx implements ABCI. -func (app *Application) CheckTx(req abci.RequestCheckTx) abci.ResponseCheckTx { +func (app *Application) CheckTx(_ context.Context, req abci.RequestCheckTx) abci.ResponseCheckTx { app.mu.Lock() defer app.mu.Unlock() @@ -168,7 +169,7 @@ func (app *Application) CheckTx(req abci.RequestCheckTx) abci.ResponseCheckTx { } // FinalizeBlock implements ABCI. -func (app *Application) FinalizeBlock(req abci.RequestFinalizeBlock) abci.ResponseFinalizeBlock { +func (app *Application) FinalizeBlock(_ context.Context, req abci.RequestFinalizeBlock) abci.ResponseFinalizeBlock { var txs = make([]*abci.ExecTxResult, len(req.Txs)) app.mu.Lock() @@ -211,7 +212,7 @@ func (app *Application) FinalizeBlock(req abci.RequestFinalizeBlock) abci.Respon } // Commit implements ABCI. -func (app *Application) Commit() abci.ResponseCommit { +func (app *Application) Commit(_ context.Context) abci.ResponseCommit { app.mu.Lock() defer app.mu.Unlock() @@ -241,7 +242,7 @@ func (app *Application) Commit() abci.ResponseCommit { } // Query implements ABCI. -func (app *Application) Query(req abci.RequestQuery) abci.ResponseQuery { +func (app *Application) Query(_ context.Context, req abci.RequestQuery) abci.ResponseQuery { app.mu.Lock() defer app.mu.Unlock() @@ -253,7 +254,7 @@ func (app *Application) Query(req abci.RequestQuery) abci.ResponseQuery { } // ListSnapshots implements ABCI. -func (app *Application) ListSnapshots(req abci.RequestListSnapshots) abci.ResponseListSnapshots { +func (app *Application) ListSnapshots(_ context.Context, req abci.RequestListSnapshots) abci.ResponseListSnapshots { app.mu.Lock() defer app.mu.Unlock() @@ -265,7 +266,7 @@ func (app *Application) ListSnapshots(req abci.RequestListSnapshots) abci.Respon } // LoadSnapshotChunk implements ABCI. -func (app *Application) LoadSnapshotChunk(req abci.RequestLoadSnapshotChunk) abci.ResponseLoadSnapshotChunk { +func (app *Application) LoadSnapshotChunk(_ context.Context, req abci.RequestLoadSnapshotChunk) abci.ResponseLoadSnapshotChunk { app.mu.Lock() defer app.mu.Unlock() @@ -277,7 +278,7 @@ func (app *Application) LoadSnapshotChunk(req abci.RequestLoadSnapshotChunk) abc } // OfferSnapshot implements ABCI. -func (app *Application) OfferSnapshot(req abci.RequestOfferSnapshot) abci.ResponseOfferSnapshot { +func (app *Application) OfferSnapshot(_ context.Context, req abci.RequestOfferSnapshot) abci.ResponseOfferSnapshot { app.mu.Lock() defer app.mu.Unlock() @@ -290,7 +291,7 @@ func (app *Application) OfferSnapshot(req abci.RequestOfferSnapshot) abci.Respon } // ApplySnapshotChunk implements ABCI. -func (app *Application) ApplySnapshotChunk(req abci.RequestApplySnapshotChunk) abci.ResponseApplySnapshotChunk { +func (app *Application) ApplySnapshotChunk(_ context.Context, req abci.RequestApplySnapshotChunk) abci.ResponseApplySnapshotChunk { app.mu.Lock() defer app.mu.Unlock() @@ -323,7 +324,7 @@ func (app *Application) ApplySnapshotChunk(req abci.RequestApplySnapshotChunk) a // If adding a special vote extension-generated transaction would cause the // total number of transaction bytes to exceed `req.MaxTxBytes`, we will not // append our special vote extension transaction. -func (app *Application) PrepareProposal(req abci.RequestPrepareProposal) abci.ResponsePrepareProposal { +func (app *Application) PrepareProposal(_ context.Context, req abci.RequestPrepareProposal) abci.ResponsePrepareProposal { var sum int64 var extCount int for _, vote := range req.LocalLastCommit.Votes { @@ -399,7 +400,7 @@ func (app *Application) PrepareProposal(req abci.RequestPrepareProposal) abci.Re // ProcessProposal implements part of the Application interface. // It accepts any proposal that does not contain a malformed transaction. -func (app *Application) ProcessProposal(req abci.RequestProcessProposal) abci.ResponseProcessProposal { +func (app *Application) ProcessProposal(_ context.Context, req abci.RequestProcessProposal) abci.ResponseProcessProposal { for _, tx := range req.Txs { k, v, err := parseTx(tx) if err != nil { @@ -425,7 +426,7 @@ func (app *Application) ProcessProposal(req abci.RequestProcessProposal) abci.Re // a new transaction will be proposed that updates a special value in the // key/value store ("extensionSum") with the sum of all of the numbers collected // from the vote extensions. -func (app *Application) ExtendVote(req abci.RequestExtendVote) abci.ResponseExtendVote { +func (app *Application) ExtendVote(_ context.Context, req abci.RequestExtendVote) abci.ResponseExtendVote { // We ignore any requests for vote extensions that don't match our expected // next height. if req.Height != int64(app.state.Height)+1 { @@ -451,7 +452,7 @@ func (app *Application) ExtendVote(req abci.RequestExtendVote) abci.ResponseExte // VerifyVoteExtension simply validates vote extensions from other validators // without doing anything about them. In this case, it just makes sure that the // vote extension is a well-formed integer value. -func (app *Application) VerifyVoteExtension(req abci.RequestVerifyVoteExtension) abci.ResponseVerifyVoteExtension { +func (app *Application) VerifyVoteExtension(_ context.Context, req abci.RequestVerifyVoteExtension) abci.ResponseVerifyVoteExtension { // We allow vote extensions to be optional if len(req.VoteExtension) == 0 { return abci.ResponseVerifyVoteExtension{ From b5e6cf50d12eeda9174c20b5ba0e7d6bf98ce33d Mon Sep 17 00:00:00 2001 From: Sam Kleinman Date: Fri, 22 Apr 2022 20:40:42 -0400 Subject: [PATCH 07/35] abci: Application should return errors errors and nilable response objects (#8396) --- abci/client/local_client.go | 42 +-- abci/client/mocks/client.go | 3 +- abci/example/kvstore/helpers.go | 5 +- abci/example/kvstore/kvstore.go | 46 +-- abci/example/kvstore/kvstore_test.go | 58 +++- abci/example/kvstore/persistent_kvstore.go | 8 +- abci/server/grpc_server.go | 42 +-- abci/server/socket_server.go | 103 +++++-- abci/types/application.go | 90 +++--- abci/types/messages.go | 56 ++-- abci/types/mocks/application.go | 269 +++++++++++++----- abci/types/mocks/base.go | 177 ------------ internal/consensus/byzantine_test.go | 3 +- internal/consensus/common_test.go | 6 +- internal/consensus/mempool_test.go | 38 +-- internal/consensus/mocks/cons_sync_reactor.go | 3 +- internal/consensus/reactor_test.go | 3 +- internal/consensus/replay_stubs.go | 10 +- internal/consensus/replay_test.go | 14 +- internal/consensus/state_test.go | 89 +++--- internal/evidence/mocks/block_store.go | 3 +- internal/mempool/mempool_test.go | 14 +- internal/mempool/mocks/mempool.go | 3 +- internal/p2p/mocks/connection.go | 3 +- internal/p2p/mocks/transport.go | 3 +- internal/state/execution_test.go | 42 +-- internal/state/helpers_test.go | 28 +- internal/state/indexer/mocks/event_sink.go | 3 +- internal/state/mocks/block_store.go | 3 +- internal/state/mocks/evidence_pool.go | 3 +- internal/state/mocks/store.go | 3 +- internal/statesync/mocks/state_provider.go | 3 +- libs/time/mocks/source.go | 3 +- light/provider/mocks/provider.go | 3 +- light/rpc/mocks/light_client.go | 3 +- rpc/client/mock/abci.go | 52 +++- rpc/client/mock/abci_test.go | 3 +- rpc/client/mocks/client.go | 3 +- spec/abci/abci.md | 48 +--- test/e2e/app/app.go | 96 +++---- 40 files changed, 717 insertions(+), 670 deletions(-) delete mode 100644 abci/types/mocks/base.go diff --git a/abci/client/local_client.go b/abci/client/local_client.go index b7bc65b23..418930fa8 100644 --- a/abci/client/local_client.go +++ b/abci/client/local_client.go @@ -44,71 +44,57 @@ func (app *localClient) Echo(_ context.Context, msg string) (*types.ResponseEcho } func (app *localClient) Info(ctx context.Context, req types.RequestInfo) (*types.ResponseInfo, error) { - res := app.Application.Info(ctx, req) - return &res, nil + return app.Application.Info(ctx, req) } func (app *localClient) CheckTx(ctx context.Context, req types.RequestCheckTx) (*types.ResponseCheckTx, error) { - res := app.Application.CheckTx(ctx, req) - return &res, nil + return app.Application.CheckTx(ctx, req) } func (app *localClient) Query(ctx context.Context, req types.RequestQuery) (*types.ResponseQuery, error) { - res := app.Application.Query(ctx, req) - return &res, nil + return app.Application.Query(ctx, req) } func (app *localClient) Commit(ctx context.Context) (*types.ResponseCommit, error) { - res := app.Application.Commit(ctx) - return &res, nil + return app.Application.Commit(ctx) } func (app *localClient) InitChain(ctx context.Context, req types.RequestInitChain) (*types.ResponseInitChain, error) { - res := app.Application.InitChain(ctx, req) - return &res, nil + return app.Application.InitChain(ctx, req) } func (app *localClient) ListSnapshots(ctx context.Context, req types.RequestListSnapshots) (*types.ResponseListSnapshots, error) { - res := app.Application.ListSnapshots(ctx, req) - return &res, nil + return app.Application.ListSnapshots(ctx, req) } func (app *localClient) OfferSnapshot(ctx context.Context, req types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { - res := app.Application.OfferSnapshot(ctx, req) - return &res, nil + return app.Application.OfferSnapshot(ctx, req) } func (app *localClient) LoadSnapshotChunk(ctx context.Context, req types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) { - res := app.Application.LoadSnapshotChunk(ctx, req) - return &res, nil + return app.Application.LoadSnapshotChunk(ctx, req) } func (app *localClient) ApplySnapshotChunk(ctx context.Context, req types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { - res := app.Application.ApplySnapshotChunk(ctx, req) - return &res, nil + return app.Application.ApplySnapshotChunk(ctx, req) } func (app *localClient) PrepareProposal(ctx context.Context, req types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) { - res := app.Application.PrepareProposal(ctx, req) - return &res, nil + return app.Application.PrepareProposal(ctx, req) } func (app *localClient) ProcessProposal(ctx context.Context, req types.RequestProcessProposal) (*types.ResponseProcessProposal, error) { - res := app.Application.ProcessProposal(ctx, req) - return &res, nil + return app.Application.ProcessProposal(ctx, req) } func (app *localClient) ExtendVote(ctx context.Context, req types.RequestExtendVote) (*types.ResponseExtendVote, error) { - res := app.Application.ExtendVote(ctx, req) - return &res, nil + return app.Application.ExtendVote(ctx, req) } func (app *localClient) VerifyVoteExtension(ctx context.Context, req types.RequestVerifyVoteExtension) (*types.ResponseVerifyVoteExtension, error) { - res := app.Application.VerifyVoteExtension(ctx, req) - return &res, nil + return app.Application.VerifyVoteExtension(ctx, req) } func (app *localClient) FinalizeBlock(ctx context.Context, req types.RequestFinalizeBlock) (*types.ResponseFinalizeBlock, error) { - res := app.Application.FinalizeBlock(ctx, req) - return &res, nil + return app.Application.FinalizeBlock(ctx, req) } diff --git a/abci/client/mocks/client.go b/abci/client/mocks/client.go index 365f45a94..5b751f50d 100644 --- a/abci/client/mocks/client.go +++ b/abci/client/mocks/client.go @@ -422,9 +422,10 @@ func (_m *Client) Wait() { _m.Called() } -// NewClient creates a new instance of Client. It also registers a cleanup function to assert the mocks expectations. +// NewClient creates a new instance of Client. It also registers the testing.TB interface on the mock and a cleanup function to assert the mocks expectations. func NewClient(t testing.TB) *Client { mock := &Client{} + mock.Mock.Test(t) t.Cleanup(func() { mock.AssertExpectations(t) }) diff --git a/abci/example/kvstore/helpers.go b/abci/example/kvstore/helpers.go index d0428cceb..25b7dc9bb 100644 --- a/abci/example/kvstore/helpers.go +++ b/abci/example/kvstore/helpers.go @@ -33,8 +33,9 @@ func RandVals(cnt int) []types.ValidatorUpdate { // InitKVStore initializes the kvstore app with some data, // which allows tests to pass and is fine as long as you // don't make any tx that modify the validator state -func InitKVStore(ctx context.Context, app *PersistentKVStoreApplication) { - app.InitChain(ctx, types.RequestInitChain{ +func InitKVStore(ctx context.Context, app *PersistentKVStoreApplication) error { + _, err := app.InitChain(ctx, types.RequestInitChain{ Validators: RandVals(1), }) + return err } diff --git a/abci/example/kvstore/kvstore.go b/abci/example/kvstore/kvstore.go index 4c31cee34..42c121e1f 100644 --- a/abci/example/kvstore/kvstore.go +++ b/abci/example/kvstore/kvstore.go @@ -91,7 +91,7 @@ func NewApplication() *Application { } } -func (app *Application) InitChain(_ context.Context, req types.RequestInitChain) types.ResponseInitChain { +func (app *Application) InitChain(_ context.Context, req types.RequestInitChain) (*types.ResponseInitChain, error) { app.mu.Lock() defer app.mu.Unlock() @@ -102,19 +102,19 @@ func (app *Application) InitChain(_ context.Context, req types.RequestInitChain) panic("problem updating validators") } } - return types.ResponseInitChain{} + return &types.ResponseInitChain{}, nil } -func (app *Application) Info(_ context.Context, req types.RequestInfo) types.ResponseInfo { +func (app *Application) Info(_ context.Context, req types.RequestInfo) (*types.ResponseInfo, error) { app.mu.Lock() defer app.mu.Unlock() - return types.ResponseInfo{ + return &types.ResponseInfo{ Data: fmt.Sprintf("{\"size\":%v}", app.state.Size), Version: version.ABCIVersion, AppVersion: ProtocolVersion, LastBlockHeight: app.state.Height, LastBlockAppHash: app.state.AppHash, - } + }, nil } // tx is either "val:pubkey!power" or "key=value" or just arbitrary bytes @@ -167,7 +167,7 @@ func (app *Application) Close() error { return app.state.db.Close() } -func (app *Application) FinalizeBlock(_ context.Context, req types.RequestFinalizeBlock) types.ResponseFinalizeBlock { +func (app *Application) FinalizeBlock(_ context.Context, req types.RequestFinalizeBlock) (*types.ResponseFinalizeBlock, error) { app.mu.Lock() defer app.mu.Unlock() @@ -196,14 +196,14 @@ func (app *Application) FinalizeBlock(_ context.Context, req types.RequestFinali respTxs[i] = app.handleTx(tx) } - return types.ResponseFinalizeBlock{TxResults: respTxs, ValidatorUpdates: app.ValUpdates} + return &types.ResponseFinalizeBlock{TxResults: respTxs, ValidatorUpdates: app.ValUpdates}, nil } -func (*Application) CheckTx(_ context.Context, req types.RequestCheckTx) types.ResponseCheckTx { - return types.ResponseCheckTx{Code: code.CodeTypeOK, GasWanted: 1} +func (*Application) CheckTx(_ context.Context, req types.RequestCheckTx) (*types.ResponseCheckTx, error) { + return &types.ResponseCheckTx{Code: code.CodeTypeOK, GasWanted: 1}, nil } -func (app *Application) Commit(_ context.Context) types.ResponseCommit { +func (app *Application) Commit(_ context.Context) (*types.ResponseCommit, error) { app.mu.Lock() defer app.mu.Unlock() @@ -214,15 +214,15 @@ func (app *Application) Commit(_ context.Context) types.ResponseCommit { app.state.Height++ saveState(app.state) - resp := types.ResponseCommit{Data: appHash} + resp := &types.ResponseCommit{Data: appHash} if app.RetainBlocks > 0 && app.state.Height >= app.RetainBlocks { resp.RetainHeight = app.state.Height - app.RetainBlocks + 1 } - return resp + return resp, nil } // Returns an associated value or nil if missing. -func (app *Application) Query(_ context.Context, reqQuery types.RequestQuery) types.ResponseQuery { +func (app *Application) Query(_ context.Context, reqQuery types.RequestQuery) (*types.ResponseQuery, error) { app.mu.Lock() defer app.mu.Unlock() @@ -233,10 +233,10 @@ func (app *Application) Query(_ context.Context, reqQuery types.RequestQuery) ty panic(err) } - return types.ResponseQuery{ + return &types.ResponseQuery{ Key: reqQuery.Data, Value: value, - } + }, nil } if reqQuery.Prove { @@ -258,7 +258,7 @@ func (app *Application) Query(_ context.Context, reqQuery types.RequestQuery) ty resQuery.Log = "exists" } - return resQuery + return &resQuery, nil } value, err := app.state.db.Get(prefixKey(reqQuery.Data)) @@ -278,25 +278,25 @@ func (app *Application) Query(_ context.Context, reqQuery types.RequestQuery) ty resQuery.Log = "exists" } - return resQuery + return &resQuery, nil } -func (app *Application) PrepareProposal(_ context.Context, req types.RequestPrepareProposal) types.ResponsePrepareProposal { +func (app *Application) PrepareProposal(_ context.Context, req types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) { app.mu.Lock() defer app.mu.Unlock() - return types.ResponsePrepareProposal{ + return &types.ResponsePrepareProposal{ TxRecords: app.substPrepareTx(req.Txs, req.MaxTxBytes), - } + }, nil } -func (*Application) ProcessProposal(_ context.Context, req types.RequestProcessProposal) types.ResponseProcessProposal { +func (*Application) ProcessProposal(_ context.Context, req types.RequestProcessProposal) (*types.ResponseProcessProposal, error) { for _, tx := range req.Txs { if len(tx) == 0 { - return types.ResponseProcessProposal{Status: types.ResponseProcessProposal_REJECT} + return &types.ResponseProcessProposal{Status: types.ResponseProcessProposal_REJECT}, nil } } - return types.ResponseProcessProposal{Status: types.ResponseProcessProposal_ACCEPT} + return &types.ResponseProcessProposal{Status: types.ResponseProcessProposal_ACCEPT}, nil } //--------------------------------------------- diff --git a/abci/example/kvstore/kvstore_test.go b/abci/example/kvstore/kvstore_test.go index 5bd9907ae..994100f6e 100644 --- a/abci/example/kvstore/kvstore_test.go +++ b/abci/example/kvstore/kvstore_test.go @@ -25,35 +25,41 @@ const ( func testKVStore(ctx context.Context, t *testing.T, app types.Application, tx []byte, key, value string) { req := types.RequestFinalizeBlock{Txs: [][]byte{tx}} - ar := app.FinalizeBlock(ctx, req) + ar, err := app.FinalizeBlock(ctx, req) + require.NoError(t, err) require.Equal(t, 1, len(ar.TxResults)) require.False(t, ar.TxResults[0].IsErr()) // repeating tx doesn't raise error - ar = app.FinalizeBlock(ctx, req) + ar, err = app.FinalizeBlock(ctx, req) + require.NoError(t, err) require.Equal(t, 1, len(ar.TxResults)) require.False(t, ar.TxResults[0].IsErr()) // commit - app.Commit(ctx) + _, err = app.Commit(ctx) + require.NoError(t, err) - info := app.Info(ctx, types.RequestInfo{}) + info, err := app.Info(ctx, types.RequestInfo{}) + require.NoError(t, err) require.NotZero(t, info.LastBlockHeight) // make sure query is fine - resQuery := app.Query(ctx, types.RequestQuery{ + resQuery, err := app.Query(ctx, types.RequestQuery{ Path: "/store", Data: []byte(key), }) + require.NoError(t, err) require.Equal(t, code.CodeTypeOK, resQuery.Code) require.Equal(t, key, string(resQuery.Key)) require.Equal(t, value, string(resQuery.Value)) require.EqualValues(t, info.LastBlockHeight, resQuery.Height) // make sure proof is fine - resQuery = app.Query(ctx, types.RequestQuery{ + resQuery, err = app.Query(ctx, types.RequestQuery{ Path: "/store", Data: []byte(key), Prove: true, }) + require.NoError(t, err) require.EqualValues(t, code.CodeTypeOK, resQuery.Code) require.Equal(t, key, string(resQuery.Key)) require.Equal(t, value, string(resQuery.Value)) @@ -100,10 +106,16 @@ func TestPersistentKVStoreInfo(t *testing.T) { logger := log.NewNopLogger() kvstore := NewPersistentKVStoreApplication(logger, dir) - InitKVStore(ctx, kvstore) + if err := InitKVStore(ctx, kvstore); err != nil { + t.Fatal(err) + } height := int64(0) - resInfo := kvstore.Info(ctx, types.RequestInfo{}) + resInfo, err := kvstore.Info(ctx, types.RequestInfo{}) + if err != nil { + t.Fatal(err) + } + if resInfo.LastBlockHeight != height { t.Fatalf("expected height of %d, got %d", height, resInfo.LastBlockHeight) } @@ -111,10 +123,19 @@ func TestPersistentKVStoreInfo(t *testing.T) { // make and apply block height = int64(1) hash := []byte("foo") - kvstore.FinalizeBlock(ctx, types.RequestFinalizeBlock{Hash: hash, Height: height}) - kvstore.Commit(ctx) + if _, err := kvstore.FinalizeBlock(ctx, types.RequestFinalizeBlock{Hash: hash, Height: height}); err != nil { + t.Fatal(err) + } - resInfo = kvstore.Info(ctx, types.RequestInfo{}) + if _, err := kvstore.Commit(ctx); err != nil { + t.Fatal(err) + + } + + resInfo, err = kvstore.Info(ctx, types.RequestInfo{}) + if err != nil { + t.Fatal(err) + } if resInfo.LastBlockHeight != height { t.Fatalf("expected height of %d, got %d", height, resInfo.LastBlockHeight) } @@ -133,9 +154,12 @@ func TestValUpdates(t *testing.T) { nInit := 5 vals := RandVals(total) // initialize with the first nInit - kvstore.InitChain(ctx, types.RequestInitChain{ + _, err := kvstore.InitChain(ctx, types.RequestInitChain{ Validators: vals[:nInit], }) + if err != nil { + t.Fatal(err) + } vals1, vals2 := vals[:nInit], kvstore.Validators() valsEqual(t, vals1, vals2) @@ -191,13 +215,19 @@ func makeApplyBlock(ctx context.Context, t *testing.T, kvstore types.Application // make and apply block height := int64(heightInt) hash := []byte("foo") - resFinalizeBlock := kvstore.FinalizeBlock(ctx, types.RequestFinalizeBlock{ + resFinalizeBlock, err := kvstore.FinalizeBlock(ctx, types.RequestFinalizeBlock{ Hash: hash, Height: height, Txs: txs, }) + if err != nil { + t.Fatal(err) + } - kvstore.Commit(ctx) + _, err = kvstore.Commit(ctx) + if err != nil { + t.Fatal(err) + } valsEqual(t, diff, resFinalizeBlock.ValidatorUpdates) diff --git a/abci/example/kvstore/persistent_kvstore.go b/abci/example/kvstore/persistent_kvstore.go index aec915e11..bbaf670e0 100644 --- a/abci/example/kvstore/persistent_kvstore.go +++ b/abci/example/kvstore/persistent_kvstore.go @@ -37,10 +37,10 @@ func NewPersistentKVStoreApplication(logger log.Logger, dbDir string) *Persisten } } -func (app *PersistentKVStoreApplication) OfferSnapshot(_ context.Context, req types.RequestOfferSnapshot) types.ResponseOfferSnapshot { - return types.ResponseOfferSnapshot{Result: types.ResponseOfferSnapshot_ABORT} +func (app *PersistentKVStoreApplication) OfferSnapshot(_ context.Context, req types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { + return &types.ResponseOfferSnapshot{Result: types.ResponseOfferSnapshot_ABORT}, nil } -func (app *PersistentKVStoreApplication) ApplySnapshotChunk(_ context.Context, req types.RequestApplySnapshotChunk) types.ResponseApplySnapshotChunk { - return types.ResponseApplySnapshotChunk{Result: types.ResponseApplySnapshotChunk_ABORT} +func (app *PersistentKVStoreApplication) ApplySnapshotChunk(_ context.Context, req types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { + return &types.ResponseApplySnapshotChunk{Result: types.ResponseApplySnapshotChunk_ABORT}, nil } diff --git a/abci/server/grpc_server.go b/abci/server/grpc_server.go index dd5bdcb69..8d84c76d2 100644 --- a/abci/server/grpc_server.go +++ b/abci/server/grpc_server.go @@ -79,71 +79,57 @@ func (app *gRPCApplication) Flush(_ context.Context, req *types.RequestFlush) (* } func (app *gRPCApplication) Info(ctx context.Context, req *types.RequestInfo) (*types.ResponseInfo, error) { - res := app.app.Info(ctx, *req) - return &res, nil + return app.app.Info(ctx, *req) } func (app *gRPCApplication) CheckTx(ctx context.Context, req *types.RequestCheckTx) (*types.ResponseCheckTx, error) { - res := app.app.CheckTx(ctx, *req) - return &res, nil + return app.app.CheckTx(ctx, *req) } func (app *gRPCApplication) Query(ctx context.Context, req *types.RequestQuery) (*types.ResponseQuery, error) { - res := app.app.Query(ctx, *req) - return &res, nil + return app.app.Query(ctx, *req) } func (app *gRPCApplication) Commit(ctx context.Context, req *types.RequestCommit) (*types.ResponseCommit, error) { - res := app.app.Commit(ctx) - return &res, nil + return app.app.Commit(ctx) } func (app *gRPCApplication) InitChain(ctx context.Context, req *types.RequestInitChain) (*types.ResponseInitChain, error) { - res := app.app.InitChain(ctx, *req) - return &res, nil + return app.app.InitChain(ctx, *req) } func (app *gRPCApplication) ListSnapshots(ctx context.Context, req *types.RequestListSnapshots) (*types.ResponseListSnapshots, error) { - res := app.app.ListSnapshots(ctx, *req) - return &res, nil + return app.app.ListSnapshots(ctx, *req) } func (app *gRPCApplication) OfferSnapshot(ctx context.Context, req *types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { - res := app.app.OfferSnapshot(ctx, *req) - return &res, nil + return app.app.OfferSnapshot(ctx, *req) } func (app *gRPCApplication) LoadSnapshotChunk(ctx context.Context, req *types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) { - res := app.app.LoadSnapshotChunk(ctx, *req) - return &res, nil + return app.app.LoadSnapshotChunk(ctx, *req) } func (app *gRPCApplication) ApplySnapshotChunk(ctx context.Context, req *types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { - res := app.app.ApplySnapshotChunk(ctx, *req) - return &res, nil + return app.app.ApplySnapshotChunk(ctx, *req) } func (app *gRPCApplication) ExtendVote(ctx context.Context, req *types.RequestExtendVote) (*types.ResponseExtendVote, error) { - res := app.app.ExtendVote(ctx, *req) - return &res, nil + return app.app.ExtendVote(ctx, *req) } func (app *gRPCApplication) VerifyVoteExtension(ctx context.Context, req *types.RequestVerifyVoteExtension) (*types.ResponseVerifyVoteExtension, error) { - res := app.app.VerifyVoteExtension(ctx, *req) - return &res, nil + return app.app.VerifyVoteExtension(ctx, *req) } func (app *gRPCApplication) PrepareProposal(ctx context.Context, req *types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) { - res := app.app.PrepareProposal(ctx, *req) - return &res, nil + return app.app.PrepareProposal(ctx, *req) } func (app *gRPCApplication) ProcessProposal(ctx context.Context, req *types.RequestProcessProposal) (*types.ResponseProcessProposal, error) { - res := app.app.ProcessProposal(ctx, *req) - return &res, nil + return app.app.ProcessProposal(ctx, *req) } func (app *gRPCApplication) FinalizeBlock(ctx context.Context, req *types.RequestFinalizeBlock) (*types.ResponseFinalizeBlock, error) { - res := app.app.FinalizeBlock(ctx, *req) - return &res, nil + return app.app.FinalizeBlock(ctx, *req) } diff --git a/abci/server/socket_server.go b/abci/server/socket_server.go index bf3dbdf09..c5cd150d1 100644 --- a/abci/server/socket_server.go +++ b/abci/server/socket_server.go @@ -159,8 +159,7 @@ func (s *SocketServer) acceptConnectionsRoutine(ctx context.Context) { } // Read requests from conn and deal with them -func (s *SocketServer) handleRequests(ctx context.Context, closer func(error), conn io.Reader, responses chan<- *types.Response, -) { +func (s *SocketServer) handleRequests(ctx context.Context, closer func(error), conn io.Reader, responses chan<- *types.Response) { var bufReader = bufio.NewReader(conn) defer func() { @@ -180,7 +179,12 @@ func (s *SocketServer) handleRequests(ctx context.Context, closer func(error), c return } - resp := s.processRequest(ctx, req) + resp, err := s.processRequest(ctx, req) + if err != nil { + closer(err) + return + } + select { case <-ctx.Done(): closer(ctx.Err()) @@ -190,42 +194,99 @@ func (s *SocketServer) handleRequests(ctx context.Context, closer func(error), c } } -func (s *SocketServer) processRequest(ctx context.Context, req *types.Request) *types.Response { +func (s *SocketServer) processRequest(ctx context.Context, req *types.Request) (*types.Response, error) { switch r := req.Value.(type) { case *types.Request_Echo: - return types.ToResponseEcho(r.Echo.Message) + return types.ToResponseEcho(r.Echo.Message), nil case *types.Request_Flush: - return types.ToResponseFlush() + return types.ToResponseFlush(), nil case *types.Request_Info: - return types.ToResponseInfo(s.app.Info(ctx, *r.Info)) + res, err := s.app.Info(ctx, *r.Info) + if err != nil { + return nil, err + } + + return types.ToResponseInfo(res), nil case *types.Request_CheckTx: - return types.ToResponseCheckTx(s.app.CheckTx(ctx, *r.CheckTx)) + res, err := s.app.CheckTx(ctx, *r.CheckTx) + if err != nil { + return nil, err + } + return types.ToResponseCheckTx(res), nil case *types.Request_Commit: - return types.ToResponseCommit(s.app.Commit(ctx)) + res, err := s.app.Commit(ctx) + if err != nil { + return nil, err + } + return types.ToResponseCommit(res), nil case *types.Request_Query: - return types.ToResponseQuery(s.app.Query(ctx, *r.Query)) + res, err := s.app.Query(ctx, *r.Query) + if err != nil { + return nil, err + } + return types.ToResponseQuery(res), nil case *types.Request_InitChain: - return types.ToResponseInitChain(s.app.InitChain(ctx, *r.InitChain)) + res, err := s.app.InitChain(ctx, *r.InitChain) + if err != nil { + return nil, err + } + return types.ToResponseInitChain(res), nil case *types.Request_ListSnapshots: - return types.ToResponseListSnapshots(s.app.ListSnapshots(ctx, *r.ListSnapshots)) + res, err := s.app.ListSnapshots(ctx, *r.ListSnapshots) + if err != nil { + return nil, err + } + return types.ToResponseListSnapshots(res), nil case *types.Request_OfferSnapshot: - return types.ToResponseOfferSnapshot(s.app.OfferSnapshot(ctx, *r.OfferSnapshot)) + res, err := s.app.OfferSnapshot(ctx, *r.OfferSnapshot) + if err != nil { + return nil, err + } + return types.ToResponseOfferSnapshot(res), nil case *types.Request_PrepareProposal: - return types.ToResponsePrepareProposal(s.app.PrepareProposal(ctx, *r.PrepareProposal)) + res, err := s.app.PrepareProposal(ctx, *r.PrepareProposal) + if err != nil { + return nil, err + } + return types.ToResponsePrepareProposal(res), nil case *types.Request_ProcessProposal: - return types.ToResponseProcessProposal(s.app.ProcessProposal(ctx, *r.ProcessProposal)) + res, err := s.app.ProcessProposal(ctx, *r.ProcessProposal) + if err != nil { + return nil, err + } + return types.ToResponseProcessProposal(res), nil case *types.Request_LoadSnapshotChunk: - return types.ToResponseLoadSnapshotChunk(s.app.LoadSnapshotChunk(ctx, *r.LoadSnapshotChunk)) + res, err := s.app.LoadSnapshotChunk(ctx, *r.LoadSnapshotChunk) + if err != nil { + return nil, err + } + return types.ToResponseLoadSnapshotChunk(res), nil case *types.Request_ApplySnapshotChunk: - return types.ToResponseApplySnapshotChunk(s.app.ApplySnapshotChunk(ctx, *r.ApplySnapshotChunk)) + res, err := s.app.ApplySnapshotChunk(ctx, *r.ApplySnapshotChunk) + if err != nil { + return nil, err + } + return types.ToResponseApplySnapshotChunk(res), nil case *types.Request_ExtendVote: - return types.ToResponseExtendVote(s.app.ExtendVote(ctx, *r.ExtendVote)) + res, err := s.app.ExtendVote(ctx, *r.ExtendVote) + if err != nil { + return nil, err + } + return types.ToResponseExtendVote(res), nil case *types.Request_VerifyVoteExtension: - return types.ToResponseVerifyVoteExtension(s.app.VerifyVoteExtension(ctx, *r.VerifyVoteExtension)) + res, err := s.app.VerifyVoteExtension(ctx, *r.VerifyVoteExtension) + if err != nil { + return nil, err + } + return types.ToResponseVerifyVoteExtension(res), nil case *types.Request_FinalizeBlock: - return types.ToResponseFinalizeBlock(s.app.FinalizeBlock(ctx, *r.FinalizeBlock)) + res, err := s.app.FinalizeBlock(ctx, *r.FinalizeBlock) + if err != nil { + return nil, err + } + return types.ToResponseFinalizeBlock(res), nil default: - return types.ToResponseException("Unknown request") + return types.ToResponseException("Unknown request"), errors.New("unknown request type") } } diff --git a/abci/types/application.go b/abci/types/application.go index c8ac12f87..abe3143c7 100644 --- a/abci/types/application.go +++ b/abci/types/application.go @@ -5,34 +5,32 @@ import "context" //go:generate ../../scripts/mockery_generate.sh Application // Application is an interface that enables any finite, deterministic state machine // to be driven by a blockchain-based replication engine via the ABCI. -// All methods take a RequestXxx argument and return a ResponseXxx argument, -// except CheckTx/DeliverTx, which take `tx []byte`, and `Commit`, which takes nothing. type Application interface { // Info/Query Connection - Info(context.Context, RequestInfo) ResponseInfo // Return application info - Query(context.Context, RequestQuery) ResponseQuery // Query for state + Info(context.Context, RequestInfo) (*ResponseInfo, error) // Return application info + Query(context.Context, RequestQuery) (*ResponseQuery, error) // Query for state // Mempool Connection - CheckTx(context.Context, RequestCheckTx) ResponseCheckTx // Validate a tx for the mempool + CheckTx(context.Context, RequestCheckTx) (*ResponseCheckTx, error) // Validate a tx for the mempool // Consensus Connection - InitChain(context.Context, RequestInitChain) ResponseInitChain // Initialize blockchain w validators/other info from TendermintCore - PrepareProposal(context.Context, RequestPrepareProposal) ResponsePrepareProposal - ProcessProposal(context.Context, RequestProcessProposal) ResponseProcessProposal + InitChain(context.Context, RequestInitChain) (*ResponseInitChain, error) // Initialize blockchain w validators/other info from TendermintCore + PrepareProposal(context.Context, RequestPrepareProposal) (*ResponsePrepareProposal, error) + ProcessProposal(context.Context, RequestProcessProposal) (*ResponseProcessProposal, error) // Commit the state and return the application Merkle root hash - Commit(context.Context) ResponseCommit + Commit(context.Context) (*ResponseCommit, error) // Create application specific vote extension - ExtendVote(context.Context, RequestExtendVote) ResponseExtendVote + ExtendVote(context.Context, RequestExtendVote) (*ResponseExtendVote, error) // Verify application's vote extension data - VerifyVoteExtension(context.Context, RequestVerifyVoteExtension) ResponseVerifyVoteExtension + VerifyVoteExtension(context.Context, RequestVerifyVoteExtension) (*ResponseVerifyVoteExtension, error) // Deliver the decided block with its txs to the Application - FinalizeBlock(context.Context, RequestFinalizeBlock) ResponseFinalizeBlock + FinalizeBlock(context.Context, RequestFinalizeBlock) (*ResponseFinalizeBlock, error) // State Sync Connection - ListSnapshots(context.Context, RequestListSnapshots) ResponseListSnapshots // List available snapshots - OfferSnapshot(context.Context, RequestOfferSnapshot) ResponseOfferSnapshot // Offer a snapshot to the application - LoadSnapshotChunk(context.Context, RequestLoadSnapshotChunk) ResponseLoadSnapshotChunk // Load a snapshot chunk - ApplySnapshotChunk(context.Context, RequestApplySnapshotChunk) ResponseApplySnapshotChunk // Apply a shapshot chunk + ListSnapshots(context.Context, RequestListSnapshots) (*ResponseListSnapshots, error) // List available snapshots + OfferSnapshot(context.Context, RequestOfferSnapshot) (*ResponseOfferSnapshot, error) // Offer a snapshot to the application + LoadSnapshotChunk(context.Context, RequestLoadSnapshotChunk) (*ResponseLoadSnapshotChunk, error) // Load a snapshot chunk + ApplySnapshotChunk(context.Context, RequestApplySnapshotChunk) (*ResponseApplySnapshotChunk, error) // Apply a shapshot chunk } //------------------------------------------------------- @@ -46,53 +44,53 @@ func NewBaseApplication() *BaseApplication { return &BaseApplication{} } -func (BaseApplication) Info(_ context.Context, req RequestInfo) ResponseInfo { - return ResponseInfo{} +func (BaseApplication) Info(_ context.Context, req RequestInfo) (*ResponseInfo, error) { + return &ResponseInfo{}, nil } -func (BaseApplication) CheckTx(_ context.Context, req RequestCheckTx) ResponseCheckTx { - return ResponseCheckTx{Code: CodeTypeOK} +func (BaseApplication) CheckTx(_ context.Context, req RequestCheckTx) (*ResponseCheckTx, error) { + return &ResponseCheckTx{Code: CodeTypeOK}, nil } -func (BaseApplication) Commit(_ context.Context) ResponseCommit { - return ResponseCommit{} +func (BaseApplication) Commit(_ context.Context) (*ResponseCommit, error) { + return &ResponseCommit{}, nil } -func (BaseApplication) ExtendVote(_ context.Context, req RequestExtendVote) ResponseExtendVote { - return ResponseExtendVote{} +func (BaseApplication) ExtendVote(_ context.Context, req RequestExtendVote) (*ResponseExtendVote, error) { + return &ResponseExtendVote{}, nil } -func (BaseApplication) VerifyVoteExtension(_ context.Context, req RequestVerifyVoteExtension) ResponseVerifyVoteExtension { - return ResponseVerifyVoteExtension{ +func (BaseApplication) VerifyVoteExtension(_ context.Context, req RequestVerifyVoteExtension) (*ResponseVerifyVoteExtension, error) { + return &ResponseVerifyVoteExtension{ Status: ResponseVerifyVoteExtension_ACCEPT, - } + }, nil } -func (BaseApplication) Query(_ context.Context, req RequestQuery) ResponseQuery { - return ResponseQuery{Code: CodeTypeOK} +func (BaseApplication) Query(_ context.Context, req RequestQuery) (*ResponseQuery, error) { + return &ResponseQuery{Code: CodeTypeOK}, nil } -func (BaseApplication) InitChain(_ context.Context, req RequestInitChain) ResponseInitChain { - return ResponseInitChain{} +func (BaseApplication) InitChain(_ context.Context, req RequestInitChain) (*ResponseInitChain, error) { + return &ResponseInitChain{}, nil } -func (BaseApplication) ListSnapshots(_ context.Context, req RequestListSnapshots) ResponseListSnapshots { - return ResponseListSnapshots{} +func (BaseApplication) ListSnapshots(_ context.Context, req RequestListSnapshots) (*ResponseListSnapshots, error) { + return &ResponseListSnapshots{}, nil } -func (BaseApplication) OfferSnapshot(_ context.Context, req RequestOfferSnapshot) ResponseOfferSnapshot { - return ResponseOfferSnapshot{} +func (BaseApplication) OfferSnapshot(_ context.Context, req RequestOfferSnapshot) (*ResponseOfferSnapshot, error) { + return &ResponseOfferSnapshot{}, nil } -func (BaseApplication) LoadSnapshotChunk(_ context.Context, _ RequestLoadSnapshotChunk) ResponseLoadSnapshotChunk { - return ResponseLoadSnapshotChunk{} +func (BaseApplication) LoadSnapshotChunk(_ context.Context, _ RequestLoadSnapshotChunk) (*ResponseLoadSnapshotChunk, error) { + return &ResponseLoadSnapshotChunk{}, nil } -func (BaseApplication) ApplySnapshotChunk(_ context.Context, req RequestApplySnapshotChunk) ResponseApplySnapshotChunk { - return ResponseApplySnapshotChunk{} +func (BaseApplication) ApplySnapshotChunk(_ context.Context, req RequestApplySnapshotChunk) (*ResponseApplySnapshotChunk, error) { + return &ResponseApplySnapshotChunk{}, nil } -func (BaseApplication) PrepareProposal(_ context.Context, req RequestPrepareProposal) ResponsePrepareProposal { +func (BaseApplication) PrepareProposal(_ context.Context, req RequestPrepareProposal) (*ResponsePrepareProposal, error) { trs := make([]*TxRecord, 0, len(req.Txs)) var totalBytes int64 for _, tx := range req.Txs { @@ -105,19 +103,19 @@ func (BaseApplication) PrepareProposal(_ context.Context, req RequestPrepareProp Tx: tx, }) } - return ResponsePrepareProposal{TxRecords: trs} + return &ResponsePrepareProposal{TxRecords: trs}, nil } -func (BaseApplication) ProcessProposal(_ context.Context, req RequestProcessProposal) ResponseProcessProposal { - return ResponseProcessProposal{Status: ResponseProcessProposal_ACCEPT} +func (BaseApplication) ProcessProposal(_ context.Context, req RequestProcessProposal) (*ResponseProcessProposal, error) { + return &ResponseProcessProposal{Status: ResponseProcessProposal_ACCEPT}, nil } -func (BaseApplication) FinalizeBlock(_ context.Context, req RequestFinalizeBlock) ResponseFinalizeBlock { +func (BaseApplication) FinalizeBlock(_ context.Context, req RequestFinalizeBlock) (*ResponseFinalizeBlock, error) { txs := make([]*ExecTxResult, len(req.Txs)) for i := range req.Txs { txs[i] = &ExecTxResult{Code: CodeTypeOK} } - return ResponseFinalizeBlock{ + return &ResponseFinalizeBlock{ TxResults: txs, - } + }, nil } diff --git a/abci/types/messages.go b/abci/types/messages.go index 74d9b9d1a..9bc3aabc0 100644 --- a/abci/types/messages.go +++ b/abci/types/messages.go @@ -143,86 +143,86 @@ func ToResponseFlush() *Response { } } -func ToResponseInfo(res ResponseInfo) *Response { +func ToResponseInfo(res *ResponseInfo) *Response { return &Response{ - Value: &Response_Info{&res}, + Value: &Response_Info{res}, } } -func ToResponseCheckTx(res ResponseCheckTx) *Response { +func ToResponseCheckTx(res *ResponseCheckTx) *Response { return &Response{ - Value: &Response_CheckTx{&res}, + Value: &Response_CheckTx{res}, } } -func ToResponseCommit(res ResponseCommit) *Response { +func ToResponseCommit(res *ResponseCommit) *Response { return &Response{ - Value: &Response_Commit{&res}, + Value: &Response_Commit{res}, } } -func ToResponseQuery(res ResponseQuery) *Response { +func ToResponseQuery(res *ResponseQuery) *Response { return &Response{ - Value: &Response_Query{&res}, + Value: &Response_Query{res}, } } -func ToResponseInitChain(res ResponseInitChain) *Response { +func ToResponseInitChain(res *ResponseInitChain) *Response { return &Response{ - Value: &Response_InitChain{&res}, + Value: &Response_InitChain{res}, } } -func ToResponseListSnapshots(res ResponseListSnapshots) *Response { +func ToResponseListSnapshots(res *ResponseListSnapshots) *Response { return &Response{ - Value: &Response_ListSnapshots{&res}, + Value: &Response_ListSnapshots{res}, } } -func ToResponseOfferSnapshot(res ResponseOfferSnapshot) *Response { +func ToResponseOfferSnapshot(res *ResponseOfferSnapshot) *Response { return &Response{ - Value: &Response_OfferSnapshot{&res}, + Value: &Response_OfferSnapshot{res}, } } -func ToResponseLoadSnapshotChunk(res ResponseLoadSnapshotChunk) *Response { +func ToResponseLoadSnapshotChunk(res *ResponseLoadSnapshotChunk) *Response { return &Response{ - Value: &Response_LoadSnapshotChunk{&res}, + Value: &Response_LoadSnapshotChunk{res}, } } -func ToResponseApplySnapshotChunk(res ResponseApplySnapshotChunk) *Response { +func ToResponseApplySnapshotChunk(res *ResponseApplySnapshotChunk) *Response { return &Response{ - Value: &Response_ApplySnapshotChunk{&res}, + Value: &Response_ApplySnapshotChunk{res}, } } -func ToResponseExtendVote(res ResponseExtendVote) *Response { +func ToResponseExtendVote(res *ResponseExtendVote) *Response { return &Response{ - Value: &Response_ExtendVote{&res}, + Value: &Response_ExtendVote{res}, } } -func ToResponseVerifyVoteExtension(res ResponseVerifyVoteExtension) *Response { +func ToResponseVerifyVoteExtension(res *ResponseVerifyVoteExtension) *Response { return &Response{ - Value: &Response_VerifyVoteExtension{&res}, + Value: &Response_VerifyVoteExtension{res}, } } -func ToResponsePrepareProposal(res ResponsePrepareProposal) *Response { +func ToResponsePrepareProposal(res *ResponsePrepareProposal) *Response { return &Response{ - Value: &Response_PrepareProposal{&res}, + Value: &Response_PrepareProposal{res}, } } -func ToResponseProcessProposal(res ResponseProcessProposal) *Response { +func ToResponseProcessProposal(res *ResponseProcessProposal) *Response { return &Response{ - Value: &Response_ProcessProposal{&res}, + Value: &Response_ProcessProposal{res}, } } -func ToResponseFinalizeBlock(res ResponseFinalizeBlock) *Response { +func ToResponseFinalizeBlock(res *ResponseFinalizeBlock) *Response { return &Response{ - Value: &Response_FinalizeBlock{&res}, + Value: &Response_FinalizeBlock{res}, } } diff --git a/abci/types/mocks/application.go b/abci/types/mocks/application.go index 4137f5f93..4b0fc64da 100644 --- a/abci/types/mocks/application.go +++ b/abci/types/mocks/application.go @@ -17,204 +17,331 @@ type Application struct { } // ApplySnapshotChunk provides a mock function with given fields: _a0, _a1 -func (_m *Application) ApplySnapshotChunk(_a0 context.Context, _a1 types.RequestApplySnapshotChunk) types.ResponseApplySnapshotChunk { +func (_m *Application) ApplySnapshotChunk(_a0 context.Context, _a1 types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { ret := _m.Called(_a0, _a1) - var r0 types.ResponseApplySnapshotChunk - if rf, ok := ret.Get(0).(func(context.Context, types.RequestApplySnapshotChunk) types.ResponseApplySnapshotChunk); ok { + var r0 *types.ResponseApplySnapshotChunk + if rf, ok := ret.Get(0).(func(context.Context, types.RequestApplySnapshotChunk) *types.ResponseApplySnapshotChunk); ok { r0 = rf(_a0, _a1) } else { - r0 = ret.Get(0).(types.ResponseApplySnapshotChunk) + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.ResponseApplySnapshotChunk) + } } - return r0 + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, types.RequestApplySnapshotChunk) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } // CheckTx provides a mock function with given fields: _a0, _a1 -func (_m *Application) CheckTx(_a0 context.Context, _a1 types.RequestCheckTx) types.ResponseCheckTx { +func (_m *Application) CheckTx(_a0 context.Context, _a1 types.RequestCheckTx) (*types.ResponseCheckTx, error) { ret := _m.Called(_a0, _a1) - var r0 types.ResponseCheckTx - if rf, ok := ret.Get(0).(func(context.Context, types.RequestCheckTx) types.ResponseCheckTx); ok { + var r0 *types.ResponseCheckTx + if rf, ok := ret.Get(0).(func(context.Context, types.RequestCheckTx) *types.ResponseCheckTx); ok { r0 = rf(_a0, _a1) } else { - r0 = ret.Get(0).(types.ResponseCheckTx) + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.ResponseCheckTx) + } } - return r0 + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, types.RequestCheckTx) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } // Commit provides a mock function with given fields: _a0 -func (_m *Application) Commit(_a0 context.Context) types.ResponseCommit { +func (_m *Application) Commit(_a0 context.Context) (*types.ResponseCommit, error) { ret := _m.Called(_a0) - var r0 types.ResponseCommit - if rf, ok := ret.Get(0).(func(context.Context) types.ResponseCommit); ok { + var r0 *types.ResponseCommit + if rf, ok := ret.Get(0).(func(context.Context) *types.ResponseCommit); ok { r0 = rf(_a0) } else { - r0 = ret.Get(0).(types.ResponseCommit) + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.ResponseCommit) + } } - return r0 + var r1 error + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } // ExtendVote provides a mock function with given fields: _a0, _a1 -func (_m *Application) ExtendVote(_a0 context.Context, _a1 types.RequestExtendVote) types.ResponseExtendVote { +func (_m *Application) ExtendVote(_a0 context.Context, _a1 types.RequestExtendVote) (*types.ResponseExtendVote, error) { ret := _m.Called(_a0, _a1) - var r0 types.ResponseExtendVote - if rf, ok := ret.Get(0).(func(context.Context, types.RequestExtendVote) types.ResponseExtendVote); ok { + var r0 *types.ResponseExtendVote + if rf, ok := ret.Get(0).(func(context.Context, types.RequestExtendVote) *types.ResponseExtendVote); ok { r0 = rf(_a0, _a1) } else { - r0 = ret.Get(0).(types.ResponseExtendVote) + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.ResponseExtendVote) + } } - return r0 + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, types.RequestExtendVote) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } // FinalizeBlock provides a mock function with given fields: _a0, _a1 -func (_m *Application) FinalizeBlock(_a0 context.Context, _a1 types.RequestFinalizeBlock) types.ResponseFinalizeBlock { +func (_m *Application) FinalizeBlock(_a0 context.Context, _a1 types.RequestFinalizeBlock) (*types.ResponseFinalizeBlock, error) { ret := _m.Called(_a0, _a1) - var r0 types.ResponseFinalizeBlock - if rf, ok := ret.Get(0).(func(context.Context, types.RequestFinalizeBlock) types.ResponseFinalizeBlock); ok { + var r0 *types.ResponseFinalizeBlock + if rf, ok := ret.Get(0).(func(context.Context, types.RequestFinalizeBlock) *types.ResponseFinalizeBlock); ok { r0 = rf(_a0, _a1) } else { - r0 = ret.Get(0).(types.ResponseFinalizeBlock) + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.ResponseFinalizeBlock) + } } - return r0 + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, types.RequestFinalizeBlock) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } // Info provides a mock function with given fields: _a0, _a1 -func (_m *Application) Info(_a0 context.Context, _a1 types.RequestInfo) types.ResponseInfo { +func (_m *Application) Info(_a0 context.Context, _a1 types.RequestInfo) (*types.ResponseInfo, error) { ret := _m.Called(_a0, _a1) - var r0 types.ResponseInfo - if rf, ok := ret.Get(0).(func(context.Context, types.RequestInfo) types.ResponseInfo); ok { + var r0 *types.ResponseInfo + if rf, ok := ret.Get(0).(func(context.Context, types.RequestInfo) *types.ResponseInfo); ok { r0 = rf(_a0, _a1) } else { - r0 = ret.Get(0).(types.ResponseInfo) + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.ResponseInfo) + } } - return r0 + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, types.RequestInfo) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } // InitChain provides a mock function with given fields: _a0, _a1 -func (_m *Application) InitChain(_a0 context.Context, _a1 types.RequestInitChain) types.ResponseInitChain { +func (_m *Application) InitChain(_a0 context.Context, _a1 types.RequestInitChain) (*types.ResponseInitChain, error) { ret := _m.Called(_a0, _a1) - var r0 types.ResponseInitChain - if rf, ok := ret.Get(0).(func(context.Context, types.RequestInitChain) types.ResponseInitChain); ok { + var r0 *types.ResponseInitChain + if rf, ok := ret.Get(0).(func(context.Context, types.RequestInitChain) *types.ResponseInitChain); ok { r0 = rf(_a0, _a1) } else { - r0 = ret.Get(0).(types.ResponseInitChain) + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.ResponseInitChain) + } } - return r0 + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, types.RequestInitChain) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } // ListSnapshots provides a mock function with given fields: _a0, _a1 -func (_m *Application) ListSnapshots(_a0 context.Context, _a1 types.RequestListSnapshots) types.ResponseListSnapshots { +func (_m *Application) ListSnapshots(_a0 context.Context, _a1 types.RequestListSnapshots) (*types.ResponseListSnapshots, error) { ret := _m.Called(_a0, _a1) - var r0 types.ResponseListSnapshots - if rf, ok := ret.Get(0).(func(context.Context, types.RequestListSnapshots) types.ResponseListSnapshots); ok { + var r0 *types.ResponseListSnapshots + if rf, ok := ret.Get(0).(func(context.Context, types.RequestListSnapshots) *types.ResponseListSnapshots); ok { r0 = rf(_a0, _a1) } else { - r0 = ret.Get(0).(types.ResponseListSnapshots) + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.ResponseListSnapshots) + } } - return r0 + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, types.RequestListSnapshots) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } // LoadSnapshotChunk provides a mock function with given fields: _a0, _a1 -func (_m *Application) LoadSnapshotChunk(_a0 context.Context, _a1 types.RequestLoadSnapshotChunk) types.ResponseLoadSnapshotChunk { +func (_m *Application) LoadSnapshotChunk(_a0 context.Context, _a1 types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) { ret := _m.Called(_a0, _a1) - var r0 types.ResponseLoadSnapshotChunk - if rf, ok := ret.Get(0).(func(context.Context, types.RequestLoadSnapshotChunk) types.ResponseLoadSnapshotChunk); ok { + var r0 *types.ResponseLoadSnapshotChunk + if rf, ok := ret.Get(0).(func(context.Context, types.RequestLoadSnapshotChunk) *types.ResponseLoadSnapshotChunk); ok { r0 = rf(_a0, _a1) } else { - r0 = ret.Get(0).(types.ResponseLoadSnapshotChunk) + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.ResponseLoadSnapshotChunk) + } } - return r0 + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, types.RequestLoadSnapshotChunk) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } // OfferSnapshot provides a mock function with given fields: _a0, _a1 -func (_m *Application) OfferSnapshot(_a0 context.Context, _a1 types.RequestOfferSnapshot) types.ResponseOfferSnapshot { +func (_m *Application) OfferSnapshot(_a0 context.Context, _a1 types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { ret := _m.Called(_a0, _a1) - var r0 types.ResponseOfferSnapshot - if rf, ok := ret.Get(0).(func(context.Context, types.RequestOfferSnapshot) types.ResponseOfferSnapshot); ok { + var r0 *types.ResponseOfferSnapshot + if rf, ok := ret.Get(0).(func(context.Context, types.RequestOfferSnapshot) *types.ResponseOfferSnapshot); ok { r0 = rf(_a0, _a1) } else { - r0 = ret.Get(0).(types.ResponseOfferSnapshot) + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.ResponseOfferSnapshot) + } } - return r0 + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, types.RequestOfferSnapshot) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } // PrepareProposal provides a mock function with given fields: _a0, _a1 -func (_m *Application) PrepareProposal(_a0 context.Context, _a1 types.RequestPrepareProposal) types.ResponsePrepareProposal { +func (_m *Application) PrepareProposal(_a0 context.Context, _a1 types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) { ret := _m.Called(_a0, _a1) - var r0 types.ResponsePrepareProposal - if rf, ok := ret.Get(0).(func(context.Context, types.RequestPrepareProposal) types.ResponsePrepareProposal); ok { + var r0 *types.ResponsePrepareProposal + if rf, ok := ret.Get(0).(func(context.Context, types.RequestPrepareProposal) *types.ResponsePrepareProposal); ok { r0 = rf(_a0, _a1) } else { - r0 = ret.Get(0).(types.ResponsePrepareProposal) + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.ResponsePrepareProposal) + } } - return r0 + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, types.RequestPrepareProposal) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } // ProcessProposal provides a mock function with given fields: _a0, _a1 -func (_m *Application) ProcessProposal(_a0 context.Context, _a1 types.RequestProcessProposal) types.ResponseProcessProposal { +func (_m *Application) ProcessProposal(_a0 context.Context, _a1 types.RequestProcessProposal) (*types.ResponseProcessProposal, error) { ret := _m.Called(_a0, _a1) - var r0 types.ResponseProcessProposal - if rf, ok := ret.Get(0).(func(context.Context, types.RequestProcessProposal) types.ResponseProcessProposal); ok { + var r0 *types.ResponseProcessProposal + if rf, ok := ret.Get(0).(func(context.Context, types.RequestProcessProposal) *types.ResponseProcessProposal); ok { r0 = rf(_a0, _a1) } else { - r0 = ret.Get(0).(types.ResponseProcessProposal) + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.ResponseProcessProposal) + } } - return r0 + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, types.RequestProcessProposal) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } // Query provides a mock function with given fields: _a0, _a1 -func (_m *Application) Query(_a0 context.Context, _a1 types.RequestQuery) types.ResponseQuery { +func (_m *Application) Query(_a0 context.Context, _a1 types.RequestQuery) (*types.ResponseQuery, error) { ret := _m.Called(_a0, _a1) - var r0 types.ResponseQuery - if rf, ok := ret.Get(0).(func(context.Context, types.RequestQuery) types.ResponseQuery); ok { + var r0 *types.ResponseQuery + if rf, ok := ret.Get(0).(func(context.Context, types.RequestQuery) *types.ResponseQuery); ok { r0 = rf(_a0, _a1) } else { - r0 = ret.Get(0).(types.ResponseQuery) + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.ResponseQuery) + } } - return r0 + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, types.RequestQuery) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } // VerifyVoteExtension provides a mock function with given fields: _a0, _a1 -func (_m *Application) VerifyVoteExtension(_a0 context.Context, _a1 types.RequestVerifyVoteExtension) types.ResponseVerifyVoteExtension { +func (_m *Application) VerifyVoteExtension(_a0 context.Context, _a1 types.RequestVerifyVoteExtension) (*types.ResponseVerifyVoteExtension, error) { ret := _m.Called(_a0, _a1) - var r0 types.ResponseVerifyVoteExtension - if rf, ok := ret.Get(0).(func(context.Context, types.RequestVerifyVoteExtension) types.ResponseVerifyVoteExtension); ok { + var r0 *types.ResponseVerifyVoteExtension + if rf, ok := ret.Get(0).(func(context.Context, types.RequestVerifyVoteExtension) *types.ResponseVerifyVoteExtension); ok { r0 = rf(_a0, _a1) } else { - r0 = ret.Get(0).(types.ResponseVerifyVoteExtension) + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.ResponseVerifyVoteExtension) + } } - return r0 + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, types.RequestVerifyVoteExtension) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } -// NewApplication creates a new instance of Application. It also registers a cleanup function to assert the mocks expectations. +// NewApplication creates a new instance of Application. It also registers the testing.TB interface on the mock and a cleanup function to assert the mocks expectations. func NewApplication(t testing.TB) *Application { mock := &Application{} + mock.Mock.Test(t) t.Cleanup(func() { mock.AssertExpectations(t) }) diff --git a/abci/types/mocks/base.go b/abci/types/mocks/base.go deleted file mode 100644 index da14fb8fe..000000000 --- a/abci/types/mocks/base.go +++ /dev/null @@ -1,177 +0,0 @@ -package mocks - -import ( - context "context" - - types "github.com/tendermint/tendermint/abci/types" -) - -// BaseMock provides a wrapper around the generated Application mock and a BaseApplication. -// BaseMock first tries to use the mock's implementation of the method. -// If no functionality was provided for the mock by the user, BaseMock dispatches -// to the BaseApplication and uses its functionality. -// BaseMock allows users to provide mocked functionality for only the methods that matter -// for their test while avoiding a panic if the code calls Application methods that are -// not relevant to the test. -type BaseMock struct { - base *types.BaseApplication - *Application -} - -func NewBaseMock() BaseMock { - return BaseMock{ - base: types.NewBaseApplication(), - Application: new(Application), - } -} - -// Info/Query Connection -// Return application info -func (m BaseMock) Info(ctx context.Context, input types.RequestInfo) (ret types.ResponseInfo) { - defer func() { - if r := recover(); r != nil { - ret = m.base.Info(ctx, input) - } - }() - ret = m.Application.Info(ctx, input) - return ret -} - -func (m BaseMock) Query(ctx context.Context, input types.RequestQuery) (ret types.ResponseQuery) { - defer func() { - if r := recover(); r != nil { - ret = m.base.Query(ctx, input) - } - }() - ret = m.Application.Query(ctx, input) - return ret -} - -// Mempool Connection -// Validate a tx for the mempool -func (m BaseMock) CheckTx(ctx context.Context, input types.RequestCheckTx) (ret types.ResponseCheckTx) { - defer func() { - if r := recover(); r != nil { - ret = m.base.CheckTx(ctx, input) - } - }() - ret = m.Application.CheckTx(ctx, input) - return ret -} - -// Consensus Connection -// Initialize blockchain w validators/other info from TendermintCore -func (m BaseMock) InitChain(ctx context.Context, input types.RequestInitChain) (ret types.ResponseInitChain) { - defer func() { - if r := recover(); r != nil { - ret = m.base.InitChain(ctx, input) - } - }() - ret = m.Application.InitChain(ctx, input) - return ret -} - -func (m BaseMock) PrepareProposal(ctx context.Context, input types.RequestPrepareProposal) (ret types.ResponsePrepareProposal) { - defer func() { - if r := recover(); r != nil { - ret = m.base.PrepareProposal(ctx, input) - } - }() - ret = m.Application.PrepareProposal(ctx, input) - return ret -} - -func (m BaseMock) ProcessProposal(ctx context.Context, input types.RequestProcessProposal) (ret types.ResponseProcessProposal) { - defer func() { - if r := recover(); r != nil { - ret = m.base.ProcessProposal(ctx, input) - } - }() - ret = m.Application.ProcessProposal(ctx, input) - return ret -} - -// Commit the state and return the application Merkle root hash -func (m BaseMock) Commit(ctx context.Context) (ret types.ResponseCommit) { - defer func() { - if r := recover(); r != nil { - ret = m.base.Commit(ctx) - } - }() - ret = m.Application.Commit(ctx) - return ret -} - -// Create application specific vote extension -func (m BaseMock) ExtendVote(ctx context.Context, input types.RequestExtendVote) (ret types.ResponseExtendVote) { - defer func() { - if r := recover(); r != nil { - ret = m.base.ExtendVote(ctx, input) - } - }() - ret = m.Application.ExtendVote(ctx, input) - return ret -} - -// Verify application's vote extension data -func (m BaseMock) VerifyVoteExtension(ctx context.Context, input types.RequestVerifyVoteExtension) (ret types.ResponseVerifyVoteExtension) { - defer func() { - if r := recover(); r != nil { - ret = m.base.VerifyVoteExtension(ctx, input) - } - }() - ret = m.Application.VerifyVoteExtension(ctx, input) - return ret -} - -// State Sync Connection -// List available snapshots -func (m BaseMock) ListSnapshots(ctx context.Context, input types.RequestListSnapshots) (ret types.ResponseListSnapshots) { - defer func() { - if r := recover(); r != nil { - ret = m.base.ListSnapshots(ctx, input) - } - }() - ret = m.Application.ListSnapshots(ctx, input) - return ret -} - -func (m BaseMock) OfferSnapshot(ctx context.Context, input types.RequestOfferSnapshot) (ret types.ResponseOfferSnapshot) { - defer func() { - if r := recover(); r != nil { - ret = m.base.OfferSnapshot(ctx, input) - } - }() - ret = m.Application.OfferSnapshot(ctx, input) - return ret -} - -func (m BaseMock) LoadSnapshotChunk(ctx context.Context, input types.RequestLoadSnapshotChunk) (ret types.ResponseLoadSnapshotChunk) { - defer func() { - if r := recover(); r != nil { - ret = m.base.LoadSnapshotChunk(ctx, input) - } - }() - ret = m.Application.LoadSnapshotChunk(ctx, input) - return ret -} - -func (m BaseMock) ApplySnapshotChunk(ctx context.Context, input types.RequestApplySnapshotChunk) (ret types.ResponseApplySnapshotChunk) { - defer func() { - if r := recover(); r != nil { - ret = m.base.ApplySnapshotChunk(ctx, input) - } - }() - ret = m.Application.ApplySnapshotChunk(ctx, input) - return ret -} - -func (m BaseMock) FinalizeBlock(ctx context.Context, input types.RequestFinalizeBlock) (ret types.ResponseFinalizeBlock) { - defer func() { - if r := recover(); r != nil { - ret = m.base.FinalizeBlock(ctx, input) - } - }() - ret = m.Application.FinalizeBlock(ctx, input) - return ret -} diff --git a/internal/consensus/byzantine_test.go b/internal/consensus/byzantine_test.go index d6287d6f1..1e8167e21 100644 --- a/internal/consensus/byzantine_test.go +++ b/internal/consensus/byzantine_test.go @@ -68,7 +68,8 @@ func TestByzantinePrevoteEquivocation(t *testing.T) { ensureDir(t, path.Dir(thisConfig.Consensus.WalFile()), 0700) // dir for wal app := kvstore.NewApplication() vals := types.TM2PB.ValidatorUpdates(state.Validators) - app.InitChain(ctx, abci.RequestInitChain{Validators: vals}) + _, err = app.InitChain(ctx, abci.RequestInitChain{Validators: vals}) + require.NoError(t, err) blockDB := dbm.NewMemDB() blockStore := store.NewBlockStore(blockDB) diff --git a/internal/consensus/common_test.go b/internal/consensus/common_test.go index 67386e65d..7bd4dd15e 100644 --- a/internal/consensus/common_test.go +++ b/internal/consensus/common_test.go @@ -821,7 +821,8 @@ func makeConsensusState( closeFuncs = append(closeFuncs, app.Close) vals := types.TM2PB.ValidatorUpdates(state.Validators) - app.InitChain(ctx, abci.RequestInitChain{Validators: vals}) + _, err = app.InitChain(ctx, abci.RequestInitChain{Validators: vals}) + require.NoError(t, err) l := logger.With("validator", i, "module", "consensus") css[i] = newStateWithConfigAndBlockStore(ctx, t, l, thisConfig, state, privVals[i], app, blockStore) @@ -892,7 +893,8 @@ func randConsensusNetWithPeers( case *kvstore.Application: state.Version.Consensus.App = kvstore.ProtocolVersion } - app.InitChain(ctx, abci.RequestInitChain{Validators: vals}) + _, err = app.InitChain(ctx, abci.RequestInitChain{Validators: vals}) + require.NoError(t, err) // sm.SaveState(stateDB,state) //height 1's validatorsInfo already saved in LoadStateFromDBOrGenesisDoc above css[i] = newStateWithConfig(ctx, t, logger.With("validator", i, "module", "consensus"), thisConfig, state, privVal, app) diff --git a/internal/consensus/mempool_test.go b/internal/consensus/mempool_test.go index 3111dbb52..593b2fde1 100644 --- a/internal/consensus/mempool_test.go +++ b/internal/consensus/mempool_test.go @@ -199,10 +199,12 @@ func TestMempoolRmBadTx(t *testing.T) { txBytes := make([]byte, 8) binary.BigEndian.PutUint64(txBytes, uint64(0)) - resFinalize := app.FinalizeBlock(ctx, abci.RequestFinalizeBlock{Txs: [][]byte{txBytes}}) + resFinalize, err := app.FinalizeBlock(ctx, abci.RequestFinalizeBlock{Txs: [][]byte{txBytes}}) + require.NoError(t, err) assert.False(t, resFinalize.TxResults[0].IsErr(), fmt.Sprintf("expected no error. got %v", resFinalize)) - resCommit := app.Commit(ctx) + resCommit, err := app.Commit(ctx) + require.NoError(t, err) assert.True(t, len(resCommit.Data) > 0) emptyMempoolCh := make(chan struct{}) @@ -267,11 +269,11 @@ func NewCounterApplication() *CounterApplication { return &CounterApplication{} } -func (app *CounterApplication) Info(_ context.Context, req abci.RequestInfo) abci.ResponseInfo { - return abci.ResponseInfo{Data: fmt.Sprintf("txs:%v", app.txCount)} +func (app *CounterApplication) Info(_ context.Context, req abci.RequestInfo) (*abci.ResponseInfo, error) { + return &abci.ResponseInfo{Data: fmt.Sprintf("txs:%v", app.txCount)}, nil } -func (app *CounterApplication) FinalizeBlock(_ context.Context, req abci.RequestFinalizeBlock) abci.ResponseFinalizeBlock { +func (app *CounterApplication) FinalizeBlock(_ context.Context, req abci.RequestFinalizeBlock) (*abci.ResponseFinalizeBlock, error) { respTxs := make([]*abci.ExecTxResult, len(req.Txs)) for i, tx := range req.Txs { txValue := txAsUint64(tx) @@ -285,18 +287,19 @@ func (app *CounterApplication) FinalizeBlock(_ context.Context, req abci.Request app.txCount++ respTxs[i] = &abci.ExecTxResult{Code: code.CodeTypeOK} } - return abci.ResponseFinalizeBlock{TxResults: respTxs} + return &abci.ResponseFinalizeBlock{TxResults: respTxs}, nil } -func (app *CounterApplication) CheckTx(_ context.Context, req abci.RequestCheckTx) abci.ResponseCheckTx { +func (app *CounterApplication) CheckTx(_ context.Context, req abci.RequestCheckTx) (*abci.ResponseCheckTx, error) { txValue := txAsUint64(req.Tx) if txValue != uint64(app.mempoolTxCount) { - return abci.ResponseCheckTx{ + return &abci.ResponseCheckTx{ Code: code.CodeTypeBadNonce, - Log: fmt.Sprintf("Invalid nonce. Expected %v, got %v", app.mempoolTxCount, txValue)} + Log: fmt.Sprintf("Invalid nonce. Expected %v, got %v", app.mempoolTxCount, txValue), + }, nil } app.mempoolTxCount++ - return abci.ResponseCheckTx{Code: code.CodeTypeOK} + return &abci.ResponseCheckTx{Code: code.CodeTypeOK}, nil } func txAsUint64(tx []byte) uint64 { @@ -305,18 +308,17 @@ func txAsUint64(tx []byte) uint64 { return binary.BigEndian.Uint64(tx8) } -func (app *CounterApplication) Commit(context.Context) abci.ResponseCommit { +func (app *CounterApplication) Commit(context.Context) (*abci.ResponseCommit, error) { app.mempoolTxCount = app.txCount if app.txCount == 0 { - return abci.ResponseCommit{} + return &abci.ResponseCommit{}, nil } hash := make([]byte, 8) binary.BigEndian.PutUint64(hash, uint64(app.txCount)) - return abci.ResponseCommit{Data: hash} + return &abci.ResponseCommit{Data: hash}, nil } -func (app *CounterApplication) PrepareProposal(_ context.Context, req abci.RequestPrepareProposal) abci.ResponsePrepareProposal { - +func (app *CounterApplication) PrepareProposal(_ context.Context, req abci.RequestPrepareProposal) (*abci.ResponsePrepareProposal, error) { trs := make([]*abci.TxRecord, 0, len(req.Txs)) var totalBytes int64 for _, tx := range req.Txs { @@ -329,9 +331,9 @@ func (app *CounterApplication) PrepareProposal(_ context.Context, req abci.Reque Tx: tx, }) } - return abci.ResponsePrepareProposal{TxRecords: trs} + return &abci.ResponsePrepareProposal{TxRecords: trs}, nil } -func (app *CounterApplication) ProcessProposal(_ context.Context, req abci.RequestProcessProposal) abci.ResponseProcessProposal { - return abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT} +func (app *CounterApplication) ProcessProposal(_ context.Context, req abci.RequestProcessProposal) (*abci.ResponseProcessProposal, error) { + return &abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT}, nil } diff --git a/internal/consensus/mocks/cons_sync_reactor.go b/internal/consensus/mocks/cons_sync_reactor.go index 801713414..f904e9129 100644 --- a/internal/consensus/mocks/cons_sync_reactor.go +++ b/internal/consensus/mocks/cons_sync_reactor.go @@ -29,9 +29,10 @@ func (_m *ConsSyncReactor) SwitchToConsensus(_a0 state.State, _a1 bool) { _m.Called(_a0, _a1) } -// NewConsSyncReactor creates a new instance of ConsSyncReactor. It also registers a cleanup function to assert the mocks expectations. +// NewConsSyncReactor creates a new instance of ConsSyncReactor. It also registers the testing.TB interface on the mock and a cleanup function to assert the mocks expectations. func NewConsSyncReactor(t testing.TB) *ConsSyncReactor { mock := &ConsSyncReactor{} + mock.Mock.Test(t) t.Cleanup(func() { mock.AssertExpectations(t) }) diff --git a/internal/consensus/reactor_test.go b/internal/consensus/reactor_test.go index 2d4e6f61a..29dac5e00 100644 --- a/internal/consensus/reactor_test.go +++ b/internal/consensus/reactor_test.go @@ -466,7 +466,8 @@ func TestReactorWithEvidence(t *testing.T) { app := kvstore.NewApplication() vals := types.TM2PB.ValidatorUpdates(state.Validators) - app.InitChain(ctx, abci.RequestInitChain{Validators: vals}) + _, err = app.InitChain(ctx, abci.RequestInitChain{Validators: vals}) + require.NoError(t, err) pv := privVals[i] blockDB := dbm.NewMemDB() diff --git a/internal/consensus/replay_stubs.go b/internal/consensus/replay_stubs.go index 141389caa..783d31206 100644 --- a/internal/consensus/replay_stubs.go +++ b/internal/consensus/replay_stubs.go @@ -75,15 +75,15 @@ type mockProxyApp struct { abciResponses *tmstate.ABCIResponses } -func (mock *mockProxyApp) FinalizeBlock(_ context.Context, req abci.RequestFinalizeBlock) abci.ResponseFinalizeBlock { +func (mock *mockProxyApp) FinalizeBlock(_ context.Context, req abci.RequestFinalizeBlock) (*abci.ResponseFinalizeBlock, error) { r := mock.abciResponses.FinalizeBlock mock.txCount++ if r == nil { - return abci.ResponseFinalizeBlock{} + return &abci.ResponseFinalizeBlock{}, nil } - return *r + return r, nil } -func (mock *mockProxyApp) Commit(context.Context) abci.ResponseCommit { - return abci.ResponseCommit{Data: mock.appHash} +func (mock *mockProxyApp) Commit(context.Context) (*abci.ResponseCommit, error) { + return &abci.ResponseCommit{Data: mock.appHash}, nil } diff --git a/internal/consensus/replay_test.go b/internal/consensus/replay_test.go index 436a7c745..072c55d50 100644 --- a/internal/consensus/replay_test.go +++ b/internal/consensus/replay_test.go @@ -1017,15 +1017,15 @@ type badApp struct { onlyLastHashIsWrong bool } -func (app *badApp) Commit(context.Context) abci.ResponseCommit { +func (app *badApp) Commit(context.Context) (*abci.ResponseCommit, error) { app.height++ if app.onlyLastHashIsWrong { if app.height == app.numBlocks { - return abci.ResponseCommit{Data: tmrand.Bytes(8)} + return &abci.ResponseCommit{Data: tmrand.Bytes(8)}, nil } - return abci.ResponseCommit{Data: []byte{app.height}} + return &abci.ResponseCommit{Data: []byte{app.height}}, nil } else if app.allHashesAreWrong { - return abci.ResponseCommit{Data: tmrand.Bytes(8)} + return &abci.ResponseCommit{Data: tmrand.Bytes(8)}, nil } panic("either allHashesAreWrong or onlyLastHashIsWrong must be set") @@ -1275,8 +1275,6 @@ type initChainApp struct { vals []abci.ValidatorUpdate } -func (ica *initChainApp) InitChain(_ context.Context, req abci.RequestInitChain) abci.ResponseInitChain { - return abci.ResponseInitChain{ - Validators: ica.vals, - } +func (ica *initChainApp) InitChain(_ context.Context, req abci.RequestInitChain) (*abci.ResponseInitChain, error) { + return &abci.ResponseInitChain{Validators: ica.vals}, nil } diff --git a/internal/consensus/state_test.go b/internal/consensus/state_test.go index 6ddadd426..2bde6974a 100644 --- a/internal/consensus/state_test.go +++ b/internal/consensus/state_test.go @@ -1912,13 +1912,13 @@ func TestProcessProposalAccept(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - m := abcimocks.NewBaseMock() + m := abcimocks.NewApplication(t) status := abci.ResponseProcessProposal_REJECT if testCase.accept { status = abci.ResponseProcessProposal_ACCEPT } - m.On("ProcessProposal", mock.Anything, mock.Anything).Return(abci.ResponseProcessProposal{Status: status}) - m.On("PrepareProposal", mock.Anything, mock.Anything).Return(abci.ResponsePrepareProposal{}) + m.On("ProcessProposal", mock.Anything, mock.Anything).Return(&abci.ResponseProcessProposal{Status: status}, nil) + m.On("PrepareProposal", mock.Anything, mock.Anything).Return(&abci.ResponsePrepareProposal{}, nil).Maybe() cs1, _ := makeState(ctx, t, makeStateArgs{config: config, application: m}) height, round := cs1.Height, cs1.Round @@ -1965,15 +1965,18 @@ func TestFinalizeBlockCalled(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - m := abcimocks.NewBaseMock() - m.On("ProcessProposal", mock.Anything, mock.Anything).Return(abci.ResponseProcessProposal{ + m := abcimocks.NewApplication(t) + m.On("ProcessProposal", mock.Anything, mock.Anything).Return(&abci.ResponseProcessProposal{ Status: abci.ResponseProcessProposal_ACCEPT, - }) - m.On("PrepareProposal", mock.Anything, mock.Anything).Return(abci.ResponsePrepareProposal{}) - m.On("VerifyVoteExtension", mock.Anything, mock.Anything).Return(abci.ResponseVerifyVoteExtension{ + }, nil) + m.On("PrepareProposal", mock.Anything, mock.Anything).Return(&abci.ResponsePrepareProposal{}, nil) + m.On("VerifyVoteExtension", mock.Anything, mock.Anything).Return(&abci.ResponseVerifyVoteExtension{ Status: abci.ResponseVerifyVoteExtension_ACCEPT, - }) - m.On("FinalizeBlock", mock.Anything, mock.Anything).Return(abci.ResponseFinalizeBlock{}).Maybe() + }, nil) + m.On("FinalizeBlock", mock.Anything, mock.Anything).Return(&abci.ResponseFinalizeBlock{}, nil).Maybe() + m.On("ExtendVote", mock.Anything, mock.Anything).Return(&abci.ResponseExtendVote{}, nil) + m.On("Commit", mock.Anything).Return(&abci.ResponseCommit{}, nil).Maybe() + cs1, vss := makeState(ctx, t, makeStateArgs{config: config, application: m}) height, round := cs1.Height, cs1.Round @@ -2026,16 +2029,17 @@ func TestExtendVoteCalled(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - m := abcimocks.NewBaseMock() - m.On("ProcessProposal", mock.Anything, mock.Anything).Return(abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT}) - m.On("PrepareProposal", mock.Anything, mock.Anything).Return(abci.ResponsePrepareProposal{}) - m.On("ExtendVote", mock.Anything, mock.Anything).Return(abci.ResponseExtendVote{ + m := abcimocks.NewApplication(t) + m.On("ProcessProposal", mock.Anything, mock.Anything).Return(&abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT}, nil) + m.On("PrepareProposal", mock.Anything, mock.Anything).Return(&abci.ResponsePrepareProposal{}, nil) + m.On("ExtendVote", mock.Anything, mock.Anything).Return(&abci.ResponseExtendVote{ VoteExtension: []byte("extension"), - }) - m.On("VerifyVoteExtension", mock.Anything, mock.Anything).Return(abci.ResponseVerifyVoteExtension{ + }, nil) + m.On("VerifyVoteExtension", mock.Anything, mock.Anything).Return(&abci.ResponseVerifyVoteExtension{ Status: abci.ResponseVerifyVoteExtension_ACCEPT, - }) - m.On("FinalizeBlock", mock.Anything, mock.Anything).Return(abci.ResponseFinalizeBlock{}).Maybe() + }, nil) + m.On("Commit", mock.Anything).Return(&abci.ResponseCommit{}, nil).Maybe() + m.On("FinalizeBlock", mock.Anything, mock.Anything).Return(&abci.ResponseFinalizeBlock{}, nil).Maybe() cs1, vss := makeState(ctx, t, makeStateArgs{config: config, application: m}) height, round := cs1.Height, cs1.Round @@ -2074,7 +2078,6 @@ func TestExtendVoteCalled(t *testing.T) { Height: height, VoteExtension: []byte("extension"), }) - signAddVotes(ctx, t, cs1, tmproto.PrecommitType, config.ChainID(), blockID, vss[1:]...) ensureNewRound(t, newRoundCh, height+1, 0) m.AssertExpectations(t) @@ -2102,16 +2105,16 @@ func TestVerifyVoteExtensionNotCalledOnAbsentPrecommit(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - m := abcimocks.NewBaseMock() - m.On("ProcessProposal", mock.Anything, mock.Anything).Return(abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT}) - m.On("PrepareProposal", mock.Anything, mock.Anything).Return(abci.ResponsePrepareProposal{}) - m.On("ExtendVote", mock.Anything, mock.Anything).Return(abci.ResponseExtendVote{ + m := abcimocks.NewApplication(t) + m.On("ProcessProposal", mock.Anything, mock.Anything).Return(&abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT}, nil) + m.On("PrepareProposal", mock.Anything, mock.Anything).Return(&abci.ResponsePrepareProposal{}, nil) + m.On("ExtendVote", mock.Anything, mock.Anything).Return(&abci.ResponseExtendVote{ VoteExtension: []byte("extension"), - }) - m.On("VerifyVoteExtension", mock.Anything, mock.Anything).Return(abci.ResponseVerifyVoteExtension{ + }, nil) + m.On("VerifyVoteExtension", mock.Anything, mock.Anything).Return(&abci.ResponseVerifyVoteExtension{ Status: abci.ResponseVerifyVoteExtension_ACCEPT, - }) - m.On("FinalizeBlock", mock.Anything, mock.Anything).Return(abci.ResponseFinalizeBlock{}).Maybe() + }, nil) + m.On("FinalizeBlock", mock.Anything, mock.Anything).Return(&abci.ResponseFinalizeBlock{}, nil).Maybe() cs1, vss := makeState(ctx, t, makeStateArgs{config: config, application: m}) height, round := cs1.Height, cs1.Round @@ -2148,6 +2151,7 @@ func TestVerifyVoteExtensionNotCalledOnAbsentPrecommit(t *testing.T) { VoteExtension: []byte("extension"), }) + m.On("Commit", mock.Anything).Return(&abci.ResponseCommit{}, nil).Maybe() signAddVotes(ctx, t, cs1, tmproto.PrecommitType, config.ChainID(), blockID, vss[2:]...) ensureNewRound(t, newRoundCh, height+1, 0) m.AssertExpectations(t) @@ -2187,13 +2191,24 @@ func TestPrepareProposalReceivesVoteExtensions(t *testing.T) { []byte("extension 3"), } - m := abcimocks.NewBaseMock() - m.On("ExtendVote", mock.Anything, mock.Anything).Return(abci.ResponseExtendVote{ + // m := abcimocks.NewApplication(t) + m := &abcimocks.Application{} + m.On("ExtendVote", mock.Anything, mock.Anything).Return(&abci.ResponseExtendVote{ VoteExtension: voteExtensions[0], - }) - m.On("PrepareProposal", mock.Anything, mock.Anything).Return(abci.ResponsePrepareProposal{}).Once() - m.On("ProcessProposal", mock.Anything, mock.Anything).Return(abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT}).Once() - m.On("VerifyVoteExtension", mock.Anything, mock.Anything).Return(abci.ResponseVerifyVoteExtension{Status: abci.ResponseVerifyVoteExtension_ACCEPT}) + }, nil) + m.On("ProcessProposal", mock.Anything, mock.Anything).Return(&abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT}, nil) + + // capture the prepare proposal request. + rpp := abci.RequestPrepareProposal{} + m.On("PrepareProposal", mock.Anything, mock.MatchedBy(func(r abci.RequestPrepareProposal) bool { + rpp = r + return true + })).Return(&abci.ResponsePrepareProposal{}, nil) + + m.On("PrepareProposal", mock.Anything, mock.Anything).Return(&abci.ResponsePrepareProposal{}, nil).Once() + m.On("VerifyVoteExtension", mock.Anything, mock.Anything).Return(&abci.ResponseVerifyVoteExtension{Status: abci.ResponseVerifyVoteExtension_ACCEPT}, nil) + m.On("Commit", mock.Anything).Return(&abci.ResponseCommit{}, nil).Maybe() + m.On("FinalizeBlock", mock.Anything, mock.Anything).Return(&abci.ResponseFinalizeBlock{}, nil) cs1, vss := makeState(ctx, t, makeStateArgs{config: config, application: m}) height, round := cs1.Height, cs1.Round @@ -2235,19 +2250,13 @@ func TestPrepareProposalReceivesVoteExtensions(t *testing.T) { incrementRound(vss[1:]...) round = 3 - // capture the prepare proposal request. - rpp := abci.RequestPrepareProposal{} - m.On("PrepareProposal", mock.Anything, mock.MatchedBy(func(r abci.RequestPrepareProposal) bool { - rpp = r - return true - })).Return(abci.ResponsePrepareProposal{}) - signAddVotes(ctx, t, cs1, tmproto.PrecommitType, config.ChainID(), types.BlockID{}, vss[1:]...) ensureNewRound(t, newRoundCh, height, round) ensureNewProposal(t, proposalCh, height, round) // ensure that the proposer received the list of vote extensions from the // previous height. + require.Len(t, rpp.LocalLastCommit.Votes, len(vss)) for i := range vss { require.Equal(t, rpp.LocalLastCommit.Votes[i].VoteExtension, voteExtensions[i]) } diff --git a/internal/evidence/mocks/block_store.go b/internal/evidence/mocks/block_store.go index 77745b15a..e45b281b9 100644 --- a/internal/evidence/mocks/block_store.go +++ b/internal/evidence/mocks/block_store.go @@ -61,9 +61,10 @@ func (_m *BlockStore) LoadBlockMeta(height int64) *types.BlockMeta { return r0 } -// NewBlockStore creates a new instance of BlockStore. It also registers a cleanup function to assert the mocks expectations. +// NewBlockStore creates a new instance of BlockStore. It also registers the testing.TB interface on the mock and a cleanup function to assert the mocks expectations. func NewBlockStore(t testing.TB) *BlockStore { mock := &BlockStore{} + mock.Mock.Test(t) t.Cleanup(func() { mock.AssertExpectations(t) }) diff --git a/internal/mempool/mempool_test.go b/internal/mempool/mempool_test.go index 5d6ba6825..0f8f0e712 100644 --- a/internal/mempool/mempool_test.go +++ b/internal/mempool/mempool_test.go @@ -36,7 +36,7 @@ type testTx struct { priority int64 } -func (app *application) CheckTx(_ context.Context, req abci.RequestCheckTx) abci.ResponseCheckTx { +func (app *application) CheckTx(_ context.Context, req abci.RequestCheckTx) (*abci.ResponseCheckTx, error) { var ( priority int64 sender string @@ -47,29 +47,29 @@ func (app *application) CheckTx(_ context.Context, req abci.RequestCheckTx) abci if len(parts) == 3 { v, err := strconv.ParseInt(string(parts[2]), 10, 64) if err != nil { - return abci.ResponseCheckTx{ + return &abci.ResponseCheckTx{ Priority: priority, Code: 100, GasWanted: 1, - } + }, nil } priority = v sender = string(parts[0]) } else { - return abci.ResponseCheckTx{ + return &abci.ResponseCheckTx{ Priority: priority, Code: 101, GasWanted: 1, - } + }, nil } - return abci.ResponseCheckTx{ + return &abci.ResponseCheckTx{ Priority: priority, Sender: sender, Code: code.CodeTypeOK, GasWanted: 1, - } + }, nil } func setup(t testing.TB, app abciclient.Client, cacheSize int, options ...TxMempoolOption) *TxMempool { diff --git a/internal/mempool/mocks/mempool.go b/internal/mempool/mocks/mempool.go index 48017c6d2..b82d7d63e 100644 --- a/internal/mempool/mocks/mempool.go +++ b/internal/mempool/mocks/mempool.go @@ -173,9 +173,10 @@ func (_m *Mempool) Update(ctx context.Context, blockHeight int64, blockTxs types return r0 } -// NewMempool creates a new instance of Mempool. It also registers a cleanup function to assert the mocks expectations. +// NewMempool creates a new instance of Mempool. It also registers the testing.TB interface on the mock and a cleanup function to assert the mocks expectations. func NewMempool(t testing.TB) *Mempool { mock := &Mempool{} + mock.Mock.Test(t) t.Cleanup(func() { mock.AssertExpectations(t) }) diff --git a/internal/p2p/mocks/connection.go b/internal/p2p/mocks/connection.go index bb9390ddb..73b6cfc3b 100644 --- a/internal/p2p/mocks/connection.go +++ b/internal/p2p/mocks/connection.go @@ -153,9 +153,10 @@ func (_m *Connection) String() string { return r0 } -// NewConnection creates a new instance of Connection. It also registers a cleanup function to assert the mocks expectations. +// NewConnection creates a new instance of Connection. It also registers the testing.TB interface on the mock and a cleanup function to assert the mocks expectations. func NewConnection(t testing.TB) *Connection { mock := &Connection{} + mock.Mock.Test(t) t.Cleanup(func() { mock.AssertExpectations(t) }) diff --git a/internal/p2p/mocks/transport.go b/internal/p2p/mocks/transport.go index 6ca4146df..d08533186 100644 --- a/internal/p2p/mocks/transport.go +++ b/internal/p2p/mocks/transport.go @@ -144,9 +144,10 @@ func (_m *Transport) String() string { return r0 } -// NewTransport creates a new instance of Transport. It also registers a cleanup function to assert the mocks expectations. +// NewTransport creates a new instance of Transport. It also registers the testing.TB interface on the mock and a cleanup function to assert the mocks expectations. func NewTransport(t testing.TB) *Transport { mock := &Transport{} + mock.Mock.Test(t) t.Cleanup(func() { mock.AssertExpectations(t) }) diff --git a/internal/state/execution_test.go b/internal/state/execution_test.go index c6caa4272..71d5b2f83 100644 --- a/internal/state/execution_test.go +++ b/internal/state/execution_test.go @@ -277,7 +277,7 @@ func TestProcessProposal(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - app := abcimocks.NewBaseMock() + app := abcimocks.NewApplication(t) logger := log.NewNopLogger() cc := abciclient.NewLocalClient(logger, app) proxyApp := proxy.New(cc, logger, proxy.NopMetrics()) @@ -343,7 +343,7 @@ func TestProcessProposal(t *testing.T) { ProposerAddress: block1.ProposerAddress, } - app.On("ProcessProposal", mock.Anything, mock.Anything).Return(abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT}) + app.On("ProcessProposal", mock.Anything, mock.Anything).Return(&abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT}, nil) acceptBlock, err := blockExec.ProcessProposal(ctx, block1, state) require.NoError(t, err) require.True(t, acceptBlock) @@ -621,8 +621,8 @@ func TestEmptyPrepareProposal(t *testing.T) { eventBus := eventbus.NewDefault(logger) require.NoError(t, eventBus.Start(ctx)) - app := abcimocks.NewBaseMock() - app.On("PrepareProposal", mock.Anything).Return(abci.ResponsePrepareProposal{}) + app := abcimocks.NewApplication(t) + app.On("PrepareProposal", mock.Anything, mock.Anything).Return(&abci.ResponsePrepareProposal{}, nil) cc := abciclient.NewLocalClient(logger, app) proxyApp := proxy.New(cc, logger, proxy.NopMetrics()) err := proxyApp.Start(ctx) @@ -680,10 +680,10 @@ func TestPrepareProposalErrorOnNonExistingRemoved(t *testing.T) { mp := &mpmocks.Mempool{} mp.On("ReapMaxBytesMaxGas", mock.Anything, mock.Anything).Return(types.Txs{}) - app := abcimocks.NewBaseMock() + app := abcimocks.NewApplication(t) // create an invalid ResponsePrepareProposal - rpp := abci.ResponsePrepareProposal{ + rpp := &abci.ResponsePrepareProposal{ TxRecords: []*abci.TxRecord{ { Action: abci.TxRecord_REMOVED, @@ -691,7 +691,7 @@ func TestPrepareProposalErrorOnNonExistingRemoved(t *testing.T) { }, }, } - app.On("PrepareProposal", mock.Anything, mock.Anything).Return(rpp) + app.On("PrepareProposal", mock.Anything, mock.Anything).Return(rpp, nil) cc := abciclient.NewLocalClient(logger, app) proxyApp := proxy.New(cc, logger, proxy.NopMetrics()) @@ -711,8 +711,8 @@ func TestPrepareProposalErrorOnNonExistingRemoved(t *testing.T) { pa, _ := state.Validators.GetByIndex(0) commit, votes := makeValidCommit(ctx, t, height, types.BlockID{}, state.Validators, privVals) block, err := blockExec.CreateProposalBlock(ctx, height, state, commit, pa, votes) - require.Nil(t, block) require.ErrorContains(t, err, "new transaction incorrectly marked as removed") + require.Nil(t, block) mp.AssertExpectations(t) } @@ -744,10 +744,10 @@ func TestPrepareProposalRemoveTxs(t *testing.T) { trs[1].Action = abci.TxRecord_REMOVED mp.On("RemoveTxByKey", mock.Anything).Return(nil).Twice() - app := abcimocks.NewBaseMock() - app.On("PrepareProposal", mock.Anything, mock.Anything).Return(abci.ResponsePrepareProposal{ + app := abcimocks.NewApplication(t) + app.On("PrepareProposal", mock.Anything, mock.Anything).Return(&abci.ResponsePrepareProposal{ TxRecords: trs, - }) + }, nil) cc := abciclient.NewLocalClient(logger, app) proxyApp := proxy.New(cc, logger, proxy.NopMetrics()) @@ -803,10 +803,10 @@ func TestPrepareProposalAddedTxsIncluded(t *testing.T) { trs[0].Action = abci.TxRecord_ADDED trs[1].Action = abci.TxRecord_ADDED - app := abcimocks.NewBaseMock() - app.On("PrepareProposal", mock.Anything, mock.Anything).Return(abci.ResponsePrepareProposal{ + app := abcimocks.NewApplication(t) + app.On("PrepareProposal", mock.Anything, mock.Anything).Return(&abci.ResponsePrepareProposal{ TxRecords: trs, - }) + }, nil) cc := abciclient.NewLocalClient(logger, app) proxyApp := proxy.New(cc, logger, proxy.NopMetrics()) @@ -859,10 +859,10 @@ func TestPrepareProposalReorderTxs(t *testing.T) { trs = trs[2:] trs = append(trs[len(trs)/2:], trs[:len(trs)/2]...) - app := abcimocks.NewBaseMock() - app.On("PrepareProposal", mock.Anything, mock.Anything).Return(abci.ResponsePrepareProposal{ + app := abcimocks.NewApplication(t) + app.On("PrepareProposal", mock.Anything, mock.Anything).Return(&abci.ResponsePrepareProposal{ TxRecords: trs, - }) + }, nil) cc := abciclient.NewLocalClient(logger, app) proxyApp := proxy.New(cc, logger, proxy.NopMetrics()) @@ -919,10 +919,10 @@ func TestPrepareProposalErrorOnTooManyTxs(t *testing.T) { trs := txsToTxRecords(types.Txs(txs)) - app := abcimocks.NewBaseMock() - app.On("PrepareProposal", mock.Anything, mock.Anything).Return(abci.ResponsePrepareProposal{ + app := abcimocks.NewApplication(t) + app.On("PrepareProposal", mock.Anything, mock.Anything).Return(&abci.ResponsePrepareProposal{ TxRecords: trs, - }) + }, nil) cc := abciclient.NewLocalClient(logger, app) proxyApp := proxy.New(cc, logger, proxy.NopMetrics()) @@ -943,8 +943,8 @@ func TestPrepareProposalErrorOnTooManyTxs(t *testing.T) { commit, votes := makeValidCommit(ctx, t, height, types.BlockID{}, state.Validators, privVals) block, err := blockExec.CreateProposalBlock(ctx, height, state, commit, pa, votes) - require.Nil(t, block) require.ErrorContains(t, err, "transaction data size exceeds maximum") + require.Nil(t, block, "") mp.AssertExpectations(t) } diff --git a/internal/state/helpers_test.go b/internal/state/helpers_test.go index e59c4c4d8..67072766a 100644 --- a/internal/state/helpers_test.go +++ b/internal/state/helpers_test.go @@ -278,11 +278,11 @@ type testApp struct { var _ abci.Application = (*testApp)(nil) -func (app *testApp) Info(_ context.Context, req abci.RequestInfo) (resInfo abci.ResponseInfo) { - return abci.ResponseInfo{} +func (app *testApp) Info(_ context.Context, req abci.RequestInfo) (*abci.ResponseInfo, error) { + return &abci.ResponseInfo{}, nil } -func (app *testApp) FinalizeBlock(_ context.Context, req abci.RequestFinalizeBlock) abci.ResponseFinalizeBlock { +func (app *testApp) FinalizeBlock(_ context.Context, req abci.RequestFinalizeBlock) (*abci.ResponseFinalizeBlock, error) { app.CommitVotes = req.DecidedLastCommit.Votes app.ByzantineValidators = req.ByzantineValidators @@ -295,7 +295,7 @@ func (app *testApp) FinalizeBlock(_ context.Context, req abci.RequestFinalizeBlo } } - return abci.ResponseFinalizeBlock{ + return &abci.ResponseFinalizeBlock{ ValidatorUpdates: app.ValidatorUpdates, ConsensusParamUpdates: &tmproto.ConsensusParams{ Version: &tmproto.VersionParams{ @@ -304,26 +304,26 @@ func (app *testApp) FinalizeBlock(_ context.Context, req abci.RequestFinalizeBlo }, Events: []abci.Event{}, TxResults: resTxs, - } + }, nil } -func (app *testApp) CheckTx(_ context.Context, req abci.RequestCheckTx) abci.ResponseCheckTx { - return abci.ResponseCheckTx{} +func (app *testApp) CheckTx(_ context.Context, req abci.RequestCheckTx) (*abci.ResponseCheckTx, error) { + return &abci.ResponseCheckTx{}, nil } -func (app *testApp) Commit(context.Context) abci.ResponseCommit { - return abci.ResponseCommit{RetainHeight: 1} +func (app *testApp) Commit(context.Context) (*abci.ResponseCommit, error) { + return &abci.ResponseCommit{RetainHeight: 1}, nil } -func (app *testApp) Query(_ context.Context, req abci.RequestQuery) (resQuery abci.ResponseQuery) { - return +func (app *testApp) Query(_ context.Context, req abci.RequestQuery) (*abci.ResponseQuery, error) { + return &abci.ResponseQuery{}, nil } -func (app *testApp) ProcessProposal(_ context.Context, req abci.RequestProcessProposal) abci.ResponseProcessProposal { +func (app *testApp) ProcessProposal(_ context.Context, req abci.RequestProcessProposal) (*abci.ResponseProcessProposal, error) { for _, tx := range req.Txs { if len(tx) == 0 { - return abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_REJECT} + return &abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_REJECT}, nil } } - return abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT} + return &abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT}, nil } diff --git a/internal/state/indexer/mocks/event_sink.go b/internal/state/indexer/mocks/event_sink.go index 0daffbaf8..decf551ab 100644 --- a/internal/state/indexer/mocks/event_sink.go +++ b/internal/state/indexer/mocks/event_sink.go @@ -168,9 +168,10 @@ func (_m *EventSink) Type() indexer.EventSinkType { return r0 } -// NewEventSink creates a new instance of EventSink. It also registers a cleanup function to assert the mocks expectations. +// NewEventSink creates a new instance of EventSink. It also registers the testing.TB interface on the mock and a cleanup function to assert the mocks expectations. func NewEventSink(t testing.TB) *EventSink { mock := &EventSink{} + mock.Mock.Test(t) t.Cleanup(func() { mock.AssertExpectations(t) }) diff --git a/internal/state/mocks/block_store.go b/internal/state/mocks/block_store.go index 7d7bbcf19..7cc7fa883 100644 --- a/internal/state/mocks/block_store.go +++ b/internal/state/mocks/block_store.go @@ -211,9 +211,10 @@ func (_m *BlockStore) Size() int64 { return r0 } -// NewBlockStore creates a new instance of BlockStore. It also registers a cleanup function to assert the mocks expectations. +// NewBlockStore creates a new instance of BlockStore. It also registers the testing.TB interface on the mock and a cleanup function to assert the mocks expectations. func NewBlockStore(t testing.TB) *BlockStore { mock := &BlockStore{} + mock.Mock.Test(t) t.Cleanup(func() { mock.AssertExpectations(t) }) diff --git a/internal/state/mocks/evidence_pool.go b/internal/state/mocks/evidence_pool.go index 1d081b3b8..49633269b 100644 --- a/internal/state/mocks/evidence_pool.go +++ b/internal/state/mocks/evidence_pool.go @@ -74,9 +74,10 @@ func (_m *EvidencePool) Update(_a0 context.Context, _a1 state.State, _a2 types.E _m.Called(_a0, _a1, _a2) } -// NewEvidencePool creates a new instance of EvidencePool. It also registers a cleanup function to assert the mocks expectations. +// NewEvidencePool creates a new instance of EvidencePool. It also registers the testing.TB interface on the mock and a cleanup function to assert the mocks expectations. func NewEvidencePool(t testing.TB) *EvidencePool { mock := &EvidencePool{} + mock.Mock.Test(t) t.Cleanup(func() { mock.AssertExpectations(t) }) diff --git a/internal/state/mocks/store.go b/internal/state/mocks/store.go index 3ef8a3ebb..9b41f3c1b 100644 --- a/internal/state/mocks/store.go +++ b/internal/state/mocks/store.go @@ -189,9 +189,10 @@ func (_m *Store) SaveValidatorSets(_a0 int64, _a1 int64, _a2 *types.ValidatorSet return r0 } -// NewStore creates a new instance of Store. It also registers a cleanup function to assert the mocks expectations. +// NewStore creates a new instance of Store. It also registers the testing.TB interface on the mock and a cleanup function to assert the mocks expectations. func NewStore(t testing.TB) *Store { mock := &Store{} + mock.Mock.Test(t) t.Cleanup(func() { mock.AssertExpectations(t) }) diff --git a/internal/statesync/mocks/state_provider.go b/internal/statesync/mocks/state_provider.go index 83287aa2f..582ebcd9c 100644 --- a/internal/statesync/mocks/state_provider.go +++ b/internal/statesync/mocks/state_provider.go @@ -85,9 +85,10 @@ func (_m *StateProvider) State(ctx context.Context, height uint64) (state.State, return r0, r1 } -// NewStateProvider creates a new instance of StateProvider. It also registers a cleanup function to assert the mocks expectations. +// NewStateProvider creates a new instance of StateProvider. It also registers the testing.TB interface on the mock and a cleanup function to assert the mocks expectations. func NewStateProvider(t testing.TB) *StateProvider { mock := &StateProvider{} + mock.Mock.Test(t) t.Cleanup(func() { mock.AssertExpectations(t) }) diff --git a/libs/time/mocks/source.go b/libs/time/mocks/source.go index 0872db5e3..7878d86f5 100644 --- a/libs/time/mocks/source.go +++ b/libs/time/mocks/source.go @@ -29,9 +29,10 @@ func (_m *Source) Now() time.Time { return r0 } -// NewSource creates a new instance of Source. It also registers a cleanup function to assert the mocks expectations. +// NewSource creates a new instance of Source. It also registers the testing.TB interface on the mock and a cleanup function to assert the mocks expectations. func NewSource(t testing.TB) *Source { mock := &Source{} + mock.Mock.Test(t) t.Cleanup(func() { mock.AssertExpectations(t) }) diff --git a/light/provider/mocks/provider.go b/light/provider/mocks/provider.go index fe0fbade5..e136046f9 100644 --- a/light/provider/mocks/provider.go +++ b/light/provider/mocks/provider.go @@ -68,9 +68,10 @@ func (_m *Provider) ReportEvidence(_a0 context.Context, _a1 types.Evidence) erro return r0 } -// NewProvider creates a new instance of Provider. It also registers a cleanup function to assert the mocks expectations. +// NewProvider creates a new instance of Provider. It also registers the testing.TB interface on the mock and a cleanup function to assert the mocks expectations. func NewProvider(t testing.TB) *Provider { mock := &Provider{} + mock.Mock.Test(t) t.Cleanup(func() { mock.AssertExpectations(t) }) diff --git a/light/rpc/mocks/light_client.go b/light/rpc/mocks/light_client.go index 4ca1c1dce..ea6d6a2d4 100644 --- a/light/rpc/mocks/light_client.go +++ b/light/rpc/mocks/light_client.go @@ -118,9 +118,10 @@ func (_m *LightClient) VerifyLightBlockAtHeight(ctx context.Context, height int6 return r0, r1 } -// NewLightClient creates a new instance of LightClient. It also registers a cleanup function to assert the mocks expectations. +// NewLightClient creates a new instance of LightClient. It also registers the testing.TB interface on the mock and a cleanup function to assert the mocks expectations. func NewLightClient(t testing.TB) *LightClient { mock := &LightClient{} + mock.Mock.Test(t) t.Cleanup(func() { mock.AssertExpectations(t) }) diff --git a/rpc/client/mock/abci.go b/rpc/client/mock/abci.go index ce751717d..ba1c2b676 100644 --- a/rpc/client/mock/abci.go +++ b/rpc/client/mock/abci.go @@ -25,7 +25,12 @@ var ( ) func (a ABCIApp) ABCIInfo(ctx context.Context) (*coretypes.ResultABCIInfo, error) { - return &coretypes.ResultABCIInfo{Response: a.App.Info(ctx, proxy.RequestInfo)}, nil + res, err := a.App.Info(ctx, proxy.RequestInfo) + if err != nil { + return nil, err + } + + return &coretypes.ResultABCIInfo{Response: *res}, nil } func (a ABCIApp) ABCIQuery(ctx context.Context, path string, data bytes.HexBytes) (*coretypes.ResultABCIQuery, error) { @@ -33,35 +38,52 @@ func (a ABCIApp) ABCIQuery(ctx context.Context, path string, data bytes.HexBytes } func (a ABCIApp) ABCIQueryWithOptions(ctx context.Context, path string, data bytes.HexBytes, opts client.ABCIQueryOptions) (*coretypes.ResultABCIQuery, error) { - q := a.App.Query(ctx, abci.RequestQuery{ + q, err := a.App.Query(ctx, abci.RequestQuery{ Data: data, Path: path, Height: opts.Height, Prove: opts.Prove, }) - return &coretypes.ResultABCIQuery{Response: q}, nil + if err != nil { + return nil, err + } + + return &coretypes.ResultABCIQuery{Response: *q}, nil } // NOTE: Caller should call a.App.Commit() separately, // this function does not actually wait for a commit. // TODO: Make it wait for a commit and set res.Height appropriately. func (a ABCIApp) BroadcastTxCommit(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTxCommit, error) { - res := coretypes.ResultBroadcastTxCommit{} - res.CheckTx = a.App.CheckTx(ctx, abci.RequestCheckTx{Tx: tx}) - if res.CheckTx.IsErr() { - return &res, nil + resp, err := a.App.CheckTx(ctx, abci.RequestCheckTx{Tx: tx}) + if err != nil { + return nil, err } - fb := a.App.FinalizeBlock(ctx, abci.RequestFinalizeBlock{Txs: [][]byte{tx}}) + + res := &coretypes.ResultBroadcastTxCommit{CheckTx: *resp} + if res.CheckTx.IsErr() { + return res, nil + } + + fb, err := a.App.FinalizeBlock(ctx, abci.RequestFinalizeBlock{Txs: [][]byte{tx}}) + if err != nil { + return nil, err + } + res.TxResult = *fb.TxResults[0] res.Height = -1 // TODO - return &res, nil + return res, nil } func (a ABCIApp) BroadcastTxAsync(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTx, error) { - c := a.App.CheckTx(ctx, abci.RequestCheckTx{Tx: tx}) + c, err := a.App.CheckTx(ctx, abci.RequestCheckTx{Tx: tx}) + if err != nil { + return nil, err + } + // and this gets written in a background thread... if !c.IsErr() { - go func() { a.App.FinalizeBlock(ctx, abci.RequestFinalizeBlock{Txs: [][]byte{tx}}) }() + go func() { _, _ = a.App.FinalizeBlock(ctx, abci.RequestFinalizeBlock{Txs: [][]byte{tx}}) }() } return &coretypes.ResultBroadcastTx{ Code: c.Code, @@ -73,10 +95,14 @@ func (a ABCIApp) BroadcastTxAsync(ctx context.Context, tx types.Tx) (*coretypes. } func (a ABCIApp) BroadcastTxSync(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTx, error) { - c := a.App.CheckTx(ctx, abci.RequestCheckTx{Tx: tx}) + c, err := a.App.CheckTx(ctx, abci.RequestCheckTx{Tx: tx}) + if err != nil { + return nil, err + } + // and this gets written in a background thread... if !c.IsErr() { - go func() { a.App.FinalizeBlock(ctx, abci.RequestFinalizeBlock{Txs: [][]byte{tx}}) }() + go func() { _, _ = a.App.FinalizeBlock(ctx, abci.RequestFinalizeBlock{Txs: [][]byte{tx}}) }() } return &coretypes.ResultBroadcastTx{ Code: c.Code, diff --git a/rpc/client/mock/abci_test.go b/rpc/client/mock/abci_test.go index aa117f058..e35ccf29c 100644 --- a/rpc/client/mock/abci_test.go +++ b/rpc/client/mock/abci_test.go @@ -185,7 +185,8 @@ func TestABCIApp(t *testing.T) { // commit // TODO: This may not be necessary in the future if res.Height == -1 { - m.App.Commit(ctx) + _, err := m.App.Commit(ctx) + require.NoError(t, err) } // check the key diff --git a/rpc/client/mocks/client.go b/rpc/client/mocks/client.go index d8cbd560d..9a286eaf2 100644 --- a/rpc/client/mocks/client.go +++ b/rpc/client/mocks/client.go @@ -798,9 +798,10 @@ func (_m *Client) Validators(ctx context.Context, height *int64, page *int, perP return r0, r1 } -// NewClient creates a new instance of Client. It also registers a cleanup function to assert the mocks expectations. +// NewClient creates a new instance of Client. It also registers the testing.TB interface on the mock and a cleanup function to assert the mocks expectations. func NewClient(t testing.TB) *Client { mock := &Client{} + mock.Mock.Test(t) t.Cleanup(func() { mock.AssertExpectations(t) }) diff --git a/spec/abci/abci.md b/spec/abci/abci.md index 2a027d1d0..5d9d59b71 100644 --- a/spec/abci/abci.md +++ b/spec/abci/abci.md @@ -13,35 +13,11 @@ replication engine. When run within the same process, Tendermint will call the A application methods directly as Go method calls. When Tendermint and the ABCI application are run as separate processes, Tendermint -opens four connections to the application for ABCI methods. The connections each -handle a subset of the ABCI method calls. These subsets are defined as follows: +opens maintains a connection over either a native socket protocol or +gRPC. -#### **Consensus** connection - -* Driven by a consensus protocol and is responsible for block execution. -* Handles the `InitChain`, `BeginBlock`, `DeliverTx`, `EndBlock`, and `Commit` method -calls. - -#### **Mempool** connection - -* For validating new transactions, before they're shared or included in a block. -* Handles the `CheckTx` calls. - -#### **Info** connection - -* For initialization and for queries from the user. -* Handles the `Info` and `Query` calls. - -#### **Snapshot** connection - -* For serving and restoring [state sync snapshots](apps.md#state-sync). -* Handles the `ListSnapshots`, `LoadSnapshotChunk`, `OfferSnapshot`, and `ApplySnapshotChunk` calls. - -Additionally, there is a `Flush` method that is called on every connection, -and an `Echo` method that is just for debugging. - -More details on managing state across connections can be found in the section on -[ABCI Applications](apps.md). +More details on managing state across connections can be found in the +section on [ABCI Applications](apps.md). ## Errors @@ -54,13 +30,17 @@ These methods also return a `Codespace` string to Tendermint. This field is used to disambiguate `Code` values returned by different domains of the application. The `Codespace` is a namespace for the `Code`. -The `Echo`, `Info`, `InitChain`, `BeginBlock`, `EndBlock`, `Commit` methods -do not return errors. An error in any of these methods represents a critical -issue that Tendermint has no reasonable way to handle. If there is an error in one -of these methods, the application must crash to ensure that the error is safely -handled by an operator. +The handling of non-zero response codes by Tendermint is described +below. -The handling of non-zero response codes by Tendermint is described below +Applications should always terminate if they encounter an issue in a +method where continuing would corrupt their own state, or for which +tendermint should not continue. + +In the Go implementation these methods take a context and may return +an error. The context exists so that applications can terminate +gracefully during shutdown, and the error return value makes it +possible for applications to singal transient errors to Tendermint. ### CheckTx diff --git a/test/e2e/app/app.go b/test/e2e/app/app.go index d4412c15c..a67c672d2 100644 --- a/test/e2e/app/app.go +++ b/test/e2e/app/app.go @@ -114,20 +114,20 @@ func NewApplication(cfg *Config) (*Application, error) { } // Info implements ABCI. -func (app *Application) Info(_ context.Context, req abci.RequestInfo) abci.ResponseInfo { +func (app *Application) Info(_ context.Context, req abci.RequestInfo) (*abci.ResponseInfo, error) { app.mu.Lock() defer app.mu.Unlock() - return abci.ResponseInfo{ + return &abci.ResponseInfo{ Version: version.ABCIVersion, AppVersion: 1, LastBlockHeight: int64(app.state.Height), LastBlockAppHash: app.state.Hash, - } + }, nil } // Info implements ABCI. -func (app *Application) InitChain(_ context.Context, req abci.RequestInitChain) abci.ResponseInitChain { +func (app *Application) InitChain(_ context.Context, req abci.RequestInitChain) (*abci.ResponseInitChain, error) { app.mu.Lock() defer app.mu.Unlock() @@ -139,7 +139,7 @@ func (app *Application) InitChain(_ context.Context, req abci.RequestInitChain) panic(err) } } - resp := abci.ResponseInitChain{ + resp := &abci.ResponseInitChain{ AppHash: app.state.Hash, ConsensusParams: &types.ConsensusParams{ Version: &types.VersionParams{ @@ -150,26 +150,26 @@ func (app *Application) InitChain(_ context.Context, req abci.RequestInitChain) if resp.Validators, err = app.validatorUpdates(0); err != nil { panic(err) } - return resp + return resp, nil } // CheckTx implements ABCI. -func (app *Application) CheckTx(_ context.Context, req abci.RequestCheckTx) abci.ResponseCheckTx { +func (app *Application) CheckTx(_ context.Context, req abci.RequestCheckTx) (*abci.ResponseCheckTx, error) { app.mu.Lock() defer app.mu.Unlock() _, _, err := parseTx(req.Tx) if err != nil { - return abci.ResponseCheckTx{ + return &abci.ResponseCheckTx{ Code: code.CodeTypeEncodingError, Log: err.Error(), - } + }, nil } - return abci.ResponseCheckTx{Code: code.CodeTypeOK, GasWanted: 1} + return &abci.ResponseCheckTx{Code: code.CodeTypeOK, GasWanted: 1}, nil } // FinalizeBlock implements ABCI. -func (app *Application) FinalizeBlock(_ context.Context, req abci.RequestFinalizeBlock) abci.ResponseFinalizeBlock { +func (app *Application) FinalizeBlock(_ context.Context, req abci.RequestFinalizeBlock) (*abci.ResponseFinalizeBlock, error) { var txs = make([]*abci.ExecTxResult, len(req.Txs)) app.mu.Lock() @@ -190,7 +190,7 @@ func (app *Application) FinalizeBlock(_ context.Context, req abci.RequestFinaliz panic(err) } - return abci.ResponseFinalizeBlock{ + return &abci.ResponseFinalizeBlock{ TxResults: txs, ValidatorUpdates: valUpdates, Events: []abci.Event{ @@ -208,11 +208,11 @@ func (app *Application) FinalizeBlock(_ context.Context, req abci.RequestFinaliz }, }, }, - } + }, nil } // Commit implements ABCI. -func (app *Application) Commit(_ context.Context) abci.ResponseCommit { +func (app *Application) Commit(_ context.Context) (*abci.ResponseCommit, error) { app.mu.Lock() defer app.mu.Unlock() @@ -235,26 +235,26 @@ func (app *Application) Commit(_ context.Context) abci.ResponseCommit { if app.cfg.RetainBlocks > 0 { retainHeight = int64(height - app.cfg.RetainBlocks + 1) } - return abci.ResponseCommit{ + return &abci.ResponseCommit{ Data: hash, RetainHeight: retainHeight, - } + }, nil } // Query implements ABCI. -func (app *Application) Query(_ context.Context, req abci.RequestQuery) abci.ResponseQuery { +func (app *Application) Query(_ context.Context, req abci.RequestQuery) (*abci.ResponseQuery, error) { app.mu.Lock() defer app.mu.Unlock() - return abci.ResponseQuery{ + return &abci.ResponseQuery{ Height: int64(app.state.Height), Key: req.Data, Value: []byte(app.state.Get(string(req.Data))), - } + }, nil } // ListSnapshots implements ABCI. -func (app *Application) ListSnapshots(_ context.Context, req abci.RequestListSnapshots) abci.ResponseListSnapshots { +func (app *Application) ListSnapshots(_ context.Context, req abci.RequestListSnapshots) (*abci.ResponseListSnapshots, error) { app.mu.Lock() defer app.mu.Unlock() @@ -262,11 +262,11 @@ func (app *Application) ListSnapshots(_ context.Context, req abci.RequestListSna if err != nil { panic(err) } - return abci.ResponseListSnapshots{Snapshots: snapshots} + return &abci.ResponseListSnapshots{Snapshots: snapshots}, nil } // LoadSnapshotChunk implements ABCI. -func (app *Application) LoadSnapshotChunk(_ context.Context, req abci.RequestLoadSnapshotChunk) abci.ResponseLoadSnapshotChunk { +func (app *Application) LoadSnapshotChunk(_ context.Context, req abci.RequestLoadSnapshotChunk) (*abci.ResponseLoadSnapshotChunk, error) { app.mu.Lock() defer app.mu.Unlock() @@ -274,11 +274,11 @@ func (app *Application) LoadSnapshotChunk(_ context.Context, req abci.RequestLoa if err != nil { panic(err) } - return abci.ResponseLoadSnapshotChunk{Chunk: chunk} + return &abci.ResponseLoadSnapshotChunk{Chunk: chunk}, nil } // OfferSnapshot implements ABCI. -func (app *Application) OfferSnapshot(_ context.Context, req abci.RequestOfferSnapshot) abci.ResponseOfferSnapshot { +func (app *Application) OfferSnapshot(_ context.Context, req abci.RequestOfferSnapshot) (*abci.ResponseOfferSnapshot, error) { app.mu.Lock() defer app.mu.Unlock() @@ -287,11 +287,11 @@ func (app *Application) OfferSnapshot(_ context.Context, req abci.RequestOfferSn } app.restoreSnapshot = req.Snapshot app.restoreChunks = [][]byte{} - return abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_ACCEPT} + return &abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_ACCEPT}, nil } // ApplySnapshotChunk implements ABCI. -func (app *Application) ApplySnapshotChunk(_ context.Context, req abci.RequestApplySnapshotChunk) abci.ResponseApplySnapshotChunk { +func (app *Application) ApplySnapshotChunk(_ context.Context, req abci.RequestApplySnapshotChunk) (*abci.ResponseApplySnapshotChunk, error) { app.mu.Lock() defer app.mu.Unlock() @@ -311,7 +311,7 @@ func (app *Application) ApplySnapshotChunk(_ context.Context, req abci.RequestAp app.restoreSnapshot = nil app.restoreChunks = nil } - return abci.ResponseApplySnapshotChunk{Result: abci.ResponseApplySnapshotChunk_ACCEPT} + return &abci.ResponseApplySnapshotChunk{Result: abci.ResponseApplySnapshotChunk_ACCEPT}, nil } // PrepareProposal will take the given transactions and attempt to prepare a @@ -324,7 +324,7 @@ func (app *Application) ApplySnapshotChunk(_ context.Context, req abci.RequestAp // If adding a special vote extension-generated transaction would cause the // total number of transaction bytes to exceed `req.MaxTxBytes`, we will not // append our special vote extension transaction. -func (app *Application) PrepareProposal(_ context.Context, req abci.RequestPrepareProposal) abci.ResponsePrepareProposal { +func (app *Application) PrepareProposal(_ context.Context, req abci.RequestPrepareProposal) (*abci.ResponsePrepareProposal, error) { var sum int64 var extCount int for _, vote := range req.LocalLastCommit.Votes { @@ -378,9 +378,9 @@ func (app *Application) PrepareProposal(_ context.Context, req abci.RequestPrepa "extTxLen", len(extTx), ) } - return abci.ResponsePrepareProposal{ + return &abci.ResponsePrepareProposal{ TxRecords: txRecords, - } + }, nil } // None of the transactions are modified by this application. trs := make([]*abci.TxRecord, 0, len(req.Txs)) @@ -395,28 +395,28 @@ func (app *Application) PrepareProposal(_ context.Context, req abci.RequestPrepa Tx: tx, }) } - return abci.ResponsePrepareProposal{TxRecords: trs} + return &abci.ResponsePrepareProposal{TxRecords: trs}, nil } // ProcessProposal implements part of the Application interface. // It accepts any proposal that does not contain a malformed transaction. -func (app *Application) ProcessProposal(_ context.Context, req abci.RequestProcessProposal) abci.ResponseProcessProposal { +func (app *Application) ProcessProposal(_ context.Context, req abci.RequestProcessProposal) (*abci.ResponseProcessProposal, error) { for _, tx := range req.Txs { k, v, err := parseTx(tx) if err != nil { app.logger.Error("malformed transaction in ProcessProposal", "tx", tx, "err", err) - return abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_REJECT} + return &abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_REJECT}, nil } // Additional check for vote extension-related txs if k == voteExtensionKey { _, err := strconv.Atoi(v) if err != nil { app.logger.Error("malformed vote extension transaction", k, v, "err", err) - return abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_REJECT} + return &abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_REJECT}, nil } } } - return abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT} + return &abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT}, nil } // ExtendVote will produce vote extensions in the form of random numbers to @@ -426,7 +426,7 @@ func (app *Application) ProcessProposal(_ context.Context, req abci.RequestProce // a new transaction will be proposed that updates a special value in the // key/value store ("extensionSum") with the sum of all of the numbers collected // from the vote extensions. -func (app *Application) ExtendVote(_ context.Context, req abci.RequestExtendVote) abci.ResponseExtendVote { +func (app *Application) ExtendVote(_ context.Context, req abci.RequestExtendVote) (*abci.ResponseExtendVote, error) { // We ignore any requests for vote extensions that don't match our expected // next height. if req.Height != int64(app.state.Height)+1 { @@ -435,7 +435,7 @@ func (app *Application) ExtendVote(_ context.Context, req abci.RequestExtendVote "expectedHeight", app.state.Height+1, "requestHeight", req.Height, ) - return abci.ResponseExtendVote{} + return &abci.ResponseExtendVote{}, nil } ext := make([]byte, binary.MaxVarintLen64) // We don't care that these values are generated by a weak random number @@ -444,20 +444,20 @@ func (app *Application) ExtendVote(_ context.Context, req abci.RequestExtendVote num := rand.Int63n(voteExtensionMaxVal) extLen := binary.PutVarint(ext, num) app.logger.Info("generated vote extension", "num", num, "ext", fmt.Sprintf("%x", ext[:extLen]), "state.Height", app.state.Height) - return abci.ResponseExtendVote{ + return &abci.ResponseExtendVote{ VoteExtension: ext[:extLen], - } + }, nil } // VerifyVoteExtension simply validates vote extensions from other validators // without doing anything about them. In this case, it just makes sure that the // vote extension is a well-formed integer value. -func (app *Application) VerifyVoteExtension(_ context.Context, req abci.RequestVerifyVoteExtension) abci.ResponseVerifyVoteExtension { +func (app *Application) VerifyVoteExtension(_ context.Context, req abci.RequestVerifyVoteExtension) (*abci.ResponseVerifyVoteExtension, error) { // We allow vote extensions to be optional if len(req.VoteExtension) == 0 { - return abci.ResponseVerifyVoteExtension{ + return &abci.ResponseVerifyVoteExtension{ Status: abci.ResponseVerifyVoteExtension_ACCEPT, - } + }, nil } if req.Height != int64(app.state.Height)+1 { app.logger.Error( @@ -465,22 +465,22 @@ func (app *Application) VerifyVoteExtension(_ context.Context, req abci.RequestV "expectedHeight", app.state.Height, "requestHeight", req.Height, ) - return abci.ResponseVerifyVoteExtension{ + return &abci.ResponseVerifyVoteExtension{ Status: abci.ResponseVerifyVoteExtension_REJECT, - } + }, nil } num, err := parseVoteExtension(req.VoteExtension) if err != nil { app.logger.Error("failed to verify vote extension", "req", req, "err", err) - return abci.ResponseVerifyVoteExtension{ + return &abci.ResponseVerifyVoteExtension{ Status: abci.ResponseVerifyVoteExtension_REJECT, - } + }, nil } app.logger.Info("verified vote extension value", "req", req, "num", num) - return abci.ResponseVerifyVoteExtension{ + return &abci.ResponseVerifyVoteExtension{ Status: abci.ResponseVerifyVoteExtension_ACCEPT, - } + }, nil } func (app *Application) Rollback() error { From 20f848508000601120b811e216c3aec63803bca4 Mon Sep 17 00:00:00 2001 From: "M. J. Fromberger" Date: Fri, 22 Apr 2022 18:02:41 -0700 Subject: [PATCH 08/35] Make encoding of HexBytes values more robust. (#8398) The HexBytes wrapper type handles decoding byte strings from JSON. In the RPC API, hashes are encoded as hex digits rather than the standard base64. Simplify the implementation of this wrapper using the TextMarshaler interface, which the encoding/json package uses for values (like these) that are meant to be wrapped in JSON strings. In addition, allow HexBytes values to be decoded from either hex OR base64 input. This preserves all existing use, but will allow us to remove some reflection special cases in the RPC decoder plumbing. Update tests to correctly tolerate empty/nil. --- libs/bytes/bytes.go | 58 +++++++++++++++------------------------- libs/bytes/bytes_test.go | 2 +- 2 files changed, 22 insertions(+), 38 deletions(-) diff --git a/libs/bytes/bytes.go b/libs/bytes/bytes.go index dd8e39737..a6be32f05 100644 --- a/libs/bytes/bytes.go +++ b/libs/bytes/bytes.go @@ -1,21 +1,16 @@ package bytes import ( - "bytes" + "encoding/base64" "encoding/hex" - "encoding/json" "fmt" "strings" ) -// HexBytes enables HEX-encoding for json/encoding. +// HexBytes is a wrapper around []byte that encodes data as hexadecimal strings +// for use in JSON. type HexBytes []byte -var ( - _ json.Marshaler = HexBytes{} - _ json.Unmarshaler = &HexBytes{} -) - // Marshal needed for protobuf compatibility func (bz HexBytes) Marshal() ([]byte, error) { return bz, nil @@ -27,41 +22,30 @@ func (bz *HexBytes) Unmarshal(data []byte) error { return nil } -// MarshalJSON implements the json.Marshaler interface. The encoding is a JSON -// quoted string of hexadecimal digits. -func (bz HexBytes) MarshalJSON() ([]byte, error) { - size := hex.EncodedLen(len(bz)) + 2 // +2 for quotation marks - buf := make([]byte, size) - hex.Encode(buf[1:], []byte(bz)) - buf[0] = '"' - buf[size-1] = '"' - - // Ensure letter digits are capitalized. - for i := 1; i < size-1; i++ { - if buf[i] >= 'a' && buf[i] <= 'f' { - buf[i] = 'A' + (buf[i] - 'a') - } - } - return buf, nil +// MarshalText encodes a HexBytes value as hexadecimal digits. +// This method is used by json.Marshal. +func (bz HexBytes) MarshalText() ([]byte, error) { + enc := hex.EncodeToString([]byte(bz)) + return []byte(strings.ToUpper(enc)), nil } -// UnmarshalJSON implements the json.Umarshaler interface. -func (bz *HexBytes) UnmarshalJSON(data []byte) error { - if bytes.Equal(data, []byte("null")) { +// UnmarshalText handles decoding of HexBytes from JSON strings. +// This method is used by json.Unmarshal. +// It allows decoding of both hex and base64-encoded byte arrays. +func (bz *HexBytes) UnmarshalText(data []byte) error { + input := string(data) + if input == "" || input == "null" { return nil } - - if len(data) < 2 || data[0] != '"' || data[len(data)-1] != '"' { - return fmt.Errorf("invalid hex string: %s", data) - } - - bz2, err := hex.DecodeString(string(data[1 : len(data)-1])) + dec, err := hex.DecodeString(input) if err != nil { - return err + dec, err = base64.StdEncoding.DecodeString(input) + + if err != nil { + return err + } } - - *bz = bz2 - + *bz = HexBytes(dec) return nil } diff --git a/libs/bytes/bytes_test.go b/libs/bytes/bytes_test.go index ce39935e8..fb1200a04 100644 --- a/libs/bytes/bytes_test.go +++ b/libs/bytes/bytes_test.go @@ -61,7 +61,7 @@ func TestJSONMarshal(t *testing.T) { t.Fatal(err) } assert.Equal(t, ts2.B1, tc.input) - assert.Equal(t, ts2.B2, HexBytes(tc.input)) + assert.Equal(t, string(ts2.B2), string(tc.input)) }) } } From a5ecd418a6791f9cfa5d2ee02149b99d78d4bd4a Mon Sep 17 00:00:00 2001 From: Sam Kleinman Date: Sat, 23 Apr 2022 08:59:18 -0400 Subject: [PATCH 09/35] abci: remove redundant methods in client (#8401) --- abci/client/client.go | 25 ++++--------------------- 1 file changed, 4 insertions(+), 21 deletions(-) diff --git a/abci/client/client.go b/abci/client/client.go index de72a0606..4508dcbc8 100644 --- a/abci/client/client.go +++ b/abci/client/client.go @@ -17,35 +17,18 @@ const ( //go:generate ../../scripts/mockery_generate.sh Client -// Client defines an interface for an ABCI client. -// -// All methods return the appropriate protobuf ResponseXxx struct and -// an error. +// Client defines the interface for an ABCI client. // // NOTE these are client errors, eg. ABCI socket connectivity issues. // Application-related errors are reflected in response via ABCI error codes -// and logs. +// and (potentially) error response. type Client interface { service.Service + types.Application Error() error - Flush(context.Context) error - Echo(ctx context.Context, msg string) (*types.ResponseEcho, error) - Info(context.Context, types.RequestInfo) (*types.ResponseInfo, error) - CheckTx(context.Context, types.RequestCheckTx) (*types.ResponseCheckTx, error) - Query(context.Context, types.RequestQuery) (*types.ResponseQuery, error) - Commit(context.Context) (*types.ResponseCommit, error) - InitChain(context.Context, types.RequestInitChain) (*types.ResponseInitChain, error) - PrepareProposal(context.Context, types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) - ProcessProposal(context.Context, types.RequestProcessProposal) (*types.ResponseProcessProposal, error) - ExtendVote(context.Context, types.RequestExtendVote) (*types.ResponseExtendVote, error) - VerifyVoteExtension(context.Context, types.RequestVerifyVoteExtension) (*types.ResponseVerifyVoteExtension, error) - FinalizeBlock(context.Context, types.RequestFinalizeBlock) (*types.ResponseFinalizeBlock, error) - ListSnapshots(context.Context, types.RequestListSnapshots) (*types.ResponseListSnapshots, error) - OfferSnapshot(context.Context, types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) - LoadSnapshotChunk(context.Context, types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) - ApplySnapshotChunk(context.Context, types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) + Echo(context.Context, string) (*types.ResponseEcho, error) } //---------------------------------------- From 001449d536309804722f18821c98f92c4020db36 Mon Sep 17 00:00:00 2001 From: "M. J. Fromberger" Date: Sat, 23 Apr 2022 09:57:42 -0700 Subject: [PATCH 10/35] Remove obsolete build tagged patch for net.Pipe. (#8399) The p2p/conn library was using a build patch to work around an old issue with the net.Conn type that has not existed since Go 1.10. Remove the workaround and update usage to use the standard net.Pipe directly. --- internal/p2p/conn/conn_go110.go | 16 -------------- internal/p2p/conn/conn_notgo110.go | 33 ---------------------------- internal/p2p/conn/connection_test.go | 12 +++++----- 3 files changed, 6 insertions(+), 55 deletions(-) delete mode 100644 internal/p2p/conn/conn_go110.go delete mode 100644 internal/p2p/conn/conn_notgo110.go diff --git a/internal/p2p/conn/conn_go110.go b/internal/p2p/conn/conn_go110.go deleted file mode 100644 index 459c3169b..000000000 --- a/internal/p2p/conn/conn_go110.go +++ /dev/null @@ -1,16 +0,0 @@ -//go:build go1.10 -// +build go1.10 - -package conn - -// Go1.10 has a proper net.Conn implementation that -// has the SetDeadline method implemented as per -// https://github.com/golang/go/commit/e2dd8ca946be884bb877e074a21727f1a685a706 -// lest we run into problems like -// https://github.com/tendermint/tendermint/issues/851 - -import "net" - -func NetPipe() (net.Conn, net.Conn) { - return net.Pipe() -} diff --git a/internal/p2p/conn/conn_notgo110.go b/internal/p2p/conn/conn_notgo110.go deleted file mode 100644 index 21dffad2c..000000000 --- a/internal/p2p/conn/conn_notgo110.go +++ /dev/null @@ -1,33 +0,0 @@ -//go:build !go1.10 -// +build !go1.10 - -package conn - -import ( - "net" - "time" -) - -// Only Go1.10 has a proper net.Conn implementation that -// has the SetDeadline method implemented as per -// https://github.com/golang/go/commit/e2dd8ca946be884bb877e074a21727f1a685a706 -// lest we run into problems like -// https://github.com/tendermint/tendermint/issues/851 -// so for go versions < Go1.10 use our custom net.Conn creator -// that doesn't return an `Unimplemented error` for net.Conn. -// Before https://github.com/tendermint/tendermint/commit/49faa79bdce5663894b3febbf4955fb1d172df04 -// we hadn't cared about errors from SetDeadline so swallow them up anyways. -type pipe struct { - net.Conn -} - -func (p *pipe) SetDeadline(t time.Time) error { - return nil -} - -func NetPipe() (net.Conn, net.Conn) { - p1, p2 := net.Pipe() - return &pipe{p1}, &pipe{p2} -} - -var _ net.Conn = (*pipe)(nil) diff --git a/internal/p2p/conn/connection_test.go b/internal/p2p/conn/connection_test.go index 49c53f6fb..5a604cd23 100644 --- a/internal/p2p/conn/connection_test.go +++ b/internal/p2p/conn/connection_test.go @@ -48,7 +48,7 @@ func createMConnectionWithCallbacks( } func TestMConnectionSendFlushStop(t *testing.T) { - server, client := NetPipe() + server, client := net.Pipe() t.Cleanup(closeAll(t, client, server)) ctx, cancel := context.WithCancel(context.Background()) @@ -85,7 +85,7 @@ func TestMConnectionSendFlushStop(t *testing.T) { } func TestMConnectionSend(t *testing.T) { - server, client := NetPipe() + server, client := net.Pipe() t.Cleanup(closeAll(t, client, server)) ctx, cancel := context.WithCancel(context.Background()) @@ -116,7 +116,7 @@ func TestMConnectionSend(t *testing.T) { } func TestMConnectionReceive(t *testing.T) { - server, client := NetPipe() + server, client := net.Pipe() t.Cleanup(closeAll(t, client, server)) receivedCh := make(chan []byte) @@ -378,7 +378,7 @@ func TestMConnectionPingPongs(t *testing.T) { } func TestMConnectionStopsAndReturnsError(t *testing.T) { - server, client := NetPipe() + server, client := net.Pipe() t.Cleanup(closeAll(t, client, server)) receivedCh := make(chan []byte) @@ -423,7 +423,7 @@ func newClientAndServerConnsForReadErrors( t *testing.T, chOnErr chan struct{}, ) (*MConnection, *MConnection) { - server, client := NetPipe() + server, client := net.Pipe() onReceive := func(context.Context, ChannelID, []byte) {} onError := func(context.Context, interface{}) {} @@ -558,7 +558,7 @@ func TestMConnectionReadErrorUnknownMsgType(t *testing.T) { } func TestMConnectionTrySend(t *testing.T) { - server, client := NetPipe() + server, client := net.Pipe() t.Cleanup(closeAll(t, client, server)) ctx, cancel := context.WithCancel(context.Background()) defer cancel() From 674908b1309f5926be94c4a7c8e30651fdc8e1f0 Mon Sep 17 00:00:00 2001 From: Sam Kleinman Date: Sun, 24 Apr 2022 12:01:39 -0400 Subject: [PATCH 11/35] abci: remove unneccessary implementations (#8403) --- abci/client/local_client.go | 64 ++----------------------------------- 1 file changed, 2 insertions(+), 62 deletions(-) diff --git a/abci/client/local_client.go b/abci/client/local_client.go index 418930fa8..1002c64e8 100644 --- a/abci/client/local_client.go +++ b/abci/client/local_client.go @@ -34,67 +34,7 @@ func NewLocalClient(logger log.Logger, app types.Application) Client { func (*localClient) OnStart(context.Context) error { return nil } func (*localClient) OnStop() {} func (*localClient) Error() error { return nil } - -//------------------------------------------------------- - -func (*localClient) Flush(context.Context) error { return nil } - -func (app *localClient) Echo(_ context.Context, msg string) (*types.ResponseEcho, error) { +func (*localClient) Flush(context.Context) error { return nil } +func (*localClient) Echo(_ context.Context, msg string) (*types.ResponseEcho, error) { return &types.ResponseEcho{Message: msg}, nil } - -func (app *localClient) Info(ctx context.Context, req types.RequestInfo) (*types.ResponseInfo, error) { - return app.Application.Info(ctx, req) -} - -func (app *localClient) CheckTx(ctx context.Context, req types.RequestCheckTx) (*types.ResponseCheckTx, error) { - return app.Application.CheckTx(ctx, req) -} - -func (app *localClient) Query(ctx context.Context, req types.RequestQuery) (*types.ResponseQuery, error) { - return app.Application.Query(ctx, req) -} - -func (app *localClient) Commit(ctx context.Context) (*types.ResponseCommit, error) { - return app.Application.Commit(ctx) -} - -func (app *localClient) InitChain(ctx context.Context, req types.RequestInitChain) (*types.ResponseInitChain, error) { - return app.Application.InitChain(ctx, req) -} - -func (app *localClient) ListSnapshots(ctx context.Context, req types.RequestListSnapshots) (*types.ResponseListSnapshots, error) { - return app.Application.ListSnapshots(ctx, req) -} - -func (app *localClient) OfferSnapshot(ctx context.Context, req types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { - return app.Application.OfferSnapshot(ctx, req) -} - -func (app *localClient) LoadSnapshotChunk(ctx context.Context, req types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) { - return app.Application.LoadSnapshotChunk(ctx, req) -} - -func (app *localClient) ApplySnapshotChunk(ctx context.Context, req types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { - return app.Application.ApplySnapshotChunk(ctx, req) -} - -func (app *localClient) PrepareProposal(ctx context.Context, req types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) { - return app.Application.PrepareProposal(ctx, req) -} - -func (app *localClient) ProcessProposal(ctx context.Context, req types.RequestProcessProposal) (*types.ResponseProcessProposal, error) { - return app.Application.ProcessProposal(ctx, req) -} - -func (app *localClient) ExtendVote(ctx context.Context, req types.RequestExtendVote) (*types.ResponseExtendVote, error) { - return app.Application.ExtendVote(ctx, req) -} - -func (app *localClient) VerifyVoteExtension(ctx context.Context, req types.RequestVerifyVoteExtension) (*types.ResponseVerifyVoteExtension, error) { - return app.Application.VerifyVoteExtension(ctx, req) -} - -func (app *localClient) FinalizeBlock(ctx context.Context, req types.RequestFinalizeBlock) (*types.ResponseFinalizeBlock, error) { - return app.Application.FinalizeBlock(ctx, req) -} From 2e5d53ea9a1022c651c8ed032390ef18e49243c6 Mon Sep 17 00:00:00 2001 From: Sam Kleinman Date: Sun, 24 Apr 2022 14:37:07 -0400 Subject: [PATCH 12/35] abci: interface should take pointers to arguments (#8404) --- abci/client/grpc_client.go | 26 +++---- abci/client/mocks/client.go | 88 +++++++++++----------- abci/client/socket_client.go | 26 +++---- abci/cmd/abci-cli/abci-cli.go | 8 +- abci/example/example_test.go | 2 +- abci/example/kvstore/helpers.go | 2 +- abci/example/kvstore/kvstore.go | 14 ++-- abci/example/kvstore/kvstore_test.go | 28 +++---- abci/example/kvstore/persistent_kvstore.go | 4 +- abci/server/grpc_server.go | 58 +------------- abci/server/socket_server.go | 26 +++---- abci/tests/server/client.go | 6 +- abci/types/application.go | 52 ++++++------- abci/types/messages.go | 52 ++++++------- abci/types/mocks/application.go | 78 +++++++++---------- internal/consensus/byzantine_test.go | 2 +- internal/consensus/common_test.go | 4 +- internal/consensus/mempool_test.go | 12 +-- internal/consensus/reactor_test.go | 2 +- internal/consensus/replay.go | 7 +- internal/consensus/replay_stubs.go | 2 +- internal/consensus/replay_test.go | 8 +- internal/consensus/state_test.go | 16 ++-- internal/mempool/mempool.go | 4 +- internal/mempool/mempool_test.go | 2 +- internal/proxy/client.go | 28 +++---- internal/proxy/client_test.go | 6 +- internal/rpc/core/abci.go | 4 +- internal/rpc/core/mempool.go | 2 +- internal/state/execution.go | 24 +++--- internal/state/execution_test.go | 2 +- internal/state/helpers_test.go | 10 +-- internal/statesync/reactor.go | 4 +- internal/statesync/reactor_test.go | 10 +-- internal/statesync/syncer.go | 6 +- internal/statesync/syncer_test.go | 54 ++++++------- node/node.go | 4 +- rpc/client/mock/abci.go | 16 ++-- test/e2e/app/app.go | 26 +++---- 39 files changed, 333 insertions(+), 392 deletions(-) diff --git a/abci/client/grpc_client.go b/abci/client/grpc_client.go index 5890d5f05..1e163056d 100644 --- a/abci/client/grpc_client.go +++ b/abci/client/grpc_client.go @@ -128,15 +128,15 @@ func (cli *grpcClient) Echo(ctx context.Context, msg string) (*types.ResponseEch return cli.client.Echo(ctx, types.ToRequestEcho(msg).GetEcho(), grpc.WaitForReady(true)) } -func (cli *grpcClient) Info(ctx context.Context, params types.RequestInfo) (*types.ResponseInfo, error) { +func (cli *grpcClient) Info(ctx context.Context, params *types.RequestInfo) (*types.ResponseInfo, error) { return cli.client.Info(ctx, types.ToRequestInfo(params).GetInfo(), grpc.WaitForReady(true)) } -func (cli *grpcClient) CheckTx(ctx context.Context, params types.RequestCheckTx) (*types.ResponseCheckTx, error) { +func (cli *grpcClient) CheckTx(ctx context.Context, params *types.RequestCheckTx) (*types.ResponseCheckTx, error) { return cli.client.CheckTx(ctx, types.ToRequestCheckTx(params).GetCheckTx(), grpc.WaitForReady(true)) } -func (cli *grpcClient) Query(ctx context.Context, params types.RequestQuery) (*types.ResponseQuery, error) { +func (cli *grpcClient) Query(ctx context.Context, params *types.RequestQuery) (*types.ResponseQuery, error) { return cli.client.Query(ctx, types.ToRequestQuery(params).GetQuery(), grpc.WaitForReady(true)) } @@ -144,42 +144,42 @@ func (cli *grpcClient) Commit(ctx context.Context) (*types.ResponseCommit, error return cli.client.Commit(ctx, types.ToRequestCommit().GetCommit(), grpc.WaitForReady(true)) } -func (cli *grpcClient) InitChain(ctx context.Context, params types.RequestInitChain) (*types.ResponseInitChain, error) { +func (cli *grpcClient) InitChain(ctx context.Context, params *types.RequestInitChain) (*types.ResponseInitChain, error) { return cli.client.InitChain(ctx, types.ToRequestInitChain(params).GetInitChain(), grpc.WaitForReady(true)) } -func (cli *grpcClient) ListSnapshots(ctx context.Context, params types.RequestListSnapshots) (*types.ResponseListSnapshots, error) { +func (cli *grpcClient) ListSnapshots(ctx context.Context, params *types.RequestListSnapshots) (*types.ResponseListSnapshots, error) { return cli.client.ListSnapshots(ctx, types.ToRequestListSnapshots(params).GetListSnapshots(), grpc.WaitForReady(true)) } -func (cli *grpcClient) OfferSnapshot(ctx context.Context, params types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { +func (cli *grpcClient) OfferSnapshot(ctx context.Context, params *types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { return cli.client.OfferSnapshot(ctx, types.ToRequestOfferSnapshot(params).GetOfferSnapshot(), grpc.WaitForReady(true)) } -func (cli *grpcClient) LoadSnapshotChunk(ctx context.Context, params types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) { +func (cli *grpcClient) LoadSnapshotChunk(ctx context.Context, params *types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) { return cli.client.LoadSnapshotChunk(ctx, types.ToRequestLoadSnapshotChunk(params).GetLoadSnapshotChunk(), grpc.WaitForReady(true)) } -func (cli *grpcClient) ApplySnapshotChunk(ctx context.Context, params types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { +func (cli *grpcClient) ApplySnapshotChunk(ctx context.Context, params *types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { return cli.client.ApplySnapshotChunk(ctx, types.ToRequestApplySnapshotChunk(params).GetApplySnapshotChunk(), grpc.WaitForReady(true)) } -func (cli *grpcClient) PrepareProposal(ctx context.Context, params types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) { +func (cli *grpcClient) PrepareProposal(ctx context.Context, params *types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) { return cli.client.PrepareProposal(ctx, types.ToRequestPrepareProposal(params).GetPrepareProposal(), grpc.WaitForReady(true)) } -func (cli *grpcClient) ProcessProposal(ctx context.Context, params types.RequestProcessProposal) (*types.ResponseProcessProposal, error) { +func (cli *grpcClient) ProcessProposal(ctx context.Context, params *types.RequestProcessProposal) (*types.ResponseProcessProposal, error) { return cli.client.ProcessProposal(ctx, types.ToRequestProcessProposal(params).GetProcessProposal(), grpc.WaitForReady(true)) } -func (cli *grpcClient) ExtendVote(ctx context.Context, params types.RequestExtendVote) (*types.ResponseExtendVote, error) { +func (cli *grpcClient) ExtendVote(ctx context.Context, params *types.RequestExtendVote) (*types.ResponseExtendVote, error) { return cli.client.ExtendVote(ctx, types.ToRequestExtendVote(params).GetExtendVote(), grpc.WaitForReady(true)) } -func (cli *grpcClient) VerifyVoteExtension(ctx context.Context, params types.RequestVerifyVoteExtension) (*types.ResponseVerifyVoteExtension, error) { +func (cli *grpcClient) VerifyVoteExtension(ctx context.Context, params *types.RequestVerifyVoteExtension) (*types.ResponseVerifyVoteExtension, error) { return cli.client.VerifyVoteExtension(ctx, types.ToRequestVerifyVoteExtension(params).GetVerifyVoteExtension(), grpc.WaitForReady(true)) } -func (cli *grpcClient) FinalizeBlock(ctx context.Context, params types.RequestFinalizeBlock) (*types.ResponseFinalizeBlock, error) { +func (cli *grpcClient) FinalizeBlock(ctx context.Context, params *types.RequestFinalizeBlock) (*types.ResponseFinalizeBlock, error) { return cli.client.FinalizeBlock(ctx, types.ToRequestFinalizeBlock(params).GetFinalizeBlock(), grpc.WaitForReady(true)) } diff --git a/abci/client/mocks/client.go b/abci/client/mocks/client.go index 5b751f50d..e5f2898f3 100644 --- a/abci/client/mocks/client.go +++ b/abci/client/mocks/client.go @@ -17,11 +17,11 @@ type Client struct { } // ApplySnapshotChunk provides a mock function with given fields: _a0, _a1 -func (_m *Client) ApplySnapshotChunk(_a0 context.Context, _a1 types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { +func (_m *Client) ApplySnapshotChunk(_a0 context.Context, _a1 *types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { ret := _m.Called(_a0, _a1) var r0 *types.ResponseApplySnapshotChunk - if rf, ok := ret.Get(0).(func(context.Context, types.RequestApplySnapshotChunk) *types.ResponseApplySnapshotChunk); ok { + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestApplySnapshotChunk) *types.ResponseApplySnapshotChunk); ok { r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { @@ -30,7 +30,7 @@ func (_m *Client) ApplySnapshotChunk(_a0 context.Context, _a1 types.RequestApply } var r1 error - if rf, ok := ret.Get(1).(func(context.Context, types.RequestApplySnapshotChunk) error); ok { + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestApplySnapshotChunk) error); ok { r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) @@ -40,11 +40,11 @@ func (_m *Client) ApplySnapshotChunk(_a0 context.Context, _a1 types.RequestApply } // CheckTx provides a mock function with given fields: _a0, _a1 -func (_m *Client) CheckTx(_a0 context.Context, _a1 types.RequestCheckTx) (*types.ResponseCheckTx, error) { +func (_m *Client) CheckTx(_a0 context.Context, _a1 *types.RequestCheckTx) (*types.ResponseCheckTx, error) { ret := _m.Called(_a0, _a1) var r0 *types.ResponseCheckTx - if rf, ok := ret.Get(0).(func(context.Context, types.RequestCheckTx) *types.ResponseCheckTx); ok { + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestCheckTx) *types.ResponseCheckTx); ok { r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { @@ -53,7 +53,7 @@ func (_m *Client) CheckTx(_a0 context.Context, _a1 types.RequestCheckTx) (*types } var r1 error - if rf, ok := ret.Get(1).(func(context.Context, types.RequestCheckTx) error); ok { + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestCheckTx) error); ok { r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) @@ -85,13 +85,13 @@ func (_m *Client) Commit(_a0 context.Context) (*types.ResponseCommit, error) { return r0, r1 } -// Echo provides a mock function with given fields: ctx, msg -func (_m *Client) Echo(ctx context.Context, msg string) (*types.ResponseEcho, error) { - ret := _m.Called(ctx, msg) +// Echo provides a mock function with given fields: _a0, _a1 +func (_m *Client) Echo(_a0 context.Context, _a1 string) (*types.ResponseEcho, error) { + ret := _m.Called(_a0, _a1) var r0 *types.ResponseEcho if rf, ok := ret.Get(0).(func(context.Context, string) *types.ResponseEcho); ok { - r0 = rf(ctx, msg) + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*types.ResponseEcho) @@ -100,7 +100,7 @@ func (_m *Client) Echo(ctx context.Context, msg string) (*types.ResponseEcho, er var r1 error if rf, ok := ret.Get(1).(func(context.Context, string) error); ok { - r1 = rf(ctx, msg) + r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) } @@ -123,11 +123,11 @@ func (_m *Client) Error() error { } // ExtendVote provides a mock function with given fields: _a0, _a1 -func (_m *Client) ExtendVote(_a0 context.Context, _a1 types.RequestExtendVote) (*types.ResponseExtendVote, error) { +func (_m *Client) ExtendVote(_a0 context.Context, _a1 *types.RequestExtendVote) (*types.ResponseExtendVote, error) { ret := _m.Called(_a0, _a1) var r0 *types.ResponseExtendVote - if rf, ok := ret.Get(0).(func(context.Context, types.RequestExtendVote) *types.ResponseExtendVote); ok { + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestExtendVote) *types.ResponseExtendVote); ok { r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { @@ -136,7 +136,7 @@ func (_m *Client) ExtendVote(_a0 context.Context, _a1 types.RequestExtendVote) ( } var r1 error - if rf, ok := ret.Get(1).(func(context.Context, types.RequestExtendVote) error); ok { + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestExtendVote) error); ok { r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) @@ -146,11 +146,11 @@ func (_m *Client) ExtendVote(_a0 context.Context, _a1 types.RequestExtendVote) ( } // FinalizeBlock provides a mock function with given fields: _a0, _a1 -func (_m *Client) FinalizeBlock(_a0 context.Context, _a1 types.RequestFinalizeBlock) (*types.ResponseFinalizeBlock, error) { +func (_m *Client) FinalizeBlock(_a0 context.Context, _a1 *types.RequestFinalizeBlock) (*types.ResponseFinalizeBlock, error) { ret := _m.Called(_a0, _a1) var r0 *types.ResponseFinalizeBlock - if rf, ok := ret.Get(0).(func(context.Context, types.RequestFinalizeBlock) *types.ResponseFinalizeBlock); ok { + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestFinalizeBlock) *types.ResponseFinalizeBlock); ok { r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { @@ -159,7 +159,7 @@ func (_m *Client) FinalizeBlock(_a0 context.Context, _a1 types.RequestFinalizeBl } var r1 error - if rf, ok := ret.Get(1).(func(context.Context, types.RequestFinalizeBlock) error); ok { + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestFinalizeBlock) error); ok { r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) @@ -183,11 +183,11 @@ func (_m *Client) Flush(_a0 context.Context) error { } // Info provides a mock function with given fields: _a0, _a1 -func (_m *Client) Info(_a0 context.Context, _a1 types.RequestInfo) (*types.ResponseInfo, error) { +func (_m *Client) Info(_a0 context.Context, _a1 *types.RequestInfo) (*types.ResponseInfo, error) { ret := _m.Called(_a0, _a1) var r0 *types.ResponseInfo - if rf, ok := ret.Get(0).(func(context.Context, types.RequestInfo) *types.ResponseInfo); ok { + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestInfo) *types.ResponseInfo); ok { r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { @@ -196,7 +196,7 @@ func (_m *Client) Info(_a0 context.Context, _a1 types.RequestInfo) (*types.Respo } var r1 error - if rf, ok := ret.Get(1).(func(context.Context, types.RequestInfo) error); ok { + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestInfo) error); ok { r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) @@ -206,11 +206,11 @@ func (_m *Client) Info(_a0 context.Context, _a1 types.RequestInfo) (*types.Respo } // InitChain provides a mock function with given fields: _a0, _a1 -func (_m *Client) InitChain(_a0 context.Context, _a1 types.RequestInitChain) (*types.ResponseInitChain, error) { +func (_m *Client) InitChain(_a0 context.Context, _a1 *types.RequestInitChain) (*types.ResponseInitChain, error) { ret := _m.Called(_a0, _a1) var r0 *types.ResponseInitChain - if rf, ok := ret.Get(0).(func(context.Context, types.RequestInitChain) *types.ResponseInitChain); ok { + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestInitChain) *types.ResponseInitChain); ok { r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { @@ -219,7 +219,7 @@ func (_m *Client) InitChain(_a0 context.Context, _a1 types.RequestInitChain) (*t } var r1 error - if rf, ok := ret.Get(1).(func(context.Context, types.RequestInitChain) error); ok { + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestInitChain) error); ok { r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) @@ -243,11 +243,11 @@ func (_m *Client) IsRunning() bool { } // ListSnapshots provides a mock function with given fields: _a0, _a1 -func (_m *Client) ListSnapshots(_a0 context.Context, _a1 types.RequestListSnapshots) (*types.ResponseListSnapshots, error) { +func (_m *Client) ListSnapshots(_a0 context.Context, _a1 *types.RequestListSnapshots) (*types.ResponseListSnapshots, error) { ret := _m.Called(_a0, _a1) var r0 *types.ResponseListSnapshots - if rf, ok := ret.Get(0).(func(context.Context, types.RequestListSnapshots) *types.ResponseListSnapshots); ok { + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestListSnapshots) *types.ResponseListSnapshots); ok { r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { @@ -256,7 +256,7 @@ func (_m *Client) ListSnapshots(_a0 context.Context, _a1 types.RequestListSnapsh } var r1 error - if rf, ok := ret.Get(1).(func(context.Context, types.RequestListSnapshots) error); ok { + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestListSnapshots) error); ok { r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) @@ -266,11 +266,11 @@ func (_m *Client) ListSnapshots(_a0 context.Context, _a1 types.RequestListSnapsh } // LoadSnapshotChunk provides a mock function with given fields: _a0, _a1 -func (_m *Client) LoadSnapshotChunk(_a0 context.Context, _a1 types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) { +func (_m *Client) LoadSnapshotChunk(_a0 context.Context, _a1 *types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) { ret := _m.Called(_a0, _a1) var r0 *types.ResponseLoadSnapshotChunk - if rf, ok := ret.Get(0).(func(context.Context, types.RequestLoadSnapshotChunk) *types.ResponseLoadSnapshotChunk); ok { + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestLoadSnapshotChunk) *types.ResponseLoadSnapshotChunk); ok { r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { @@ -279,7 +279,7 @@ func (_m *Client) LoadSnapshotChunk(_a0 context.Context, _a1 types.RequestLoadSn } var r1 error - if rf, ok := ret.Get(1).(func(context.Context, types.RequestLoadSnapshotChunk) error); ok { + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestLoadSnapshotChunk) error); ok { r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) @@ -289,11 +289,11 @@ func (_m *Client) LoadSnapshotChunk(_a0 context.Context, _a1 types.RequestLoadSn } // OfferSnapshot provides a mock function with given fields: _a0, _a1 -func (_m *Client) OfferSnapshot(_a0 context.Context, _a1 types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { +func (_m *Client) OfferSnapshot(_a0 context.Context, _a1 *types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { ret := _m.Called(_a0, _a1) var r0 *types.ResponseOfferSnapshot - if rf, ok := ret.Get(0).(func(context.Context, types.RequestOfferSnapshot) *types.ResponseOfferSnapshot); ok { + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestOfferSnapshot) *types.ResponseOfferSnapshot); ok { r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { @@ -302,7 +302,7 @@ func (_m *Client) OfferSnapshot(_a0 context.Context, _a1 types.RequestOfferSnaps } var r1 error - if rf, ok := ret.Get(1).(func(context.Context, types.RequestOfferSnapshot) error); ok { + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestOfferSnapshot) error); ok { r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) @@ -312,11 +312,11 @@ func (_m *Client) OfferSnapshot(_a0 context.Context, _a1 types.RequestOfferSnaps } // PrepareProposal provides a mock function with given fields: _a0, _a1 -func (_m *Client) PrepareProposal(_a0 context.Context, _a1 types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) { +func (_m *Client) PrepareProposal(_a0 context.Context, _a1 *types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) { ret := _m.Called(_a0, _a1) var r0 *types.ResponsePrepareProposal - if rf, ok := ret.Get(0).(func(context.Context, types.RequestPrepareProposal) *types.ResponsePrepareProposal); ok { + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestPrepareProposal) *types.ResponsePrepareProposal); ok { r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { @@ -325,7 +325,7 @@ func (_m *Client) PrepareProposal(_a0 context.Context, _a1 types.RequestPrepareP } var r1 error - if rf, ok := ret.Get(1).(func(context.Context, types.RequestPrepareProposal) error); ok { + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestPrepareProposal) error); ok { r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) @@ -335,11 +335,11 @@ func (_m *Client) PrepareProposal(_a0 context.Context, _a1 types.RequestPrepareP } // ProcessProposal provides a mock function with given fields: _a0, _a1 -func (_m *Client) ProcessProposal(_a0 context.Context, _a1 types.RequestProcessProposal) (*types.ResponseProcessProposal, error) { +func (_m *Client) ProcessProposal(_a0 context.Context, _a1 *types.RequestProcessProposal) (*types.ResponseProcessProposal, error) { ret := _m.Called(_a0, _a1) var r0 *types.ResponseProcessProposal - if rf, ok := ret.Get(0).(func(context.Context, types.RequestProcessProposal) *types.ResponseProcessProposal); ok { + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestProcessProposal) *types.ResponseProcessProposal); ok { r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { @@ -348,7 +348,7 @@ func (_m *Client) ProcessProposal(_a0 context.Context, _a1 types.RequestProcessP } var r1 error - if rf, ok := ret.Get(1).(func(context.Context, types.RequestProcessProposal) error); ok { + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestProcessProposal) error); ok { r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) @@ -358,11 +358,11 @@ func (_m *Client) ProcessProposal(_a0 context.Context, _a1 types.RequestProcessP } // Query provides a mock function with given fields: _a0, _a1 -func (_m *Client) Query(_a0 context.Context, _a1 types.RequestQuery) (*types.ResponseQuery, error) { +func (_m *Client) Query(_a0 context.Context, _a1 *types.RequestQuery) (*types.ResponseQuery, error) { ret := _m.Called(_a0, _a1) var r0 *types.ResponseQuery - if rf, ok := ret.Get(0).(func(context.Context, types.RequestQuery) *types.ResponseQuery); ok { + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestQuery) *types.ResponseQuery); ok { r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { @@ -371,7 +371,7 @@ func (_m *Client) Query(_a0 context.Context, _a1 types.RequestQuery) (*types.Res } var r1 error - if rf, ok := ret.Get(1).(func(context.Context, types.RequestQuery) error); ok { + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestQuery) error); ok { r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) @@ -395,11 +395,11 @@ func (_m *Client) Start(_a0 context.Context) error { } // VerifyVoteExtension provides a mock function with given fields: _a0, _a1 -func (_m *Client) VerifyVoteExtension(_a0 context.Context, _a1 types.RequestVerifyVoteExtension) (*types.ResponseVerifyVoteExtension, error) { +func (_m *Client) VerifyVoteExtension(_a0 context.Context, _a1 *types.RequestVerifyVoteExtension) (*types.ResponseVerifyVoteExtension, error) { ret := _m.Called(_a0, _a1) var r0 *types.ResponseVerifyVoteExtension - if rf, ok := ret.Get(0).(func(context.Context, types.RequestVerifyVoteExtension) *types.ResponseVerifyVoteExtension); ok { + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestVerifyVoteExtension) *types.ResponseVerifyVoteExtension); ok { r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { @@ -408,7 +408,7 @@ func (_m *Client) VerifyVoteExtension(_a0 context.Context, _a1 types.RequestVeri } var r1 error - if rf, ok := ret.Get(1).(func(context.Context, types.RequestVerifyVoteExtension) error); ok { + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestVerifyVoteExtension) error); ok { r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) diff --git a/abci/client/socket_client.go b/abci/client/socket_client.go index b06fb6718..aa4fdcbe9 100644 --- a/abci/client/socket_client.go +++ b/abci/client/socket_client.go @@ -250,7 +250,7 @@ func (cli *socketClient) Echo(ctx context.Context, msg string) (*types.ResponseE return res.GetEcho(), nil } -func (cli *socketClient) Info(ctx context.Context, req types.RequestInfo) (*types.ResponseInfo, error) { +func (cli *socketClient) Info(ctx context.Context, req *types.RequestInfo) (*types.ResponseInfo, error) { res, err := cli.doRequest(ctx, types.ToRequestInfo(req)) if err != nil { return nil, err @@ -258,7 +258,7 @@ func (cli *socketClient) Info(ctx context.Context, req types.RequestInfo) (*type return res.GetInfo(), nil } -func (cli *socketClient) CheckTx(ctx context.Context, req types.RequestCheckTx) (*types.ResponseCheckTx, error) { +func (cli *socketClient) CheckTx(ctx context.Context, req *types.RequestCheckTx) (*types.ResponseCheckTx, error) { res, err := cli.doRequest(ctx, types.ToRequestCheckTx(req)) if err != nil { return nil, err @@ -266,7 +266,7 @@ func (cli *socketClient) CheckTx(ctx context.Context, req types.RequestCheckTx) return res.GetCheckTx(), nil } -func (cli *socketClient) Query(ctx context.Context, req types.RequestQuery) (*types.ResponseQuery, error) { +func (cli *socketClient) Query(ctx context.Context, req *types.RequestQuery) (*types.ResponseQuery, error) { res, err := cli.doRequest(ctx, types.ToRequestQuery(req)) if err != nil { return nil, err @@ -282,7 +282,7 @@ func (cli *socketClient) Commit(ctx context.Context) (*types.ResponseCommit, err return res.GetCommit(), nil } -func (cli *socketClient) InitChain(ctx context.Context, req types.RequestInitChain) (*types.ResponseInitChain, error) { +func (cli *socketClient) InitChain(ctx context.Context, req *types.RequestInitChain) (*types.ResponseInitChain, error) { res, err := cli.doRequest(ctx, types.ToRequestInitChain(req)) if err != nil { return nil, err @@ -290,7 +290,7 @@ func (cli *socketClient) InitChain(ctx context.Context, req types.RequestInitCha return res.GetInitChain(), nil } -func (cli *socketClient) ListSnapshots(ctx context.Context, req types.RequestListSnapshots) (*types.ResponseListSnapshots, error) { +func (cli *socketClient) ListSnapshots(ctx context.Context, req *types.RequestListSnapshots) (*types.ResponseListSnapshots, error) { res, err := cli.doRequest(ctx, types.ToRequestListSnapshots(req)) if err != nil { return nil, err @@ -298,7 +298,7 @@ func (cli *socketClient) ListSnapshots(ctx context.Context, req types.RequestLis return res.GetListSnapshots(), nil } -func (cli *socketClient) OfferSnapshot(ctx context.Context, req types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { +func (cli *socketClient) OfferSnapshot(ctx context.Context, req *types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { res, err := cli.doRequest(ctx, types.ToRequestOfferSnapshot(req)) if err != nil { return nil, err @@ -306,7 +306,7 @@ func (cli *socketClient) OfferSnapshot(ctx context.Context, req types.RequestOff return res.GetOfferSnapshot(), nil } -func (cli *socketClient) LoadSnapshotChunk(ctx context.Context, req types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) { +func (cli *socketClient) LoadSnapshotChunk(ctx context.Context, req *types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) { res, err := cli.doRequest(ctx, types.ToRequestLoadSnapshotChunk(req)) if err != nil { return nil, err @@ -314,7 +314,7 @@ func (cli *socketClient) LoadSnapshotChunk(ctx context.Context, req types.Reques return res.GetLoadSnapshotChunk(), nil } -func (cli *socketClient) ApplySnapshotChunk(ctx context.Context, req types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { +func (cli *socketClient) ApplySnapshotChunk(ctx context.Context, req *types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { res, err := cli.doRequest(ctx, types.ToRequestApplySnapshotChunk(req)) if err != nil { return nil, err @@ -322,7 +322,7 @@ func (cli *socketClient) ApplySnapshotChunk(ctx context.Context, req types.Reque return res.GetApplySnapshotChunk(), nil } -func (cli *socketClient) PrepareProposal(ctx context.Context, req types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) { +func (cli *socketClient) PrepareProposal(ctx context.Context, req *types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) { res, err := cli.doRequest(ctx, types.ToRequestPrepareProposal(req)) if err != nil { return nil, err @@ -330,7 +330,7 @@ func (cli *socketClient) PrepareProposal(ctx context.Context, req types.RequestP return res.GetPrepareProposal(), nil } -func (cli *socketClient) ProcessProposal(ctx context.Context, req types.RequestProcessProposal) (*types.ResponseProcessProposal, error) { +func (cli *socketClient) ProcessProposal(ctx context.Context, req *types.RequestProcessProposal) (*types.ResponseProcessProposal, error) { res, err := cli.doRequest(ctx, types.ToRequestProcessProposal(req)) if err != nil { return nil, err @@ -338,7 +338,7 @@ func (cli *socketClient) ProcessProposal(ctx context.Context, req types.RequestP return res.GetProcessProposal(), nil } -func (cli *socketClient) ExtendVote(ctx context.Context, req types.RequestExtendVote) (*types.ResponseExtendVote, error) { +func (cli *socketClient) ExtendVote(ctx context.Context, req *types.RequestExtendVote) (*types.ResponseExtendVote, error) { res, err := cli.doRequest(ctx, types.ToRequestExtendVote(req)) if err != nil { return nil, err @@ -346,7 +346,7 @@ func (cli *socketClient) ExtendVote(ctx context.Context, req types.RequestExtend return res.GetExtendVote(), nil } -func (cli *socketClient) VerifyVoteExtension(ctx context.Context, req types.RequestVerifyVoteExtension) (*types.ResponseVerifyVoteExtension, error) { +func (cli *socketClient) VerifyVoteExtension(ctx context.Context, req *types.RequestVerifyVoteExtension) (*types.ResponseVerifyVoteExtension, error) { res, err := cli.doRequest(ctx, types.ToRequestVerifyVoteExtension(req)) if err != nil { return nil, err @@ -354,7 +354,7 @@ func (cli *socketClient) VerifyVoteExtension(ctx context.Context, req types.Requ return res.GetVerifyVoteExtension(), nil } -func (cli *socketClient) FinalizeBlock(ctx context.Context, req types.RequestFinalizeBlock) (*types.ResponseFinalizeBlock, error) { +func (cli *socketClient) FinalizeBlock(ctx context.Context, req *types.RequestFinalizeBlock) (*types.ResponseFinalizeBlock, error) { res, err := cli.doRequest(ctx, types.ToRequestFinalizeBlock(req)) if err != nil { return nil, err diff --git a/abci/cmd/abci-cli/abci-cli.go b/abci/cmd/abci-cli/abci-cli.go index 7bfea4a4c..cb1603be3 100644 --- a/abci/cmd/abci-cli/abci-cli.go +++ b/abci/cmd/abci-cli/abci-cli.go @@ -482,7 +482,7 @@ func cmdInfo(cmd *cobra.Command, args []string) error { if len(args) == 1 { version = args[0] } - res, err := client.Info(cmd.Context(), types.RequestInfo{Version: version}) + res, err := client.Info(cmd.Context(), &types.RequestInfo{Version: version}) if err != nil { return err } @@ -511,7 +511,7 @@ func cmdFinalizeBlock(cmd *cobra.Command, args []string) error { } txs[i] = txBytes } - res, err := client.FinalizeBlock(cmd.Context(), types.RequestFinalizeBlock{Txs: txs}) + res, err := client.FinalizeBlock(cmd.Context(), &types.RequestFinalizeBlock{Txs: txs}) if err != nil { return err } @@ -539,7 +539,7 @@ func cmdCheckTx(cmd *cobra.Command, args []string) error { if err != nil { return err } - res, err := client.CheckTx(cmd.Context(), types.RequestCheckTx{Tx: txBytes}) + res, err := client.CheckTx(cmd.Context(), &types.RequestCheckTx{Tx: txBytes}) if err != nil { return err } @@ -579,7 +579,7 @@ func cmdQuery(cmd *cobra.Command, args []string) error { return err } - resQuery, err := client.Query(cmd.Context(), types.RequestQuery{ + resQuery, err := client.Query(cmd.Context(), &types.RequestQuery{ Data: queryBytes, Path: flagPath, Height: int64(flagHeight), diff --git a/abci/example/example_test.go b/abci/example/example_test.go index 6da090e9d..066d4071d 100644 --- a/abci/example/example_test.go +++ b/abci/example/example_test.go @@ -77,7 +77,7 @@ func testBulk(ctx context.Context, t *testing.T, logger log.Logger, app types.Ap require.NoError(t, err) // Construct request - rfb := types.RequestFinalizeBlock{Txs: make([][]byte, numDeliverTxs)} + rfb := &types.RequestFinalizeBlock{Txs: make([][]byte, numDeliverTxs)} for counter := 0; counter < numDeliverTxs; counter++ { rfb.Txs[counter] = []byte("test") } diff --git a/abci/example/kvstore/helpers.go b/abci/example/kvstore/helpers.go index 25b7dc9bb..8a2a8a35b 100644 --- a/abci/example/kvstore/helpers.go +++ b/abci/example/kvstore/helpers.go @@ -34,7 +34,7 @@ func RandVals(cnt int) []types.ValidatorUpdate { // which allows tests to pass and is fine as long as you // don't make any tx that modify the validator state func InitKVStore(ctx context.Context, app *PersistentKVStoreApplication) error { - _, err := app.InitChain(ctx, types.RequestInitChain{ + _, err := app.InitChain(ctx, &types.RequestInitChain{ Validators: RandVals(1), }) return err diff --git a/abci/example/kvstore/kvstore.go b/abci/example/kvstore/kvstore.go index 42c121e1f..61d129239 100644 --- a/abci/example/kvstore/kvstore.go +++ b/abci/example/kvstore/kvstore.go @@ -91,7 +91,7 @@ func NewApplication() *Application { } } -func (app *Application) InitChain(_ context.Context, req types.RequestInitChain) (*types.ResponseInitChain, error) { +func (app *Application) InitChain(_ context.Context, req *types.RequestInitChain) (*types.ResponseInitChain, error) { app.mu.Lock() defer app.mu.Unlock() @@ -105,7 +105,7 @@ func (app *Application) InitChain(_ context.Context, req types.RequestInitChain) return &types.ResponseInitChain{}, nil } -func (app *Application) Info(_ context.Context, req types.RequestInfo) (*types.ResponseInfo, error) { +func (app *Application) Info(_ context.Context, req *types.RequestInfo) (*types.ResponseInfo, error) { app.mu.Lock() defer app.mu.Unlock() return &types.ResponseInfo{ @@ -167,7 +167,7 @@ func (app *Application) Close() error { return app.state.db.Close() } -func (app *Application) FinalizeBlock(_ context.Context, req types.RequestFinalizeBlock) (*types.ResponseFinalizeBlock, error) { +func (app *Application) FinalizeBlock(_ context.Context, req *types.RequestFinalizeBlock) (*types.ResponseFinalizeBlock, error) { app.mu.Lock() defer app.mu.Unlock() @@ -199,7 +199,7 @@ func (app *Application) FinalizeBlock(_ context.Context, req types.RequestFinali return &types.ResponseFinalizeBlock{TxResults: respTxs, ValidatorUpdates: app.ValUpdates}, nil } -func (*Application) CheckTx(_ context.Context, req types.RequestCheckTx) (*types.ResponseCheckTx, error) { +func (*Application) CheckTx(_ context.Context, req *types.RequestCheckTx) (*types.ResponseCheckTx, error) { return &types.ResponseCheckTx{Code: code.CodeTypeOK, GasWanted: 1}, nil } @@ -222,7 +222,7 @@ func (app *Application) Commit(_ context.Context) (*types.ResponseCommit, error) } // Returns an associated value or nil if missing. -func (app *Application) Query(_ context.Context, reqQuery types.RequestQuery) (*types.ResponseQuery, error) { +func (app *Application) Query(_ context.Context, reqQuery *types.RequestQuery) (*types.ResponseQuery, error) { app.mu.Lock() defer app.mu.Unlock() @@ -281,7 +281,7 @@ func (app *Application) Query(_ context.Context, reqQuery types.RequestQuery) (* return &resQuery, nil } -func (app *Application) PrepareProposal(_ context.Context, req types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) { +func (app *Application) PrepareProposal(_ context.Context, req *types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) { app.mu.Lock() defer app.mu.Unlock() @@ -290,7 +290,7 @@ func (app *Application) PrepareProposal(_ context.Context, req types.RequestPrep }, nil } -func (*Application) ProcessProposal(_ context.Context, req types.RequestProcessProposal) (*types.ResponseProcessProposal, error) { +func (*Application) ProcessProposal(_ context.Context, req *types.RequestProcessProposal) (*types.ResponseProcessProposal, error) { for _, tx := range req.Txs { if len(tx) == 0 { return &types.ResponseProcessProposal{Status: types.ResponseProcessProposal_REJECT}, nil diff --git a/abci/example/kvstore/kvstore_test.go b/abci/example/kvstore/kvstore_test.go index 994100f6e..9631bc1ab 100644 --- a/abci/example/kvstore/kvstore_test.go +++ b/abci/example/kvstore/kvstore_test.go @@ -24,7 +24,7 @@ const ( ) func testKVStore(ctx context.Context, t *testing.T, app types.Application, tx []byte, key, value string) { - req := types.RequestFinalizeBlock{Txs: [][]byte{tx}} + req := &types.RequestFinalizeBlock{Txs: [][]byte{tx}} ar, err := app.FinalizeBlock(ctx, req) require.NoError(t, err) require.Equal(t, 1, len(ar.TxResults)) @@ -38,12 +38,12 @@ func testKVStore(ctx context.Context, t *testing.T, app types.Application, tx [] _, err = app.Commit(ctx) require.NoError(t, err) - info, err := app.Info(ctx, types.RequestInfo{}) + info, err := app.Info(ctx, &types.RequestInfo{}) require.NoError(t, err) require.NotZero(t, info.LastBlockHeight) // make sure query is fine - resQuery, err := app.Query(ctx, types.RequestQuery{ + resQuery, err := app.Query(ctx, &types.RequestQuery{ Path: "/store", Data: []byte(key), }) @@ -54,7 +54,7 @@ func testKVStore(ctx context.Context, t *testing.T, app types.Application, tx [] require.EqualValues(t, info.LastBlockHeight, resQuery.Height) // make sure proof is fine - resQuery, err = app.Query(ctx, types.RequestQuery{ + resQuery, err = app.Query(ctx, &types.RequestQuery{ Path: "/store", Data: []byte(key), Prove: true, @@ -111,7 +111,7 @@ func TestPersistentKVStoreInfo(t *testing.T) { } height := int64(0) - resInfo, err := kvstore.Info(ctx, types.RequestInfo{}) + resInfo, err := kvstore.Info(ctx, &types.RequestInfo{}) if err != nil { t.Fatal(err) } @@ -123,7 +123,7 @@ func TestPersistentKVStoreInfo(t *testing.T) { // make and apply block height = int64(1) hash := []byte("foo") - if _, err := kvstore.FinalizeBlock(ctx, types.RequestFinalizeBlock{Hash: hash, Height: height}); err != nil { + if _, err := kvstore.FinalizeBlock(ctx, &types.RequestFinalizeBlock{Hash: hash, Height: height}); err != nil { t.Fatal(err) } @@ -132,7 +132,7 @@ func TestPersistentKVStoreInfo(t *testing.T) { } - resInfo, err = kvstore.Info(ctx, types.RequestInfo{}) + resInfo, err = kvstore.Info(ctx, &types.RequestInfo{}) if err != nil { t.Fatal(err) } @@ -154,7 +154,7 @@ func TestValUpdates(t *testing.T) { nInit := 5 vals := RandVals(total) // initialize with the first nInit - _, err := kvstore.InitChain(ctx, types.RequestInitChain{ + _, err := kvstore.InitChain(ctx, &types.RequestInitChain{ Validators: vals[:nInit], }) if err != nil { @@ -215,7 +215,7 @@ func makeApplyBlock(ctx context.Context, t *testing.T, kvstore types.Application // make and apply block height := int64(heightInt) hash := []byte("foo") - resFinalizeBlock, err := kvstore.FinalizeBlock(ctx, types.RequestFinalizeBlock{ + resFinalizeBlock, err := kvstore.FinalizeBlock(ctx, &types.RequestFinalizeBlock{ Hash: hash, Height: height, Txs: txs, @@ -350,12 +350,12 @@ func runClientTests(ctx context.Context, t *testing.T, client abciclient.Client) } func testClient(ctx context.Context, t *testing.T, app abciclient.Client, tx []byte, key, value string) { - ar, err := app.FinalizeBlock(ctx, types.RequestFinalizeBlock{Txs: [][]byte{tx}}) + ar, err := app.FinalizeBlock(ctx, &types.RequestFinalizeBlock{Txs: [][]byte{tx}}) require.NoError(t, err) require.Equal(t, 1, len(ar.TxResults)) require.False(t, ar.TxResults[0].IsErr()) // repeating FinalizeBlock doesn't raise error - ar, err = app.FinalizeBlock(ctx, types.RequestFinalizeBlock{Txs: [][]byte{tx}}) + ar, err = app.FinalizeBlock(ctx, &types.RequestFinalizeBlock{Txs: [][]byte{tx}}) require.NoError(t, err) require.Equal(t, 1, len(ar.TxResults)) require.False(t, ar.TxResults[0].IsErr()) @@ -363,12 +363,12 @@ func testClient(ctx context.Context, t *testing.T, app abciclient.Client, tx []b _, err = app.Commit(ctx) require.NoError(t, err) - info, err := app.Info(ctx, types.RequestInfo{}) + info, err := app.Info(ctx, &types.RequestInfo{}) require.NoError(t, err) require.NotZero(t, info.LastBlockHeight) // make sure query is fine - resQuery, err := app.Query(ctx, types.RequestQuery{ + resQuery, err := app.Query(ctx, &types.RequestQuery{ Path: "/store", Data: []byte(key), }) @@ -379,7 +379,7 @@ func testClient(ctx context.Context, t *testing.T, app abciclient.Client, tx []b require.EqualValues(t, info.LastBlockHeight, resQuery.Height) // make sure proof is fine - resQuery, err = app.Query(ctx, types.RequestQuery{ + resQuery, err = app.Query(ctx, &types.RequestQuery{ Path: "/store", Data: []byte(key), Prove: true, diff --git a/abci/example/kvstore/persistent_kvstore.go b/abci/example/kvstore/persistent_kvstore.go index bbaf670e0..bede5d517 100644 --- a/abci/example/kvstore/persistent_kvstore.go +++ b/abci/example/kvstore/persistent_kvstore.go @@ -37,10 +37,10 @@ func NewPersistentKVStoreApplication(logger log.Logger, dbDir string) *Persisten } } -func (app *PersistentKVStoreApplication) OfferSnapshot(_ context.Context, req types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { +func (app *PersistentKVStoreApplication) OfferSnapshot(_ context.Context, req *types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { return &types.ResponseOfferSnapshot{Result: types.ResponseOfferSnapshot_ABORT}, nil } -func (app *PersistentKVStoreApplication) ApplySnapshotChunk(_ context.Context, req types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { +func (app *PersistentKVStoreApplication) ApplySnapshotChunk(_ context.Context, req *types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { return &types.ResponseApplySnapshotChunk{Result: types.ResponseApplySnapshotChunk_ABORT}, nil } diff --git a/abci/server/grpc_server.go b/abci/server/grpc_server.go index 8d84c76d2..0dfee8169 100644 --- a/abci/server/grpc_server.go +++ b/abci/server/grpc_server.go @@ -44,7 +44,7 @@ func (s *GRPCServer) OnStart(ctx context.Context) error { } s.server = grpc.NewServer() - types.RegisterABCIApplicationServer(s.server, &gRPCApplication{app: s.app}) + types.RegisterABCIApplicationServer(s.server, &gRPCApplication{Application: s.app}) s.logger.Info("Listening", "proto", s.proto, "addr", s.addr) go func() { @@ -67,7 +67,7 @@ func (s *GRPCServer) OnStop() { s.server.Stop() } // gRPCApplication is a gRPC shim for Application type gRPCApplication struct { - app types.Application + types.Application } func (app *gRPCApplication) Echo(_ context.Context, req *types.RequestEcho) (*types.ResponseEcho, error) { @@ -78,58 +78,6 @@ func (app *gRPCApplication) Flush(_ context.Context, req *types.RequestFlush) (* return &types.ResponseFlush{}, nil } -func (app *gRPCApplication) Info(ctx context.Context, req *types.RequestInfo) (*types.ResponseInfo, error) { - return app.app.Info(ctx, *req) -} - -func (app *gRPCApplication) CheckTx(ctx context.Context, req *types.RequestCheckTx) (*types.ResponseCheckTx, error) { - return app.app.CheckTx(ctx, *req) -} - -func (app *gRPCApplication) Query(ctx context.Context, req *types.RequestQuery) (*types.ResponseQuery, error) { - return app.app.Query(ctx, *req) -} - func (app *gRPCApplication) Commit(ctx context.Context, req *types.RequestCommit) (*types.ResponseCommit, error) { - return app.app.Commit(ctx) -} - -func (app *gRPCApplication) InitChain(ctx context.Context, req *types.RequestInitChain) (*types.ResponseInitChain, error) { - return app.app.InitChain(ctx, *req) -} - -func (app *gRPCApplication) ListSnapshots(ctx context.Context, req *types.RequestListSnapshots) (*types.ResponseListSnapshots, error) { - return app.app.ListSnapshots(ctx, *req) -} - -func (app *gRPCApplication) OfferSnapshot(ctx context.Context, req *types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { - return app.app.OfferSnapshot(ctx, *req) -} - -func (app *gRPCApplication) LoadSnapshotChunk(ctx context.Context, req *types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) { - return app.app.LoadSnapshotChunk(ctx, *req) -} - -func (app *gRPCApplication) ApplySnapshotChunk(ctx context.Context, req *types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { - return app.app.ApplySnapshotChunk(ctx, *req) -} - -func (app *gRPCApplication) ExtendVote(ctx context.Context, req *types.RequestExtendVote) (*types.ResponseExtendVote, error) { - return app.app.ExtendVote(ctx, *req) -} - -func (app *gRPCApplication) VerifyVoteExtension(ctx context.Context, req *types.RequestVerifyVoteExtension) (*types.ResponseVerifyVoteExtension, error) { - return app.app.VerifyVoteExtension(ctx, *req) -} - -func (app *gRPCApplication) PrepareProposal(ctx context.Context, req *types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) { - return app.app.PrepareProposal(ctx, *req) -} - -func (app *gRPCApplication) ProcessProposal(ctx context.Context, req *types.RequestProcessProposal) (*types.ResponseProcessProposal, error) { - return app.app.ProcessProposal(ctx, *req) -} - -func (app *gRPCApplication) FinalizeBlock(ctx context.Context, req *types.RequestFinalizeBlock) (*types.ResponseFinalizeBlock, error) { - return app.app.FinalizeBlock(ctx, *req) + return app.Application.Commit(ctx) } diff --git a/abci/server/socket_server.go b/abci/server/socket_server.go index c5cd150d1..570ecfb4e 100644 --- a/abci/server/socket_server.go +++ b/abci/server/socket_server.go @@ -201,14 +201,14 @@ func (s *SocketServer) processRequest(ctx context.Context, req *types.Request) ( case *types.Request_Flush: return types.ToResponseFlush(), nil case *types.Request_Info: - res, err := s.app.Info(ctx, *r.Info) + res, err := s.app.Info(ctx, r.Info) if err != nil { return nil, err } return types.ToResponseInfo(res), nil case *types.Request_CheckTx: - res, err := s.app.CheckTx(ctx, *r.CheckTx) + res, err := s.app.CheckTx(ctx, r.CheckTx) if err != nil { return nil, err } @@ -220,67 +220,67 @@ func (s *SocketServer) processRequest(ctx context.Context, req *types.Request) ( } return types.ToResponseCommit(res), nil case *types.Request_Query: - res, err := s.app.Query(ctx, *r.Query) + res, err := s.app.Query(ctx, r.Query) if err != nil { return nil, err } return types.ToResponseQuery(res), nil case *types.Request_InitChain: - res, err := s.app.InitChain(ctx, *r.InitChain) + res, err := s.app.InitChain(ctx, r.InitChain) if err != nil { return nil, err } return types.ToResponseInitChain(res), nil case *types.Request_ListSnapshots: - res, err := s.app.ListSnapshots(ctx, *r.ListSnapshots) + res, err := s.app.ListSnapshots(ctx, r.ListSnapshots) if err != nil { return nil, err } return types.ToResponseListSnapshots(res), nil case *types.Request_OfferSnapshot: - res, err := s.app.OfferSnapshot(ctx, *r.OfferSnapshot) + res, err := s.app.OfferSnapshot(ctx, r.OfferSnapshot) if err != nil { return nil, err } return types.ToResponseOfferSnapshot(res), nil case *types.Request_PrepareProposal: - res, err := s.app.PrepareProposal(ctx, *r.PrepareProposal) + res, err := s.app.PrepareProposal(ctx, r.PrepareProposal) if err != nil { return nil, err } return types.ToResponsePrepareProposal(res), nil case *types.Request_ProcessProposal: - res, err := s.app.ProcessProposal(ctx, *r.ProcessProposal) + res, err := s.app.ProcessProposal(ctx, r.ProcessProposal) if err != nil { return nil, err } return types.ToResponseProcessProposal(res), nil case *types.Request_LoadSnapshotChunk: - res, err := s.app.LoadSnapshotChunk(ctx, *r.LoadSnapshotChunk) + res, err := s.app.LoadSnapshotChunk(ctx, r.LoadSnapshotChunk) if err != nil { return nil, err } return types.ToResponseLoadSnapshotChunk(res), nil case *types.Request_ApplySnapshotChunk: - res, err := s.app.ApplySnapshotChunk(ctx, *r.ApplySnapshotChunk) + res, err := s.app.ApplySnapshotChunk(ctx, r.ApplySnapshotChunk) if err != nil { return nil, err } return types.ToResponseApplySnapshotChunk(res), nil case *types.Request_ExtendVote: - res, err := s.app.ExtendVote(ctx, *r.ExtendVote) + res, err := s.app.ExtendVote(ctx, r.ExtendVote) if err != nil { return nil, err } return types.ToResponseExtendVote(res), nil case *types.Request_VerifyVoteExtension: - res, err := s.app.VerifyVoteExtension(ctx, *r.VerifyVoteExtension) + res, err := s.app.VerifyVoteExtension(ctx, r.VerifyVoteExtension) if err != nil { return nil, err } return types.ToResponseVerifyVoteExtension(res), nil case *types.Request_FinalizeBlock: - res, err := s.app.FinalizeBlock(ctx, *r.FinalizeBlock) + res, err := s.app.FinalizeBlock(ctx, r.FinalizeBlock) if err != nil { return nil, err } diff --git a/abci/tests/server/client.go b/abci/tests/server/client.go index 9273e8046..b02fd0b14 100644 --- a/abci/tests/server/client.go +++ b/abci/tests/server/client.go @@ -21,7 +21,7 @@ func InitChain(ctx context.Context, client abciclient.Client) error { power := mrand.Int() vals[i] = types.UpdateValidator(pubkey, int64(power), "") } - _, err := client.InitChain(ctx, types.RequestInitChain{ + _, err := client.InitChain(ctx, &types.RequestInitChain{ Validators: vals, }) if err != nil { @@ -50,7 +50,7 @@ func Commit(ctx context.Context, client abciclient.Client, hashExp []byte) error } func FinalizeBlock(ctx context.Context, client abciclient.Client, txBytes [][]byte, codeExp []uint32, dataExp []byte) error { - res, _ := client.FinalizeBlock(ctx, types.RequestFinalizeBlock{Txs: txBytes}) + res, _ := client.FinalizeBlock(ctx, &types.RequestFinalizeBlock{Txs: txBytes}) for i, tx := range res.TxResults { code, data, log := tx.Code, tx.Data, tx.Log if code != codeExp[i] { @@ -71,7 +71,7 @@ func FinalizeBlock(ctx context.Context, client abciclient.Client, txBytes [][]by } func CheckTx(ctx context.Context, client abciclient.Client, txBytes []byte, codeExp uint32, dataExp []byte) error { - res, _ := client.CheckTx(ctx, types.RequestCheckTx{Tx: txBytes}) + res, _ := client.CheckTx(ctx, &types.RequestCheckTx{Tx: txBytes}) code, data, log := res.Code, res.Data, res.Log if code != codeExp { fmt.Println("Failed test: CheckTx") diff --git a/abci/types/application.go b/abci/types/application.go index abe3143c7..e74b87743 100644 --- a/abci/types/application.go +++ b/abci/types/application.go @@ -7,30 +7,30 @@ import "context" // to be driven by a blockchain-based replication engine via the ABCI. type Application interface { // Info/Query Connection - Info(context.Context, RequestInfo) (*ResponseInfo, error) // Return application info - Query(context.Context, RequestQuery) (*ResponseQuery, error) // Query for state + Info(context.Context, *RequestInfo) (*ResponseInfo, error) // Return application info + Query(context.Context, *RequestQuery) (*ResponseQuery, error) // Query for state // Mempool Connection - CheckTx(context.Context, RequestCheckTx) (*ResponseCheckTx, error) // Validate a tx for the mempool + CheckTx(context.Context, *RequestCheckTx) (*ResponseCheckTx, error) // Validate a tx for the mempool // Consensus Connection - InitChain(context.Context, RequestInitChain) (*ResponseInitChain, error) // Initialize blockchain w validators/other info from TendermintCore - PrepareProposal(context.Context, RequestPrepareProposal) (*ResponsePrepareProposal, error) - ProcessProposal(context.Context, RequestProcessProposal) (*ResponseProcessProposal, error) + InitChain(context.Context, *RequestInitChain) (*ResponseInitChain, error) // Initialize blockchain w validators/other info from TendermintCore + PrepareProposal(context.Context, *RequestPrepareProposal) (*ResponsePrepareProposal, error) + ProcessProposal(context.Context, *RequestProcessProposal) (*ResponseProcessProposal, error) // Commit the state and return the application Merkle root hash Commit(context.Context) (*ResponseCommit, error) // Create application specific vote extension - ExtendVote(context.Context, RequestExtendVote) (*ResponseExtendVote, error) + ExtendVote(context.Context, *RequestExtendVote) (*ResponseExtendVote, error) // Verify application's vote extension data - VerifyVoteExtension(context.Context, RequestVerifyVoteExtension) (*ResponseVerifyVoteExtension, error) + VerifyVoteExtension(context.Context, *RequestVerifyVoteExtension) (*ResponseVerifyVoteExtension, error) // Deliver the decided block with its txs to the Application - FinalizeBlock(context.Context, RequestFinalizeBlock) (*ResponseFinalizeBlock, error) + FinalizeBlock(context.Context, *RequestFinalizeBlock) (*ResponseFinalizeBlock, error) // State Sync Connection - ListSnapshots(context.Context, RequestListSnapshots) (*ResponseListSnapshots, error) // List available snapshots - OfferSnapshot(context.Context, RequestOfferSnapshot) (*ResponseOfferSnapshot, error) // Offer a snapshot to the application - LoadSnapshotChunk(context.Context, RequestLoadSnapshotChunk) (*ResponseLoadSnapshotChunk, error) // Load a snapshot chunk - ApplySnapshotChunk(context.Context, RequestApplySnapshotChunk) (*ResponseApplySnapshotChunk, error) // Apply a shapshot chunk + ListSnapshots(context.Context, *RequestListSnapshots) (*ResponseListSnapshots, error) // List available snapshots + OfferSnapshot(context.Context, *RequestOfferSnapshot) (*ResponseOfferSnapshot, error) // Offer a snapshot to the application + LoadSnapshotChunk(context.Context, *RequestLoadSnapshotChunk) (*ResponseLoadSnapshotChunk, error) // Load a snapshot chunk + ApplySnapshotChunk(context.Context, *RequestApplySnapshotChunk) (*ResponseApplySnapshotChunk, error) // Apply a shapshot chunk } //------------------------------------------------------- @@ -44,11 +44,11 @@ func NewBaseApplication() *BaseApplication { return &BaseApplication{} } -func (BaseApplication) Info(_ context.Context, req RequestInfo) (*ResponseInfo, error) { +func (BaseApplication) Info(_ context.Context, req *RequestInfo) (*ResponseInfo, error) { return &ResponseInfo{}, nil } -func (BaseApplication) CheckTx(_ context.Context, req RequestCheckTx) (*ResponseCheckTx, error) { +func (BaseApplication) CheckTx(_ context.Context, req *RequestCheckTx) (*ResponseCheckTx, error) { return &ResponseCheckTx{Code: CodeTypeOK}, nil } @@ -56,41 +56,41 @@ func (BaseApplication) Commit(_ context.Context) (*ResponseCommit, error) { return &ResponseCommit{}, nil } -func (BaseApplication) ExtendVote(_ context.Context, req RequestExtendVote) (*ResponseExtendVote, error) { +func (BaseApplication) ExtendVote(_ context.Context, req *RequestExtendVote) (*ResponseExtendVote, error) { return &ResponseExtendVote{}, nil } -func (BaseApplication) VerifyVoteExtension(_ context.Context, req RequestVerifyVoteExtension) (*ResponseVerifyVoteExtension, error) { +func (BaseApplication) VerifyVoteExtension(_ context.Context, req *RequestVerifyVoteExtension) (*ResponseVerifyVoteExtension, error) { return &ResponseVerifyVoteExtension{ Status: ResponseVerifyVoteExtension_ACCEPT, }, nil } -func (BaseApplication) Query(_ context.Context, req RequestQuery) (*ResponseQuery, error) { +func (BaseApplication) Query(_ context.Context, req *RequestQuery) (*ResponseQuery, error) { return &ResponseQuery{Code: CodeTypeOK}, nil } -func (BaseApplication) InitChain(_ context.Context, req RequestInitChain) (*ResponseInitChain, error) { +func (BaseApplication) InitChain(_ context.Context, req *RequestInitChain) (*ResponseInitChain, error) { return &ResponseInitChain{}, nil } -func (BaseApplication) ListSnapshots(_ context.Context, req RequestListSnapshots) (*ResponseListSnapshots, error) { +func (BaseApplication) ListSnapshots(_ context.Context, req *RequestListSnapshots) (*ResponseListSnapshots, error) { return &ResponseListSnapshots{}, nil } -func (BaseApplication) OfferSnapshot(_ context.Context, req RequestOfferSnapshot) (*ResponseOfferSnapshot, error) { +func (BaseApplication) OfferSnapshot(_ context.Context, req *RequestOfferSnapshot) (*ResponseOfferSnapshot, error) { return &ResponseOfferSnapshot{}, nil } -func (BaseApplication) LoadSnapshotChunk(_ context.Context, _ RequestLoadSnapshotChunk) (*ResponseLoadSnapshotChunk, error) { +func (BaseApplication) LoadSnapshotChunk(_ context.Context, _ *RequestLoadSnapshotChunk) (*ResponseLoadSnapshotChunk, error) { return &ResponseLoadSnapshotChunk{}, nil } -func (BaseApplication) ApplySnapshotChunk(_ context.Context, req RequestApplySnapshotChunk) (*ResponseApplySnapshotChunk, error) { +func (BaseApplication) ApplySnapshotChunk(_ context.Context, req *RequestApplySnapshotChunk) (*ResponseApplySnapshotChunk, error) { return &ResponseApplySnapshotChunk{}, nil } -func (BaseApplication) PrepareProposal(_ context.Context, req RequestPrepareProposal) (*ResponsePrepareProposal, error) { +func (BaseApplication) PrepareProposal(_ context.Context, req *RequestPrepareProposal) (*ResponsePrepareProposal, error) { trs := make([]*TxRecord, 0, len(req.Txs)) var totalBytes int64 for _, tx := range req.Txs { @@ -106,11 +106,11 @@ func (BaseApplication) PrepareProposal(_ context.Context, req RequestPrepareProp return &ResponsePrepareProposal{TxRecords: trs}, nil } -func (BaseApplication) ProcessProposal(_ context.Context, req RequestProcessProposal) (*ResponseProcessProposal, error) { +func (BaseApplication) ProcessProposal(_ context.Context, req *RequestProcessProposal) (*ResponseProcessProposal, error) { return &ResponseProcessProposal{Status: ResponseProcessProposal_ACCEPT}, nil } -func (BaseApplication) FinalizeBlock(_ context.Context, req RequestFinalizeBlock) (*ResponseFinalizeBlock, error) { +func (BaseApplication) FinalizeBlock(_ context.Context, req *RequestFinalizeBlock) (*ResponseFinalizeBlock, error) { txs := make([]*ExecTxResult, len(req.Txs)) for i := range req.Txs { txs[i] = &ExecTxResult{Code: CodeTypeOK} diff --git a/abci/types/messages.go b/abci/types/messages.go index 9bc3aabc0..80ab19525 100644 --- a/abci/types/messages.go +++ b/abci/types/messages.go @@ -39,15 +39,15 @@ func ToRequestFlush() *Request { } } -func ToRequestInfo(req RequestInfo) *Request { +func ToRequestInfo(req *RequestInfo) *Request { return &Request{ - Value: &Request_Info{&req}, + Value: &Request_Info{req}, } } -func ToRequestCheckTx(req RequestCheckTx) *Request { +func ToRequestCheckTx(req *RequestCheckTx) *Request { return &Request{ - Value: &Request_CheckTx{&req}, + Value: &Request_CheckTx{req}, } } @@ -57,69 +57,69 @@ func ToRequestCommit() *Request { } } -func ToRequestQuery(req RequestQuery) *Request { +func ToRequestQuery(req *RequestQuery) *Request { return &Request{ - Value: &Request_Query{&req}, + Value: &Request_Query{req}, } } -func ToRequestInitChain(req RequestInitChain) *Request { +func ToRequestInitChain(req *RequestInitChain) *Request { return &Request{ - Value: &Request_InitChain{&req}, + Value: &Request_InitChain{req}, } } -func ToRequestListSnapshots(req RequestListSnapshots) *Request { +func ToRequestListSnapshots(req *RequestListSnapshots) *Request { return &Request{ - Value: &Request_ListSnapshots{&req}, + Value: &Request_ListSnapshots{req}, } } -func ToRequestOfferSnapshot(req RequestOfferSnapshot) *Request { +func ToRequestOfferSnapshot(req *RequestOfferSnapshot) *Request { return &Request{ - Value: &Request_OfferSnapshot{&req}, + Value: &Request_OfferSnapshot{req}, } } -func ToRequestLoadSnapshotChunk(req RequestLoadSnapshotChunk) *Request { +func ToRequestLoadSnapshotChunk(req *RequestLoadSnapshotChunk) *Request { return &Request{ - Value: &Request_LoadSnapshotChunk{&req}, + Value: &Request_LoadSnapshotChunk{req}, } } -func ToRequestApplySnapshotChunk(req RequestApplySnapshotChunk) *Request { +func ToRequestApplySnapshotChunk(req *RequestApplySnapshotChunk) *Request { return &Request{ - Value: &Request_ApplySnapshotChunk{&req}, + Value: &Request_ApplySnapshotChunk{req}, } } -func ToRequestExtendVote(req RequestExtendVote) *Request { +func ToRequestExtendVote(req *RequestExtendVote) *Request { return &Request{ - Value: &Request_ExtendVote{&req}, + Value: &Request_ExtendVote{req}, } } -func ToRequestVerifyVoteExtension(req RequestVerifyVoteExtension) *Request { +func ToRequestVerifyVoteExtension(req *RequestVerifyVoteExtension) *Request { return &Request{ - Value: &Request_VerifyVoteExtension{&req}, + Value: &Request_VerifyVoteExtension{req}, } } -func ToRequestPrepareProposal(req RequestPrepareProposal) *Request { +func ToRequestPrepareProposal(req *RequestPrepareProposal) *Request { return &Request{ - Value: &Request_PrepareProposal{&req}, + Value: &Request_PrepareProposal{req}, } } -func ToRequestProcessProposal(req RequestProcessProposal) *Request { +func ToRequestProcessProposal(req *RequestProcessProposal) *Request { return &Request{ - Value: &Request_ProcessProposal{&req}, + Value: &Request_ProcessProposal{req}, } } -func ToRequestFinalizeBlock(req RequestFinalizeBlock) *Request { +func ToRequestFinalizeBlock(req *RequestFinalizeBlock) *Request { return &Request{ - Value: &Request_FinalizeBlock{&req}, + Value: &Request_FinalizeBlock{req}, } } diff --git a/abci/types/mocks/application.go b/abci/types/mocks/application.go index 4b0fc64da..2d35c481f 100644 --- a/abci/types/mocks/application.go +++ b/abci/types/mocks/application.go @@ -17,11 +17,11 @@ type Application struct { } // ApplySnapshotChunk provides a mock function with given fields: _a0, _a1 -func (_m *Application) ApplySnapshotChunk(_a0 context.Context, _a1 types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { +func (_m *Application) ApplySnapshotChunk(_a0 context.Context, _a1 *types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { ret := _m.Called(_a0, _a1) var r0 *types.ResponseApplySnapshotChunk - if rf, ok := ret.Get(0).(func(context.Context, types.RequestApplySnapshotChunk) *types.ResponseApplySnapshotChunk); ok { + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestApplySnapshotChunk) *types.ResponseApplySnapshotChunk); ok { r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { @@ -30,7 +30,7 @@ func (_m *Application) ApplySnapshotChunk(_a0 context.Context, _a1 types.Request } var r1 error - if rf, ok := ret.Get(1).(func(context.Context, types.RequestApplySnapshotChunk) error); ok { + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestApplySnapshotChunk) error); ok { r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) @@ -40,11 +40,11 @@ func (_m *Application) ApplySnapshotChunk(_a0 context.Context, _a1 types.Request } // CheckTx provides a mock function with given fields: _a0, _a1 -func (_m *Application) CheckTx(_a0 context.Context, _a1 types.RequestCheckTx) (*types.ResponseCheckTx, error) { +func (_m *Application) CheckTx(_a0 context.Context, _a1 *types.RequestCheckTx) (*types.ResponseCheckTx, error) { ret := _m.Called(_a0, _a1) var r0 *types.ResponseCheckTx - if rf, ok := ret.Get(0).(func(context.Context, types.RequestCheckTx) *types.ResponseCheckTx); ok { + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestCheckTx) *types.ResponseCheckTx); ok { r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { @@ -53,7 +53,7 @@ func (_m *Application) CheckTx(_a0 context.Context, _a1 types.RequestCheckTx) (* } var r1 error - if rf, ok := ret.Get(1).(func(context.Context, types.RequestCheckTx) error); ok { + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestCheckTx) error); ok { r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) @@ -86,11 +86,11 @@ func (_m *Application) Commit(_a0 context.Context) (*types.ResponseCommit, error } // ExtendVote provides a mock function with given fields: _a0, _a1 -func (_m *Application) ExtendVote(_a0 context.Context, _a1 types.RequestExtendVote) (*types.ResponseExtendVote, error) { +func (_m *Application) ExtendVote(_a0 context.Context, _a1 *types.RequestExtendVote) (*types.ResponseExtendVote, error) { ret := _m.Called(_a0, _a1) var r0 *types.ResponseExtendVote - if rf, ok := ret.Get(0).(func(context.Context, types.RequestExtendVote) *types.ResponseExtendVote); ok { + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestExtendVote) *types.ResponseExtendVote); ok { r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { @@ -99,7 +99,7 @@ func (_m *Application) ExtendVote(_a0 context.Context, _a1 types.RequestExtendVo } var r1 error - if rf, ok := ret.Get(1).(func(context.Context, types.RequestExtendVote) error); ok { + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestExtendVote) error); ok { r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) @@ -109,11 +109,11 @@ func (_m *Application) ExtendVote(_a0 context.Context, _a1 types.RequestExtendVo } // FinalizeBlock provides a mock function with given fields: _a0, _a1 -func (_m *Application) FinalizeBlock(_a0 context.Context, _a1 types.RequestFinalizeBlock) (*types.ResponseFinalizeBlock, error) { +func (_m *Application) FinalizeBlock(_a0 context.Context, _a1 *types.RequestFinalizeBlock) (*types.ResponseFinalizeBlock, error) { ret := _m.Called(_a0, _a1) var r0 *types.ResponseFinalizeBlock - if rf, ok := ret.Get(0).(func(context.Context, types.RequestFinalizeBlock) *types.ResponseFinalizeBlock); ok { + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestFinalizeBlock) *types.ResponseFinalizeBlock); ok { r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { @@ -122,7 +122,7 @@ func (_m *Application) FinalizeBlock(_a0 context.Context, _a1 types.RequestFinal } var r1 error - if rf, ok := ret.Get(1).(func(context.Context, types.RequestFinalizeBlock) error); ok { + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestFinalizeBlock) error); ok { r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) @@ -132,11 +132,11 @@ func (_m *Application) FinalizeBlock(_a0 context.Context, _a1 types.RequestFinal } // Info provides a mock function with given fields: _a0, _a1 -func (_m *Application) Info(_a0 context.Context, _a1 types.RequestInfo) (*types.ResponseInfo, error) { +func (_m *Application) Info(_a0 context.Context, _a1 *types.RequestInfo) (*types.ResponseInfo, error) { ret := _m.Called(_a0, _a1) var r0 *types.ResponseInfo - if rf, ok := ret.Get(0).(func(context.Context, types.RequestInfo) *types.ResponseInfo); ok { + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestInfo) *types.ResponseInfo); ok { r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { @@ -145,7 +145,7 @@ func (_m *Application) Info(_a0 context.Context, _a1 types.RequestInfo) (*types. } var r1 error - if rf, ok := ret.Get(1).(func(context.Context, types.RequestInfo) error); ok { + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestInfo) error); ok { r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) @@ -155,11 +155,11 @@ func (_m *Application) Info(_a0 context.Context, _a1 types.RequestInfo) (*types. } // InitChain provides a mock function with given fields: _a0, _a1 -func (_m *Application) InitChain(_a0 context.Context, _a1 types.RequestInitChain) (*types.ResponseInitChain, error) { +func (_m *Application) InitChain(_a0 context.Context, _a1 *types.RequestInitChain) (*types.ResponseInitChain, error) { ret := _m.Called(_a0, _a1) var r0 *types.ResponseInitChain - if rf, ok := ret.Get(0).(func(context.Context, types.RequestInitChain) *types.ResponseInitChain); ok { + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestInitChain) *types.ResponseInitChain); ok { r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { @@ -168,7 +168,7 @@ func (_m *Application) InitChain(_a0 context.Context, _a1 types.RequestInitChain } var r1 error - if rf, ok := ret.Get(1).(func(context.Context, types.RequestInitChain) error); ok { + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestInitChain) error); ok { r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) @@ -178,11 +178,11 @@ func (_m *Application) InitChain(_a0 context.Context, _a1 types.RequestInitChain } // ListSnapshots provides a mock function with given fields: _a0, _a1 -func (_m *Application) ListSnapshots(_a0 context.Context, _a1 types.RequestListSnapshots) (*types.ResponseListSnapshots, error) { +func (_m *Application) ListSnapshots(_a0 context.Context, _a1 *types.RequestListSnapshots) (*types.ResponseListSnapshots, error) { ret := _m.Called(_a0, _a1) var r0 *types.ResponseListSnapshots - if rf, ok := ret.Get(0).(func(context.Context, types.RequestListSnapshots) *types.ResponseListSnapshots); ok { + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestListSnapshots) *types.ResponseListSnapshots); ok { r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { @@ -191,7 +191,7 @@ func (_m *Application) ListSnapshots(_a0 context.Context, _a1 types.RequestListS } var r1 error - if rf, ok := ret.Get(1).(func(context.Context, types.RequestListSnapshots) error); ok { + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestListSnapshots) error); ok { r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) @@ -201,11 +201,11 @@ func (_m *Application) ListSnapshots(_a0 context.Context, _a1 types.RequestListS } // LoadSnapshotChunk provides a mock function with given fields: _a0, _a1 -func (_m *Application) LoadSnapshotChunk(_a0 context.Context, _a1 types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) { +func (_m *Application) LoadSnapshotChunk(_a0 context.Context, _a1 *types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) { ret := _m.Called(_a0, _a1) var r0 *types.ResponseLoadSnapshotChunk - if rf, ok := ret.Get(0).(func(context.Context, types.RequestLoadSnapshotChunk) *types.ResponseLoadSnapshotChunk); ok { + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestLoadSnapshotChunk) *types.ResponseLoadSnapshotChunk); ok { r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { @@ -214,7 +214,7 @@ func (_m *Application) LoadSnapshotChunk(_a0 context.Context, _a1 types.RequestL } var r1 error - if rf, ok := ret.Get(1).(func(context.Context, types.RequestLoadSnapshotChunk) error); ok { + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestLoadSnapshotChunk) error); ok { r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) @@ -224,11 +224,11 @@ func (_m *Application) LoadSnapshotChunk(_a0 context.Context, _a1 types.RequestL } // OfferSnapshot provides a mock function with given fields: _a0, _a1 -func (_m *Application) OfferSnapshot(_a0 context.Context, _a1 types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { +func (_m *Application) OfferSnapshot(_a0 context.Context, _a1 *types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { ret := _m.Called(_a0, _a1) var r0 *types.ResponseOfferSnapshot - if rf, ok := ret.Get(0).(func(context.Context, types.RequestOfferSnapshot) *types.ResponseOfferSnapshot); ok { + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestOfferSnapshot) *types.ResponseOfferSnapshot); ok { r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { @@ -237,7 +237,7 @@ func (_m *Application) OfferSnapshot(_a0 context.Context, _a1 types.RequestOffer } var r1 error - if rf, ok := ret.Get(1).(func(context.Context, types.RequestOfferSnapshot) error); ok { + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestOfferSnapshot) error); ok { r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) @@ -247,11 +247,11 @@ func (_m *Application) OfferSnapshot(_a0 context.Context, _a1 types.RequestOffer } // PrepareProposal provides a mock function with given fields: _a0, _a1 -func (_m *Application) PrepareProposal(_a0 context.Context, _a1 types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) { +func (_m *Application) PrepareProposal(_a0 context.Context, _a1 *types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) { ret := _m.Called(_a0, _a1) var r0 *types.ResponsePrepareProposal - if rf, ok := ret.Get(0).(func(context.Context, types.RequestPrepareProposal) *types.ResponsePrepareProposal); ok { + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestPrepareProposal) *types.ResponsePrepareProposal); ok { r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { @@ -260,7 +260,7 @@ func (_m *Application) PrepareProposal(_a0 context.Context, _a1 types.RequestPre } var r1 error - if rf, ok := ret.Get(1).(func(context.Context, types.RequestPrepareProposal) error); ok { + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestPrepareProposal) error); ok { r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) @@ -270,11 +270,11 @@ func (_m *Application) PrepareProposal(_a0 context.Context, _a1 types.RequestPre } // ProcessProposal provides a mock function with given fields: _a0, _a1 -func (_m *Application) ProcessProposal(_a0 context.Context, _a1 types.RequestProcessProposal) (*types.ResponseProcessProposal, error) { +func (_m *Application) ProcessProposal(_a0 context.Context, _a1 *types.RequestProcessProposal) (*types.ResponseProcessProposal, error) { ret := _m.Called(_a0, _a1) var r0 *types.ResponseProcessProposal - if rf, ok := ret.Get(0).(func(context.Context, types.RequestProcessProposal) *types.ResponseProcessProposal); ok { + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestProcessProposal) *types.ResponseProcessProposal); ok { r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { @@ -283,7 +283,7 @@ func (_m *Application) ProcessProposal(_a0 context.Context, _a1 types.RequestPro } var r1 error - if rf, ok := ret.Get(1).(func(context.Context, types.RequestProcessProposal) error); ok { + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestProcessProposal) error); ok { r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) @@ -293,11 +293,11 @@ func (_m *Application) ProcessProposal(_a0 context.Context, _a1 types.RequestPro } // Query provides a mock function with given fields: _a0, _a1 -func (_m *Application) Query(_a0 context.Context, _a1 types.RequestQuery) (*types.ResponseQuery, error) { +func (_m *Application) Query(_a0 context.Context, _a1 *types.RequestQuery) (*types.ResponseQuery, error) { ret := _m.Called(_a0, _a1) var r0 *types.ResponseQuery - if rf, ok := ret.Get(0).(func(context.Context, types.RequestQuery) *types.ResponseQuery); ok { + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestQuery) *types.ResponseQuery); ok { r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { @@ -306,7 +306,7 @@ func (_m *Application) Query(_a0 context.Context, _a1 types.RequestQuery) (*type } var r1 error - if rf, ok := ret.Get(1).(func(context.Context, types.RequestQuery) error); ok { + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestQuery) error); ok { r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) @@ -316,11 +316,11 @@ func (_m *Application) Query(_a0 context.Context, _a1 types.RequestQuery) (*type } // VerifyVoteExtension provides a mock function with given fields: _a0, _a1 -func (_m *Application) VerifyVoteExtension(_a0 context.Context, _a1 types.RequestVerifyVoteExtension) (*types.ResponseVerifyVoteExtension, error) { +func (_m *Application) VerifyVoteExtension(_a0 context.Context, _a1 *types.RequestVerifyVoteExtension) (*types.ResponseVerifyVoteExtension, error) { ret := _m.Called(_a0, _a1) var r0 *types.ResponseVerifyVoteExtension - if rf, ok := ret.Get(0).(func(context.Context, types.RequestVerifyVoteExtension) *types.ResponseVerifyVoteExtension); ok { + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestVerifyVoteExtension) *types.ResponseVerifyVoteExtension); ok { r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { @@ -329,7 +329,7 @@ func (_m *Application) VerifyVoteExtension(_a0 context.Context, _a1 types.Reques } var r1 error - if rf, ok := ret.Get(1).(func(context.Context, types.RequestVerifyVoteExtension) error); ok { + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestVerifyVoteExtension) error); ok { r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) diff --git a/internal/consensus/byzantine_test.go b/internal/consensus/byzantine_test.go index 1e8167e21..804ebdb18 100644 --- a/internal/consensus/byzantine_test.go +++ b/internal/consensus/byzantine_test.go @@ -68,7 +68,7 @@ func TestByzantinePrevoteEquivocation(t *testing.T) { ensureDir(t, path.Dir(thisConfig.Consensus.WalFile()), 0700) // dir for wal app := kvstore.NewApplication() vals := types.TM2PB.ValidatorUpdates(state.Validators) - _, err = app.InitChain(ctx, abci.RequestInitChain{Validators: vals}) + _, err = app.InitChain(ctx, &abci.RequestInitChain{Validators: vals}) require.NoError(t, err) blockDB := dbm.NewMemDB() diff --git a/internal/consensus/common_test.go b/internal/consensus/common_test.go index 7bd4dd15e..515a74d1a 100644 --- a/internal/consensus/common_test.go +++ b/internal/consensus/common_test.go @@ -821,7 +821,7 @@ func makeConsensusState( closeFuncs = append(closeFuncs, app.Close) vals := types.TM2PB.ValidatorUpdates(state.Validators) - _, err = app.InitChain(ctx, abci.RequestInitChain{Validators: vals}) + _, err = app.InitChain(ctx, &abci.RequestInitChain{Validators: vals}) require.NoError(t, err) l := logger.With("validator", i, "module", "consensus") @@ -893,7 +893,7 @@ func randConsensusNetWithPeers( case *kvstore.Application: state.Version.Consensus.App = kvstore.ProtocolVersion } - _, err = app.InitChain(ctx, abci.RequestInitChain{Validators: vals}) + _, err = app.InitChain(ctx, &abci.RequestInitChain{Validators: vals}) require.NoError(t, err) // sm.SaveState(stateDB,state) //height 1's validatorsInfo already saved in LoadStateFromDBOrGenesisDoc above diff --git a/internal/consensus/mempool_test.go b/internal/consensus/mempool_test.go index 593b2fde1..ac04e4027 100644 --- a/internal/consensus/mempool_test.go +++ b/internal/consensus/mempool_test.go @@ -199,7 +199,7 @@ func TestMempoolRmBadTx(t *testing.T) { txBytes := make([]byte, 8) binary.BigEndian.PutUint64(txBytes, uint64(0)) - resFinalize, err := app.FinalizeBlock(ctx, abci.RequestFinalizeBlock{Txs: [][]byte{txBytes}}) + resFinalize, err := app.FinalizeBlock(ctx, &abci.RequestFinalizeBlock{Txs: [][]byte{txBytes}}) require.NoError(t, err) assert.False(t, resFinalize.TxResults[0].IsErr(), fmt.Sprintf("expected no error. got %v", resFinalize)) @@ -269,11 +269,11 @@ func NewCounterApplication() *CounterApplication { return &CounterApplication{} } -func (app *CounterApplication) Info(_ context.Context, req abci.RequestInfo) (*abci.ResponseInfo, error) { +func (app *CounterApplication) Info(_ context.Context, req *abci.RequestInfo) (*abci.ResponseInfo, error) { return &abci.ResponseInfo{Data: fmt.Sprintf("txs:%v", app.txCount)}, nil } -func (app *CounterApplication) FinalizeBlock(_ context.Context, req abci.RequestFinalizeBlock) (*abci.ResponseFinalizeBlock, error) { +func (app *CounterApplication) FinalizeBlock(_ context.Context, req *abci.RequestFinalizeBlock) (*abci.ResponseFinalizeBlock, error) { respTxs := make([]*abci.ExecTxResult, len(req.Txs)) for i, tx := range req.Txs { txValue := txAsUint64(tx) @@ -290,7 +290,7 @@ func (app *CounterApplication) FinalizeBlock(_ context.Context, req abci.Request return &abci.ResponseFinalizeBlock{TxResults: respTxs}, nil } -func (app *CounterApplication) CheckTx(_ context.Context, req abci.RequestCheckTx) (*abci.ResponseCheckTx, error) { +func (app *CounterApplication) CheckTx(_ context.Context, req *abci.RequestCheckTx) (*abci.ResponseCheckTx, error) { txValue := txAsUint64(req.Tx) if txValue != uint64(app.mempoolTxCount) { return &abci.ResponseCheckTx{ @@ -318,7 +318,7 @@ func (app *CounterApplication) Commit(context.Context) (*abci.ResponseCommit, er return &abci.ResponseCommit{Data: hash}, nil } -func (app *CounterApplication) PrepareProposal(_ context.Context, req abci.RequestPrepareProposal) (*abci.ResponsePrepareProposal, error) { +func (app *CounterApplication) PrepareProposal(_ context.Context, req *abci.RequestPrepareProposal) (*abci.ResponsePrepareProposal, error) { trs := make([]*abci.TxRecord, 0, len(req.Txs)) var totalBytes int64 for _, tx := range req.Txs { @@ -334,6 +334,6 @@ func (app *CounterApplication) PrepareProposal(_ context.Context, req abci.Reque return &abci.ResponsePrepareProposal{TxRecords: trs}, nil } -func (app *CounterApplication) ProcessProposal(_ context.Context, req abci.RequestProcessProposal) (*abci.ResponseProcessProposal, error) { +func (app *CounterApplication) ProcessProposal(_ context.Context, req *abci.RequestProcessProposal) (*abci.ResponseProcessProposal, error) { return &abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT}, nil } diff --git a/internal/consensus/reactor_test.go b/internal/consensus/reactor_test.go index 29dac5e00..8a9abdf43 100644 --- a/internal/consensus/reactor_test.go +++ b/internal/consensus/reactor_test.go @@ -466,7 +466,7 @@ func TestReactorWithEvidence(t *testing.T) { app := kvstore.NewApplication() vals := types.TM2PB.ValidatorUpdates(state.Validators) - _, err = app.InitChain(ctx, abci.RequestInitChain{Validators: vals}) + _, err = app.InitChain(ctx, &abci.RequestInitChain{Validators: vals}) require.NoError(t, err) pv := privVals[i] diff --git a/internal/consensus/replay.go b/internal/consensus/replay.go index 17435d273..fac7c91ac 100644 --- a/internal/consensus/replay.go +++ b/internal/consensus/replay.go @@ -239,7 +239,7 @@ func (h *Handshaker) NBlocks() int { func (h *Handshaker) Handshake(ctx context.Context, appClient abciclient.Client) error { // Handshake is done via ABCI Info on the query conn. - res, err := appClient.Info(ctx, proxy.RequestInfo) + res, err := appClient.Info(ctx, &proxy.RequestInfo) if err != nil { return fmt.Errorf("error calling Info: %w", err) } @@ -307,15 +307,14 @@ func (h *Handshaker) ReplayBlocks( validatorSet := types.NewValidatorSet(validators) nextVals := types.TM2PB.ValidatorUpdates(validatorSet) pbParams := h.genDoc.ConsensusParams.ToProto() - req := abci.RequestInitChain{ + res, err := appClient.InitChain(ctx, &abci.RequestInitChain{ Time: h.genDoc.GenesisTime, ChainId: h.genDoc.ChainID, InitialHeight: h.genDoc.InitialHeight, ConsensusParams: &pbParams, Validators: nextVals, AppStateBytes: h.genDoc.AppState, - } - res, err := appClient.InitChain(ctx, req) + }) if err != nil { return nil, err } diff --git a/internal/consensus/replay_stubs.go b/internal/consensus/replay_stubs.go index 783d31206..3cd5bdac0 100644 --- a/internal/consensus/replay_stubs.go +++ b/internal/consensus/replay_stubs.go @@ -75,7 +75,7 @@ type mockProxyApp struct { abciResponses *tmstate.ABCIResponses } -func (mock *mockProxyApp) FinalizeBlock(_ context.Context, req abci.RequestFinalizeBlock) (*abci.ResponseFinalizeBlock, error) { +func (mock *mockProxyApp) FinalizeBlock(_ context.Context, req *abci.RequestFinalizeBlock) (*abci.ResponseFinalizeBlock, error) { r := mock.abciResponses.FinalizeBlock mock.txCount++ if r == nil { diff --git a/internal/consensus/replay_test.go b/internal/consensus/replay_test.go index 072c55d50..f112f23e8 100644 --- a/internal/consensus/replay_test.go +++ b/internal/consensus/replay_test.go @@ -788,7 +788,7 @@ func testHandshakeReplay( require.NoError(t, err, "Error on abci handshake") // get the latest app hash from the app - res, err := proxyApp.Info(ctx, abci.RequestInfo{Version: ""}) + res, err := proxyApp.Info(ctx, &abci.RequestInfo{Version: ""}) if err != nil { t.Fatal(err) } @@ -856,7 +856,7 @@ func buildAppStateFromChain( state.Version.Consensus.App = kvstore.ProtocolVersion // simulate handshake, receive app version validators := types.TM2PB.ValidatorUpdates(state.Validators) - _, err := appClient.InitChain(ctx, abci.RequestInitChain{ + _, err := appClient.InitChain(ctx, &abci.RequestInitChain{ Validators: validators, }) require.NoError(t, err) @@ -910,7 +910,7 @@ func buildTMStateFromChain( state.Version.Consensus.App = kvstore.ProtocolVersion // simulate handshake, receive app version validators := types.TM2PB.ValidatorUpdates(state.Validators) - _, err := proxyApp.InitChain(ctx, abci.RequestInitChain{ + _, err := proxyApp.InitChain(ctx, &abci.RequestInitChain{ Validators: validators, }) require.NoError(t, err) @@ -1275,6 +1275,6 @@ type initChainApp struct { vals []abci.ValidatorUpdate } -func (ica *initChainApp) InitChain(_ context.Context, req abci.RequestInitChain) (*abci.ResponseInitChain, error) { +func (ica *initChainApp) InitChain(_ context.Context, req *abci.RequestInitChain) (*abci.ResponseInitChain, error) { return &abci.ResponseInitChain{Validators: ica.vals}, nil } diff --git a/internal/consensus/state_test.go b/internal/consensus/state_test.go index 2bde6974a..d4dd83202 100644 --- a/internal/consensus/state_test.go +++ b/internal/consensus/state_test.go @@ -2067,12 +2067,12 @@ func TestExtendVoteCalled(t *testing.T) { ensurePrecommit(t, voteCh, height, round) - m.AssertCalled(t, "ExtendVote", ctx, abci.RequestExtendVote{ + m.AssertCalled(t, "ExtendVote", ctx, &abci.RequestExtendVote{ Height: height, Hash: blockID.Hash, }) - m.AssertCalled(t, "VerifyVoteExtension", ctx, abci.RequestVerifyVoteExtension{ + m.AssertCalled(t, "VerifyVoteExtension", ctx, &abci.RequestVerifyVoteExtension{ Hash: blockID.Hash, ValidatorAddress: addr, Height: height, @@ -2088,7 +2088,7 @@ func TestExtendVoteCalled(t *testing.T) { pv, err := pv.GetPubKey(ctx) require.NoError(t, err) addr := pv.Address() - m.AssertCalled(t, "VerifyVoteExtension", ctx, abci.RequestVerifyVoteExtension{ + m.AssertCalled(t, "VerifyVoteExtension", ctx, &abci.RequestVerifyVoteExtension{ Hash: blockID.Hash, ValidatorAddress: addr, Height: height, @@ -2139,12 +2139,12 @@ func TestVerifyVoteExtensionNotCalledOnAbsentPrecommit(t *testing.T) { ensurePrecommit(t, voteCh, height, round) - m.AssertCalled(t, "ExtendVote", mock.Anything, abci.RequestExtendVote{ + m.AssertCalled(t, "ExtendVote", mock.Anything, &abci.RequestExtendVote{ Height: height, Hash: blockID.Hash, }) - m.AssertCalled(t, "VerifyVoteExtension", mock.Anything, abci.RequestVerifyVoteExtension{ + m.AssertCalled(t, "VerifyVoteExtension", mock.Anything, &abci.RequestVerifyVoteExtension{ Hash: blockID.Hash, ValidatorAddress: addr, Height: height, @@ -2162,7 +2162,7 @@ func TestVerifyVoteExtensionNotCalledOnAbsentPrecommit(t *testing.T) { require.NoError(t, err) addr = pv.Address() - m.AssertNotCalled(t, "VerifyVoteExtension", ctx, abci.RequestVerifyVoteExtension{ + m.AssertNotCalled(t, "VerifyVoteExtension", ctx, &abci.RequestVerifyVoteExtension{ Hash: blockID.Hash, ValidatorAddress: addr, Height: height, @@ -2199,8 +2199,8 @@ func TestPrepareProposalReceivesVoteExtensions(t *testing.T) { m.On("ProcessProposal", mock.Anything, mock.Anything).Return(&abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT}, nil) // capture the prepare proposal request. - rpp := abci.RequestPrepareProposal{} - m.On("PrepareProposal", mock.Anything, mock.MatchedBy(func(r abci.RequestPrepareProposal) bool { + rpp := &abci.RequestPrepareProposal{} + m.On("PrepareProposal", mock.Anything, mock.MatchedBy(func(r *abci.RequestPrepareProposal) bool { rpp = r return true })).Return(&abci.ResponsePrepareProposal{}, nil) diff --git a/internal/mempool/mempool.go b/internal/mempool/mempool.go index 6fcfe86c1..629fa0bda 100644 --- a/internal/mempool/mempool.go +++ b/internal/mempool/mempool.go @@ -260,7 +260,7 @@ func (txmp *TxMempool) CheckTx( return types.ErrTxInCache } - res, err := txmp.proxyAppConn.CheckTx(ctx, abci.RequestCheckTx{Tx: tx}) + res, err := txmp.proxyAppConn.CheckTx(ctx, &abci.RequestCheckTx{Tx: tx}) if err != nil { txmp.cache.Remove(tx) return err @@ -700,7 +700,7 @@ func (txmp *TxMempool) updateReCheckTxs(ctx context.Context) { // Only execute CheckTx if the transaction is not marked as removed which // could happen if the transaction was evicted. if !txmp.txStore.IsTxRemoved(wtx.hash) { - res, err := txmp.proxyAppConn.CheckTx(ctx, abci.RequestCheckTx{ + res, err := txmp.proxyAppConn.CheckTx(ctx, &abci.RequestCheckTx{ Tx: wtx.tx, Type: abci.CheckTxType_Recheck, }) diff --git a/internal/mempool/mempool_test.go b/internal/mempool/mempool_test.go index 0f8f0e712..946377b1c 100644 --- a/internal/mempool/mempool_test.go +++ b/internal/mempool/mempool_test.go @@ -36,7 +36,7 @@ type testTx struct { priority int64 } -func (app *application) CheckTx(_ context.Context, req abci.RequestCheckTx) (*abci.ResponseCheckTx, error) { +func (app *application) CheckTx(_ context.Context, req *abci.RequestCheckTx) (*abci.ResponseCheckTx, error) { var ( priority int64 sender string diff --git a/internal/proxy/client.go b/internal/proxy/client.go index 2af1b1021..735c99656 100644 --- a/internal/proxy/client.go +++ b/internal/proxy/client.go @@ -124,32 +124,32 @@ func kill() error { return p.Signal(syscall.SIGABRT) } -func (app *proxyClient) InitChain(ctx context.Context, req types.RequestInitChain) (*types.ResponseInitChain, error) { +func (app *proxyClient) InitChain(ctx context.Context, req *types.RequestInitChain) (*types.ResponseInitChain, error) { defer addTimeSample(app.metrics.MethodTiming.With("method", "init_chain", "type", "sync"))() return app.client.InitChain(ctx, req) } -func (app *proxyClient) PrepareProposal(ctx context.Context, req types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) { +func (app *proxyClient) PrepareProposal(ctx context.Context, req *types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) { defer addTimeSample(app.metrics.MethodTiming.With("method", "prepare_proposal", "type", "sync"))() return app.client.PrepareProposal(ctx, req) } -func (app *proxyClient) ProcessProposal(ctx context.Context, req types.RequestProcessProposal) (*types.ResponseProcessProposal, error) { +func (app *proxyClient) ProcessProposal(ctx context.Context, req *types.RequestProcessProposal) (*types.ResponseProcessProposal, error) { defer addTimeSample(app.metrics.MethodTiming.With("method", "process_proposal", "type", "sync"))() return app.client.ProcessProposal(ctx, req) } -func (app *proxyClient) ExtendVote(ctx context.Context, req types.RequestExtendVote) (*types.ResponseExtendVote, error) { +func (app *proxyClient) ExtendVote(ctx context.Context, req *types.RequestExtendVote) (*types.ResponseExtendVote, error) { defer addTimeSample(app.metrics.MethodTiming.With("method", "extend_vote", "type", "sync"))() return app.client.ExtendVote(ctx, req) } -func (app *proxyClient) VerifyVoteExtension(ctx context.Context, req types.RequestVerifyVoteExtension) (*types.ResponseVerifyVoteExtension, error) { +func (app *proxyClient) VerifyVoteExtension(ctx context.Context, req *types.RequestVerifyVoteExtension) (*types.ResponseVerifyVoteExtension, error) { defer addTimeSample(app.metrics.MethodTiming.With("method", "verify_vote_extension", "type", "sync"))() return app.client.VerifyVoteExtension(ctx, req) } -func (app *proxyClient) FinalizeBlock(ctx context.Context, req types.RequestFinalizeBlock) (*types.ResponseFinalizeBlock, error) { +func (app *proxyClient) FinalizeBlock(ctx context.Context, req *types.RequestFinalizeBlock) (*types.ResponseFinalizeBlock, error) { defer addTimeSample(app.metrics.MethodTiming.With("method", "finalize_block", "type", "sync"))() return app.client.FinalizeBlock(ctx, req) } @@ -164,7 +164,7 @@ func (app *proxyClient) Flush(ctx context.Context) error { return app.client.Flush(ctx) } -func (app *proxyClient) CheckTx(ctx context.Context, req types.RequestCheckTx) (*types.ResponseCheckTx, error) { +func (app *proxyClient) CheckTx(ctx context.Context, req *types.RequestCheckTx) (*types.ResponseCheckTx, error) { defer addTimeSample(app.metrics.MethodTiming.With("method", "check_tx", "type", "sync"))() return app.client.CheckTx(ctx, req) } @@ -174,32 +174,32 @@ func (app *proxyClient) Echo(ctx context.Context, msg string) (*types.ResponseEc return app.client.Echo(ctx, msg) } -func (app *proxyClient) Info(ctx context.Context, req types.RequestInfo) (*types.ResponseInfo, error) { +func (app *proxyClient) Info(ctx context.Context, req *types.RequestInfo) (*types.ResponseInfo, error) { defer addTimeSample(app.metrics.MethodTiming.With("method", "info", "type", "sync"))() return app.client.Info(ctx, req) } -func (app *proxyClient) Query(ctx context.Context, reqQuery types.RequestQuery) (*types.ResponseQuery, error) { +func (app *proxyClient) Query(ctx context.Context, req *types.RequestQuery) (*types.ResponseQuery, error) { defer addTimeSample(app.metrics.MethodTiming.With("method", "query", "type", "sync"))() - return app.client.Query(ctx, reqQuery) + return app.client.Query(ctx, req) } -func (app *proxyClient) ListSnapshots(ctx context.Context, req types.RequestListSnapshots) (*types.ResponseListSnapshots, error) { +func (app *proxyClient) ListSnapshots(ctx context.Context, req *types.RequestListSnapshots) (*types.ResponseListSnapshots, error) { defer addTimeSample(app.metrics.MethodTiming.With("method", "list_snapshots", "type", "sync"))() return app.client.ListSnapshots(ctx, req) } -func (app *proxyClient) OfferSnapshot(ctx context.Context, req types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { +func (app *proxyClient) OfferSnapshot(ctx context.Context, req *types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { defer addTimeSample(app.metrics.MethodTiming.With("method", "offer_snapshot", "type", "sync"))() return app.client.OfferSnapshot(ctx, req) } -func (app *proxyClient) LoadSnapshotChunk(ctx context.Context, req types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) { +func (app *proxyClient) LoadSnapshotChunk(ctx context.Context, req *types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) { defer addTimeSample(app.metrics.MethodTiming.With("method", "load_snapshot_chunk", "type", "sync"))() return app.client.LoadSnapshotChunk(ctx, req) } -func (app *proxyClient) ApplySnapshotChunk(ctx context.Context, req types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { +func (app *proxyClient) ApplySnapshotChunk(ctx context.Context, req *types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { defer addTimeSample(app.metrics.MethodTiming.With("method", "apply_snapshot_chunk", "type", "sync"))() return app.client.ApplySnapshotChunk(ctx, req) } diff --git a/internal/proxy/client_test.go b/internal/proxy/client_test.go index 057177a60..09ac3f2c8 100644 --- a/internal/proxy/client_test.go +++ b/internal/proxy/client_test.go @@ -30,7 +30,7 @@ import ( type appConnTestI interface { Echo(context.Context, string) (*types.ResponseEcho, error) Flush(context.Context) error - Info(context.Context, types.RequestInfo) (*types.ResponseInfo, error) + Info(context.Context, *types.RequestInfo) (*types.ResponseInfo, error) } type appConnTest struct { @@ -49,7 +49,7 @@ func (app *appConnTest) Flush(ctx context.Context) error { return app.appConn.Flush(ctx) } -func (app *appConnTest) Info(ctx context.Context, req types.RequestInfo) (*types.ResponseInfo, error) { +func (app *appConnTest) Info(ctx context.Context, req *types.RequestInfo) (*types.ResponseInfo, error) { return app.appConn.Info(ctx, req) } @@ -164,7 +164,7 @@ func TestInfo(t *testing.T) { proxy := newAppConnTest(client) t.Log("Connected") - resInfo, err := proxy.Info(ctx, RequestInfo) + resInfo, err := proxy.Info(ctx, &RequestInfo) require.NoError(t, err) if resInfo.Data != "{\"size\":0}" { diff --git a/internal/rpc/core/abci.go b/internal/rpc/core/abci.go index 8f5e61d55..dc7a5bdfe 100644 --- a/internal/rpc/core/abci.go +++ b/internal/rpc/core/abci.go @@ -18,7 +18,7 @@ func (env *Environment) ABCIQuery( height int64, prove bool, ) (*coretypes.ResultABCIQuery, error) { - resQuery, err := env.ProxyApp.Query(ctx, abci.RequestQuery{ + resQuery, err := env.ProxyApp.Query(ctx, &abci.RequestQuery{ Path: path, Data: data, Height: height, @@ -34,7 +34,7 @@ func (env *Environment) ABCIQuery( // ABCIInfo gets some info about the application. // More: https://docs.tendermint.com/master/rpc/#/ABCI/abci_info func (env *Environment) ABCIInfo(ctx context.Context) (*coretypes.ResultABCIInfo, error) { - resInfo, err := env.ProxyApp.Info(ctx, proxy.RequestInfo) + resInfo, err := env.ProxyApp.Info(ctx, &proxy.RequestInfo) if err != nil { return nil, err } diff --git a/internal/rpc/core/mempool.go b/internal/rpc/core/mempool.go index a852aeb1d..450adf4d5 100644 --- a/internal/rpc/core/mempool.go +++ b/internal/rpc/core/mempool.go @@ -176,7 +176,7 @@ func (env *Environment) NumUnconfirmedTxs(ctx context.Context) (*coretypes.Resul // be added to the mempool either. // More: https://docs.tendermint.com/master/rpc/#/Tx/check_tx func (env *Environment) CheckTx(ctx context.Context, tx types.Tx) (*coretypes.ResultCheckTx, error) { - res, err := env.ProxyApp.CheckTx(ctx, abci.RequestCheckTx{Tx: tx}) + res, err := env.ProxyApp.CheckTx(ctx, &abci.RequestCheckTx{Tx: tx}) if err != nil { return nil, err } diff --git a/internal/state/execution.go b/internal/state/execution.go index 0b2c83dbc..06dfc0b5c 100644 --- a/internal/state/execution.go +++ b/internal/state/execution.go @@ -106,7 +106,7 @@ func (blockExec *BlockExecutor) CreateProposalBlock( localLastCommit := buildLastCommitInfo(block, blockExec.store, state.InitialHeight) rpp, err := blockExec.appClient.PrepareProposal( ctx, - abci.RequestPrepareProposal{ + &abci.RequestPrepareProposal{ MaxTxBytes: maxDataBytes, Txs: block.Txs.ToSliceOfBytes(), LocalLastCommit: extendedCommitInfo(localLastCommit, votes), @@ -148,7 +148,7 @@ func (blockExec *BlockExecutor) ProcessProposal( block *types.Block, state State, ) (bool, error) { - req := abci.RequestProcessProposal{ + resp, err := blockExec.appClient.ProcessProposal(ctx, &abci.RequestProcessProposal{ Hash: block.Header.Hash(), Height: block.Header.Height, Time: block.Header.Time, @@ -157,9 +157,7 @@ func (blockExec *BlockExecutor) ProcessProposal( ByzantineValidators: block.Evidence.ToABCI(), ProposerAddress: block.ProposerAddress, NextValidatorsHash: block.NextValidatorsHash, - } - - resp, err := blockExec.appClient.ProcessProposal(ctx, req) + }) if err != nil { return false, ErrInvalidBlock(err) } @@ -211,7 +209,7 @@ func (blockExec *BlockExecutor) ApplyBlock( startTime := time.Now().UnixNano() finalizeBlockResponse, err := blockExec.appClient.FinalizeBlock( ctx, - abci.RequestFinalizeBlock{ + &abci.RequestFinalizeBlock{ Hash: block.Hash(), Height: block.Header.Height, Time: block.Header.Time, @@ -298,12 +296,10 @@ func (blockExec *BlockExecutor) ApplyBlock( } func (blockExec *BlockExecutor) ExtendVote(ctx context.Context, vote *types.Vote) ([]byte, error) { - req := abci.RequestExtendVote{ + resp, err := blockExec.appClient.ExtendVote(ctx, &abci.RequestExtendVote{ Hash: vote.BlockID.Hash, Height: vote.Height, - } - - resp, err := blockExec.appClient.ExtendVote(ctx, req) + }) if err != nil { panic(fmt.Errorf("ExtendVote call failed: %w", err)) } @@ -311,14 +307,12 @@ func (blockExec *BlockExecutor) ExtendVote(ctx context.Context, vote *types.Vote } func (blockExec *BlockExecutor) VerifyVoteExtension(ctx context.Context, vote *types.Vote) error { - req := abci.RequestVerifyVoteExtension{ + resp, err := blockExec.appClient.VerifyVoteExtension(ctx, &abci.RequestVerifyVoteExtension{ Hash: vote.BlockID.Hash, ValidatorAddress: vote.ValidatorAddress, Height: vote.Height, VoteExtension: vote.Extension, - } - - resp, err := blockExec.appClient.VerifyVoteExtension(ctx, req) + }) if err != nil { panic(fmt.Errorf("VerifyVoteExtension call failed: %w", err)) } @@ -636,7 +630,7 @@ func ExecCommitBlock( ) ([]byte, error) { finalizeBlockResponse, err := appConn.FinalizeBlock( ctx, - abci.RequestFinalizeBlock{ + &abci.RequestFinalizeBlock{ Hash: block.Hash(), Height: block.Height, Time: block.Time, diff --git a/internal/state/execution_test.go b/internal/state/execution_test.go index 71d5b2f83..317f09706 100644 --- a/internal/state/execution_test.go +++ b/internal/state/execution_test.go @@ -329,7 +329,7 @@ func TestProcessProposal(t *testing.T) { block1 := sf.MakeBlock(state, height, lastCommit) block1.Txs = txs - expectedRpp := abci.RequestProcessProposal{ + expectedRpp := &abci.RequestProcessProposal{ Txs: block1.Txs.ToSliceOfBytes(), Hash: block1.Hash(), Height: block1.Header.Height, diff --git a/internal/state/helpers_test.go b/internal/state/helpers_test.go index 67072766a..07dd0d865 100644 --- a/internal/state/helpers_test.go +++ b/internal/state/helpers_test.go @@ -278,11 +278,11 @@ type testApp struct { var _ abci.Application = (*testApp)(nil) -func (app *testApp) Info(_ context.Context, req abci.RequestInfo) (*abci.ResponseInfo, error) { +func (app *testApp) Info(_ context.Context, req *abci.RequestInfo) (*abci.ResponseInfo, error) { return &abci.ResponseInfo{}, nil } -func (app *testApp) FinalizeBlock(_ context.Context, req abci.RequestFinalizeBlock) (*abci.ResponseFinalizeBlock, error) { +func (app *testApp) FinalizeBlock(_ context.Context, req *abci.RequestFinalizeBlock) (*abci.ResponseFinalizeBlock, error) { app.CommitVotes = req.DecidedLastCommit.Votes app.ByzantineValidators = req.ByzantineValidators @@ -307,7 +307,7 @@ func (app *testApp) FinalizeBlock(_ context.Context, req abci.RequestFinalizeBlo }, nil } -func (app *testApp) CheckTx(_ context.Context, req abci.RequestCheckTx) (*abci.ResponseCheckTx, error) { +func (app *testApp) CheckTx(_ context.Context, req *abci.RequestCheckTx) (*abci.ResponseCheckTx, error) { return &abci.ResponseCheckTx{}, nil } @@ -315,11 +315,11 @@ func (app *testApp) Commit(context.Context) (*abci.ResponseCommit, error) { return &abci.ResponseCommit{RetainHeight: 1}, nil } -func (app *testApp) Query(_ context.Context, req abci.RequestQuery) (*abci.ResponseQuery, error) { +func (app *testApp) Query(_ context.Context, req *abci.RequestQuery) (*abci.ResponseQuery, error) { return &abci.ResponseQuery{}, nil } -func (app *testApp) ProcessProposal(_ context.Context, req abci.RequestProcessProposal) (*abci.ResponseProcessProposal, error) { +func (app *testApp) ProcessProposal(_ context.Context, req *abci.RequestProcessProposal) (*abci.ResponseProcessProposal, error) { for _, tx := range req.Txs { if len(tx) == 0 { return &abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_REJECT}, nil diff --git a/internal/statesync/reactor.go b/internal/statesync/reactor.go index 795da5063..fb2749a02 100644 --- a/internal/statesync/reactor.go +++ b/internal/statesync/reactor.go @@ -688,7 +688,7 @@ func (r *Reactor) handleChunkMessage(ctx context.Context, envelope *p2p.Envelope "chunk", msg.Index, "peer", envelope.From, ) - resp, err := r.conn.LoadSnapshotChunk(ctx, abci.RequestLoadSnapshotChunk{ + resp, err := r.conn.LoadSnapshotChunk(ctx, &abci.RequestLoadSnapshotChunk{ Height: msg.Height, Format: msg.Format, Chunk: msg.Index, @@ -1015,7 +1015,7 @@ func (r *Reactor) processPeerUpdates(ctx context.Context, peerUpdates *p2p.PeerU // recentSnapshots fetches the n most recent snapshots from the app func (r *Reactor) recentSnapshots(ctx context.Context, n uint32) ([]*snapshot, error) { - resp, err := r.conn.ListSnapshots(ctx, abci.RequestListSnapshots{}) + resp, err := r.conn.ListSnapshots(ctx, &abci.RequestListSnapshots{}) if err != nil { return nil, err } diff --git a/internal/statesync/reactor_test.go b/internal/statesync/reactor_test.go index 86c84a9ed..c6b2c2d2b 100644 --- a/internal/statesync/reactor_test.go +++ b/internal/statesync/reactor_test.go @@ -204,15 +204,15 @@ func TestReactor_Sync(t *testing.T) { rts := setup(ctx, t, nil, nil, 100) chain := buildLightBlockChain(ctx, t, 1, 10, time.Now()) // app accepts any snapshot - rts.conn.On("OfferSnapshot", ctx, mock.AnythingOfType("types.RequestOfferSnapshot")). + rts.conn.On("OfferSnapshot", ctx, mock.IsType(&abci.RequestOfferSnapshot{})). Return(&abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_ACCEPT}, nil) // app accepts every chunk - rts.conn.On("ApplySnapshotChunk", ctx, mock.AnythingOfType("types.RequestApplySnapshotChunk")). + rts.conn.On("ApplySnapshotChunk", ctx, mock.IsType(&abci.RequestApplySnapshotChunk{})). Return(&abci.ResponseApplySnapshotChunk{Result: abci.ResponseApplySnapshotChunk_ACCEPT}, nil) // app query returns valid state app hash - rts.conn.On("Info", mock.Anything, proxy.RequestInfo).Return(&abci.ResponseInfo{ + rts.conn.On("Info", mock.Anything, &proxy.RequestInfo).Return(&abci.ResponseInfo{ AppVersion: testAppVersion, LastBlockHeight: snapshotHeight, LastBlockAppHash: chain[snapshotHeight+1].AppHash, @@ -307,7 +307,7 @@ func TestReactor_ChunkRequest(t *testing.T) { // mock ABCI connection to return local snapshots conn := &clientmocks.Client{} - conn.On("LoadSnapshotChunk", mock.Anything, abci.RequestLoadSnapshotChunk{ + conn.On("LoadSnapshotChunk", mock.Anything, &abci.RequestLoadSnapshotChunk{ Height: tc.request.Height, Format: tc.request.Format, Chunk: tc.request.Index, @@ -396,7 +396,7 @@ func TestReactor_SnapshotsRequest(t *testing.T) { // mock ABCI connection to return local snapshots conn := &clientmocks.Client{} - conn.On("ListSnapshots", mock.Anything, abci.RequestListSnapshots{}).Return(&abci.ResponseListSnapshots{ + conn.On("ListSnapshots", mock.Anything, &abci.RequestListSnapshots{}).Return(&abci.ResponseListSnapshots{ Snapshots: tc.snapshots, }, nil) diff --git a/internal/statesync/syncer.go b/internal/statesync/syncer.go index c2cca9a7c..47e058c19 100644 --- a/internal/statesync/syncer.go +++ b/internal/statesync/syncer.go @@ -337,7 +337,7 @@ func (s *syncer) Sync(ctx context.Context, snapshot *snapshot, chunks *chunkQueu func (s *syncer) offerSnapshot(ctx context.Context, snapshot *snapshot) error { s.logger.Info("Offering snapshot to ABCI app", "height", snapshot.Height, "format", snapshot.Format, "hash", snapshot.Hash) - resp, err := s.conn.OfferSnapshot(ctx, abci.RequestOfferSnapshot{ + resp, err := s.conn.OfferSnapshot(ctx, &abci.RequestOfferSnapshot{ Snapshot: &abci.Snapshot{ Height: snapshot.Height, Format: snapshot.Format, @@ -379,7 +379,7 @@ func (s *syncer) applyChunks(ctx context.Context, chunks *chunkQueue, start time return fmt.Errorf("failed to fetch chunk: %w", err) } - resp, err := s.conn.ApplySnapshotChunk(ctx, abci.RequestApplySnapshotChunk{ + resp, err := s.conn.ApplySnapshotChunk(ctx, &abci.RequestApplySnapshotChunk{ Index: chunk.Index, Chunk: chunk.Chunk, Sender: string(chunk.Sender), @@ -519,7 +519,7 @@ func (s *syncer) requestChunk(ctx context.Context, snapshot *snapshot, chunk uin // verifyApp verifies the sync, checking the app hash, last block height and app version func (s *syncer) verifyApp(ctx context.Context, snapshot *snapshot, appVersion uint64) error { - resp, err := s.conn.Info(ctx, proxy.RequestInfo) + resp, err := s.conn.Info(ctx, &proxy.RequestInfo) if err != nil { return fmt.Errorf("failed to query ABCI app for appHash: %w", err) } diff --git a/internal/statesync/syncer_test.go b/internal/statesync/syncer_test.go index e3bf49259..3fc3f0db4 100644 --- a/internal/statesync/syncer_test.go +++ b/internal/statesync/syncer_test.go @@ -109,7 +109,7 @@ func TestSyncer_SyncAny(t *testing.T) { // We start a sync, with peers sending back chunks when requested. We first reject the snapshot // with height 2 format 2, and accept the snapshot at height 1. - conn.On("OfferSnapshot", mock.Anything, abci.RequestOfferSnapshot{ + conn.On("OfferSnapshot", mock.Anything, &abci.RequestOfferSnapshot{ Snapshot: &abci.Snapshot{ Height: 2, Format: 2, @@ -118,7 +118,7 @@ func TestSyncer_SyncAny(t *testing.T) { }, AppHash: []byte("app_hash_2"), }).Return(&abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_REJECT_FORMAT}, nil) - conn.On("OfferSnapshot", mock.Anything, abci.RequestOfferSnapshot{ + conn.On("OfferSnapshot", mock.Anything, &abci.RequestOfferSnapshot{ Snapshot: &abci.Snapshot{ Height: s.Height, Format: s.Format, @@ -170,7 +170,7 @@ func TestSyncer_SyncAny(t *testing.T) { // The first time we're applying chunk 2 we tell it to retry the snapshot and discard chunk 1, // which should cause it to keep the existing chunk 0 and 2, and restart restoration from // beginning. We also wait for a little while, to exercise the retry logic in fetchChunks(). - conn.On("ApplySnapshotChunk", mock.Anything, abci.RequestApplySnapshotChunk{ + conn.On("ApplySnapshotChunk", mock.Anything, &abci.RequestApplySnapshotChunk{ Index: 2, Chunk: []byte{1, 1, 2}, }).Once().Run(func(args mock.Arguments) { time.Sleep(1 * time.Second) }).Return( &abci.ResponseApplySnapshotChunk{ @@ -178,16 +178,16 @@ func TestSyncer_SyncAny(t *testing.T) { RefetchChunks: []uint32{1}, }, nil) - conn.On("ApplySnapshotChunk", mock.Anything, abci.RequestApplySnapshotChunk{ + conn.On("ApplySnapshotChunk", mock.Anything, &abci.RequestApplySnapshotChunk{ Index: 0, Chunk: []byte{1, 1, 0}, }).Times(2).Return(&abci.ResponseApplySnapshotChunk{Result: abci.ResponseApplySnapshotChunk_ACCEPT}, nil) - conn.On("ApplySnapshotChunk", mock.Anything, abci.RequestApplySnapshotChunk{ + conn.On("ApplySnapshotChunk", mock.Anything, &abci.RequestApplySnapshotChunk{ Index: 1, Chunk: []byte{1, 1, 1}, }).Times(2).Return(&abci.ResponseApplySnapshotChunk{Result: abci.ResponseApplySnapshotChunk_ACCEPT}, nil) - conn.On("ApplySnapshotChunk", mock.Anything, abci.RequestApplySnapshotChunk{ + conn.On("ApplySnapshotChunk", mock.Anything, &abci.RequestApplySnapshotChunk{ Index: 2, Chunk: []byte{1, 1, 2}, }).Once().Return(&abci.ResponseApplySnapshotChunk{Result: abci.ResponseApplySnapshotChunk_ACCEPT}, nil) - conn.On("Info", mock.Anything, proxy.RequestInfo).Return(&abci.ResponseInfo{ + conn.On("Info", mock.Anything, &proxy.RequestInfo).Return(&abci.ResponseInfo{ AppVersion: testAppVersion, LastBlockHeight: 1, LastBlockAppHash: []byte("app_hash"), @@ -247,7 +247,7 @@ func TestSyncer_SyncAny_abort(t *testing.T) { _, err := rts.syncer.AddSnapshot(peerID, s) require.NoError(t, err) - rts.conn.On("OfferSnapshot", mock.Anything, abci.RequestOfferSnapshot{ + rts.conn.On("OfferSnapshot", mock.Anything, &abci.RequestOfferSnapshot{ Snapshot: toABCI(s), AppHash: []byte("app_hash"), }).Once().Return(&abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_ABORT}, nil) @@ -281,15 +281,15 @@ func TestSyncer_SyncAny_reject(t *testing.T) { _, err = rts.syncer.AddSnapshot(peerID, s11) require.NoError(t, err) - rts.conn.On("OfferSnapshot", mock.Anything, abci.RequestOfferSnapshot{ + rts.conn.On("OfferSnapshot", mock.Anything, &abci.RequestOfferSnapshot{ Snapshot: toABCI(s22), AppHash: []byte("app_hash"), }).Once().Return(&abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_REJECT}, nil) - rts.conn.On("OfferSnapshot", mock.Anything, abci.RequestOfferSnapshot{ + rts.conn.On("OfferSnapshot", mock.Anything, &abci.RequestOfferSnapshot{ Snapshot: toABCI(s12), AppHash: []byte("app_hash"), }).Once().Return(&abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_REJECT}, nil) - rts.conn.On("OfferSnapshot", mock.Anything, abci.RequestOfferSnapshot{ + rts.conn.On("OfferSnapshot", mock.Anything, &abci.RequestOfferSnapshot{ Snapshot: toABCI(s11), AppHash: []byte("app_hash"), }).Once().Return(&abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_REJECT}, nil) @@ -323,11 +323,11 @@ func TestSyncer_SyncAny_reject_format(t *testing.T) { _, err = rts.syncer.AddSnapshot(peerID, s11) require.NoError(t, err) - rts.conn.On("OfferSnapshot", mock.Anything, abci.RequestOfferSnapshot{ + rts.conn.On("OfferSnapshot", mock.Anything, &abci.RequestOfferSnapshot{ Snapshot: toABCI(s22), AppHash: []byte("app_hash"), }).Once().Return(&abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_REJECT_FORMAT}, nil) - rts.conn.On("OfferSnapshot", mock.Anything, abci.RequestOfferSnapshot{ + rts.conn.On("OfferSnapshot", mock.Anything, &abci.RequestOfferSnapshot{ Snapshot: toABCI(s11), AppHash: []byte("app_hash"), }).Once().Return(&abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_ABORT}, nil) @@ -372,11 +372,11 @@ func TestSyncer_SyncAny_reject_sender(t *testing.T) { _, err = rts.syncer.AddSnapshot(peerCID, sbc) require.NoError(t, err) - rts.conn.On("OfferSnapshot", mock.Anything, abci.RequestOfferSnapshot{ + rts.conn.On("OfferSnapshot", mock.Anything, &abci.RequestOfferSnapshot{ Snapshot: toABCI(sbc), AppHash: []byte("app_hash"), }).Once().Return(&abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_REJECT_SENDER}, nil) - rts.conn.On("OfferSnapshot", mock.Anything, abci.RequestOfferSnapshot{ + rts.conn.On("OfferSnapshot", mock.Anything, &abci.RequestOfferSnapshot{ Snapshot: toABCI(sa), AppHash: []byte("app_hash"), }).Once().Return(&abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_REJECT}, nil) @@ -402,7 +402,7 @@ func TestSyncer_SyncAny_abciError(t *testing.T) { _, err := rts.syncer.AddSnapshot(peerID, s) require.NoError(t, err) - rts.conn.On("OfferSnapshot", mock.Anything, abci.RequestOfferSnapshot{ + rts.conn.On("OfferSnapshot", mock.Anything, &abci.RequestOfferSnapshot{ Snapshot: toABCI(s), AppHash: []byte("app_hash"), }).Once().Return(nil, errBoom) @@ -445,7 +445,7 @@ func TestSyncer_offerSnapshot(t *testing.T) { rts := setup(ctx, t, nil, stateProvider, 2) s := &snapshot{Height: 1, Format: 1, Chunks: 3, Hash: []byte{1, 2, 3}, trustedAppHash: []byte("app_hash")} - rts.conn.On("OfferSnapshot", mock.Anything, abci.RequestOfferSnapshot{ + rts.conn.On("OfferSnapshot", mock.Anything, &abci.RequestOfferSnapshot{ Snapshot: toABCI(s), AppHash: []byte("app_hash"), }).Return(&abci.ResponseOfferSnapshot{Result: tc.result}, tc.err) @@ -506,11 +506,11 @@ func TestSyncer_applyChunks_Results(t *testing.T) { _, err = chunks.Add(&chunk{Height: 1, Format: 1, Index: 0, Chunk: body}) require.NoError(t, err) - rts.conn.On("ApplySnapshotChunk", mock.Anything, abci.RequestApplySnapshotChunk{ + rts.conn.On("ApplySnapshotChunk", mock.Anything, &abci.RequestApplySnapshotChunk{ Index: 0, Chunk: body, }).Once().Return(&abci.ResponseApplySnapshotChunk{Result: tc.result}, tc.err) if tc.result == abci.ResponseApplySnapshotChunk_RETRY { - rts.conn.On("ApplySnapshotChunk", mock.Anything, abci.RequestApplySnapshotChunk{ + rts.conn.On("ApplySnapshotChunk", mock.Anything, &abci.RequestApplySnapshotChunk{ Index: 0, Chunk: body, }).Once().Return(&abci.ResponseApplySnapshotChunk{ Result: abci.ResponseApplySnapshotChunk_ACCEPT}, nil) @@ -573,13 +573,13 @@ func TestSyncer_applyChunks_RefetchChunks(t *testing.T) { require.NoError(t, err) // The first two chunks are accepted, before the last one asks for 1 to be refetched - rts.conn.On("ApplySnapshotChunk", mock.Anything, abci.RequestApplySnapshotChunk{ + rts.conn.On("ApplySnapshotChunk", mock.Anything, &abci.RequestApplySnapshotChunk{ Index: 0, Chunk: []byte{0}, }).Once().Return(&abci.ResponseApplySnapshotChunk{Result: abci.ResponseApplySnapshotChunk_ACCEPT}, nil) - rts.conn.On("ApplySnapshotChunk", mock.Anything, abci.RequestApplySnapshotChunk{ + rts.conn.On("ApplySnapshotChunk", mock.Anything, &abci.RequestApplySnapshotChunk{ Index: 1, Chunk: []byte{1}, }).Once().Return(&abci.ResponseApplySnapshotChunk{Result: abci.ResponseApplySnapshotChunk_ACCEPT}, nil) - rts.conn.On("ApplySnapshotChunk", mock.Anything, abci.RequestApplySnapshotChunk{ + rts.conn.On("ApplySnapshotChunk", mock.Anything, &abci.RequestApplySnapshotChunk{ Index: 2, Chunk: []byte{2}, }).Once().Return(&abci.ResponseApplySnapshotChunk{ Result: tc.result, @@ -673,13 +673,13 @@ func TestSyncer_applyChunks_RejectSenders(t *testing.T) { require.NoError(t, err) // The first two chunks are accepted, before the last one asks for b sender to be rejected - rts.conn.On("ApplySnapshotChunk", mock.Anything, abci.RequestApplySnapshotChunk{ + rts.conn.On("ApplySnapshotChunk", mock.Anything, &abci.RequestApplySnapshotChunk{ Index: 0, Chunk: []byte{0}, Sender: "aa", }).Once().Return(&abci.ResponseApplySnapshotChunk{Result: abci.ResponseApplySnapshotChunk_ACCEPT}, nil) - rts.conn.On("ApplySnapshotChunk", mock.Anything, abci.RequestApplySnapshotChunk{ + rts.conn.On("ApplySnapshotChunk", mock.Anything, &abci.RequestApplySnapshotChunk{ Index: 1, Chunk: []byte{1}, Sender: "bb", }).Once().Return(&abci.ResponseApplySnapshotChunk{Result: abci.ResponseApplySnapshotChunk_ACCEPT}, nil) - rts.conn.On("ApplySnapshotChunk", mock.Anything, abci.RequestApplySnapshotChunk{ + rts.conn.On("ApplySnapshotChunk", mock.Anything, &abci.RequestApplySnapshotChunk{ Index: 2, Chunk: []byte{2}, Sender: "cc", }).Once().Return(&abci.ResponseApplySnapshotChunk{ Result: tc.result, @@ -688,7 +688,7 @@ func TestSyncer_applyChunks_RejectSenders(t *testing.T) { // On retry, the last chunk will be tried again, so we just accept it then. if tc.result == abci.ResponseApplySnapshotChunk_RETRY { - rts.conn.On("ApplySnapshotChunk", mock.Anything, abci.RequestApplySnapshotChunk{ + rts.conn.On("ApplySnapshotChunk", mock.Anything, &abci.RequestApplySnapshotChunk{ Index: 2, Chunk: []byte{2}, Sender: "cc", }).Once().Return(&abci.ResponseApplySnapshotChunk{Result: abci.ResponseApplySnapshotChunk_ACCEPT}, nil) } @@ -761,7 +761,7 @@ func TestSyncer_verifyApp(t *testing.T) { rts := setup(ctx, t, nil, nil, 2) - rts.conn.On("Info", mock.Anything, proxy.RequestInfo).Return(tc.response, tc.err) + rts.conn.On("Info", mock.Anything, &proxy.RequestInfo).Return(tc.response, tc.err) err := rts.syncer.verifyApp(ctx, s, appVersion) unwrapped := errors.Unwrap(err) if unwrapped != nil { diff --git a/node/node.go b/node/node.go index c3aeaccf1..5c63a3253 100644 --- a/node/node.go +++ b/node/node.go @@ -720,7 +720,7 @@ func getRouterConfig(conf *config.Config, appClient abciclient.Client) p2p.Route if conf.FilterPeers && appClient != nil { opts.FilterPeerByID = func(ctx context.Context, id types.NodeID) error { - res, err := appClient.Query(ctx, abci.RequestQuery{ + res, err := appClient.Query(ctx, &abci.RequestQuery{ Path: fmt.Sprintf("/p2p/filter/id/%s", id), }) if err != nil { @@ -734,7 +734,7 @@ func getRouterConfig(conf *config.Config, appClient abciclient.Client) p2p.Route } opts.FilterPeerByIP = func(ctx context.Context, ip net.IP, port uint16) error { - res, err := appClient.Query(ctx, abci.RequestQuery{ + res, err := appClient.Query(ctx, &abci.RequestQuery{ Path: fmt.Sprintf("/p2p/filter/addr/%s", net.JoinHostPort(ip.String(), strconv.Itoa(int(port)))), }) if err != nil { diff --git a/rpc/client/mock/abci.go b/rpc/client/mock/abci.go index ba1c2b676..a6aebdb14 100644 --- a/rpc/client/mock/abci.go +++ b/rpc/client/mock/abci.go @@ -25,7 +25,7 @@ var ( ) func (a ABCIApp) ABCIInfo(ctx context.Context) (*coretypes.ResultABCIInfo, error) { - res, err := a.App.Info(ctx, proxy.RequestInfo) + res, err := a.App.Info(ctx, &proxy.RequestInfo) if err != nil { return nil, err } @@ -38,7 +38,7 @@ func (a ABCIApp) ABCIQuery(ctx context.Context, path string, data bytes.HexBytes } func (a ABCIApp) ABCIQueryWithOptions(ctx context.Context, path string, data bytes.HexBytes, opts client.ABCIQueryOptions) (*coretypes.ResultABCIQuery, error) { - q, err := a.App.Query(ctx, abci.RequestQuery{ + q, err := a.App.Query(ctx, &abci.RequestQuery{ Data: data, Path: path, Height: opts.Height, @@ -55,7 +55,7 @@ func (a ABCIApp) ABCIQueryWithOptions(ctx context.Context, path string, data byt // this function does not actually wait for a commit. // TODO: Make it wait for a commit and set res.Height appropriately. func (a ABCIApp) BroadcastTxCommit(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTxCommit, error) { - resp, err := a.App.CheckTx(ctx, abci.RequestCheckTx{Tx: tx}) + resp, err := a.App.CheckTx(ctx, &abci.RequestCheckTx{Tx: tx}) if err != nil { return nil, err } @@ -65,7 +65,7 @@ func (a ABCIApp) BroadcastTxCommit(ctx context.Context, tx types.Tx) (*coretypes return res, nil } - fb, err := a.App.FinalizeBlock(ctx, abci.RequestFinalizeBlock{Txs: [][]byte{tx}}) + fb, err := a.App.FinalizeBlock(ctx, &abci.RequestFinalizeBlock{Txs: [][]byte{tx}}) if err != nil { return nil, err } @@ -76,14 +76,14 @@ func (a ABCIApp) BroadcastTxCommit(ctx context.Context, tx types.Tx) (*coretypes } func (a ABCIApp) BroadcastTxAsync(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTx, error) { - c, err := a.App.CheckTx(ctx, abci.RequestCheckTx{Tx: tx}) + c, err := a.App.CheckTx(ctx, &abci.RequestCheckTx{Tx: tx}) if err != nil { return nil, err } // and this gets written in a background thread... if !c.IsErr() { - go func() { _, _ = a.App.FinalizeBlock(ctx, abci.RequestFinalizeBlock{Txs: [][]byte{tx}}) }() + go func() { _, _ = a.App.FinalizeBlock(ctx, &abci.RequestFinalizeBlock{Txs: [][]byte{tx}}) }() } return &coretypes.ResultBroadcastTx{ Code: c.Code, @@ -95,14 +95,14 @@ func (a ABCIApp) BroadcastTxAsync(ctx context.Context, tx types.Tx) (*coretypes. } func (a ABCIApp) BroadcastTxSync(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTx, error) { - c, err := a.App.CheckTx(ctx, abci.RequestCheckTx{Tx: tx}) + c, err := a.App.CheckTx(ctx, &abci.RequestCheckTx{Tx: tx}) if err != nil { return nil, err } // and this gets written in a background thread... if !c.IsErr() { - go func() { _, _ = a.App.FinalizeBlock(ctx, abci.RequestFinalizeBlock{Txs: [][]byte{tx}}) }() + go func() { _, _ = a.App.FinalizeBlock(ctx, &abci.RequestFinalizeBlock{Txs: [][]byte{tx}}) }() } return &coretypes.ResultBroadcastTx{ Code: c.Code, diff --git a/test/e2e/app/app.go b/test/e2e/app/app.go index a67c672d2..64ccd2e28 100644 --- a/test/e2e/app/app.go +++ b/test/e2e/app/app.go @@ -114,7 +114,7 @@ func NewApplication(cfg *Config) (*Application, error) { } // Info implements ABCI. -func (app *Application) Info(_ context.Context, req abci.RequestInfo) (*abci.ResponseInfo, error) { +func (app *Application) Info(_ context.Context, req *abci.RequestInfo) (*abci.ResponseInfo, error) { app.mu.Lock() defer app.mu.Unlock() @@ -127,7 +127,7 @@ func (app *Application) Info(_ context.Context, req abci.RequestInfo) (*abci.Res } // Info implements ABCI. -func (app *Application) InitChain(_ context.Context, req abci.RequestInitChain) (*abci.ResponseInitChain, error) { +func (app *Application) InitChain(_ context.Context, req *abci.RequestInitChain) (*abci.ResponseInitChain, error) { app.mu.Lock() defer app.mu.Unlock() @@ -154,7 +154,7 @@ func (app *Application) InitChain(_ context.Context, req abci.RequestInitChain) } // CheckTx implements ABCI. -func (app *Application) CheckTx(_ context.Context, req abci.RequestCheckTx) (*abci.ResponseCheckTx, error) { +func (app *Application) CheckTx(_ context.Context, req *abci.RequestCheckTx) (*abci.ResponseCheckTx, error) { app.mu.Lock() defer app.mu.Unlock() @@ -169,7 +169,7 @@ func (app *Application) CheckTx(_ context.Context, req abci.RequestCheckTx) (*ab } // FinalizeBlock implements ABCI. -func (app *Application) FinalizeBlock(_ context.Context, req abci.RequestFinalizeBlock) (*abci.ResponseFinalizeBlock, error) { +func (app *Application) FinalizeBlock(_ context.Context, req *abci.RequestFinalizeBlock) (*abci.ResponseFinalizeBlock, error) { var txs = make([]*abci.ExecTxResult, len(req.Txs)) app.mu.Lock() @@ -242,7 +242,7 @@ func (app *Application) Commit(_ context.Context) (*abci.ResponseCommit, error) } // Query implements ABCI. -func (app *Application) Query(_ context.Context, req abci.RequestQuery) (*abci.ResponseQuery, error) { +func (app *Application) Query(_ context.Context, req *abci.RequestQuery) (*abci.ResponseQuery, error) { app.mu.Lock() defer app.mu.Unlock() @@ -254,7 +254,7 @@ func (app *Application) Query(_ context.Context, req abci.RequestQuery) (*abci.R } // ListSnapshots implements ABCI. -func (app *Application) ListSnapshots(_ context.Context, req abci.RequestListSnapshots) (*abci.ResponseListSnapshots, error) { +func (app *Application) ListSnapshots(_ context.Context, req *abci.RequestListSnapshots) (*abci.ResponseListSnapshots, error) { app.mu.Lock() defer app.mu.Unlock() @@ -266,7 +266,7 @@ func (app *Application) ListSnapshots(_ context.Context, req abci.RequestListSna } // LoadSnapshotChunk implements ABCI. -func (app *Application) LoadSnapshotChunk(_ context.Context, req abci.RequestLoadSnapshotChunk) (*abci.ResponseLoadSnapshotChunk, error) { +func (app *Application) LoadSnapshotChunk(_ context.Context, req *abci.RequestLoadSnapshotChunk) (*abci.ResponseLoadSnapshotChunk, error) { app.mu.Lock() defer app.mu.Unlock() @@ -278,7 +278,7 @@ func (app *Application) LoadSnapshotChunk(_ context.Context, req abci.RequestLoa } // OfferSnapshot implements ABCI. -func (app *Application) OfferSnapshot(_ context.Context, req abci.RequestOfferSnapshot) (*abci.ResponseOfferSnapshot, error) { +func (app *Application) OfferSnapshot(_ context.Context, req *abci.RequestOfferSnapshot) (*abci.ResponseOfferSnapshot, error) { app.mu.Lock() defer app.mu.Unlock() @@ -291,7 +291,7 @@ func (app *Application) OfferSnapshot(_ context.Context, req abci.RequestOfferSn } // ApplySnapshotChunk implements ABCI. -func (app *Application) ApplySnapshotChunk(_ context.Context, req abci.RequestApplySnapshotChunk) (*abci.ResponseApplySnapshotChunk, error) { +func (app *Application) ApplySnapshotChunk(_ context.Context, req *abci.RequestApplySnapshotChunk) (*abci.ResponseApplySnapshotChunk, error) { app.mu.Lock() defer app.mu.Unlock() @@ -324,7 +324,7 @@ func (app *Application) ApplySnapshotChunk(_ context.Context, req abci.RequestAp // If adding a special vote extension-generated transaction would cause the // total number of transaction bytes to exceed `req.MaxTxBytes`, we will not // append our special vote extension transaction. -func (app *Application) PrepareProposal(_ context.Context, req abci.RequestPrepareProposal) (*abci.ResponsePrepareProposal, error) { +func (app *Application) PrepareProposal(_ context.Context, req *abci.RequestPrepareProposal) (*abci.ResponsePrepareProposal, error) { var sum int64 var extCount int for _, vote := range req.LocalLastCommit.Votes { @@ -400,7 +400,7 @@ func (app *Application) PrepareProposal(_ context.Context, req abci.RequestPrepa // ProcessProposal implements part of the Application interface. // It accepts any proposal that does not contain a malformed transaction. -func (app *Application) ProcessProposal(_ context.Context, req abci.RequestProcessProposal) (*abci.ResponseProcessProposal, error) { +func (app *Application) ProcessProposal(_ context.Context, req *abci.RequestProcessProposal) (*abci.ResponseProcessProposal, error) { for _, tx := range req.Txs { k, v, err := parseTx(tx) if err != nil { @@ -426,7 +426,7 @@ func (app *Application) ProcessProposal(_ context.Context, req abci.RequestProce // a new transaction will be proposed that updates a special value in the // key/value store ("extensionSum") with the sum of all of the numbers collected // from the vote extensions. -func (app *Application) ExtendVote(_ context.Context, req abci.RequestExtendVote) (*abci.ResponseExtendVote, error) { +func (app *Application) ExtendVote(_ context.Context, req *abci.RequestExtendVote) (*abci.ResponseExtendVote, error) { // We ignore any requests for vote extensions that don't match our expected // next height. if req.Height != int64(app.state.Height)+1 { @@ -452,7 +452,7 @@ func (app *Application) ExtendVote(_ context.Context, req abci.RequestExtendVote // VerifyVoteExtension simply validates vote extensions from other validators // without doing anything about them. In this case, it just makes sure that the // vote extension is a well-formed integer value. -func (app *Application) VerifyVoteExtension(_ context.Context, req abci.RequestVerifyVoteExtension) (*abci.ResponseVerifyVoteExtension, error) { +func (app *Application) VerifyVoteExtension(_ context.Context, req *abci.RequestVerifyVoteExtension) (*abci.ResponseVerifyVoteExtension, error) { // We allow vote extensions to be optional if len(req.VoteExtension) == 0 { return &abci.ResponseVerifyVoteExtension{ From 5b38bc17b1c33648110210d05ac1a19b1cbe8df7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Apr 2022 11:50:11 +0000 Subject: [PATCH 13/35] build(deps): Bump bufbuild/buf-setup-action from 1.3.1 to 1.4.0 (#8405) Bumps [bufbuild/buf-setup-action](https://github.com/bufbuild/buf-setup-action) from 1.3.1 to 1.4.0.
Release notes

Sourced from bufbuild/buf-setup-action's releases.

v1.4.0

  • Set the default buf version to v1.4.0
Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=bufbuild/buf-setup-action&package-manager=github_actions&previous-version=1.3.1&new-version=1.4.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- .github/workflows/proto-lint.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/proto-lint.yml b/.github/workflows/proto-lint.yml index 8d0da6798..b1fbeab9d 100644 --- a/.github/workflows/proto-lint.yml +++ b/.github/workflows/proto-lint.yml @@ -15,7 +15,7 @@ jobs: timeout-minutes: 5 steps: - uses: actions/checkout@v3 - - uses: bufbuild/buf-setup-action@v1.3.1 + - uses: bufbuild/buf-setup-action@v1.4.0 - uses: bufbuild/buf-lint-action@v1 with: input: 'proto' From a4190208a35100064d63d66cbcdea79adeceb3f0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Apr 2022 11:52:01 +0000 Subject: [PATCH 14/35] build(deps): Bump codecov/codecov-action from 3.0.0 to 3.1.0 (#8406) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 3.0.0 to 3.1.0.
Release notes

Sourced from codecov/codecov-action's releases.

v3.1.0

3.1.0

Features

  • #699 Incorporate xcode arguments for the Codecov uploader

Dependencies

  • #694 build(deps-dev): bump @​vercel/ncc from 0.33.3 to 0.33.4
  • #696 build(deps-dev): bump @​types/node from 17.0.23 to 17.0.25
  • #698 build(deps-dev): bump jest-junit from 13.0.0 to 13.2.0
Changelog

Sourced from codecov/codecov-action's changelog.

3.1.0

Features

  • #699 Incorporate xcode arguments for the Codecov uploader

Dependencies

  • #694 build(deps-dev): bump @​vercel/ncc from 0.33.3 to 0.33.4
  • #696 build(deps-dev): bump @​types/node from 17.0.23 to 17.0.25
  • #698 build(deps-dev): bump jest-junit from 13.0.0 to 13.2.0
Commits
  • 81cd2dc Merge pull request #699 from codecov/feat-xcode
  • a03184e feat: add xcode support
  • 6a6a9ae Merge pull request #694 from codecov/dependabot/npm_and_yarn/vercel/ncc-0.33.4
  • 92a872a Merge pull request #696 from codecov/dependabot/npm_and_yarn/types/node-17.0.25
  • 43a9c18 Merge pull request #698 from codecov/dependabot/npm_and_yarn/jest-junit-13.2.0
  • 13ce822 Merge pull request #690 from codecov/ci-v3
  • 4d6dbaa build(deps-dev): bump jest-junit from 13.0.0 to 13.2.0
  • 98f0f19 build(deps-dev): bump @​types/node from 17.0.23 to 17.0.25
  • d3021d9 build(deps-dev): bump @​vercel/ncc from 0.33.3 to 0.33.4
  • 2c83f35 Update makefile to v3
  • See full diff in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=codecov/codecov-action&package-manager=github_actions&previous-version=3.0.0&new-version=3.1.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 7ee964d21..6ce8a4d34 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -69,7 +69,7 @@ jobs: - run: | cat ./*profile.out | grep -v "mode: set" >> coverage.txt if: env.GIT_DIFF - - uses: codecov/codecov-action@v3.0.0 + - uses: codecov/codecov-action@v3.1.0 with: file: ./coverage.txt if: env.GIT_DIFF From 701eff89682bfdd270c0d94276ac26f1744a277a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Apr 2022 12:04:57 +0000 Subject: [PATCH 15/35] build(deps): Bump google.golang.org/grpc from 1.45.0 to 1.46.0 (#8408) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.45.0 to 1.46.0.
Release notes

Sourced from google.golang.org/grpc's releases.

Release 1.46.0

New Features

  • server: Support setting TCP_USER_TIMEOUT on grpc.Server connections using keepalive.ServerParameters.Time (#5219)
  • client: perform graceful switching of LB policies in the ClientConn by default (#5285)
  • all: improve logging by including channelz identifier in log messages (#5192)

API Changes

  • grpc: delete WithBalancerName() API, deprecated over 4 years ago in #1697 (#5232)
  • balancer: change BuildOptions.ChannelzParentID to an opaque identifier instead of int (#5192)
    • Note: the balancer package is labeled as EXPERIMENTAL, and we don't believe users were using this field.

Behavior Changes

  • client: change connectivity state to TransientFailure in pick_first LB policy when all addresses are removed (#5274)
    • This is a minor change that brings grpc-go's behavior in line with the intended behavior and how C and Java behave.
  • metadata: add client-side validation of HTTP-invalid metadata before attempting to send (#4886)

Bug Fixes

  • metadata: make a copy of the value slices in FromContext() functions so that modifications won't be made to the original copy (#5267)
  • client: handle invalid service configs by applying the default, if applicable (#5238)
  • xds: the xds client will now apply a 1 second backoff before recreating ADS or LRS streams (#5280)

Dependencies

Commits
  • e8d06c5 Change version to 1.46.0 (#5296)
  • efbd542 gcp/observability: correctly test this module in presubmit tests (#5300) (#5307)
  • 4467a29 gcp/observability: implement logging via binarylog (#5196)
  • 18fdf54 cmd/protoc-gen-go-grpc: allow hooks to modify client structs and service hand...
  • 337b815 interop: build client without timeout; add logs to help debug failures (#5294)
  • e583b19 xds: Add RLS in xDS e2e test (#5281)
  • 0066bf6 grpc: perform graceful switching of LB policies in the ClientConn by defaul...
  • 3cccf6a xdsclient: always backoff between new streams even after successful stream (#...
  • 4e78093 xds: ignore routes with unsupported cluster specifiers (#5269)
  • 99aae34 cluster manager: Add Graceful Switch functionality to Cluster Manager (#5265)
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=google.golang.org/grpc&package-manager=go_modules&previous-version=1.45.0&new-version=1.46.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- go.mod | 2 +- go.sum | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index cb6e322d2..33f5e5a6d 100644 --- a/go.mod +++ b/go.mod @@ -32,7 +32,7 @@ require ( golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 golang.org/x/net v0.0.0-20220412020605-290c469a71a5 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c - google.golang.org/grpc v1.45.0 + google.golang.org/grpc v1.46.0 gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b // indirect pgregory.net/rapid v0.4.7 ) diff --git a/go.sum b/go.sum index 9a11ff196..1609c9a40 100644 --- a/go.sum +++ b/go.sum @@ -275,6 +275,7 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.m github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/go-control-plane v0.10.1/go.mod h1:AY7fTTXNdv/aJ2O5jwpxAPOWUZ7hQAEvzN5Pf27BkQQ= +github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.0.14/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v0.6.2/go.mod h1:2t7qjJNvHPx8IjnBOzl9E9/baC+qXE/TeeyBRzgJDws= @@ -1698,8 +1699,9 @@ google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9K google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.45.0 h1:NEpgUqV3Z+ZjkqMsxMg11IaDrXY4RY6CQukSGK0uI1M= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= +google.golang.org/grpc v1.46.0 h1:oCjezcn6g6A75TGoKYBPgKmVBLexhYLM6MebdrPApP8= +google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= From 02c1c8ecb45c06c38753cde57e7573bc69dcdfe9 Mon Sep 17 00:00:00 2001 From: Sam Kleinman Date: Mon, 25 Apr 2022 12:08:22 -0400 Subject: [PATCH 16/35] config: minor template infrastructure (#8411) --- config/toml.go | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/config/toml.go b/config/toml.go index 7f49249e9..578718ca5 100644 --- a/config/toml.go +++ b/config/toml.go @@ -12,8 +12,8 @@ import ( tmrand "github.com/tendermint/tendermint/libs/rand" ) -// DefaultDirPerm is the default permissions used when creating directories. -const DefaultDirPerm = 0700 +// defaultDirPerm is the default permissions used when creating directories. +const defaultDirPerm = 0700 var configTemplate *template.Template @@ -32,13 +32,13 @@ func init() { // EnsureRoot creates the root, config, and data directories if they don't exist, // and panics if it fails. func EnsureRoot(rootDir string) { - if err := tmos.EnsureDir(rootDir, DefaultDirPerm); err != nil { + if err := tmos.EnsureDir(rootDir, defaultDirPerm); err != nil { panic(err.Error()) } - if err := tmos.EnsureDir(filepath.Join(rootDir, defaultConfigDir), DefaultDirPerm); err != nil { + if err := tmos.EnsureDir(filepath.Join(rootDir, defaultConfigDir), defaultDirPerm); err != nil { panic(err.Error()) } - if err := tmos.EnsureDir(filepath.Join(rootDir, defaultDataDir), DefaultDirPerm); err != nil { + if err := tmos.EnsureDir(filepath.Join(rootDir, defaultDataDir), defaultDirPerm); err != nil { panic(err.Error()) } } @@ -566,10 +566,10 @@ func ResetTestRootWithChainID(dir, testName string, chainID string) (*Config, er return nil, err } // ensure config and data subdirs are created - if err := tmos.EnsureDir(filepath.Join(rootDir, defaultConfigDir), DefaultDirPerm); err != nil { + if err := tmos.EnsureDir(filepath.Join(rootDir, defaultConfigDir), defaultDirPerm); err != nil { return nil, err } - if err := tmos.EnsureDir(filepath.Join(rootDir, defaultDataDir), DefaultDirPerm); err != nil { + if err := tmos.EnsureDir(filepath.Join(rootDir, defaultDataDir), defaultDirPerm); err != nil { return nil, err } @@ -612,7 +612,7 @@ func writeFile(filePath string, contents []byte, mode os.FileMode) error { return nil } -var testGenesisFmt = `{ +const testGenesisFmt = `{ "genesis_time": "2018-10-10T08:20:13.695936996Z", "chain_id": "%s", "initial_height": "1", @@ -659,7 +659,7 @@ var testGenesisFmt = `{ "app_hash": "" }` -var testPrivValidatorKey = `{ +const testPrivValidatorKey = `{ "address": "A3258DCBF45DCA0DF052981870F2D1441A36D145", "pub_key": { "type": "tendermint/PubKeyEd25519", @@ -671,7 +671,7 @@ var testPrivValidatorKey = `{ } }` -var testPrivValidatorState = `{ +const testPrivValidatorState = `{ "height": "0", "round": 0, "step": 0 From e36052c80e6f96ff7b3bc1e1fb718e5fa28f5893 Mon Sep 17 00:00:00 2001 From: Sam Kleinman Date: Mon, 25 Apr 2022 12:35:59 -0400 Subject: [PATCH 17/35] crypto: remove unused code (#8412) --- crypto/ed25519/ed25519.go | 11 ++++---- crypto/example_test.go | 28 -------------------- crypto/hash.go | 11 -------- crypto/merkle/proof_value.go | 11 ++++---- crypto/random.go | 26 +++---------------- crypto/secp256k1/secp256k1.go | 10 +++++--- crypto/sr25519/batch.go | 3 ++- crypto/sr25519/privkey.go | 11 ++++---- crypto/tmhash/hash.go | 46 +++------------------------------ crypto/tmhash/hash_test.go | 48 ----------------------------------- crypto/version.go | 3 --- test/e2e/runner/evidence.go | 4 +-- types/params.go | 12 +++------ 13 files changed, 36 insertions(+), 188 deletions(-) delete mode 100644 crypto/example_test.go delete mode 100644 crypto/hash.go delete mode 100644 crypto/tmhash/hash_test.go delete mode 100644 crypto/version.go diff --git a/crypto/ed25519/ed25519.go b/crypto/ed25519/ed25519.go index ffd4a3ed1..7282e5c70 100644 --- a/crypto/ed25519/ed25519.go +++ b/crypto/ed25519/ed25519.go @@ -2,6 +2,8 @@ package ed25519 import ( "bytes" + "crypto/rand" + "crypto/sha256" "crypto/subtle" "errors" "fmt" @@ -124,7 +126,7 @@ func (privKey PrivKey) Type() string { // It uses OS randomness in conjunction with the current global random seed // in tendermint/libs/common to generate the private key. func GenPrivKey() PrivKey { - return genPrivKey(crypto.CReader()) + return genPrivKey(rand.Reader) } // genPrivKey generates a new ed25519 private key using the provided reader. @@ -142,9 +144,8 @@ func genPrivKey(rand io.Reader) PrivKey { // NOTE: secret should be the output of a KDF like bcrypt, // if it's derived from user input. func GenPrivKeyFromSecret(secret []byte) PrivKey { - seed := crypto.Sha256(secret) // Not Ripemd160 because we want 32 bytes. - - return PrivKey(ed25519.NewKeyFromSeed(seed)) + seed := sha256.Sum256(secret) + return PrivKey(ed25519.NewKeyFromSeed(seed[:])) } //------------------------------------- @@ -229,5 +230,5 @@ func (b *BatchVerifier) Add(key crypto.PubKey, msg, signature []byte) error { } func (b *BatchVerifier) Verify() (bool, []bool) { - return b.BatchVerifier.Verify(crypto.CReader()) + return b.BatchVerifier.Verify(rand.Reader) } diff --git a/crypto/example_test.go b/crypto/example_test.go deleted file mode 100644 index f1d0013d4..000000000 --- a/crypto/example_test.go +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2017 Tendermint. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package crypto_test - -import ( - "fmt" - - "github.com/tendermint/tendermint/crypto" -) - -func ExampleSha256() { - sum := crypto.Sha256([]byte("This is Tendermint")) - fmt.Printf("%x\n", sum) - // Output: - // f91afb642f3d1c87c17eb01aae5cb65c242dfdbe7cf1066cc260f4ce5d33b94e -} diff --git a/crypto/hash.go b/crypto/hash.go deleted file mode 100644 index e1d22523f..000000000 --- a/crypto/hash.go +++ /dev/null @@ -1,11 +0,0 @@ -package crypto - -import ( - "crypto/sha256" -) - -func Sha256(bytes []byte) []byte { - hasher := sha256.New() - hasher.Write(bytes) - return hasher.Sum(nil) -} diff --git a/crypto/merkle/proof_value.go b/crypto/merkle/proof_value.go index 842dc8201..0f4f2eb3d 100644 --- a/crypto/merkle/proof_value.go +++ b/crypto/merkle/proof_value.go @@ -2,9 +2,9 @@ package merkle import ( "bytes" + "crypto/sha256" "fmt" - "github.com/tendermint/tendermint/crypto/tmhash" tmcrypto "github.com/tendermint/tendermint/proto/tendermint/crypto" ) @@ -79,14 +79,13 @@ func (op ValueOp) Run(args [][]byte) ([][]byte, error) { return nil, fmt.Errorf("expected 1 arg, got %v", len(args)) } value := args[0] - hasher := tmhash.New() - hasher.Write(value) - vhash := hasher.Sum(nil) + + vhash := sha256.Sum256(value) bz := new(bytes.Buffer) // Wrap to hash the KVPair. - encodeByteSlice(bz, op.key) //nolint: errcheck // does not error - encodeByteSlice(bz, vhash) //nolint: errcheck // does not error + encodeByteSlice(bz, op.key) //nolint: errcheck // does not error + encodeByteSlice(bz, vhash[:]) //nolint: errcheck // does not error kvhash := leafHash(bz.Bytes()) if !bytes.Equal(kvhash, op.Proof.LeafHash) { diff --git a/crypto/random.go b/crypto/random.go index 275fb1044..d3e66801c 100644 --- a/crypto/random.go +++ b/crypto/random.go @@ -1,35 +1,15 @@ package crypto import ( - crand "crypto/rand" - "encoding/hex" - "io" + "crypto/rand" ) // This only uses the OS's randomness -func randBytes(numBytes int) []byte { +func CRandBytes(numBytes int) []byte { b := make([]byte, numBytes) - _, err := crand.Read(b) + _, err := rand.Read(b) if err != nil { panic(err) } return b } - -// This only uses the OS's randomness -func CRandBytes(numBytes int) []byte { - return randBytes(numBytes) -} - -// CRandHex returns a hex encoded string that's floor(numDigits/2) * 2 long. -// -// Note: CRandHex(24) gives 96 bits of randomness that -// are usually strong enough for most purposes. -func CRandHex(numDigits int) string { - return hex.EncodeToString(CRandBytes(numDigits / 2)) -} - -// Returns a crand.Reader. -func CReader() io.Reader { - return crand.Reader -} diff --git a/crypto/secp256k1/secp256k1.go b/crypto/secp256k1/secp256k1.go index 7892cfbb1..d0626456c 100644 --- a/crypto/secp256k1/secp256k1.go +++ b/crypto/secp256k1/secp256k1.go @@ -2,6 +2,7 @@ package secp256k1 import ( "bytes" + "crypto/rand" "crypto/sha256" "crypto/subtle" "fmt" @@ -70,7 +71,7 @@ func (privKey PrivKey) Type() string { // GenPrivKey generates a new ECDSA private key on curve secp256k1 private key. // It uses OS randomness to generate the private key. func GenPrivKey() PrivKey { - return genPrivKey(crypto.CReader()) + return genPrivKey(rand.Reader) } // genPrivKey generates a new secp256k1 private key using the provided reader. @@ -190,8 +191,8 @@ var secp256k1halfN = new(big.Int).Rsh(secp256k1.S256().N, 1) // The returned signature will be of the form R || S (in lower-S form). func (privKey PrivKey) Sign(msg []byte) ([]byte, error) { priv, _ := secp256k1.PrivKeyFromBytes(secp256k1.S256(), privKey) - - sig, err := priv.Sign(crypto.Sha256(msg)) + seed := sha256.Sum256(msg) + sig, err := priv.Sign(seed[:]) if err != nil { return nil, err } @@ -220,7 +221,8 @@ func (pubKey PubKey) VerifySignature(msg []byte, sigStr []byte) bool { return false } - return signature.Verify(crypto.Sha256(msg), pub) + seed := sha256.Sum256(msg) + return signature.Verify(seed[:], pub) } // Read Signature struct from R || S. Caller needs to ensure diff --git a/crypto/sr25519/batch.go b/crypto/sr25519/batch.go index 462728598..3e959fbbf 100644 --- a/crypto/sr25519/batch.go +++ b/crypto/sr25519/batch.go @@ -1,6 +1,7 @@ package sr25519 import ( + "crypto/rand" "fmt" "github.com/oasisprotocol/curve25519-voi/primitives/sr25519" @@ -42,5 +43,5 @@ func (b *BatchVerifier) Add(key crypto.PubKey, msg, signature []byte) error { } func (b *BatchVerifier) Verify() (bool, []bool) { - return b.BatchVerifier.Verify(crypto.CReader()) + return b.BatchVerifier.Verify(rand.Reader) } diff --git a/crypto/sr25519/privkey.go b/crypto/sr25519/privkey.go index 4e9cc995f..c8da94d5d 100644 --- a/crypto/sr25519/privkey.go +++ b/crypto/sr25519/privkey.go @@ -1,6 +1,8 @@ package sr25519 import ( + "crypto/rand" + "crypto/sha256" "encoding/json" "fmt" "io" @@ -48,7 +50,7 @@ func (privKey PrivKey) Sign(msg []byte) ([]byte, error) { st := signingCtx.NewTranscriptBytes(msg) - sig, err := privKey.kp.Sign(crypto.CReader(), st) + sig, err := privKey.kp.Sign(rand.Reader, st) if err != nil { return nil, fmt.Errorf("sr25519: failed to sign message: %w", err) } @@ -132,7 +134,7 @@ func (privKey *PrivKey) UnmarshalJSON(data []byte) error { // It uses OS randomness in conjunction with the current global random seed // in tendermint/libs/common to generate the private key. func GenPrivKey() PrivKey { - return genPrivKey(crypto.CReader()) + return genPrivKey(rand.Reader) } func genPrivKey(rng io.Reader) PrivKey { @@ -154,10 +156,9 @@ func genPrivKey(rng io.Reader) PrivKey { // NOTE: secret should be the output of a KDF like bcrypt, // if it's derived from user input. func GenPrivKeyFromSecret(secret []byte) PrivKey { - seed := crypto.Sha256(secret) // Not Ripemd160 because we want 32 bytes. - + seed := sha256.Sum256(secret) var privKey PrivKey - if err := privKey.msk.UnmarshalBinary(seed); err != nil { + if err := privKey.msk.UnmarshalBinary(seed[:]); err != nil { panic("sr25519: failed to deserialize MiniSecretKey: " + err.Error()) } diff --git a/crypto/tmhash/hash.go b/crypto/tmhash/hash.go index f9b958242..91e55bca4 100644 --- a/crypto/tmhash/hash.go +++ b/crypto/tmhash/hash.go @@ -2,19 +2,14 @@ package tmhash import ( "crypto/sha256" - "hash" ) const ( - Size = sha256.Size - BlockSize = sha256.BlockSize + Size = sha256.Size + BlockSize = sha256.BlockSize + TruncatedSize = 20 ) -// New returns a new hash.Hash. -func New() hash.Hash { - return sha256.New() -} - // Sum returns the SHA256 of the bz. func Sum(bz []byte) []byte { h := sha256.Sum256(bz) @@ -23,41 +18,6 @@ func Sum(bz []byte) []byte { //------------------------------------------------------------- -const ( - TruncatedSize = 20 -) - -type sha256trunc struct { - sha256 hash.Hash -} - -func (h sha256trunc) Write(p []byte) (n int, err error) { - return h.sha256.Write(p) -} -func (h sha256trunc) Sum(b []byte) []byte { - shasum := h.sha256.Sum(b) - return shasum[:TruncatedSize] -} - -func (h sha256trunc) Reset() { - h.sha256.Reset() -} - -func (h sha256trunc) Size() int { - return TruncatedSize -} - -func (h sha256trunc) BlockSize() int { - return h.sha256.BlockSize() -} - -// NewTruncated returns a new hash.Hash. -func NewTruncated() hash.Hash { - return sha256trunc{ - sha256: sha256.New(), - } -} - // SumTruncated returns the first 20 bytes of SHA256 of the bz. func SumTruncated(bz []byte) []byte { hash := sha256.Sum256(bz) diff --git a/crypto/tmhash/hash_test.go b/crypto/tmhash/hash_test.go deleted file mode 100644 index cf9991b3b..000000000 --- a/crypto/tmhash/hash_test.go +++ /dev/null @@ -1,48 +0,0 @@ -package tmhash_test - -import ( - "crypto/sha256" - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - - "github.com/tendermint/tendermint/crypto/tmhash" -) - -func TestHash(t *testing.T) { - testVector := []byte("abc") - hasher := tmhash.New() - _, err := hasher.Write(testVector) - require.NoError(t, err) - bz := hasher.Sum(nil) - - bz2 := tmhash.Sum(testVector) - - hasher = sha256.New() - _, err = hasher.Write(testVector) - require.NoError(t, err) - bz3 := hasher.Sum(nil) - - assert.Equal(t, bz, bz2) - assert.Equal(t, bz, bz3) -} - -func TestHashTruncated(t *testing.T) { - testVector := []byte("abc") - hasher := tmhash.NewTruncated() - _, err := hasher.Write(testVector) - require.NoError(t, err) - bz := hasher.Sum(nil) - - bz2 := tmhash.SumTruncated(testVector) - - hasher = sha256.New() - _, err = hasher.Write(testVector) - require.NoError(t, err) - bz3 := hasher.Sum(nil) - bz3 = bz3[:tmhash.TruncatedSize] - - assert.Equal(t, bz, bz2) - assert.Equal(t, bz, bz3) -} diff --git a/crypto/version.go b/crypto/version.go deleted file mode 100644 index 77c0bed8a..000000000 --- a/crypto/version.go +++ /dev/null @@ -1,3 +0,0 @@ -package crypto - -const Version = "0.9.0-dev" diff --git a/test/e2e/runner/evidence.go b/test/e2e/runner/evidence.go index b29b574a2..10db5d58b 100644 --- a/test/e2e/runner/evidence.go +++ b/test/e2e/runner/evidence.go @@ -63,7 +63,6 @@ func InjectEvidence(ctx context.Context, logger log.Logger, r *rand.Rand, testne if err != nil { return err } - valSet, err := types.ValidatorSetFromExistingValidators(valRes.Validators) if err != nil { return err @@ -289,8 +288,7 @@ func makeBlockID(hash []byte, partSetSize uint32, partSetHash []byte) types.Bloc } } -func mutateValidatorSet(ctx context.Context, privVals []types.MockPV, vals *types.ValidatorSet, -) ([]types.PrivValidator, *types.ValidatorSet, error) { +func mutateValidatorSet(ctx context.Context, privVals []types.MockPV, vals *types.ValidatorSet) ([]types.PrivValidator, *types.ValidatorSet, error) { newVal, newPrivVal, err := factory.Validator(ctx, 10) if err != nil { return nil, nil, err diff --git a/types/params.go b/types/params.go index c0e5e3a00..e8ee6fcdf 100644 --- a/types/params.go +++ b/types/params.go @@ -1,6 +1,7 @@ package types import ( + "crypto/sha256" "errors" "fmt" "time" @@ -8,7 +9,6 @@ import ( "github.com/tendermint/tendermint/crypto/ed25519" "github.com/tendermint/tendermint/crypto/secp256k1" "github.com/tendermint/tendermint/crypto/sr25519" - "github.com/tendermint/tendermint/crypto/tmhash" tmstrings "github.com/tendermint/tendermint/libs/strings" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" ) @@ -328,8 +328,6 @@ func (params ConsensusParams) ValidateConsensusParams() error { // This allows the ConsensusParams to evolve more without breaking the block // protocol. No need for a Merkle tree here, just a small struct to hash. func (params ConsensusParams) HashConsensusParams() []byte { - hasher := tmhash.New() - hp := tmproto.HashedParams{ BlockMaxBytes: params.Block.MaxBytes, BlockMaxGas: params.Block.MaxGas, @@ -340,11 +338,9 @@ func (params ConsensusParams) HashConsensusParams() []byte { panic(err) } - _, err = hasher.Write(bz) - if err != nil { - panic(err) - } - return hasher.Sum(nil) + sum := sha256.Sum256(bz) + + return sum[:] } func (params *ConsensusParams) Equals(params2 *ConsensusParams) bool { From dcfbd9bc3d96adca16ab840c03a5333f7e0e4e61 Mon Sep 17 00:00:00 2001 From: Thane Thomson Date: Tue, 26 Apr 2022 08:02:17 -0400 Subject: [PATCH 18/35] abci++: Remove intermediate protos (#8414) * Sync protos with their intermediates Signed-off-by: Thane Thomson * Remove intermediate protos and their supporting scripts Signed-off-by: Thane Thomson * make proto-gen Signed-off-by: Thane Thomson --- Makefile | 6 - abci/types/types.pb.go | 435 +++++++------- proto/tendermint/abci/types.proto | 7 +- .../tendermint/abci/types.proto.intermediate | 535 ------------------ proto/tendermint/types/params.pb.go | 2 +- proto/tendermint/types/types.pb.go | 4 +- proto/tendermint/types/types.proto | 4 +- .../tendermint/types/types.proto.intermediate | 192 ------- scripts/abci-gen.sh | 29 - scripts/protopackage.sh | 23 - 10 files changed, 225 insertions(+), 1012 deletions(-) delete mode 100644 proto/tendermint/abci/types.proto.intermediate delete mode 100644 proto/tendermint/types/types.proto.intermediate delete mode 100755 scripts/abci-gen.sh delete mode 100755 scripts/protopackage.sh diff --git a/Makefile b/Makefile index ba8850164..703220953 100644 --- a/Makefile +++ b/Makefile @@ -117,12 +117,6 @@ proto-check-breaking: check-proto-deps @buf breaking --against ".git" .PHONY: proto-check-breaking -# TODO: Should be removed when work on ABCI++ is complete. -# For more information, see https://github.com/tendermint/tendermint/issues/8066 -abci-proto-gen: - ./scripts/abci-gen.sh -.PHONY: abci-proto-gen - ############################################################################### ### Build ABCI ### ############################################################################### diff --git a/abci/types/types.pb.go b/abci/types/types.pb.go index 04c7ee9a6..dd1308628 100644 --- a/abci/types/types.pb.go +++ b/abci/types/types.pb.go @@ -4235,224 +4235,223 @@ func init() { func init() { proto.RegisterFile("tendermint/abci/types.proto", fileDescriptor_252557cfdd89a31a) } var fileDescriptor_252557cfdd89a31a = []byte{ - // 3459 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x5b, 0x4b, 0x93, 0x1b, 0xd5, - 0xf5, 0x97, 0x5a, 0xef, 0xa3, 0xd1, 0x63, 0xee, 0x0c, 0x46, 0x16, 0xf6, 0x8c, 0x69, 0x97, 0xc1, - 0x36, 0x30, 0xe6, 0x3f, 0xfe, 0x1b, 0x4c, 0x0c, 0xa1, 0x66, 0x34, 0x32, 0x1a, 0x7b, 0x3c, 0x33, - 0xf4, 0x68, 0x4c, 0x91, 0x87, 0x9b, 0x96, 0xfa, 0xce, 0xa8, 0xb1, 0xa4, 0x6e, 0xba, 0x5b, 0x83, - 0x86, 0x65, 0x28, 0x36, 0x54, 0xaa, 0xc2, 0x26, 0x95, 0xa4, 0x2a, 0xec, 0x92, 0xaa, 0xe4, 0x1b, - 0x64, 0x95, 0x55, 0x16, 0x2c, 0xb2, 0x60, 0x95, 0xa4, 0xb2, 0x20, 0x29, 0xd8, 0xe5, 0x0b, 0x64, - 0x97, 0xa4, 0xee, 0xa3, 0x5f, 0x52, 0xb7, 0x1e, 0x18, 0xa8, 0x4a, 0x85, 0x9d, 0xfa, 0xf4, 0x39, - 0xa7, 0xef, 0xe3, 0xdc, 0xf3, 0xf8, 0x9d, 0x2b, 0x78, 0xc2, 0xc6, 0x7d, 0x15, 0x9b, 0x3d, 0xad, - 0x6f, 0x5f, 0x53, 0x5a, 0x6d, 0xed, 0x9a, 0x7d, 0x6a, 0x60, 0x6b, 0xcd, 0x30, 0x75, 0x5b, 0x47, - 0x25, 0xef, 0xe5, 0x1a, 0x79, 0x59, 0x3d, 0xef, 0xe3, 0x6e, 0x9b, 0xa7, 0x86, 0xad, 0x5f, 0x33, - 0x4c, 0x5d, 0x3f, 0x62, 0xfc, 0xd5, 0x73, 0xbe, 0xd7, 0x54, 0x8f, 0x5f, 0x5b, 0xe0, 0x2d, 0x17, - 0x7e, 0x88, 0x4f, 0x9d, 0xb7, 0xe7, 0xc7, 0x64, 0x0d, 0xc5, 0x54, 0x7a, 0xce, 0xeb, 0xd5, 0x63, - 0x5d, 0x3f, 0xee, 0xe2, 0x6b, 0xf4, 0xa9, 0x35, 0x38, 0xba, 0x66, 0x6b, 0x3d, 0x6c, 0xd9, 0x4a, - 0xcf, 0xe0, 0x0c, 0xcb, 0xc7, 0xfa, 0xb1, 0x4e, 0x7f, 0x5e, 0x23, 0xbf, 0x18, 0x55, 0xfc, 0x37, - 0x40, 0x46, 0xc2, 0xef, 0x0c, 0xb0, 0x65, 0xa3, 0x75, 0x48, 0xe2, 0x76, 0x47, 0xaf, 0xc4, 0x2f, - 0xc4, 0x2f, 0xe7, 0xd7, 0xcf, 0xad, 0x8d, 0x4c, 0x6e, 0x8d, 0xf3, 0xd5, 0xdb, 0x1d, 0xbd, 0x11, - 0x93, 0x28, 0x2f, 0xba, 0x01, 0xa9, 0xa3, 0xee, 0xc0, 0xea, 0x54, 0x04, 0x2a, 0x74, 0x3e, 0x4a, - 0xe8, 0x36, 0x61, 0x6a, 0xc4, 0x24, 0xc6, 0x4d, 0x3e, 0xa5, 0xf5, 0x8f, 0xf4, 0x4a, 0x62, 0xf2, - 0xa7, 0xb6, 0xfb, 0x47, 0xf4, 0x53, 0x84, 0x17, 0x6d, 0x02, 0x68, 0x7d, 0xcd, 0x96, 0xdb, 0x1d, - 0x45, 0xeb, 0x57, 0x92, 0x54, 0xf2, 0xc9, 0x68, 0x49, 0xcd, 0xae, 0x11, 0xc6, 0x46, 0x4c, 0xca, - 0x69, 0xce, 0x03, 0x19, 0xee, 0x3b, 0x03, 0x6c, 0x9e, 0x56, 0x52, 0x93, 0x87, 0xfb, 0x3a, 0x61, - 0x22, 0xc3, 0xa5, 0xdc, 0x68, 0x1b, 0xf2, 0x2d, 0x7c, 0xac, 0xf5, 0xe5, 0x56, 0x57, 0x6f, 0x3f, - 0xac, 0xa4, 0xa9, 0xb0, 0x18, 0x25, 0xbc, 0x49, 0x58, 0x37, 0x09, 0xe7, 0xa6, 0x50, 0x89, 0x37, - 0x62, 0x12, 0xb4, 0x5c, 0x0a, 0x7a, 0x19, 0xb2, 0xed, 0x0e, 0x6e, 0x3f, 0x94, 0xed, 0x61, 0x25, - 0x43, 0xf5, 0xac, 0x46, 0xe9, 0xa9, 0x11, 0xbe, 0xe6, 0xb0, 0x11, 0x93, 0x32, 0x6d, 0xf6, 0x13, - 0xdd, 0x06, 0x50, 0x71, 0x57, 0x3b, 0xc1, 0x26, 0x91, 0xcf, 0x4e, 0x5e, 0x83, 0x2d, 0xc6, 0xd9, - 0x1c, 0xf2, 0x61, 0xe4, 0x54, 0x87, 0x80, 0x6a, 0x90, 0xc3, 0x7d, 0x95, 0x4f, 0x27, 0x47, 0xd5, - 0x5c, 0x88, 0xdc, 0xef, 0xbe, 0xea, 0x9f, 0x4c, 0x16, 0xf3, 0x67, 0x74, 0x13, 0xd2, 0x6d, 0xbd, - 0xd7, 0xd3, 0xec, 0x0a, 0x50, 0x0d, 0x2b, 0x91, 0x13, 0xa1, 0x5c, 0x8d, 0x98, 0xc4, 0xf9, 0xd1, - 0x2e, 0x14, 0xbb, 0x9a, 0x65, 0xcb, 0x56, 0x5f, 0x31, 0xac, 0x8e, 0x6e, 0x5b, 0x95, 0x3c, 0xd5, - 0x70, 0x29, 0x4a, 0xc3, 0x8e, 0x66, 0xd9, 0x07, 0x0e, 0x73, 0x23, 0x26, 0x15, 0xba, 0x7e, 0x02, - 0xd1, 0xa7, 0x1f, 0x1d, 0x61, 0xd3, 0x55, 0x58, 0x59, 0x98, 0xac, 0x6f, 0x8f, 0x70, 0x3b, 0xf2, - 0x44, 0x9f, 0xee, 0x27, 0xa0, 0xef, 0xc3, 0x52, 0x57, 0x57, 0x54, 0x57, 0x9d, 0xdc, 0xee, 0x0c, - 0xfa, 0x0f, 0x2b, 0x05, 0xaa, 0xf4, 0x4a, 0xe4, 0x20, 0x75, 0x45, 0x75, 0x54, 0xd4, 0x88, 0x40, - 0x23, 0x26, 0x2d, 0x76, 0x47, 0x89, 0xe8, 0x01, 0x2c, 0x2b, 0x86, 0xd1, 0x3d, 0x1d, 0xd5, 0x5e, - 0xa4, 0xda, 0xaf, 0x46, 0x69, 0xdf, 0x20, 0x32, 0xa3, 0xea, 0x91, 0x32, 0x46, 0x45, 0x4d, 0x28, - 0x1b, 0x26, 0x36, 0x14, 0x13, 0xcb, 0x86, 0xa9, 0x1b, 0xba, 0xa5, 0x74, 0x2b, 0x25, 0xaa, 0xfb, - 0xe9, 0x28, 0xdd, 0xfb, 0x8c, 0x7f, 0x9f, 0xb3, 0x37, 0x62, 0x52, 0xc9, 0x08, 0x92, 0x98, 0x56, - 0xbd, 0x8d, 0x2d, 0xcb, 0xd3, 0x5a, 0x9e, 0xa6, 0x95, 0xf2, 0x07, 0xb5, 0x06, 0x48, 0xa8, 0x0e, - 0x79, 0x3c, 0x24, 0xe2, 0xf2, 0x89, 0x6e, 0xe3, 0xca, 0xe2, 0xe4, 0x83, 0x55, 0xa7, 0xac, 0xf7, - 0x75, 0x1b, 0x93, 0x43, 0x85, 0xdd, 0x27, 0xa4, 0xc0, 0x63, 0x27, 0xd8, 0xd4, 0x8e, 0x4e, 0xa9, - 0x1a, 0x99, 0xbe, 0xb1, 0x34, 0xbd, 0x5f, 0x41, 0x54, 0xe1, 0x33, 0x51, 0x0a, 0xef, 0x53, 0x21, - 0xa2, 0xa2, 0xee, 0x88, 0x34, 0x62, 0xd2, 0xd2, 0xc9, 0x38, 0x99, 0x98, 0xd8, 0x91, 0xd6, 0x57, - 0xba, 0xda, 0x7b, 0x98, 0x1f, 0x9b, 0xa5, 0xc9, 0x26, 0x76, 0x9b, 0x73, 0xd3, 0xb3, 0x42, 0x4c, - 0xec, 0xc8, 0x4f, 0xd8, 0xcc, 0x40, 0xea, 0x44, 0xe9, 0x0e, 0xb0, 0xf8, 0x34, 0xe4, 0x7d, 0x8e, - 0x15, 0x55, 0x20, 0xd3, 0xc3, 0x96, 0xa5, 0x1c, 0x63, 0xea, 0x87, 0x73, 0x92, 0xf3, 0x28, 0x16, - 0x61, 0xc1, 0xef, 0x4c, 0xc5, 0x8f, 0xe2, 0xae, 0x24, 0xf1, 0x93, 0x44, 0xf2, 0x04, 0x9b, 0x74, - 0xda, 0x5c, 0x92, 0x3f, 0xa2, 0x8b, 0x50, 0xa0, 0x43, 0x96, 0x9d, 0xf7, 0xc4, 0x59, 0x27, 0xa5, - 0x05, 0x4a, 0xbc, 0xcf, 0x99, 0x56, 0x21, 0x6f, 0xac, 0x1b, 0x2e, 0x4b, 0x82, 0xb2, 0x80, 0xb1, - 0x6e, 0x38, 0x0c, 0x4f, 0xc2, 0x02, 0x99, 0x9f, 0xcb, 0x91, 0xa4, 0x1f, 0xc9, 0x13, 0x1a, 0x67, - 0x11, 0xff, 0x28, 0x40, 0x79, 0xd4, 0x01, 0xa3, 0x9b, 0x90, 0x24, 0xb1, 0x88, 0x87, 0x95, 0xea, - 0x1a, 0x0b, 0x54, 0x6b, 0x4e, 0xa0, 0x5a, 0x6b, 0x3a, 0x81, 0x6a, 0x33, 0xfb, 0xc9, 0x67, 0xab, - 0xb1, 0x8f, 0xfe, 0xb6, 0x1a, 0x97, 0xa8, 0x04, 0x3a, 0x4b, 0x7c, 0xa5, 0xa2, 0xf5, 0x65, 0x4d, - 0xa5, 0x43, 0xce, 0x11, 0x47, 0xa8, 0x68, 0xfd, 0x6d, 0x15, 0xed, 0x40, 0xb9, 0xad, 0xf7, 0x2d, - 0xdc, 0xb7, 0x06, 0x96, 0xcc, 0x02, 0x21, 0x0f, 0x26, 0x01, 0x77, 0xc8, 0xc2, 0x6b, 0xcd, 0xe1, - 0xdc, 0xa7, 0x8c, 0x52, 0xa9, 0x1d, 0x24, 0x10, 0xb7, 0x7a, 0xa2, 0x74, 0x35, 0x55, 0xb1, 0x75, - 0xd3, 0xaa, 0x24, 0x2f, 0x24, 0x42, 0xfd, 0xe1, 0x7d, 0x87, 0xe5, 0xd0, 0x50, 0x15, 0x1b, 0x6f, - 0x26, 0xc9, 0x70, 0x25, 0x9f, 0x24, 0x7a, 0x0a, 0x4a, 0x8a, 0x61, 0xc8, 0x96, 0xad, 0xd8, 0x58, - 0x6e, 0x9d, 0xda, 0xd8, 0xa2, 0x81, 0x66, 0x41, 0x2a, 0x28, 0x86, 0x71, 0x40, 0xa8, 0x9b, 0x84, - 0x88, 0x2e, 0x41, 0x91, 0xc4, 0x24, 0x4d, 0xe9, 0xca, 0x1d, 0xac, 0x1d, 0x77, 0x6c, 0x1a, 0x52, - 0x12, 0x52, 0x81, 0x53, 0x1b, 0x94, 0x28, 0xaa, 0xee, 0x8e, 0xd3, 0x78, 0x84, 0x10, 0x24, 0x55, - 0xc5, 0x56, 0xe8, 0x4a, 0x2e, 0x48, 0xf4, 0x37, 0xa1, 0x19, 0x8a, 0xdd, 0xe1, 0xeb, 0x43, 0x7f, - 0xa3, 0x33, 0x90, 0xe6, 0x6a, 0x13, 0x54, 0x2d, 0x7f, 0x42, 0xcb, 0x90, 0x32, 0x4c, 0xfd, 0x04, - 0xd3, 0xad, 0xcb, 0x4a, 0xec, 0x41, 0x7c, 0x5f, 0x80, 0xc5, 0xb1, 0xc8, 0x45, 0xf4, 0x76, 0x14, - 0xab, 0xe3, 0x7c, 0x8b, 0xfc, 0x46, 0x2f, 0x10, 0xbd, 0x8a, 0x8a, 0x4d, 0x1e, 0xed, 0x2b, 0xe3, - 0x4b, 0xdd, 0xa0, 0xef, 0xf9, 0xd2, 0x70, 0x6e, 0x74, 0x17, 0xca, 0x5d, 0xc5, 0xb2, 0x65, 0xe6, - 0xfd, 0x65, 0x5f, 0xe4, 0x7f, 0x62, 0x6c, 0x91, 0x59, 0xac, 0x20, 0x06, 0xcd, 0x95, 0x14, 0x89, - 0xa8, 0x47, 0x45, 0x87, 0xb0, 0xdc, 0x3a, 0x7d, 0x4f, 0xe9, 0xdb, 0x5a, 0x1f, 0xcb, 0x63, 0xbb, - 0x36, 0x9e, 0x4a, 0xdc, 0xd3, 0xac, 0x16, 0xee, 0x28, 0x27, 0x9a, 0xee, 0x0c, 0x6b, 0xc9, 0x95, - 0x77, 0x77, 0xd4, 0x12, 0x25, 0x28, 0x06, 0xc3, 0x2e, 0x2a, 0x82, 0x60, 0x0f, 0xf9, 0xfc, 0x05, - 0x7b, 0x88, 0x9e, 0x87, 0x24, 0x99, 0x23, 0x9d, 0x7b, 0x31, 0xe4, 0x43, 0x5c, 0xae, 0x79, 0x6a, - 0x60, 0x89, 0x72, 0x8a, 0xa2, 0x7b, 0x1a, 0xdc, 0x50, 0x3c, 0xaa, 0x55, 0xbc, 0x02, 0xa5, 0x91, - 0x38, 0xeb, 0xdb, 0xbe, 0xb8, 0x7f, 0xfb, 0xc4, 0x12, 0x14, 0x02, 0x01, 0x55, 0x3c, 0x03, 0xcb, - 0x61, 0xf1, 0x51, 0xec, 0xb8, 0xf4, 0x40, 0x9c, 0x43, 0x37, 0x20, 0xeb, 0x06, 0x48, 0x76, 0x1a, - 0xcf, 0x8e, 0xcd, 0xc2, 0x61, 0x96, 0x5c, 0x56, 0x72, 0x0c, 0x89, 0x55, 0x53, 0x73, 0x10, 0xe8, - 0xc0, 0x33, 0x8a, 0x61, 0x34, 0x14, 0xab, 0x23, 0xbe, 0x05, 0x95, 0xa8, 0xe0, 0x37, 0x32, 0x8d, - 0xa4, 0x6b, 0x85, 0x67, 0x20, 0x7d, 0xa4, 0x9b, 0x3d, 0xc5, 0xa6, 0xca, 0x0a, 0x12, 0x7f, 0x22, - 0xd6, 0xc9, 0x02, 0x61, 0x82, 0x92, 0xd9, 0x83, 0x28, 0xc3, 0xd9, 0xc8, 0x00, 0x48, 0x44, 0xb4, - 0xbe, 0x8a, 0xd9, 0x7a, 0x16, 0x24, 0xf6, 0xe0, 0x29, 0x62, 0x83, 0x65, 0x0f, 0xe4, 0xb3, 0x16, - 0x9d, 0x2b, 0xd5, 0x9f, 0x93, 0xf8, 0x93, 0xf8, 0xdb, 0x04, 0x9c, 0x09, 0x0f, 0x83, 0xe8, 0x02, - 0x2c, 0xf4, 0x94, 0xa1, 0x6c, 0x0f, 0xf9, 0x59, 0x66, 0xdb, 0x01, 0x3d, 0x65, 0xd8, 0x1c, 0xb2, - 0x83, 0x5c, 0x86, 0x84, 0x3d, 0xb4, 0x2a, 0xc2, 0x85, 0xc4, 0xe5, 0x05, 0x89, 0xfc, 0x44, 0x87, - 0xb0, 0xd8, 0xd5, 0xdb, 0x4a, 0x57, 0xf6, 0x59, 0x3c, 0x37, 0xf6, 0x8b, 0x63, 0x8b, 0xcd, 0x02, - 0x1a, 0x56, 0xc7, 0x8c, 0xbe, 0x44, 0x75, 0xec, 0xb8, 0x96, 0xff, 0x35, 0x59, 0xbd, 0x6f, 0x8f, - 0x52, 0x01, 0x4f, 0xe1, 0xf8, 0xec, 0xf4, 0xdc, 0x3e, 0xfb, 0x79, 0x58, 0xee, 0xe3, 0xa1, 0xed, - 0x1b, 0x23, 0x33, 0x9c, 0x0c, 0xdd, 0x0b, 0x44, 0xde, 0x79, 0xdf, 0x27, 0x36, 0x84, 0xae, 0xd0, - 0xcc, 0xc2, 0xd0, 0x2d, 0x6c, 0xca, 0x8a, 0xaa, 0x9a, 0xd8, 0xb2, 0x68, 0x66, 0xbb, 0x40, 0xd3, - 0x05, 0x4a, 0xdf, 0x60, 0x64, 0xf1, 0x17, 0xfe, 0xbd, 0x0a, 0x66, 0x12, 0x7c, 0x27, 0xe2, 0xde, - 0x4e, 0x1c, 0xc0, 0x32, 0x97, 0x57, 0x03, 0x9b, 0x21, 0xcc, 0xea, 0x79, 0x90, 0x23, 0x3e, 0xc3, - 0x3e, 0x24, 0x1e, 0x6d, 0x1f, 0x1c, 0x6f, 0x9b, 0xf4, 0x79, 0xdb, 0xff, 0xb2, 0xbd, 0x79, 0xd5, - 0x8d, 0x22, 0x5e, 0x9a, 0x16, 0x1a, 0x45, 0xbc, 0x79, 0x09, 0x01, 0xf7, 0xf6, 0xcb, 0x38, 0x54, - 0xa3, 0xf3, 0xb2, 0x50, 0x55, 0xcf, 0xc0, 0xa2, 0x3b, 0x17, 0x77, 0x7c, 0xec, 0xd4, 0x97, 0xdd, - 0x17, 0x7c, 0x80, 0x91, 0x51, 0xf1, 0x12, 0x14, 0x47, 0xb2, 0x46, 0xb6, 0x0b, 0x85, 0x13, 0xff, - 0xf7, 0xc5, 0x9f, 0x26, 0x5c, 0xaf, 0x1a, 0x48, 0xed, 0x42, 0x2c, 0xef, 0x75, 0x58, 0x52, 0x71, - 0x5b, 0x53, 0xbf, 0xac, 0xe1, 0x2d, 0x72, 0xe9, 0x6f, 0xed, 0x6e, 0x06, 0xbb, 0xfb, 0x73, 0x1e, - 0xb2, 0x12, 0xb6, 0x0c, 0x92, 0xd2, 0xa1, 0x4d, 0xc8, 0xe1, 0x61, 0x1b, 0x1b, 0xb6, 0x93, 0x05, - 0x87, 0x57, 0x13, 0x8c, 0xbb, 0xee, 0x70, 0x92, 0xda, 0xd8, 0x15, 0x43, 0xd7, 0x39, 0x0c, 0x12, - 0x8d, 0x68, 0x70, 0x71, 0x3f, 0x0e, 0xf2, 0x82, 0x83, 0x83, 0x24, 0x22, 0x4b, 0x61, 0x26, 0x35, - 0x02, 0x84, 0x5c, 0xe7, 0x40, 0x48, 0x72, 0xca, 0xc7, 0x02, 0x48, 0x48, 0x2d, 0x80, 0x84, 0xa4, - 0xa6, 0x4c, 0x33, 0x02, 0x0a, 0x79, 0xc1, 0x81, 0x42, 0xd2, 0x53, 0x46, 0x3c, 0x82, 0x85, 0xdc, - 0x09, 0x62, 0x21, 0x99, 0x88, 0xd0, 0xe6, 0x48, 0x4f, 0x04, 0x43, 0x5e, 0xf1, 0x81, 0x21, 0xd9, - 0x48, 0x14, 0x82, 0x29, 0x0a, 0x41, 0x43, 0x5e, 0x0b, 0xa0, 0x21, 0xb9, 0x29, 0xeb, 0x30, 0x01, - 0x0e, 0xd9, 0xf2, 0xc3, 0x21, 0x10, 0x89, 0xaa, 0xf0, 0x7d, 0x8f, 0xc2, 0x43, 0x5e, 0x72, 0xf1, - 0x90, 0x7c, 0x24, 0xb0, 0xc3, 0xe7, 0x32, 0x0a, 0x88, 0xec, 0x8d, 0x01, 0x22, 0x0c, 0xc0, 0x78, - 0x2a, 0x52, 0xc5, 0x14, 0x44, 0x64, 0x6f, 0x0c, 0x11, 0x29, 0x4c, 0x51, 0x38, 0x05, 0x12, 0xf9, - 0x41, 0x38, 0x24, 0x12, 0x0d, 0x5a, 0xf0, 0x61, 0xce, 0x86, 0x89, 0xc8, 0x11, 0x98, 0x48, 0x29, - 0xb2, 0x7e, 0x67, 0xea, 0x67, 0x06, 0x45, 0x0e, 0x43, 0x40, 0x11, 0x06, 0x5f, 0x5c, 0x8e, 0x54, - 0x3e, 0x03, 0x2a, 0x72, 0x18, 0x82, 0x8a, 0x2c, 0x4e, 0x55, 0x3b, 0x15, 0x16, 0xb9, 0x1d, 0x84, - 0x45, 0xd0, 0x94, 0x33, 0x16, 0x89, 0x8b, 0xb4, 0xa2, 0x70, 0x11, 0x86, 0x5d, 0x3c, 0x1b, 0xa9, - 0x71, 0x0e, 0x60, 0x64, 0x6f, 0x0c, 0x18, 0x59, 0x9e, 0x62, 0x69, 0xb3, 0x22, 0x23, 0x57, 0x48, - 0x46, 0x31, 0xe2, 0xaa, 0x49, 0x72, 0x8f, 0x4d, 0x53, 0x37, 0x39, 0xc6, 0xc1, 0x1e, 0xc4, 0xcb, - 0xa4, 0x52, 0xf6, 0xdc, 0xf2, 0x04, 0x14, 0x85, 0x16, 0x51, 0x3e, 0x57, 0x2c, 0xfe, 0x2e, 0xee, - 0xc9, 0xd2, 0x02, 0xd3, 0x5f, 0x65, 0xe7, 0x78, 0x95, 0xed, 0xc3, 0x56, 0x84, 0x20, 0xb6, 0xb2, - 0x0a, 0x79, 0x52, 0x1c, 0x8d, 0xc0, 0x26, 0x8a, 0xe1, 0xc2, 0x26, 0x57, 0x61, 0x91, 0x26, 0x01, - 0x0c, 0x81, 0xe1, 0x91, 0x35, 0x49, 0x23, 0x6b, 0x89, 0xbc, 0x60, 0xab, 0xc0, 0x42, 0xec, 0x73, - 0xb0, 0xe4, 0xe3, 0x75, 0x8b, 0x2e, 0x86, 0x21, 0x94, 0x5d, 0xee, 0x0d, 0x5e, 0x7d, 0xfd, 0x21, - 0xee, 0xad, 0x90, 0x87, 0xb7, 0x84, 0x41, 0x23, 0xf1, 0xaf, 0x08, 0x1a, 0x11, 0xbe, 0x34, 0x34, - 0xe2, 0x2f, 0x22, 0x13, 0xc1, 0x22, 0xf2, 0x9f, 0x71, 0x6f, 0x4f, 0x5c, 0xa0, 0xa3, 0xad, 0xab, - 0x98, 0x97, 0x75, 0xf4, 0x37, 0x49, 0xb3, 0xba, 0xfa, 0x31, 0x2f, 0xde, 0xc8, 0x4f, 0xc2, 0xe5, - 0xc6, 0xce, 0x1c, 0x0f, 0x8d, 0x6e, 0x45, 0xc8, 0x72, 0x17, 0x5e, 0x11, 0x96, 0x21, 0xf1, 0x10, - 0xb3, 0x48, 0xb7, 0x20, 0x91, 0x9f, 0x84, 0x8f, 0x1a, 0x19, 0xcf, 0x41, 0xd8, 0x03, 0xba, 0x09, - 0x39, 0xda, 0xae, 0x91, 0x75, 0xc3, 0xe2, 0x01, 0x29, 0x90, 0xae, 0xb1, 0xae, 0xcc, 0xda, 0x3e, - 0xe1, 0xd9, 0x33, 0x2c, 0x29, 0x6b, 0xf0, 0x5f, 0xbe, 0xa4, 0x29, 0x17, 0x48, 0x9a, 0xce, 0x41, - 0x8e, 0x8c, 0xde, 0x32, 0x94, 0x36, 0xa6, 0x91, 0x25, 0x27, 0x79, 0x04, 0xf1, 0x01, 0xa0, 0xf1, - 0x38, 0x89, 0x1a, 0x90, 0xc6, 0x27, 0xb8, 0x6f, 0xb3, 0x9c, 0x32, 0xbf, 0x7e, 0x66, 0xbc, 0x6e, - 0x24, 0xaf, 0x37, 0x2b, 0x64, 0x91, 0xff, 0xf1, 0xd9, 0x6a, 0x99, 0x71, 0x3f, 0xab, 0xf7, 0x34, - 0x1b, 0xf7, 0x0c, 0xfb, 0x54, 0xe2, 0xf2, 0xe2, 0x5f, 0x05, 0x28, 0x8d, 0xc4, 0xcf, 0xd0, 0xb5, - 0x75, 0x4c, 0x5e, 0xf0, 0x01, 0x4b, 0xb3, 0xad, 0xf7, 0x79, 0x80, 0x63, 0xc5, 0x92, 0xdf, 0x55, - 0xfa, 0x36, 0x56, 0xf9, 0xa2, 0xe7, 0x8e, 0x15, 0xeb, 0x0d, 0x4a, 0x20, 0xbb, 0x4e, 0x5e, 0x0f, - 0x2c, 0xac, 0x72, 0x88, 0x2b, 0x73, 0xac, 0x58, 0x87, 0x16, 0x56, 0x7d, 0xb3, 0xcc, 0x3c, 0xda, - 0x2c, 0x83, 0x6b, 0x9c, 0x1d, 0x59, 0x63, 0x5f, 0xdd, 0x9f, 0xf3, 0xd7, 0xfd, 0xa8, 0x0a, 0x59, - 0xc3, 0xd4, 0x74, 0x53, 0xb3, 0x4f, 0xe9, 0xc6, 0x24, 0x24, 0xf7, 0x19, 0x5d, 0x84, 0x42, 0x0f, - 0xf7, 0x0c, 0x5d, 0xef, 0xca, 0xcc, 0xd9, 0xe4, 0xa9, 0xe8, 0x02, 0x27, 0xd6, 0xa9, 0xcf, 0xf9, - 0x40, 0xf0, 0x4e, 0x9f, 0x87, 0xef, 0x7c, 0xb5, 0xcb, 0xbb, 0x12, 0xb2, 0xbc, 0x3e, 0x0a, 0x99, - 0xc4, 0xc8, 0xfa, 0xba, 0xcf, 0xdf, 0xd4, 0x02, 0x8b, 0x3f, 0xa6, 0xa0, 0x6f, 0x30, 0x37, 0x42, - 0x07, 0xfe, 0xca, 0x6c, 0x40, 0x9d, 0x82, 0x63, 0xce, 0xb3, 0x7a, 0x0f, 0xaf, 0x82, 0x63, 0x64, - 0x0b, 0xbd, 0x09, 0x8f, 0x8f, 0x78, 0x36, 0x57, 0xb5, 0x30, 0xab, 0x83, 0x7b, 0x2c, 0xe8, 0xe0, - 0x1c, 0xd5, 0xde, 0x62, 0x25, 0x1e, 0xf1, 0xcc, 0x6d, 0x43, 0x31, 0x98, 0xe6, 0x85, 0x6e, 0xff, - 0x45, 0x28, 0x98, 0xd8, 0x56, 0xb4, 0xbe, 0x1c, 0xa8, 0x49, 0x17, 0x18, 0x91, 0xe3, 0xbf, 0xfb, - 0xf0, 0x58, 0x68, 0xba, 0x87, 0x5e, 0x84, 0x9c, 0x97, 0x29, 0xb2, 0x55, 0x9d, 0x80, 0xe4, 0x79, - 0xbc, 0xe2, 0xef, 0xe3, 0x9e, 0xca, 0x20, 0x36, 0x58, 0x87, 0xb4, 0x89, 0xad, 0x41, 0x97, 0xa1, - 0x75, 0xc5, 0xf5, 0xe7, 0x66, 0x4b, 0x14, 0x09, 0x75, 0xd0, 0xb5, 0x25, 0x2e, 0x2c, 0x3e, 0x80, - 0x34, 0xa3, 0xa0, 0x3c, 0x64, 0x0e, 0x77, 0xef, 0xee, 0xee, 0xbd, 0xb1, 0x5b, 0x8e, 0x21, 0x80, - 0xf4, 0x46, 0xad, 0x56, 0xdf, 0x6f, 0x96, 0xe3, 0x28, 0x07, 0xa9, 0x8d, 0xcd, 0x3d, 0xa9, 0x59, - 0x16, 0x08, 0x59, 0xaa, 0xdf, 0xa9, 0xd7, 0x9a, 0xe5, 0x04, 0x5a, 0x84, 0x02, 0xfb, 0x2d, 0xdf, - 0xde, 0x93, 0xee, 0x6d, 0x34, 0xcb, 0x49, 0x1f, 0xe9, 0xa0, 0xbe, 0xbb, 0x55, 0x97, 0xca, 0x29, - 0xf1, 0xff, 0xe0, 0x6c, 0x64, 0x6a, 0xe9, 0x01, 0x7f, 0x71, 0x1f, 0xf0, 0x27, 0xfe, 0x5c, 0x80, - 0x6a, 0x74, 0xbe, 0x88, 0xee, 0x8c, 0x4c, 0x7c, 0x7d, 0x8e, 0x64, 0x73, 0x64, 0xf6, 0xe8, 0x12, - 0x14, 0x4d, 0x7c, 0x84, 0xed, 0x76, 0x87, 0xe5, 0xaf, 0x2c, 0x60, 0x16, 0xa4, 0x02, 0xa7, 0x52, - 0x21, 0x8b, 0xb1, 0xbd, 0x8d, 0xdb, 0xb6, 0xcc, 0x7c, 0x11, 0x33, 0xba, 0x1c, 0x61, 0x23, 0xd4, - 0x03, 0x46, 0x14, 0xdf, 0x9a, 0x6b, 0x2d, 0x73, 0x90, 0x92, 0xea, 0x4d, 0xe9, 0xcd, 0x72, 0x02, - 0x21, 0x28, 0xd2, 0x9f, 0xf2, 0xc1, 0xee, 0xc6, 0xfe, 0x41, 0x63, 0x8f, 0xac, 0xe5, 0x12, 0x94, - 0x9c, 0xb5, 0x74, 0x88, 0x29, 0xf1, 0x4f, 0x02, 0x3c, 0x1e, 0x91, 0xed, 0xa2, 0x9b, 0x00, 0xf6, - 0x50, 0x36, 0x71, 0x5b, 0x37, 0xd5, 0x68, 0x23, 0x6b, 0x0e, 0x25, 0xca, 0x21, 0xe5, 0x6c, 0xfe, - 0xcb, 0x9a, 0x80, 0x17, 0xa3, 0x97, 0xb9, 0x52, 0x32, 0x2b, 0xe7, 0xa8, 0x9d, 0x0f, 0x81, 0x45, - 0x71, 0x9b, 0x28, 0xa6, 0x6b, 0x4b, 0x15, 0x53, 0x7e, 0x74, 0x2f, 0xcc, 0xa9, 0xcc, 0xd8, 0xad, - 0x99, 0xcf, 0x9d, 0xa4, 0x1e, 0xcd, 0x9d, 0x88, 0xbf, 0x4a, 0xf8, 0x17, 0x36, 0x98, 0xdc, 0xef, - 0x41, 0xda, 0xb2, 0x15, 0x7b, 0x60, 0x71, 0x83, 0x7b, 0x71, 0xd6, 0x4a, 0x61, 0xcd, 0xf9, 0x71, - 0x40, 0xc5, 0x25, 0xae, 0xe6, 0xdb, 0xf5, 0xb6, 0xc4, 0x1b, 0x50, 0x0c, 0x2e, 0x4e, 0xf4, 0x91, - 0xf1, 0x7c, 0x8e, 0x20, 0xde, 0xf2, 0xf2, 0x2f, 0x1f, 0x68, 0x39, 0x0e, 0x08, 0xc6, 0xc3, 0x00, - 0xc1, 0x5f, 0xc7, 0xe1, 0x89, 0x09, 0xf5, 0x12, 0x7a, 0x7d, 0x64, 0x9f, 0x5f, 0x9a, 0xa7, 0xda, - 0x5a, 0x63, 0xb4, 0xe0, 0x4e, 0x8b, 0xd7, 0x61, 0xc1, 0x4f, 0x9f, 0x6d, 0x92, 0x3f, 0x49, 0x78, - 0x3e, 0x3f, 0x88, 0x5c, 0x7e, 0x65, 0x89, 0xe6, 0x88, 0x9d, 0x09, 0x73, 0xda, 0x59, 0x68, 0xb2, - 0x90, 0xf8, 0xfa, 0x92, 0x85, 0xe4, 0x23, 0x26, 0x0b, 0xfe, 0x03, 0x97, 0x0a, 0x1e, 0xb8, 0xb1, - 0xb8, 0x9e, 0x0e, 0x89, 0xeb, 0x6f, 0x02, 0xf8, 0x1a, 0x9a, 0xcb, 0x90, 0x32, 0xf5, 0x41, 0x5f, - 0xa5, 0x66, 0x92, 0x92, 0xd8, 0x03, 0xba, 0x01, 0x29, 0x62, 0x6e, 0xce, 0x62, 0x8e, 0x7b, 0x5e, - 0x62, 0x2e, 0x3e, 0xcc, 0x98, 0x71, 0x8b, 0x1a, 0xa0, 0xf1, 0xa6, 0x52, 0xc4, 0x27, 0x5e, 0x09, - 0x7e, 0xe2, 0xc9, 0xc8, 0xf6, 0x54, 0xf8, 0xa7, 0xde, 0x83, 0x14, 0x35, 0x0f, 0x92, 0xdf, 0xd0, - 0xc6, 0x28, 0x2f, 0x98, 0xc9, 0x6f, 0xf4, 0x43, 0x00, 0xc5, 0xb6, 0x4d, 0xad, 0x35, 0xf0, 0x3e, - 0xb0, 0x1a, 0x6e, 0x5e, 0x1b, 0x0e, 0xdf, 0xe6, 0x39, 0x6e, 0x67, 0xcb, 0x9e, 0xa8, 0xcf, 0xd6, - 0x7c, 0x0a, 0xc5, 0x5d, 0x28, 0x06, 0x65, 0x9d, 0x12, 0x8f, 0x8d, 0x21, 0x58, 0xe2, 0xb1, 0x8a, - 0x9d, 0x97, 0x78, 0x6e, 0x81, 0x98, 0x60, 0x3d, 0x70, 0xfa, 0x20, 0xfe, 0x2b, 0x0e, 0x0b, 0x7e, - 0xeb, 0xfc, 0x5f, 0xab, 0x92, 0xc4, 0x0f, 0xe2, 0x90, 0x75, 0x27, 0x1f, 0xd1, 0x80, 0xf6, 0xd6, - 0x4e, 0xf0, 0xb7, 0x5b, 0x59, 0x47, 0x3b, 0xe1, 0xf6, 0xc9, 0x6f, 0xb9, 0x09, 0x55, 0x14, 0xa8, - 0xed, 0x5f, 0x69, 0xe7, 0xaa, 0x00, 0xcf, 0x1f, 0x7f, 0xc6, 0xc7, 0x41, 0x32, 0x09, 0xf4, 0x1d, - 0x48, 0x2b, 0x6d, 0x17, 0xca, 0x2f, 0x86, 0x60, 0xbb, 0x0e, 0xeb, 0x5a, 0x73, 0xb8, 0x41, 0x39, - 0x25, 0x2e, 0xc1, 0x47, 0x25, 0xb8, 0x7d, 0xf6, 0x57, 0x89, 0x5e, 0xc6, 0x13, 0x74, 0x9b, 0x45, - 0x80, 0xc3, 0xdd, 0x7b, 0x7b, 0x5b, 0xdb, 0xb7, 0xb7, 0xeb, 0x5b, 0x3c, 0xa5, 0xda, 0xda, 0xaa, - 0x6f, 0x95, 0x05, 0xc2, 0x27, 0xd5, 0xef, 0xed, 0xdd, 0xaf, 0x6f, 0x95, 0x13, 0xe2, 0x2d, 0xc8, - 0xb9, 0xae, 0x07, 0x55, 0x20, 0xe3, 0xb4, 0x25, 0xe2, 0xdc, 0x01, 0xf0, 0x2e, 0xd3, 0x32, 0xa4, - 0x0c, 0xfd, 0x5d, 0xde, 0x65, 0x4e, 0x48, 0xec, 0x41, 0x54, 0xa1, 0x34, 0xe2, 0xb7, 0xd0, 0x2d, - 0xc8, 0x18, 0x83, 0x96, 0xec, 0x18, 0xed, 0x48, 0x13, 0xc7, 0x41, 0x1a, 0x06, 0xad, 0xae, 0xd6, - 0xbe, 0x8b, 0x4f, 0x9d, 0x65, 0x32, 0x06, 0xad, 0xbb, 0xcc, 0xb6, 0xd9, 0x57, 0x04, 0xff, 0x57, - 0x7e, 0x14, 0x87, 0xac, 0x73, 0x56, 0xd1, 0x77, 0x21, 0xe7, 0xfa, 0x44, 0xf7, 0xee, 0x4d, 0xa4, - 0x33, 0xe5, 0xfa, 0x3d, 0x11, 0x74, 0x15, 0x16, 0x2d, 0xed, 0xb8, 0xef, 0xf4, 0xb0, 0x18, 0xb4, - 0x27, 0xd0, 0x43, 0x53, 0x62, 0x2f, 0x76, 0x1c, 0x3c, 0xea, 0x4e, 0x32, 0x9b, 0x28, 0x27, 0xef, - 0x24, 0xb3, 0xc9, 0x72, 0x8a, 0x84, 0xc5, 0xf2, 0xa8, 0xe3, 0xf8, 0x26, 0x07, 0x13, 0x12, 0xbe, - 0x13, 0x61, 0xe1, 0xfb, 0x7d, 0x01, 0xf2, 0xbe, 0x2e, 0x19, 0xfa, 0x7f, 0x9f, 0x17, 0x2b, 0x86, - 0xc4, 0x1d, 0x1f, 0xaf, 0x77, 0xc5, 0x23, 0x38, 0x31, 0x61, 0xfe, 0x89, 0x45, 0x35, 0x25, 0x9d, - 0x66, 0x5b, 0x72, 0xee, 0x66, 0xdb, 0xb3, 0x80, 0x6c, 0xdd, 0x56, 0xba, 0xf2, 0x89, 0x6e, 0x6b, - 0xfd, 0x63, 0x99, 0xd9, 0x09, 0xf3, 0x39, 0x65, 0xfa, 0xe6, 0x3e, 0x7d, 0xb1, 0xef, 0x9a, 0x8c, - 0x5b, 0x03, 0xce, 0x7b, 0x63, 0xe3, 0x0c, 0xa4, 0x79, 0x99, 0xc3, 0xae, 0x6c, 0xf0, 0xa7, 0xd0, - 0xae, 0x62, 0x15, 0xb2, 0x3d, 0x6c, 0x2b, 0xd4, 0x81, 0xb2, 0x98, 0xe9, 0x3e, 0x5f, 0x7d, 0x09, - 0xf2, 0xbe, 0xcb, 0x33, 0xc4, 0xa7, 0xee, 0xd6, 0xdf, 0x28, 0xc7, 0xaa, 0x99, 0x0f, 0x3f, 0xbe, - 0x90, 0xd8, 0xc5, 0xef, 0x92, 0xe3, 0x26, 0xd5, 0x6b, 0x8d, 0x7a, 0xed, 0x6e, 0x39, 0x5e, 0xcd, - 0x7f, 0xf8, 0xf1, 0x85, 0x8c, 0x84, 0x69, 0x13, 0xe8, 0xea, 0x5d, 0x28, 0x8d, 0x6c, 0x4c, 0xf0, - 0x74, 0x23, 0x28, 0x6e, 0x1d, 0xee, 0xef, 0x6c, 0xd7, 0x36, 0x9a, 0x75, 0xf9, 0xfe, 0x5e, 0xb3, - 0x5e, 0x8e, 0xa3, 0xc7, 0x61, 0x69, 0x67, 0xfb, 0xb5, 0x46, 0x53, 0xae, 0xed, 0x6c, 0xd7, 0x77, - 0x9b, 0xf2, 0x46, 0xb3, 0xb9, 0x51, 0xbb, 0x5b, 0x16, 0xd6, 0x7f, 0x93, 0x87, 0xd2, 0xc6, 0x66, - 0x6d, 0x9b, 0x14, 0x7a, 0x5a, 0x5b, 0xa1, 0xbe, 0xa2, 0x06, 0x49, 0x8a, 0x28, 0x4f, 0xbc, 0x0e, - 0x5d, 0x9d, 0xdc, 0x25, 0x44, 0xb7, 0x21, 0x45, 0xc1, 0x66, 0x34, 0xf9, 0x7e, 0x74, 0x75, 0x4a, - 0xdb, 0x90, 0x0c, 0x86, 0x1e, 0xa7, 0x89, 0x17, 0xa6, 0xab, 0x93, 0xbb, 0x88, 0x68, 0x07, 0x32, - 0x0e, 0x16, 0x38, 0xed, 0xea, 0x71, 0x75, 0x6a, 0x3b, 0x8e, 0x4c, 0x8d, 0x61, 0xb6, 0x93, 0xef, - 0x52, 0x57, 0xa7, 0xf4, 0x17, 0xd1, 0x36, 0xa4, 0x39, 0x5c, 0x32, 0xe5, 0x1a, 0x71, 0x75, 0x5a, - 0x5b, 0x0d, 0x49, 0x90, 0xf3, 0xd0, 0xf0, 0xe9, 0x37, 0xc4, 0xab, 0x33, 0xb4, 0x4e, 0xd1, 0x03, - 0x28, 0x04, 0x21, 0x98, 0xd9, 0xae, 0x2a, 0x57, 0x67, 0x6c, 0xe0, 0x11, 0xfd, 0x41, 0x3c, 0x66, - 0xb6, 0xab, 0xcb, 0xd5, 0x19, 0xfb, 0x79, 0xe8, 0x6d, 0x58, 0x1c, 0xc7, 0x4b, 0x66, 0xbf, 0xc9, - 0x5c, 0x9d, 0xa3, 0xc3, 0x87, 0x7a, 0x80, 0x42, 0x70, 0x96, 0x39, 0x2e, 0x36, 0x57, 0xe7, 0x69, - 0xf8, 0x21, 0x15, 0x4a, 0xa3, 0xd8, 0xc5, 0xac, 0x17, 0x9d, 0xab, 0x33, 0x37, 0xff, 0xd8, 0x57, - 0x82, 0x85, 0xfc, 0xac, 0x17, 0x9f, 0xab, 0x33, 0xf7, 0x02, 0xd1, 0x21, 0x80, 0xaf, 0x10, 0x9d, - 0xe1, 0x22, 0x74, 0x75, 0x96, 0xae, 0x20, 0x32, 0x60, 0x29, 0xac, 0x42, 0x9d, 0xe7, 0x5e, 0x74, - 0x75, 0xae, 0x66, 0x21, 0xb1, 0xe7, 0x60, 0xad, 0x39, 0xdb, 0x3d, 0xe9, 0xea, 0x8c, 0x5d, 0xc3, - 0xcd, 0xfa, 0x27, 0x9f, 0xaf, 0xc4, 0x3f, 0xfd, 0x7c, 0x25, 0xfe, 0xf7, 0xcf, 0x57, 0xe2, 0x1f, - 0x7d, 0xb1, 0x12, 0xfb, 0xf4, 0x8b, 0x95, 0xd8, 0x5f, 0xbe, 0x58, 0x89, 0x7d, 0xef, 0x99, 0x63, - 0xcd, 0xee, 0x0c, 0x5a, 0x6b, 0x6d, 0xbd, 0x77, 0xcd, 0xff, 0x97, 0x99, 0xb0, 0xbf, 0xf1, 0xb4, - 0xd2, 0x34, 0xa0, 0x5e, 0xff, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x97, 0x52, 0xf8, 0x77, 0xe6, - 0x33, 0x00, 0x00, + // 3451 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x5b, 0xcb, 0x73, 0x23, 0xe5, + 0xb5, 0x97, 0x5a, 0xef, 0x23, 0xeb, 0xe1, 0xcf, 0x66, 0xd0, 0x88, 0x19, 0x7b, 0xe8, 0xa9, 0x81, + 0x99, 0x01, 0x3c, 0x5c, 0xcf, 0x1d, 0x18, 0xee, 0xc0, 0xa5, 0x6c, 0x59, 0x83, 0xcc, 0x78, 0x6c, + 0xd3, 0x96, 0x4d, 0x71, 0x6f, 0x32, 0x4d, 0x4b, 0xfd, 0xd9, 0x6a, 0x46, 0x52, 0x37, 0xdd, 0x2d, + 0x23, 0xb3, 0x0c, 0xc5, 0x86, 0x4a, 0x55, 0xd8, 0xa4, 0x92, 0x54, 0x85, 0x5d, 0x52, 0x95, 0xfc, + 0x07, 0x59, 0x65, 0x95, 0x05, 0x8b, 0x2c, 0x58, 0x25, 0xa9, 0x2c, 0x48, 0x0a, 0x76, 0xf9, 0x07, + 0xb2, 0x4b, 0x52, 0xdf, 0xa3, 0x5f, 0x52, 0xb7, 0x1e, 0x0c, 0x50, 0x95, 0x0a, 0x3b, 0xf5, 0xe9, + 0x73, 0x4e, 0x7f, 0x8f, 0xf3, 0x9d, 0xc7, 0xef, 0x7c, 0x82, 0x27, 0x6c, 0xdc, 0x57, 0xb1, 0xd9, + 0xd3, 0xfa, 0xf6, 0x0d, 0xa5, 0xd5, 0xd6, 0x6e, 0xd8, 0x67, 0x06, 0xb6, 0xd6, 0x0c, 0x53, 0xb7, + 0x75, 0x54, 0xf2, 0x5e, 0xae, 0x91, 0x97, 0xd5, 0x8b, 0x3e, 0xee, 0xb6, 0x79, 0x66, 0xd8, 0xfa, + 0x0d, 0xc3, 0xd4, 0xf5, 0x63, 0xc6, 0x5f, 0xbd, 0xe0, 0x7b, 0x4d, 0xf5, 0xf8, 0xb5, 0x05, 0xde, + 0x72, 0xe1, 0x87, 0xf8, 0xcc, 0x79, 0x7b, 0x71, 0x4c, 0xd6, 0x50, 0x4c, 0xa5, 0xe7, 0xbc, 0x5e, + 0x3d, 0xd1, 0xf5, 0x93, 0x2e, 0xbe, 0x41, 0x9f, 0x5a, 0x83, 0xe3, 0x1b, 0xb6, 0xd6, 0xc3, 0x96, + 0xad, 0xf4, 0x0c, 0xce, 0xb0, 0x7c, 0xa2, 0x9f, 0xe8, 0xf4, 0xe7, 0x0d, 0xf2, 0x8b, 0x51, 0xc5, + 0x7f, 0x02, 0x64, 0x24, 0xfc, 0xee, 0x00, 0x5b, 0x36, 0x5a, 0x87, 0x24, 0x6e, 0x77, 0xf4, 0x4a, + 0xfc, 0x52, 0xfc, 0x6a, 0x7e, 0xfd, 0xc2, 0xda, 0xc8, 0xe4, 0xd6, 0x38, 0x5f, 0xbd, 0xdd, 0xd1, + 0x1b, 0x31, 0x89, 0xf2, 0xa2, 0x5b, 0x90, 0x3a, 0xee, 0x0e, 0xac, 0x4e, 0x45, 0xa0, 0x42, 0x17, + 0xa3, 0x84, 0xee, 0x12, 0xa6, 0x46, 0x4c, 0x62, 0xdc, 0xe4, 0x53, 0x5a, 0xff, 0x58, 0xaf, 0x24, + 0x26, 0x7f, 0x6a, 0xbb, 0x7f, 0x4c, 0x3f, 0x45, 0x78, 0xd1, 0x26, 0x80, 0xd6, 0xd7, 0x6c, 0xb9, + 0xdd, 0x51, 0xb4, 0x7e, 0x25, 0x49, 0x25, 0x9f, 0x8c, 0x96, 0xd4, 0xec, 0x1a, 0x61, 0x6c, 0xc4, + 0xa4, 0x9c, 0xe6, 0x3c, 0x90, 0xe1, 0xbe, 0x3b, 0xc0, 0xe6, 0x59, 0x25, 0x35, 0x79, 0xb8, 0x6f, + 0x10, 0x26, 0x32, 0x5c, 0xca, 0x8d, 0xb6, 0x21, 0xdf, 0xc2, 0x27, 0x5a, 0x5f, 0x6e, 0x75, 0xf5, + 0xf6, 0xc3, 0x4a, 0x9a, 0x0a, 0x8b, 0x51, 0xc2, 0x9b, 0x84, 0x75, 0x93, 0x70, 0x6e, 0x0a, 0x95, + 0x78, 0x23, 0x26, 0x41, 0xcb, 0xa5, 0xa0, 0x97, 0x21, 0xdb, 0xee, 0xe0, 0xf6, 0x43, 0xd9, 0x1e, + 0x56, 0x32, 0x54, 0xcf, 0x6a, 0x94, 0x9e, 0x1a, 0xe1, 0x6b, 0x0e, 0x1b, 0x31, 0x29, 0xd3, 0x66, + 0x3f, 0xd1, 0x5d, 0x00, 0x15, 0x77, 0xb5, 0x53, 0x6c, 0x12, 0xf9, 0xec, 0xe4, 0x35, 0xd8, 0x62, + 0x9c, 0xcd, 0x21, 0x1f, 0x46, 0x4e, 0x75, 0x08, 0xa8, 0x06, 0x39, 0xdc, 0x57, 0xf9, 0x74, 0x72, + 0x54, 0xcd, 0xa5, 0xc8, 0xfd, 0xee, 0xab, 0xfe, 0xc9, 0x64, 0x31, 0x7f, 0x46, 0xb7, 0x21, 0xdd, + 0xd6, 0x7b, 0x3d, 0xcd, 0xae, 0x00, 0xd5, 0xb0, 0x12, 0x39, 0x11, 0xca, 0xd5, 0x88, 0x49, 0x9c, + 0x1f, 0xed, 0x42, 0xb1, 0xab, 0x59, 0xb6, 0x6c, 0xf5, 0x15, 0xc3, 0xea, 0xe8, 0xb6, 0x55, 0xc9, + 0x53, 0x0d, 0x57, 0xa2, 0x34, 0xec, 0x68, 0x96, 0x7d, 0xe0, 0x30, 0x37, 0x62, 0x52, 0xa1, 0xeb, + 0x27, 0x10, 0x7d, 0xfa, 0xf1, 0x31, 0x36, 0x5d, 0x85, 0x95, 0x85, 0xc9, 0xfa, 0xf6, 0x08, 0xb7, + 0x23, 0x4f, 0xf4, 0xe9, 0x7e, 0x02, 0xfa, 0x7f, 0x58, 0xea, 0xea, 0x8a, 0xea, 0xaa, 0x93, 0xdb, + 0x9d, 0x41, 0xff, 0x61, 0xa5, 0x40, 0x95, 0x5e, 0x8b, 0x1c, 0xa4, 0xae, 0xa8, 0x8e, 0x8a, 0x1a, + 0x11, 0x68, 0xc4, 0xa4, 0xc5, 0xee, 0x28, 0x11, 0x3d, 0x80, 0x65, 0xc5, 0x30, 0xba, 0x67, 0xa3, + 0xda, 0x8b, 0x54, 0xfb, 0xf5, 0x28, 0xed, 0x1b, 0x44, 0x66, 0x54, 0x3d, 0x52, 0xc6, 0xa8, 0xa8, + 0x09, 0x65, 0xc3, 0xc4, 0x86, 0x62, 0x62, 0xd9, 0x30, 0x75, 0x43, 0xb7, 0x94, 0x6e, 0xa5, 0x44, + 0x75, 0x3f, 0x1d, 0xa5, 0x7b, 0x9f, 0xf1, 0xef, 0x73, 0xf6, 0x46, 0x4c, 0x2a, 0x19, 0x41, 0x12, + 0xd3, 0xaa, 0xb7, 0xb1, 0x65, 0x79, 0x5a, 0xcb, 0xd3, 0xb4, 0x52, 0xfe, 0xa0, 0xd6, 0x00, 0x09, + 0xd5, 0x21, 0x8f, 0x87, 0x44, 0x5c, 0x3e, 0xd5, 0x6d, 0x5c, 0x59, 0x9c, 0x7c, 0xb0, 0xea, 0x94, + 0xf5, 0x48, 0xb7, 0x31, 0x39, 0x54, 0xd8, 0x7d, 0x42, 0x0a, 0x3c, 0x76, 0x8a, 0x4d, 0xed, 0xf8, + 0x8c, 0xaa, 0x91, 0xe9, 0x1b, 0x4b, 0xd3, 0xfb, 0x15, 0x44, 0x15, 0x3e, 0x13, 0xa5, 0xf0, 0x88, + 0x0a, 0x11, 0x15, 0x75, 0x47, 0xa4, 0x11, 0x93, 0x96, 0x4e, 0xc7, 0xc9, 0xc4, 0xc4, 0x8e, 0xb5, + 0xbe, 0xd2, 0xd5, 0xde, 0xc7, 0xfc, 0xd8, 0x2c, 0x4d, 0x36, 0xb1, 0xbb, 0x9c, 0x9b, 0x9e, 0x15, + 0x62, 0x62, 0xc7, 0x7e, 0xc2, 0x66, 0x06, 0x52, 0xa7, 0x4a, 0x77, 0x80, 0xc5, 0xa7, 0x21, 0xef, + 0x73, 0xac, 0xa8, 0x02, 0x99, 0x1e, 0xb6, 0x2c, 0xe5, 0x04, 0x53, 0x3f, 0x9c, 0x93, 0x9c, 0x47, + 0xb1, 0x08, 0x0b, 0x7e, 0x67, 0x2a, 0x7e, 0x1c, 0x77, 0x25, 0x89, 0x9f, 0x24, 0x92, 0xa7, 0xd8, + 0xa4, 0xd3, 0xe6, 0x92, 0xfc, 0x11, 0x5d, 0x86, 0x02, 0x1d, 0xb2, 0xec, 0xbc, 0x27, 0xce, 0x3a, + 0x29, 0x2d, 0x50, 0xe2, 0x11, 0x67, 0x5a, 0x85, 0xbc, 0xb1, 0x6e, 0xb8, 0x2c, 0x09, 0xca, 0x02, + 0xc6, 0xba, 0xe1, 0x30, 0x3c, 0x09, 0x0b, 0x64, 0x7e, 0x2e, 0x47, 0x92, 0x7e, 0x24, 0x4f, 0x68, + 0x9c, 0x45, 0xfc, 0xbd, 0x00, 0xe5, 0x51, 0x07, 0x8c, 0x6e, 0x43, 0x92, 0xc4, 0x22, 0x1e, 0x56, + 0xaa, 0x6b, 0x2c, 0x50, 0xad, 0x39, 0x81, 0x6a, 0xad, 0xe9, 0x04, 0xaa, 0xcd, 0xec, 0xa7, 0x9f, + 0xaf, 0xc6, 0x3e, 0xfe, 0xcb, 0x6a, 0x5c, 0xa2, 0x12, 0xe8, 0x3c, 0xf1, 0x95, 0x8a, 0xd6, 0x97, + 0x35, 0x95, 0x0e, 0x39, 0x47, 0x1c, 0xa1, 0xa2, 0xf5, 0xb7, 0x55, 0xb4, 0x03, 0xe5, 0xb6, 0xde, + 0xb7, 0x70, 0xdf, 0x1a, 0x58, 0x32, 0x0b, 0x84, 0x3c, 0x98, 0x04, 0xdc, 0x21, 0x0b, 0xaf, 0x35, + 0x87, 0x73, 0x9f, 0x32, 0x4a, 0xa5, 0x76, 0x90, 0x40, 0xdc, 0xea, 0xa9, 0xd2, 0xd5, 0x54, 0xc5, + 0xd6, 0x4d, 0xab, 0x92, 0xbc, 0x94, 0x08, 0xf5, 0x87, 0x47, 0x0e, 0xcb, 0xa1, 0xa1, 0x2a, 0x36, + 0xde, 0x4c, 0x92, 0xe1, 0x4a, 0x3e, 0x49, 0xf4, 0x14, 0x94, 0x14, 0xc3, 0x90, 0x2d, 0x5b, 0xb1, + 0xb1, 0xdc, 0x3a, 0xb3, 0xb1, 0x45, 0x03, 0xcd, 0x82, 0x54, 0x50, 0x0c, 0xe3, 0x80, 0x50, 0x37, + 0x09, 0x11, 0x5d, 0x81, 0x22, 0x89, 0x49, 0x9a, 0xd2, 0x95, 0x3b, 0x58, 0x3b, 0xe9, 0xd8, 0x34, + 0xa4, 0x24, 0xa4, 0x02, 0xa7, 0x36, 0x28, 0x51, 0x54, 0xdd, 0x1d, 0xa7, 0xf1, 0x08, 0x21, 0x48, + 0xaa, 0x8a, 0xad, 0xd0, 0x95, 0x5c, 0x90, 0xe8, 0x6f, 0x42, 0x33, 0x14, 0xbb, 0xc3, 0xd7, 0x87, + 0xfe, 0x46, 0xe7, 0x20, 0xcd, 0xd5, 0x26, 0xa8, 0x5a, 0xfe, 0x84, 0x96, 0x21, 0x65, 0x98, 0xfa, + 0x29, 0xa6, 0x5b, 0x97, 0x95, 0xd8, 0x83, 0xf8, 0x81, 0x00, 0x8b, 0x63, 0x91, 0x8b, 0xe8, 0xed, + 0x28, 0x56, 0xc7, 0xf9, 0x16, 0xf9, 0x8d, 0x5e, 0x20, 0x7a, 0x15, 0x15, 0x9b, 0x3c, 0xda, 0x57, + 0xc6, 0x97, 0xba, 0x41, 0xdf, 0xf3, 0xa5, 0xe1, 0xdc, 0xe8, 0x1e, 0x94, 0xbb, 0x8a, 0x65, 0xcb, + 0xcc, 0xfb, 0xcb, 0xbe, 0xc8, 0xff, 0xc4, 0xd8, 0x22, 0xb3, 0x58, 0x41, 0x0c, 0x9a, 0x2b, 0x29, + 0x12, 0x51, 0x8f, 0x8a, 0x0e, 0x61, 0xb9, 0x75, 0xf6, 0xbe, 0xd2, 0xb7, 0xb5, 0x3e, 0x96, 0xc7, + 0x76, 0x6d, 0x3c, 0x95, 0xb8, 0xaf, 0x59, 0x2d, 0xdc, 0x51, 0x4e, 0x35, 0xdd, 0x19, 0xd6, 0x92, + 0x2b, 0xef, 0xee, 0xa8, 0x25, 0x4a, 0x50, 0x0c, 0x86, 0x5d, 0x54, 0x04, 0xc1, 0x1e, 0xf2, 0xf9, + 0x0b, 0xf6, 0x10, 0x3d, 0x0f, 0x49, 0x32, 0x47, 0x3a, 0xf7, 0x62, 0xc8, 0x87, 0xb8, 0x5c, 0xf3, + 0xcc, 0xc0, 0x12, 0xe5, 0x14, 0x45, 0xf7, 0x34, 0xb8, 0xa1, 0x78, 0x54, 0xab, 0x78, 0x0d, 0x4a, + 0x23, 0x71, 0xd6, 0xb7, 0x7d, 0x71, 0xff, 0xf6, 0x89, 0x25, 0x28, 0x04, 0x02, 0xaa, 0x78, 0x0e, + 0x96, 0xc3, 0xe2, 0xa3, 0xd8, 0x71, 0xe9, 0x81, 0x38, 0x87, 0x6e, 0x41, 0xd6, 0x0d, 0x90, 0xec, + 0x34, 0x9e, 0x1f, 0x9b, 0x85, 0xc3, 0x2c, 0xb9, 0xac, 0xe4, 0x18, 0x12, 0xab, 0xa6, 0xe6, 0x20, + 0xd0, 0x81, 0x67, 0x14, 0xc3, 0x68, 0x28, 0x56, 0x47, 0x7c, 0x1b, 0x2a, 0x51, 0xc1, 0x6f, 0x64, + 0x1a, 0x49, 0xd7, 0x0a, 0xcf, 0x41, 0xfa, 0x58, 0x37, 0x7b, 0x8a, 0x4d, 0x95, 0x15, 0x24, 0xfe, + 0x44, 0xac, 0x93, 0x05, 0xc2, 0x04, 0x25, 0xb3, 0x07, 0x51, 0x86, 0xf3, 0x91, 0x01, 0x90, 0x88, + 0x68, 0x7d, 0x15, 0xb3, 0xf5, 0x2c, 0x48, 0xec, 0xc1, 0x53, 0xc4, 0x06, 0xcb, 0x1e, 0xc8, 0x67, + 0x2d, 0x3a, 0x57, 0xaa, 0x3f, 0x27, 0xf1, 0x27, 0xf1, 0xd7, 0x09, 0x38, 0x17, 0x1e, 0x06, 0xd1, + 0x25, 0x58, 0xe8, 0x29, 0x43, 0xd9, 0x1e, 0xf2, 0xb3, 0xcc, 0xb6, 0x03, 0x7a, 0xca, 0xb0, 0x39, + 0x64, 0x07, 0xb9, 0x0c, 0x09, 0x7b, 0x68, 0x55, 0x84, 0x4b, 0x89, 0xab, 0x0b, 0x12, 0xf9, 0x89, + 0x0e, 0x61, 0xb1, 0xab, 0xb7, 0x95, 0xae, 0xec, 0xb3, 0x78, 0x6e, 0xec, 0x97, 0xc7, 0x16, 0x9b, + 0x05, 0x34, 0xac, 0x8e, 0x19, 0x7d, 0x89, 0xea, 0xd8, 0x71, 0x2d, 0xff, 0x1b, 0xb2, 0x7a, 0xdf, + 0x1e, 0xa5, 0x02, 0x9e, 0xc2, 0xf1, 0xd9, 0xe9, 0xb9, 0x7d, 0xf6, 0xf3, 0xb0, 0xdc, 0xc7, 0x43, + 0xdb, 0x37, 0x46, 0x66, 0x38, 0x19, 0xba, 0x17, 0x88, 0xbc, 0xf3, 0xbe, 0x4f, 0x6c, 0x08, 0x5d, + 0xa3, 0x99, 0x85, 0xa1, 0x5b, 0xd8, 0x94, 0x15, 0x55, 0x35, 0xb1, 0x65, 0xd1, 0xcc, 0x76, 0x81, + 0xa6, 0x0b, 0x94, 0xbe, 0xc1, 0xc8, 0xe2, 0xcf, 0xfc, 0x7b, 0x15, 0xcc, 0x24, 0xf8, 0x4e, 0xc4, + 0xbd, 0x9d, 0x38, 0x80, 0x65, 0x2e, 0xaf, 0x06, 0x36, 0x43, 0x98, 0xd5, 0xf3, 0x20, 0x47, 0x7c, + 0x86, 0x7d, 0x48, 0x3c, 0xda, 0x3e, 0x38, 0xde, 0x36, 0xe9, 0xf3, 0xb6, 0xff, 0x66, 0x7b, 0xf3, + 0xaa, 0x1b, 0x45, 0xbc, 0x34, 0x2d, 0x34, 0x8a, 0x78, 0xf3, 0x12, 0x02, 0xee, 0xed, 0xe7, 0x71, + 0xa8, 0x46, 0xe7, 0x65, 0xa1, 0xaa, 0x9e, 0x81, 0x45, 0x77, 0x2e, 0xee, 0xf8, 0xd8, 0xa9, 0x2f, + 0xbb, 0x2f, 0xf8, 0x00, 0x23, 0xa3, 0xe2, 0x15, 0x28, 0x8e, 0x64, 0x8d, 0x6c, 0x17, 0x0a, 0xa7, + 0xfe, 0xef, 0x8b, 0x3f, 0x4e, 0xb8, 0x5e, 0x35, 0x90, 0xda, 0x85, 0x58, 0xde, 0x1b, 0xb0, 0xa4, + 0xe2, 0xb6, 0xa6, 0x7e, 0x55, 0xc3, 0x5b, 0xe4, 0xd2, 0xdf, 0xd9, 0xdd, 0x0c, 0x76, 0xf7, 0xc7, + 0x3c, 0x64, 0x25, 0x6c, 0x19, 0x24, 0xa5, 0x43, 0x9b, 0x90, 0xc3, 0xc3, 0x36, 0x36, 0x6c, 0x27, + 0x0b, 0x0e, 0xaf, 0x26, 0x18, 0x77, 0xdd, 0xe1, 0x24, 0xb5, 0xb1, 0x2b, 0x86, 0x6e, 0x72, 0x18, + 0x24, 0x1a, 0xd1, 0xe0, 0xe2, 0x7e, 0x1c, 0xe4, 0x05, 0x07, 0x07, 0x49, 0x44, 0x96, 0xc2, 0x4c, + 0x6a, 0x04, 0x08, 0xb9, 0xc9, 0x81, 0x90, 0xe4, 0x94, 0x8f, 0x05, 0x90, 0x90, 0x5a, 0x00, 0x09, + 0x49, 0x4d, 0x99, 0x66, 0x04, 0x14, 0xf2, 0x82, 0x03, 0x85, 0xa4, 0xa7, 0x8c, 0x78, 0x04, 0x0b, + 0x79, 0x3d, 0x88, 0x85, 0x64, 0x22, 0x42, 0x9b, 0x23, 0x3d, 0x11, 0x0c, 0x79, 0xc5, 0x07, 0x86, + 0x64, 0x23, 0x51, 0x08, 0xa6, 0x28, 0x04, 0x0d, 0x79, 0x2d, 0x80, 0x86, 0xe4, 0xa6, 0xac, 0xc3, + 0x04, 0x38, 0x64, 0xcb, 0x0f, 0x87, 0x40, 0x24, 0xaa, 0xc2, 0xf7, 0x3d, 0x0a, 0x0f, 0x79, 0xc9, + 0xc5, 0x43, 0xf2, 0x91, 0xc0, 0x0e, 0x9f, 0xcb, 0x28, 0x20, 0xb2, 0x37, 0x06, 0x88, 0x30, 0x00, + 0xe3, 0xa9, 0x48, 0x15, 0x53, 0x10, 0x91, 0xbd, 0x31, 0x44, 0xa4, 0x30, 0x45, 0xe1, 0x14, 0x48, + 0xe4, 0x7b, 0xe1, 0x90, 0x48, 0x34, 0x68, 0xc1, 0x87, 0x39, 0x1b, 0x26, 0x22, 0x47, 0x60, 0x22, + 0xa5, 0xc8, 0xfa, 0x9d, 0xa9, 0x9f, 0x19, 0x14, 0x39, 0x0c, 0x01, 0x45, 0x18, 0x7c, 0x71, 0x35, + 0x52, 0xf9, 0x0c, 0xa8, 0xc8, 0x61, 0x08, 0x2a, 0xb2, 0x38, 0x55, 0xed, 0x54, 0x58, 0xe4, 0x6e, + 0x10, 0x16, 0x41, 0x53, 0xce, 0x58, 0x24, 0x2e, 0xd2, 0x8a, 0xc2, 0x45, 0x18, 0x76, 0xf1, 0x6c, + 0xa4, 0xc6, 0x39, 0x80, 0x91, 0xbd, 0x31, 0x60, 0x64, 0x79, 0x8a, 0xa5, 0xcd, 0x8a, 0x8c, 0x5c, + 0x23, 0x19, 0xc5, 0x88, 0xab, 0x26, 0xc9, 0x3d, 0x36, 0x4d, 0xdd, 0xe4, 0x18, 0x07, 0x7b, 0x10, + 0xaf, 0x92, 0x4a, 0xd9, 0x73, 0xcb, 0x13, 0x50, 0x14, 0x5a, 0x44, 0xf9, 0x5c, 0xb1, 0xf8, 0x9b, + 0xb8, 0x27, 0x4b, 0x0b, 0x4c, 0x7f, 0x95, 0x9d, 0xe3, 0x55, 0xb6, 0x0f, 0x5b, 0x11, 0x82, 0xd8, + 0xca, 0x2a, 0xe4, 0x49, 0x71, 0x34, 0x02, 0x9b, 0x28, 0x86, 0x0b, 0x9b, 0x5c, 0x87, 0x45, 0x9a, + 0x04, 0x30, 0x04, 0x86, 0x47, 0xd6, 0x24, 0x8d, 0xac, 0x25, 0xf2, 0x82, 0xad, 0x02, 0x0b, 0xb1, + 0xcf, 0xc1, 0x92, 0x8f, 0xd7, 0x2d, 0xba, 0x18, 0x86, 0x50, 0x76, 0xb9, 0x37, 0x78, 0xf5, 0xf5, + 0xbb, 0xb8, 0xb7, 0x42, 0x1e, 0xde, 0x12, 0x06, 0x8d, 0xc4, 0xbf, 0x26, 0x68, 0x44, 0xf8, 0xca, + 0xd0, 0x88, 0xbf, 0x88, 0x4c, 0x04, 0x8b, 0xc8, 0xbf, 0xc7, 0xbd, 0x3d, 0x71, 0x81, 0x8e, 0xb6, + 0xae, 0x62, 0x5e, 0xd6, 0xd1, 0xdf, 0x24, 0xcd, 0xea, 0xea, 0x27, 0xbc, 0x78, 0x23, 0x3f, 0x09, + 0x97, 0x1b, 0x3b, 0x73, 0x3c, 0x34, 0xba, 0x15, 0x21, 0xcb, 0x5d, 0x78, 0x45, 0x58, 0x86, 0xc4, + 0x43, 0xcc, 0x22, 0xdd, 0x82, 0x44, 0x7e, 0x12, 0x3e, 0x6a, 0x64, 0x3c, 0x07, 0x61, 0x0f, 0xe8, + 0x36, 0xe4, 0x68, 0xbb, 0x46, 0xd6, 0x0d, 0x8b, 0x07, 0xa4, 0x40, 0xba, 0xc6, 0xba, 0x32, 0x6b, + 0xfb, 0x84, 0x67, 0xcf, 0xb0, 0xa4, 0xac, 0xc1, 0x7f, 0xf9, 0x92, 0xa6, 0x5c, 0x20, 0x69, 0xba, + 0x00, 0x39, 0x32, 0x7a, 0xcb, 0x50, 0xda, 0x98, 0x46, 0x96, 0x9c, 0xe4, 0x11, 0xc4, 0x07, 0x80, + 0xc6, 0xe3, 0x24, 0x6a, 0x40, 0x1a, 0x9f, 0xe2, 0xbe, 0xcd, 0x72, 0xca, 0xfc, 0xfa, 0xb9, 0xf1, + 0xba, 0x91, 0xbc, 0xde, 0xac, 0x90, 0x45, 0xfe, 0xdb, 0xe7, 0xab, 0x65, 0xc6, 0xfd, 0xac, 0xde, + 0xd3, 0x6c, 0xdc, 0x33, 0xec, 0x33, 0x89, 0xcb, 0x8b, 0x7f, 0x16, 0xa0, 0x34, 0x12, 0x3f, 0x43, + 0xd7, 0xd6, 0x31, 0x79, 0xc1, 0x07, 0x2c, 0xcd, 0xb6, 0xde, 0x17, 0x01, 0x4e, 0x14, 0x4b, 0x7e, + 0x4f, 0xe9, 0xdb, 0x58, 0xe5, 0x8b, 0x9e, 0x3b, 0x51, 0xac, 0x37, 0x29, 0x81, 0xec, 0x3a, 0x79, + 0x3d, 0xb0, 0xb0, 0xca, 0x21, 0xae, 0xcc, 0x89, 0x62, 0x1d, 0x5a, 0x58, 0xf5, 0xcd, 0x32, 0xf3, + 0x68, 0xb3, 0x0c, 0xae, 0x71, 0x76, 0x64, 0x8d, 0x7d, 0x75, 0x7f, 0xce, 0x5f, 0xf7, 0xa3, 0x2a, + 0x64, 0x0d, 0x53, 0xd3, 0x4d, 0xcd, 0x3e, 0xa3, 0x1b, 0x93, 0x90, 0xdc, 0x67, 0x74, 0x19, 0x0a, + 0x3d, 0xdc, 0x33, 0x74, 0xbd, 0x2b, 0x33, 0x67, 0x93, 0xa7, 0xa2, 0x0b, 0x9c, 0x58, 0xa7, 0x3e, + 0xe7, 0x43, 0xc1, 0x3b, 0x7d, 0x1e, 0xbe, 0xf3, 0xf5, 0x2e, 0xef, 0x4a, 0xc8, 0xf2, 0xfa, 0x28, + 0x64, 0x12, 0x23, 0xeb, 0xeb, 0x3e, 0x7f, 0x5b, 0x0b, 0x2c, 0xfe, 0x90, 0x82, 0xbe, 0xc1, 0xdc, + 0x08, 0x1d, 0xf8, 0x2b, 0xb3, 0x01, 0x75, 0x0a, 0x8e, 0x39, 0xcf, 0xea, 0x3d, 0xbc, 0x0a, 0x8e, + 0x91, 0x2d, 0xf4, 0x16, 0x3c, 0x3e, 0xe2, 0xd9, 0x5c, 0xd5, 0xc2, 0xac, 0x0e, 0xee, 0xb1, 0xa0, + 0x83, 0x73, 0x54, 0x7b, 0x8b, 0x95, 0x78, 0xc4, 0x33, 0xb7, 0x0d, 0xc5, 0x60, 0x9a, 0x17, 0xba, + 0xfd, 0x97, 0xa1, 0x60, 0x62, 0x5b, 0xd1, 0xfa, 0x72, 0xa0, 0x26, 0x5d, 0x60, 0x44, 0x8e, 0xff, + 0xee, 0xc3, 0x63, 0xa1, 0xe9, 0x1e, 0x7a, 0x11, 0x72, 0x5e, 0xa6, 0xc8, 0x56, 0x75, 0x02, 0x92, + 0xe7, 0xf1, 0x8a, 0xbf, 0x8d, 0x7b, 0x2a, 0x83, 0xd8, 0x60, 0x1d, 0xd2, 0x26, 0xb6, 0x06, 0x5d, + 0x86, 0xd6, 0x15, 0xd7, 0x9f, 0x9b, 0x2d, 0x51, 0x24, 0xd4, 0x41, 0xd7, 0x96, 0xb8, 0xb0, 0xf8, + 0x00, 0xd2, 0x8c, 0x82, 0xf2, 0x90, 0x39, 0xdc, 0xbd, 0xb7, 0xbb, 0xf7, 0xe6, 0x6e, 0x39, 0x86, + 0x00, 0xd2, 0x1b, 0xb5, 0x5a, 0x7d, 0xbf, 0x59, 0x8e, 0xa3, 0x1c, 0xa4, 0x36, 0x36, 0xf7, 0xa4, + 0x66, 0x59, 0x20, 0x64, 0xa9, 0xfe, 0x7a, 0xbd, 0xd6, 0x2c, 0x27, 0xd0, 0x22, 0x14, 0xd8, 0x6f, + 0xf9, 0xee, 0x9e, 0x74, 0x7f, 0xa3, 0x59, 0x4e, 0xfa, 0x48, 0x07, 0xf5, 0xdd, 0xad, 0xba, 0x54, + 0x4e, 0x89, 0xff, 0x05, 0xe7, 0x23, 0x53, 0x4b, 0x0f, 0xf8, 0x8b, 0xfb, 0x80, 0x3f, 0xf1, 0xa7, + 0x02, 0x54, 0xa3, 0xf3, 0x45, 0xf4, 0xfa, 0xc8, 0xc4, 0xd7, 0xe7, 0x48, 0x36, 0x47, 0x66, 0x8f, + 0xae, 0x40, 0xd1, 0xc4, 0xc7, 0xd8, 0x6e, 0x77, 0x58, 0xfe, 0xca, 0x02, 0x66, 0x41, 0x2a, 0x70, + 0x2a, 0x15, 0xb2, 0x18, 0xdb, 0x3b, 0xb8, 0x6d, 0xcb, 0xcc, 0x17, 0x31, 0xa3, 0xcb, 0x11, 0x36, + 0x42, 0x3d, 0x60, 0x44, 0xf1, 0xed, 0xb9, 0xd6, 0x32, 0x07, 0x29, 0xa9, 0xde, 0x94, 0xde, 0x2a, + 0x27, 0x10, 0x82, 0x22, 0xfd, 0x29, 0x1f, 0xec, 0x6e, 0xec, 0x1f, 0x34, 0xf6, 0xc8, 0x5a, 0x2e, + 0x41, 0xc9, 0x59, 0x4b, 0x87, 0x98, 0x12, 0xff, 0x20, 0xc0, 0xe3, 0x11, 0xd9, 0x2e, 0xba, 0x0d, + 0x60, 0x0f, 0x65, 0x13, 0xb7, 0x75, 0x53, 0x8d, 0x36, 0xb2, 0xe6, 0x50, 0xa2, 0x1c, 0x52, 0xce, + 0xe6, 0xbf, 0xac, 0x09, 0x78, 0x31, 0x7a, 0x99, 0x2b, 0x25, 0xb3, 0x72, 0x8e, 0xda, 0xc5, 0x10, + 0x58, 0x14, 0xb7, 0x89, 0x62, 0xba, 0xb6, 0x54, 0x31, 0xe5, 0x47, 0xf7, 0xc3, 0x9c, 0xca, 0x8c, + 0xdd, 0x9a, 0xf9, 0xdc, 0x49, 0xea, 0xd1, 0xdc, 0x89, 0xf8, 0x8b, 0x84, 0x7f, 0x61, 0x83, 0xc9, + 0xfd, 0x1e, 0xa4, 0x2d, 0x5b, 0xb1, 0x07, 0x16, 0x37, 0xb8, 0x17, 0x67, 0xad, 0x14, 0xd6, 0x9c, + 0x1f, 0x07, 0x54, 0x5c, 0xe2, 0x6a, 0xbe, 0x5b, 0x6f, 0x4b, 0xbc, 0x05, 0xc5, 0xe0, 0xe2, 0x44, + 0x1f, 0x19, 0xcf, 0xe7, 0x08, 0xe2, 0x1d, 0x2f, 0xff, 0xf2, 0x81, 0x96, 0xe3, 0x80, 0x60, 0x3c, + 0x0c, 0x10, 0xfc, 0x65, 0x1c, 0x9e, 0x98, 0x50, 0x2f, 0xa1, 0x37, 0x46, 0xf6, 0xf9, 0xa5, 0x79, + 0xaa, 0xad, 0x35, 0x46, 0x0b, 0xee, 0xb4, 0x78, 0x13, 0x16, 0xfc, 0xf4, 0xd9, 0x26, 0xf9, 0xa3, + 0x84, 0xe7, 0xf3, 0x83, 0xc8, 0xe5, 0xd7, 0x96, 0x68, 0x8e, 0xd8, 0x99, 0x30, 0xa7, 0x9d, 0x85, + 0x26, 0x0b, 0x89, 0x6f, 0x2e, 0x59, 0x48, 0x3e, 0x62, 0xb2, 0xe0, 0x3f, 0x70, 0xa9, 0xe0, 0x81, + 0x1b, 0x8b, 0xeb, 0xe9, 0x90, 0xb8, 0xfe, 0x16, 0x80, 0xaf, 0xa1, 0xb9, 0x0c, 0x29, 0x53, 0x1f, + 0xf4, 0x55, 0x6a, 0x26, 0x29, 0x89, 0x3d, 0xa0, 0x5b, 0x90, 0x22, 0xe6, 0xe6, 0x2c, 0xe6, 0xb8, + 0xe7, 0x25, 0xe6, 0xe2, 0xc3, 0x8c, 0x19, 0xb7, 0xa8, 0x01, 0x1a, 0x6f, 0x2a, 0x45, 0x7c, 0xe2, + 0x95, 0xe0, 0x27, 0x9e, 0x8c, 0x6c, 0x4f, 0x85, 0x7f, 0xea, 0x7d, 0x48, 0x51, 0xf3, 0x20, 0xf9, + 0x0d, 0x6d, 0x8c, 0xf2, 0x82, 0x99, 0xfc, 0x46, 0xdf, 0x07, 0x50, 0x6c, 0xdb, 0xd4, 0x5a, 0x03, + 0xef, 0x03, 0xab, 0xe1, 0xe6, 0xb5, 0xe1, 0xf0, 0x6d, 0x5e, 0xe0, 0x76, 0xb6, 0xec, 0x89, 0xfa, + 0x6c, 0xcd, 0xa7, 0x50, 0xdc, 0x85, 0x62, 0x50, 0xd6, 0x29, 0xf1, 0xd8, 0x18, 0x82, 0x25, 0x1e, + 0xab, 0xd8, 0x79, 0x89, 0xe7, 0x16, 0x88, 0x09, 0xd6, 0x03, 0xa7, 0x0f, 0xe2, 0x3f, 0xe2, 0xb0, + 0xe0, 0xb7, 0xce, 0xff, 0xb4, 0x2a, 0x49, 0xfc, 0x30, 0x0e, 0x59, 0x77, 0xf2, 0x11, 0x0d, 0x68, + 0x6f, 0xed, 0x04, 0x7f, 0xbb, 0x95, 0x75, 0xb4, 0x13, 0x6e, 0x9f, 0xfc, 0x8e, 0x9b, 0x50, 0x45, + 0x81, 0xda, 0xfe, 0x95, 0x76, 0xae, 0x0a, 0xf0, 0xfc, 0xf1, 0x27, 0x7c, 0x1c, 0x24, 0x93, 0x40, + 0xff, 0x03, 0x69, 0xa5, 0xed, 0x42, 0xf9, 0xc5, 0x10, 0x6c, 0xd7, 0x61, 0x5d, 0x6b, 0x0e, 0x37, + 0x28, 0xa7, 0xc4, 0x25, 0xf8, 0xa8, 0x04, 0xb7, 0xcf, 0xfe, 0x2a, 0xd1, 0xcb, 0x78, 0x82, 0x6e, + 0xb3, 0x08, 0x70, 0xb8, 0x7b, 0x7f, 0x6f, 0x6b, 0xfb, 0xee, 0x76, 0x7d, 0x8b, 0xa7, 0x54, 0x5b, + 0x5b, 0xf5, 0xad, 0xb2, 0x40, 0xf8, 0xa4, 0xfa, 0xfd, 0xbd, 0xa3, 0xfa, 0x56, 0x39, 0x21, 0xde, + 0x81, 0x9c, 0xeb, 0x7a, 0x50, 0x05, 0x32, 0x4e, 0x5b, 0x22, 0xce, 0x1d, 0x00, 0xef, 0x32, 0x2d, + 0x43, 0xca, 0xd0, 0xdf, 0xe3, 0x5d, 0xe6, 0x84, 0xc4, 0x1e, 0x44, 0x15, 0x4a, 0x23, 0x7e, 0x0b, + 0xdd, 0x81, 0x8c, 0x31, 0x68, 0xc9, 0x8e, 0xd1, 0x8e, 0x34, 0x71, 0x1c, 0xa4, 0x61, 0xd0, 0xea, + 0x6a, 0xed, 0x7b, 0xf8, 0xcc, 0x59, 0x26, 0x63, 0xd0, 0xba, 0xc7, 0x6c, 0x9b, 0x7d, 0x45, 0xf0, + 0x7f, 0xe5, 0x14, 0xb2, 0xce, 0x51, 0x45, 0xff, 0x0b, 0x39, 0xd7, 0x25, 0xba, 0x57, 0x6f, 0x22, + 0x7d, 0x29, 0x57, 0xef, 0x89, 0xa0, 0xeb, 0xb0, 0x68, 0x69, 0x27, 0x7d, 0xa7, 0x85, 0xc5, 0x90, + 0x3d, 0x81, 0x9e, 0x99, 0x12, 0x7b, 0xb1, 0xe3, 0xc0, 0x51, 0x24, 0x12, 0x96, 0x47, 0x7d, 0xc5, + 0xb7, 0x39, 0x80, 0x90, 0x88, 0x9d, 0x08, 0x8b, 0xd8, 0x1f, 0x08, 0x90, 0xf7, 0x35, 0xc6, 0xd0, + 0x7f, 0xfb, 0x1c, 0x57, 0x31, 0x24, 0xd4, 0xf8, 0x78, 0xbd, 0x5b, 0x1d, 0xc1, 0x89, 0x09, 0xf3, + 0x4f, 0x2c, 0xaa, 0x0f, 0xe9, 0xf4, 0xd7, 0x92, 0x73, 0xf7, 0xd7, 0x9e, 0x05, 0x64, 0xeb, 0xb6, + 0xd2, 0x95, 0x4f, 0x75, 0x5b, 0xeb, 0x9f, 0xc8, 0xcc, 0x34, 0x98, 0x9b, 0x29, 0xd3, 0x37, 0x47, + 0xf4, 0xc5, 0x3e, 0xb5, 0x92, 0x1f, 0xc4, 0x21, 0xeb, 0x96, 0x7d, 0xf3, 0x5e, 0xd2, 0x38, 0x07, + 0x69, 0x5e, 0xd9, 0xb0, 0x5b, 0x1a, 0xfc, 0x29, 0xb4, 0x91, 0x58, 0x85, 0x6c, 0x0f, 0xdb, 0x0a, + 0xf5, 0x99, 0x2c, 0x4c, 0xba, 0xcf, 0xd7, 0x5f, 0x82, 0xbc, 0xef, 0xbe, 0x0c, 0x71, 0xa3, 0xbb, + 0xf5, 0x37, 0xcb, 0xb1, 0x6a, 0xe6, 0xa3, 0x4f, 0x2e, 0x25, 0x76, 0xf1, 0x7b, 0xe4, 0x84, 0x49, + 0xf5, 0x5a, 0xa3, 0x5e, 0xbb, 0x57, 0x8e, 0x57, 0xf3, 0x1f, 0x7d, 0x72, 0x29, 0x23, 0x61, 0xda, + 0xf7, 0xb9, 0x7e, 0x0f, 0x4a, 0x23, 0x1b, 0x13, 0x3c, 0xd0, 0x08, 0x8a, 0x5b, 0x87, 0xfb, 0x3b, + 0xdb, 0xb5, 0x8d, 0x66, 0x5d, 0x3e, 0xda, 0x6b, 0xd6, 0xcb, 0x71, 0xf4, 0x38, 0x2c, 0xed, 0x6c, + 0xbf, 0xd6, 0x68, 0xca, 0xb5, 0x9d, 0xed, 0xfa, 0x6e, 0x53, 0xde, 0x68, 0x36, 0x37, 0x6a, 0xf7, + 0xca, 0xc2, 0xfa, 0xaf, 0xf2, 0x50, 0xda, 0xd8, 0xac, 0x6d, 0x93, 0xda, 0x4e, 0x6b, 0x2b, 0xd4, + 0x3d, 0xd4, 0x20, 0x49, 0x41, 0xe4, 0x89, 0x37, 0xa0, 0xab, 0x93, 0x1b, 0x83, 0xe8, 0x2e, 0xa4, + 0x28, 0xbe, 0x8c, 0x26, 0x5f, 0x89, 0xae, 0x4e, 0xe9, 0x14, 0x92, 0xc1, 0xd0, 0xe3, 0x34, 0xf1, + 0x8e, 0x74, 0x75, 0x72, 0xe3, 0x10, 0xed, 0x40, 0xc6, 0x81, 0xff, 0xa6, 0xdd, 0x36, 0xae, 0x4e, + 0xed, 0xc0, 0x91, 0xa9, 0x31, 0x98, 0x76, 0xf2, 0xf5, 0xe9, 0xea, 0x94, 0x96, 0x22, 0xda, 0x86, + 0x34, 0x47, 0x48, 0xa6, 0xdc, 0x1c, 0xae, 0x4e, 0xeb, 0xa4, 0x21, 0x09, 0x72, 0x1e, 0x00, 0x3e, + 0xfd, 0x52, 0x78, 0x75, 0x86, 0x6e, 0x29, 0x7a, 0x00, 0x85, 0x20, 0xea, 0x32, 0xdb, 0xed, 0xe4, + 0xea, 0x8c, 0x3d, 0x3b, 0xa2, 0x3f, 0x08, 0xc1, 0xcc, 0x76, 0x5b, 0xb9, 0x3a, 0x63, 0x0b, 0x0f, + 0xbd, 0x03, 0x8b, 0xe3, 0x10, 0xc9, 0xec, 0x97, 0x97, 0xab, 0x73, 0x34, 0xf5, 0x50, 0x0f, 0x50, + 0x08, 0xb4, 0x32, 0xc7, 0x5d, 0xe6, 0xea, 0x3c, 0x3d, 0x3e, 0xa4, 0x42, 0x69, 0x14, 0xae, 0x98, + 0xf5, 0x6e, 0x73, 0x75, 0xe6, 0x7e, 0x1f, 0xfb, 0x4a, 0xb0, 0x76, 0x9f, 0xf5, 0xae, 0x73, 0x75, + 0xe6, 0xf6, 0x1f, 0x3a, 0x04, 0xf0, 0xd5, 0x9e, 0x33, 0xdc, 0x7d, 0xae, 0xce, 0xd2, 0x08, 0x44, + 0x06, 0x2c, 0x85, 0x15, 0xa5, 0xf3, 0x5c, 0x85, 0xae, 0xce, 0xd5, 0x1f, 0x24, 0xf6, 0x1c, 0x2c, + 0x2f, 0x67, 0xbb, 0x1a, 0x5d, 0x9d, 0xb1, 0x51, 0xb8, 0x59, 0xff, 0xf4, 0x8b, 0x95, 0xf8, 0x67, + 0x5f, 0xac, 0xc4, 0xff, 0xfa, 0xc5, 0x4a, 0xfc, 0xe3, 0x2f, 0x57, 0x62, 0x9f, 0x7d, 0xb9, 0x12, + 0xfb, 0xd3, 0x97, 0x2b, 0xb1, 0xff, 0x7b, 0xe6, 0x44, 0xb3, 0x3b, 0x83, 0xd6, 0x5a, 0x5b, 0xef, + 0xdd, 0xf0, 0xff, 0x4b, 0x26, 0xec, 0x9f, 0x3b, 0xad, 0x34, 0x0d, 0xa8, 0x37, 0xff, 0x15, 0x00, + 0x00, 0xff, 0xff, 0xa5, 0x05, 0x49, 0xaf, 0xd9, 0x33, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/proto/tendermint/abci/types.proto b/proto/tendermint/abci/types.proto index be13be433..d8143feb3 100644 --- a/proto/tendermint/abci/types.proto +++ b/proto/tendermint/abci/types.proto @@ -3,8 +3,6 @@ package tendermint.abci; option go_package = "github.com/tendermint/tendermint/abci/types"; -// For more information on gogo.proto, see: -// https://github.com/gogo/protobuf/blob/master/extensions.md import "tendermint/crypto/proof.proto"; import "tendermint/types/types.proto"; import "tendermint/crypto/keys.proto"; @@ -354,7 +352,6 @@ message ResponseExtendVote { bytes vote_extension = 1; } - message ResponseVerifyVoteExtension { VerifyStatus status = 1; @@ -383,6 +380,9 @@ message CommitInfo { repeated VoteInfo votes = 2 [(gogoproto.nullable) = false]; } +// ExtendedCommitInfo is similar to CommitInfo except that it is only used in +// the PrepareProposal request such that Tendermint can provide vote extensions +// to the application. message ExtendedCommitInfo { // The round at which the block proposer decided in the previous height. int32 round = 1; @@ -476,7 +476,6 @@ message ExtendedVoteInfo { bytes vote_extension = 3; } - enum MisbehaviorType { UNKNOWN = 0; DUPLICATE_VOTE = 1; diff --git a/proto/tendermint/abci/types.proto.intermediate b/proto/tendermint/abci/types.proto.intermediate deleted file mode 100644 index d4ed656f4..000000000 --- a/proto/tendermint/abci/types.proto.intermediate +++ /dev/null @@ -1,535 +0,0 @@ -syntax = "proto3"; -package tendermint.abci; - -import "tendermint/crypto/proof.proto"; -import "tendermint/types/types.proto"; -import "tendermint/crypto/keys.proto"; -import "tendermint/types/params.proto"; -import "google/protobuf/timestamp.proto"; -import "gogoproto/gogo.proto"; - -// This file is a temporary workaround to enable development during the ABCI++ -// project. This file should be deleted and any references to it removed when -// the ongoing work on ABCI++ is completed. -// -// For the duration of ABCI++, this file should be able to build the `abci/types/types.pb.go` -// file. Any changes that update that file must come as a result of a change in -// this .proto file. -// For more information, see https://github.com/tendermint/tendermint/issues/8066 - -//---------------------------------------- -// Request types - -message Request { - oneof value { - RequestEcho echo = 1; - RequestFlush flush = 2; - RequestInfo info = 3; - RequestInitChain init_chain = 4; - RequestQuery query = 5; - RequestBeginBlock begin_block = 6 [deprecated = true]; - RequestCheckTx check_tx = 7; - RequestDeliverTx deliver_tx = 8 [deprecated = true]; - RequestEndBlock end_block = 9 [deprecated = true]; - RequestCommit commit = 10; - RequestListSnapshots list_snapshots = 11; - RequestOfferSnapshot offer_snapshot = 12; - RequestLoadSnapshotChunk load_snapshot_chunk = 13; - RequestApplySnapshotChunk apply_snapshot_chunk = 14; - RequestPrepareProposal prepare_proposal = 15; - RequestProcessProposal process_proposal = 16; - RequestExtendVote extend_vote = 17; - RequestVerifyVoteExtension verify_vote_extension = 18; - RequestFinalizeBlock finalize_block = 19; - } -} - -message RequestEcho { - string message = 1; -} - -message RequestFlush {} - -message RequestInfo { - string version = 1; - uint64 block_version = 2; - uint64 p2p_version = 3; - string abci_version = 4; -} - -message RequestInitChain { - google.protobuf.Timestamp time = 1 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; - string chain_id = 2; - tendermint.types.ConsensusParams consensus_params = 3; - repeated ValidatorUpdate validators = 4 [(gogoproto.nullable) = false]; - bytes app_state_bytes = 5; - int64 initial_height = 6; -} - -message RequestQuery { - bytes data = 1; - string path = 2; - int64 height = 3; - bool prove = 4; -} - -message RequestBeginBlock { - bytes hash = 1; - tendermint.types.Header header = 2 [(gogoproto.nullable) = false]; - CommitInfo last_commit_info = 3 [(gogoproto.nullable) = false]; - repeated Misbehavior byzantine_validators = 4 [(gogoproto.nullable) = false]; -} - -enum CheckTxType { - NEW = 0 [(gogoproto.enumvalue_customname) = "New"]; - RECHECK = 1 [(gogoproto.enumvalue_customname) = "Recheck"]; -} - -message RequestCheckTx { - bytes tx = 1; - CheckTxType type = 2; -} - -message RequestDeliverTx { - bytes tx = 1; -} - -message RequestEndBlock { - int64 height = 1; -} - -message RequestCommit {} - -// lists available snapshots -message RequestListSnapshots {} - -// offers a snapshot to the application -message RequestOfferSnapshot { - Snapshot snapshot = 1; // snapshot offered by peers - bytes app_hash = 2; // light client-verified app hash for snapshot height -} - -// loads a snapshot chunk -message RequestLoadSnapshotChunk { - uint64 height = 1; - uint32 format = 2; - uint32 chunk = 3; -} - -// Applies a snapshot chunk -message RequestApplySnapshotChunk { - uint32 index = 1; - bytes chunk = 2; - string sender = 3; -} - -message RequestPrepareProposal { - // the modified transactions cannot exceed this size. - int64 max_tx_bytes = 1; - // txs is an array of transactions that will be included in a block, - // sent to the app for possible modifications. - repeated bytes txs = 2; - ExtendedCommitInfo local_last_commit = 3 [(gogoproto.nullable) = false]; - repeated Misbehavior byzantine_validators = 4 [(gogoproto.nullable) = false]; - int64 height = 5; - google.protobuf.Timestamp time = 6 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; - bytes next_validators_hash = 7; - // address of the public key of the validator proposing the block. - bytes proposer_address = 8; -} - -message RequestProcessProposal { - repeated bytes txs = 1; - CommitInfo proposed_last_commit = 2 [(gogoproto.nullable) = false]; - repeated Misbehavior byzantine_validators = 3 [(gogoproto.nullable) = false]; - // hash is the merkle root hash of the fields of the proposed block. - bytes hash = 4; - int64 height = 5; - google.protobuf.Timestamp time = 6 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; - bytes next_validators_hash = 7; - // address of the public key of the original proposer of the block. - bytes proposer_address = 8; -} - -// Extends a vote with application-side injection -message RequestExtendVote { - bytes hash = 1; - int64 height = 2; -} - -// Verify the vote extension -message RequestVerifyVoteExtension { - bytes hash = 1; - bytes validator_address = 2; - int64 height = 3; - bytes vote_extension = 4; -} - -message RequestFinalizeBlock { - repeated bytes txs = 1; - CommitInfo decided_last_commit = 2 [(gogoproto.nullable) = false]; - repeated Misbehavior byzantine_validators = 3 [(gogoproto.nullable) = false]; - // hash is the merkle root hash of the fields of the proposed block. - bytes hash = 4; - int64 height = 5; - google.protobuf.Timestamp time = 6 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; - bytes next_validators_hash = 7; - // proposer_address is the address of the public key of the original proposer of the block. - bytes proposer_address = 8; -} - -//---------------------------------------- -// Response types - -message Response { - oneof value { - ResponseException exception = 1; - ResponseEcho echo = 2; - ResponseFlush flush = 3; - ResponseInfo info = 4; - ResponseInitChain init_chain = 5; - ResponseQuery query = 6; - ResponseBeginBlock begin_block = 7 [deprecated = true]; - ResponseCheckTx check_tx = 8; - ResponseDeliverTx deliver_tx = 9 [deprecated = true]; - ResponseEndBlock end_block = 10 [deprecated = true]; - ResponseCommit commit = 11; - ResponseListSnapshots list_snapshots = 12; - ResponseOfferSnapshot offer_snapshot = 13; - ResponseLoadSnapshotChunk load_snapshot_chunk = 14; - ResponseApplySnapshotChunk apply_snapshot_chunk = 15; - ResponsePrepareProposal prepare_proposal = 16; - ResponseProcessProposal process_proposal = 17; - ResponseExtendVote extend_vote = 18; - ResponseVerifyVoteExtension verify_vote_extension = 19; - ResponseFinalizeBlock finalize_block = 20; - } -} - -// nondeterministic -message ResponseException { - string error = 1; -} - -message ResponseEcho { - string message = 1; -} - -message ResponseFlush {} - -message ResponseInfo { - string data = 1; - - // this is the software version of the application. TODO: remove? - string version = 2; - uint64 app_version = 3; - - int64 last_block_height = 4; - bytes last_block_app_hash = 5; -} - -message ResponseInitChain { - tendermint.types.ConsensusParams consensus_params = 1; - repeated ValidatorUpdate validators = 2 [(gogoproto.nullable) = false]; - bytes app_hash = 3; -} - -message ResponseQuery { - uint32 code = 1; - // bytes data = 2; // use "value" instead. - string log = 3; // nondeterministic - string info = 4; // nondeterministic - int64 index = 5; - bytes key = 6; - bytes value = 7; - tendermint.crypto.ProofOps proof_ops = 8; - int64 height = 9; - string codespace = 10; -} - -message ResponseBeginBlock { - repeated Event events = 1 [(gogoproto.nullable) = false, (gogoproto.jsontag) = "events,omitempty"]; -} - -message ResponseCheckTx { - uint32 code = 1; - bytes data = 2; - string log = 3; // nondeterministic - string info = 4; // nondeterministic - int64 gas_wanted = 5; - int64 gas_used = 6; - repeated Event events = 7 [(gogoproto.nullable) = false, (gogoproto.jsontag) = "events,omitempty"]; - string codespace = 8; - string sender = 9; - int64 priority = 10; - - // mempool_error is set by Tendermint. - - // ABCI applications creating a ResponseCheckTX should not set mempool_error. - string mempool_error = 11; -} - -message ResponseDeliverTx { - uint32 code = 1; - bytes data = 2; - string log = 3; // nondeterministic - string info = 4; // nondeterministic - int64 gas_wanted = 5 [json_name = "gas_wanted"]; - int64 gas_used = 6 [json_name = "gas_used"]; - repeated Event events = 7 - [(gogoproto.nullable) = false, (gogoproto.jsontag) = "events,omitempty"]; // nondeterministic - string codespace = 8; -} - -message ResponseEndBlock { - repeated ValidatorUpdate validator_updates = 1 [(gogoproto.nullable) = false]; - tendermint.types.ConsensusParams consensus_param_updates = 2; - repeated Event events = 3 [(gogoproto.nullable) = false, (gogoproto.jsontag) = "events,omitempty"]; -} - -message ResponseCommit { - // reserve 1 - bytes data = 2; - int64 retain_height = 3; -} - -message ResponseListSnapshots { - repeated Snapshot snapshots = 1; -} - -message ResponseOfferSnapshot { - Result result = 1; - - enum Result { - UNKNOWN = 0; // Unknown result, abort all snapshot restoration - ACCEPT = 1; // Snapshot accepted, apply chunks - ABORT = 2; // Abort all snapshot restoration - REJECT = 3; // Reject this specific snapshot, try others - REJECT_FORMAT = 4; // Reject all snapshots of this format, try others - REJECT_SENDER = 5; // Reject all snapshots from the sender(s), try others - } -} - -message ResponseLoadSnapshotChunk { - bytes chunk = 1; -} - -message ResponseApplySnapshotChunk { - Result result = 1; - repeated uint32 refetch_chunks = 2; // Chunks to refetch and reapply - repeated string reject_senders = 3; // Chunk senders to reject and ban - - enum Result { - UNKNOWN = 0; // Unknown result, abort all snapshot restoration - ACCEPT = 1; // Chunk successfully accepted - ABORT = 2; // Abort all snapshot restoration - RETRY = 3; // Retry chunk (combine with refetch and reject) - RETRY_SNAPSHOT = 4; // Retry snapshot (combine with refetch and reject) - REJECT_SNAPSHOT = 5; // Reject this snapshot, try others - } -} - -message ResponsePrepareProposal { - repeated TxRecord tx_records = 1; - bytes app_hash = 2; - repeated ExecTxResult tx_results = 3; - repeated ValidatorUpdate validator_updates = 4; - tendermint.types.ConsensusParams consensus_param_updates = 5; -} - -message ResponseProcessProposal { - ProposalStatus status = 1; - bytes app_hash = 2; - repeated ExecTxResult tx_results = 3; - repeated ValidatorUpdate validator_updates = 4; - tendermint.types.ConsensusParams consensus_param_updates = 5; - - enum ProposalStatus { - UNKNOWN = 0; - ACCEPT = 1; - REJECT = 2; - } -} - -message ResponseExtendVote { - bytes vote_extension = 1; -} - -message ResponseVerifyVoteExtension { - VerifyStatus status = 1; - - enum VerifyStatus { - UNKNOWN = 0; - ACCEPT = 1; - REJECT = 2; - } -} - -message ResponseFinalizeBlock { - repeated Event events = 1 - [(gogoproto.nullable) = false, (gogoproto.jsontag) = "events,omitempty"]; - repeated ExecTxResult tx_results = 2; - repeated ValidatorUpdate validator_updates = 3 [(gogoproto.nullable) = false]; - tendermint.types.ConsensusParams consensus_param_updates = 4; - bytes app_hash = 5; - int64 retain_height = 6; -} - -//---------------------------------------- -// Misc. - -message CommitInfo { - int32 round = 1; - repeated VoteInfo votes = 2 [(gogoproto.nullable) = false]; -} - -// ExtendedCommitInfo is similar to CommitInfo except that it is only used in -// the PrepareProposal request such that Tendermint can provide vote extensions -// to the application. -message ExtendedCommitInfo { - // The round at which the block proposer decided in the previous height. - int32 round = 1; - // List of validators' addresses in the last validator set with their voting - // information, including vote extensions. - repeated ExtendedVoteInfo votes = 2 [(gogoproto.nullable) = false]; -} - -// Event allows application developers to attach additional information to -// ResponseBeginBlock, ResponseEndBlock, ResponseCheckTx and ResponseDeliverTx. -// Later, transactions may be queried using these events. -message Event { - string type = 1; - repeated EventAttribute attributes = 2 [(gogoproto.nullable) = false, (gogoproto.jsontag) = "attributes,omitempty"]; -} - -// EventAttribute is a single key-value pair, associated with an event. -message EventAttribute { - string key = 1; - string value = 2; - bool index = 3; // nondeterministic -} - -// ExecTxResult contains results of executing one individual transaction. -// -// * Its structure is equivalent to #ResponseDeliverTx which will be deprecated/deleted -message ExecTxResult { - uint32 code = 1; - bytes data = 2; - string log = 3; // nondeterministic - string info = 4; // nondeterministic - int64 gas_wanted = 5; - int64 gas_used = 6; - repeated Event events = 7 - [(gogoproto.nullable) = false, (gogoproto.jsontag) = "events,omitempty"]; // nondeterministic - string codespace = 8; -} - -// TxResult contains results of executing the transaction. -// -// One usage is indexing transaction results. -message TxResult { - int64 height = 1; - uint32 index = 2; - bytes tx = 3; - ExecTxResult result = 4 [(gogoproto.nullable) = false]; -} - -message TxRecord { - TxAction action = 1; - bytes tx = 2; - - // TxAction contains App-provided information on what to do with a transaction that is part of a raw proposal - enum TxAction { - UNKNOWN = 0; // Unknown action - UNMODIFIED = 1; // The Application did not modify this transaction. - ADDED = 2; // The Application added this transaction. - REMOVED = 3; // The Application wants this transaction removed from the proposal and the mempool. - } -} - -//---------------------------------------- -// Blockchain Types - -// Validator -message Validator { - bytes address = 1; // The first 20 bytes of SHA256(public key) - // PubKey pub_key = 2 [(gogoproto.nullable)=false]; - int64 power = 3; // The voting power -} - -// ValidatorUpdate -message ValidatorUpdate { - tendermint.crypto.PublicKey pub_key = 1 [(gogoproto.nullable) = false]; - int64 power = 2; -} - -// VoteInfo -message VoteInfo { - Validator validator = 1 [(gogoproto.nullable) = false]; - bool signed_last_block = 2; - reserved 3; // Placeholder for tendermint_signed_extension in v0.37 - reserved 4; // Placeholder for app_signed_extension in v0.37 -} - -// ExtendedVoteInfo -message ExtendedVoteInfo { - // The validator that sent the vote. - Validator validator = 1 [(gogoproto.nullable) = false]; - // Indicates whether the validator signed the last block, allowing for rewards based on validator availability. - bool signed_last_block = 2; - // Non-deterministic extension provided by the sending validator's application. - bytes vote_extension = 3; -} - -enum MisbehaviorType { - UNKNOWN = 0; - DUPLICATE_VOTE = 1; - LIGHT_CLIENT_ATTACK = 2; -} - -message Misbehavior { - MisbehaviorType type = 1; - // The offending validator - Validator validator = 2 [(gogoproto.nullable) = false]; - // The height when the offense occurred - int64 height = 3; - // The corresponding time where the offense occurred - google.protobuf.Timestamp time = 4 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; - // Total voting power of the validator set in case the ABCI application does - // not store historical validators. - // https://github.com/tendermint/tendermint/issues/4581 - int64 total_voting_power = 5; -} - -//---------------------------------------- -// State Sync Types - -message Snapshot { - uint64 height = 1; // The height at which the snapshot was taken - uint32 format = 2; // The application-specific snapshot format - uint32 chunks = 3; // Number of chunks in the snapshot - bytes hash = 4; // Arbitrary snapshot hash, equal only if identical - bytes metadata = 5; // Arbitrary application metadata -} - -//---------------------------------------- -// Service Definition - -service ABCIApplication { - rpc Echo(RequestEcho) returns (ResponseEcho); - rpc Flush(RequestFlush) returns (ResponseFlush); - rpc Info(RequestInfo) returns (ResponseInfo); - rpc CheckTx(RequestCheckTx) returns (ResponseCheckTx); - rpc Query(RequestQuery) returns (ResponseQuery); - rpc Commit(RequestCommit) returns (ResponseCommit); - rpc InitChain(RequestInitChain) returns (ResponseInitChain); - rpc ListSnapshots(RequestListSnapshots) returns (ResponseListSnapshots); - rpc OfferSnapshot(RequestOfferSnapshot) returns (ResponseOfferSnapshot); - rpc LoadSnapshotChunk(RequestLoadSnapshotChunk) returns (ResponseLoadSnapshotChunk); - rpc ApplySnapshotChunk(RequestApplySnapshotChunk) returns (ResponseApplySnapshotChunk); - rpc PrepareProposal(RequestPrepareProposal) returns (ResponsePrepareProposal); - rpc ProcessProposal(RequestProcessProposal) returns (ResponseProcessProposal); - rpc ExtendVote(RequestExtendVote) returns (ResponseExtendVote); - rpc VerifyVoteExtension(RequestVerifyVoteExtension) returns (ResponseVerifyVoteExtension); - rpc FinalizeBlock(RequestFinalizeBlock) returns (ResponseFinalizeBlock); -} diff --git a/proto/tendermint/types/params.pb.go b/proto/tendermint/types/params.pb.go index c8b8594e1..41d417b91 100644 --- a/proto/tendermint/types/params.pb.go +++ b/proto/tendermint/types/params.pb.go @@ -394,7 +394,7 @@ func (m *HashedParams) GetBlockMaxGas() int64 { // see the specification of proposer-based timestamps: // https://github.com/tendermint/tendermint/tree/master/spec/consensus/proposer-based-timestamp type SynchronyParams struct { - // message_delay bounds how long a proposal message may take to reach all validators on a newtork + // message_delay bounds how long a proposal message may take to reach all validators on a network // and still be considered valid. MessageDelay *time.Duration `protobuf:"bytes,1,opt,name=message_delay,json=messageDelay,proto3,stdduration" json:"message_delay,omitempty"` // precision bounds how skewed a proposer's clock may be from any validator diff --git a/proto/tendermint/types/types.pb.go b/proto/tendermint/types/types.pb.go index 370a3714e..1904afcd1 100644 --- a/proto/tendermint/types/types.pb.go +++ b/proto/tendermint/types/types.pb.go @@ -29,7 +29,7 @@ var _ = time.Kitchen // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package -// BlockIdFlag indicates which BlcokID the signature is for +// BlockIdFlag indicates which BlockID the signature is for type BlockIDFlag int32 const ( @@ -480,7 +480,7 @@ type Vote struct { // messages. Extension []byte `protobuf:"bytes,9,opt,name=extension,proto3" json:"extension,omitempty"` // Vote extension signature by the validator if they participated in - // consensus for the associated block. + // consensus for the associated block. Only valid for precommit messages. ExtensionSignature []byte `protobuf:"bytes,10,opt,name=extension_signature,json=extensionSignature,proto3" json:"extension_signature,omitempty"` } diff --git a/proto/tendermint/types/types.proto b/proto/tendermint/types/types.proto index 34013b418..e2b8a46c8 100644 --- a/proto/tendermint/types/types.proto +++ b/proto/tendermint/types/types.proto @@ -9,7 +9,7 @@ import "tendermint/crypto/proof.proto"; import "tendermint/version/types.proto"; import "tendermint/types/validator.proto"; -// BlockIdFlag indicates which BlcokID the signature is for +// BlockIdFlag indicates which BlockID the signature is for enum BlockIDFlag { option (gogoproto.goproto_enum_stringer) = true; option (gogoproto.goproto_enum_prefix) = false; @@ -119,7 +119,7 @@ message Vote { // messages. bytes extension = 9; // Vote extension signature by the validator if they participated in - // consensus for the associated block. + // consensus for the associated block. Only valid for precommit messages. bytes extension_signature = 10; } diff --git a/proto/tendermint/types/types.proto.intermediate b/proto/tendermint/types/types.proto.intermediate deleted file mode 100644 index 280cd7133..000000000 --- a/proto/tendermint/types/types.proto.intermediate +++ /dev/null @@ -1,192 +0,0 @@ -syntax = "proto3"; -package tendermint.types; - -import "gogoproto/gogo.proto"; -import "google/protobuf/timestamp.proto"; -import "tendermint/crypto/proof.proto"; -import "tendermint/version/types.proto"; -import "tendermint/types/validator.proto"; - -// This file is a temporary workaround to enable development during the ABCI++ -// project. This file should be deleted and any references to it removed when -// the ongoing work on ABCI++ is completed. -// -// This file supports building of the `tendermint.abci` proto package. -// For more information, see https://github.com/tendermint/tendermint/issues/8066 - -// BlockIdFlag indicates which BlockID the signature is for -enum BlockIDFlag { - option (gogoproto.goproto_enum_stringer) = true; - option (gogoproto.goproto_enum_prefix) = false; - - BLOCK_ID_FLAG_UNKNOWN = 0 - [(gogoproto.enumvalue_customname) = "BlockIDFlagUnknown"]; - BLOCK_ID_FLAG_ABSENT = 1 - [(gogoproto.enumvalue_customname) = "BlockIDFlagAbsent"]; - BLOCK_ID_FLAG_COMMIT = 2 - [(gogoproto.enumvalue_customname) = "BlockIDFlagCommit"]; - BLOCK_ID_FLAG_NIL = 3 [(gogoproto.enumvalue_customname) = "BlockIDFlagNil"]; -} - -// SignedMsgType is a type of signed message in the consensus. -enum SignedMsgType { - option (gogoproto.goproto_enum_stringer) = true; - option (gogoproto.goproto_enum_prefix) = false; - - SIGNED_MSG_TYPE_UNKNOWN = 0 - [(gogoproto.enumvalue_customname) = "UnknownType"]; - // Votes - SIGNED_MSG_TYPE_PREVOTE = 1 - [(gogoproto.enumvalue_customname) = "PrevoteType"]; - SIGNED_MSG_TYPE_PRECOMMIT = 2 - [(gogoproto.enumvalue_customname) = "PrecommitType"]; - - // Proposals - SIGNED_MSG_TYPE_PROPOSAL = 32 - [(gogoproto.enumvalue_customname) = "ProposalType"]; -} - -// PartsetHeader -message PartSetHeader { - uint32 total = 1; - bytes hash = 2; -} - -message Part { - uint32 index = 1; - bytes bytes = 2; - tendermint.crypto.Proof proof = 3 [(gogoproto.nullable) = false]; -} - -// BlockID -message BlockID { - bytes hash = 1; - PartSetHeader part_set_header = 2 [(gogoproto.nullable) = false]; -} - -// -------------------------------- - -// Header defines the structure of a Tendermint block header. -message Header { - // basic block info - tendermint.version.Consensus version = 1 [(gogoproto.nullable) = false]; - string chain_id = 2 [(gogoproto.customname) = "ChainID"]; - int64 height = 3; - google.protobuf.Timestamp time = 4 - [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; - - // prev block info - BlockID last_block_id = 5 [(gogoproto.nullable) = false]; - - // hashes of block data - bytes last_commit_hash = 6; // commit from validators from the last block - bytes data_hash = 7; // transactions - - // hashes from the app output from the prev block - bytes validators_hash = 8; // validators for the current block - bytes next_validators_hash = 9; // validators for the next block - bytes consensus_hash = 10; // consensus params for current block - bytes app_hash = 11; // state after txs from the previous block - bytes last_results_hash = - 12; // root hash of all results from the txs from the previous block - - // consensus info - bytes evidence_hash = 13; // evidence included in the block - bytes proposer_address = 14; // original proposer of the block -} - -// Data contains the set of transactions included in the block -message Data { - // Txs that will be applied by state @ block.Height+1. - // NOTE: not all txs here are valid. We're just agreeing on the order first. - // This means that block.AppHash does not include these txs. - repeated bytes txs = 1; -} - -// Vote represents a prevote, precommit, or commit vote from validators for -// consensus. -message Vote { - SignedMsgType type = 1; - int64 height = 2; - int32 round = 3; - BlockID block_id = 4 [ - (gogoproto.nullable) = false, - (gogoproto.customname) = "BlockID" - ]; // zero if vote is nil. - google.protobuf.Timestamp timestamp = 5 - [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; - bytes validator_address = 6; - int32 validator_index = 7; - bytes signature = 8; - VoteExtension vote_extension = 9; -} - -// VoteExtension is app-defined additional information to the validator votes. -message VoteExtension { - bytes app_data_to_sign = 1; - bytes app_data_self_authenticating = 2; -} - -// VoteExtensionToSign is a subset of VoteExtension that is signed by the validators private key. -// VoteExtensionToSign is extracted from an existing VoteExtension. -message VoteExtensionToSign { - bytes app_data_to_sign = 1; -} - -// Commit contains the evidence that a block was committed by a set of -// validators. -message Commit { - int64 height = 1; - int32 round = 2; - BlockID block_id = 3 - [(gogoproto.nullable) = false, (gogoproto.customname) = "BlockID"]; - repeated CommitSig signatures = 4 [(gogoproto.nullable) = false]; -} - -// CommitSig is a part of the Vote included in a Commit. -message CommitSig { - BlockIDFlag block_id_flag = 1; - bytes validator_address = 2; - google.protobuf.Timestamp timestamp = 3 - [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; - bytes signature = 4; - VoteExtensionToSign vote_extension = 5; -} - -message Proposal { - SignedMsgType type = 1; - int64 height = 2; - int32 round = 3; - int32 pol_round = 4; - BlockID block_id = 5 - [(gogoproto.customname) = "BlockID", (gogoproto.nullable) = false]; - google.protobuf.Timestamp timestamp = 6 - [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; - bytes signature = 7; -} - -message SignedHeader { - Header header = 1; - Commit commit = 2; -} - -message LightBlock { - SignedHeader signed_header = 1; - tendermint.types.ValidatorSet validator_set = 2; -} - -message BlockMeta { - BlockID block_id = 1 - [(gogoproto.customname) = "BlockID", (gogoproto.nullable) = false]; - int64 block_size = 2; - Header header = 3 [(gogoproto.nullable) = false]; - int64 num_txs = 4; -} - -// TxProof represents a Merkle proof of the presence of a transaction in the -// Merkle tree. -message TxProof { - bytes root_hash = 1; - bytes data = 2; - tendermint.crypto.Proof proof = 3; -} diff --git a/scripts/abci-gen.sh b/scripts/abci-gen.sh deleted file mode 100755 index 1e602aaec..000000000 --- a/scripts/abci-gen.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env bash - -# This file was added during development of ABCI++. This file is a script to allow -# the intermediate proto files to be built while active development proceeds -# on ABCI++. -# This file should be removed when work on ABCI++ is complete. -# For more information, see https://github.com/tendermint/tendermint/issues/8066. -set -euo pipefail - -cp ./proto/tendermint/abci/types.proto.intermediate ./proto/tendermint/abci/types.proto -cp ./proto/tendermint/types/types.proto.intermediate ./proto/tendermint/types/types.proto - -MODNAME="$(go list -m)" -find ./proto/tendermint -name '*.proto' -not -path "./proto/tendermint/abci/types.proto" \ - -exec ./scripts/protopackage.sh {} "$MODNAME" ';' - -./scripts/protopackage.sh ./proto/tendermint/abci/types.proto $MODNAME "abci/types" - -make proto-gen - -echo "proto files have been compiled" - -echo "checking out copied files" - -find proto/tendermint/ -name '*.proto' -not -path "*.intermediate"\ - | xargs -I {} git checkout {} - -find proto/tendermint/ -name '*.pb.go' \ - | xargs -I {} git checkout {} diff --git a/scripts/protopackage.sh b/scripts/protopackage.sh deleted file mode 100755 index fe3e78c8a..000000000 --- a/scripts/protopackage.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash -set -eo pipefail - -# This script appends the "option go_package" proto option to the file located at $FNAME. -# This option specifies what the package will be named when imported by other packages. -# This option is not directly included in the proto files to allow the files to more easily -# be hosted in github.com/tendermint/spec and shared between other repos. -# If the option is already specified in the file, it will be replaced using the -# arguments passed to this script. - -FNAME="${1:?missing required .proto filename}" -MODNAME=$(echo $2| sed 's/\//\\\//g') -PACKAGE="$(dirname $FNAME | sed 's/^\.\/\(.*\)/\1/g' | sed 's/\//\\\//g')" -if [[ ! -z "$3" ]]; then - PACKAGE="$(echo $3 | sed 's/\//\\\//g')" -fi - - -if ! grep -q 'option\s\+go_package\s\+=\s\+.*;' $FNAME; then - sed -i "s/\(package tendermint.*\)/\1\n\noption go_package = \"$MODNAME\/$PACKAGE\";/g" $FNAME -else - sed -i "s/option\s\+go_package\s\+=\s\+.*;/option go_package = \"$MODNAME\/$PACKAGE\";/g" $FNAME -fi From c44e6d1799a6d4f98360bcde6abf2bc682c093a9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Apr 2022 15:01:57 +0000 Subject: [PATCH 19/35] build(deps): Bump github.com/vektra/mockery/v2 from 2.12.0 to 2.12.1 (#8417) Bumps [github.com/vektra/mockery/v2](https://github.com/vektra/mockery) from 2.12.0 to 2.12.1.
Release notes

Sourced from github.com/vektra/mockery/v2's releases.

v2.12.1

Changelog

  • facf60b Add extra test cases for increasing code coverage.
  • 2e1360a Collapse if statements and rename interface in the fixtures.
  • 8bdc90d Fix test on go1.18.
  • fe03b57 Fix tests.
  • b8c62f7 Fix: avoid package name collision with inPackage (#291)
  • c9dc740 Merge pull request #422 from i-sevostyanov/fix-package-collision
  • 58a7f18 Merge pull request #452 from grongor/refactor-first-letter-helper
  • 749b2d6 Refactor mock name generation
Commits
  • c9dc740 Merge pull request #422 from i-sevostyanov/fix-package-collision
  • facf60b Add extra test cases for increasing code coverage.
  • 8bdc90d Fix test on go1.18.
  • fe03b57 Fix tests.
  • 2e1360a Collapse if statements and rename interface in the fixtures.
  • b8c62f7 Fix: avoid package name collision with inPackage (#291)
  • 58a7f18 Merge pull request #452 from grongor/refactor-first-letter-helper
  • 749b2d6 Refactor mock name generation
  • See full diff in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/vektra/mockery/v2&package-manager=go_modules&previous-version=2.12.0&new-version=2.12.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 33f5e5a6d..e13f0b7fb 100644 --- a/go.mod +++ b/go.mod @@ -42,7 +42,7 @@ require ( github.com/creachadair/taskgroup v0.3.2 github.com/golangci/golangci-lint v1.45.2 github.com/google/go-cmp v0.5.7 - github.com/vektra/mockery/v2 v2.12.0 + github.com/vektra/mockery/v2 v2.12.1 gotest.tools v2.2.0+incompatible ) diff --git a/go.sum b/go.sum index 1609c9a40..d8f113b48 100644 --- a/go.sum +++ b/go.sum @@ -1056,8 +1056,8 @@ github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyC github.com/valyala/fasthttp v1.30.0/go.mod h1:2rsYD01CKFrjjsvFxx75KlEUNpWNBY9JWD3K/7o2Cus= github.com/valyala/quicktemplate v1.7.0/go.mod h1:sqKJnoaOF88V07vkO+9FL8fb9uZg/VPSJnLYn+LmLk8= github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= -github.com/vektra/mockery/v2 v2.12.0 h1:g3lq1ni5swlT9y6jYBx/CITVpwg3vsWrhKIuIweAxYI= -github.com/vektra/mockery/v2 v2.12.0/go.mod h1:8vf4KDDUptfkyypzdHLuE7OE2xA7Gdt60WgIS8PgD+U= +github.com/vektra/mockery/v2 v2.12.1 h1:BAJk2fGjVg/P9Fi+BxZD1/ZeKTOclpeAb/SKCc12zXc= +github.com/vektra/mockery/v2 v2.12.1/go.mod h1:8vf4KDDUptfkyypzdHLuE7OE2xA7Gdt60WgIS8PgD+U= github.com/viki-org/dnscache v0.0.0-20130720023526-c70c1f23c5d8/go.mod h1:dniwbG03GafCjFohMDmz6Zc6oCuiqgH6tGNyXTkHzXE= github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= From b626b0a7198c78efdbce368c188a64c75bd4e704 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 27 Apr 2022 13:21:03 +0000 Subject: [PATCH 20/35] build(deps): Bump github.com/google/go-cmp from 0.5.7 to 0.5.8 (#8422) Bumps [github.com/google/go-cmp](https://github.com/google/go-cmp) from 0.5.7 to 0.5.8.
Release notes

Sourced from github.com/google/go-cmp's releases.

v0.5.8

Reporter changes:

  • (#293) Fix printing of types in reporter output for interface and pointer types
  • (#294) Use string formatting for slice of bytes in more circumstances

Dependency changes:

  • (#292) Update minimum supported version to go1.13 and remove xerrors dependency
Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/google/go-cmp&package-manager=go_modules&previous-version=0.5.7&new-version=0.5.8)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- go.mod | 2 +- go.sum | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index e13f0b7fb..f03deab1a 100644 --- a/go.mod +++ b/go.mod @@ -41,7 +41,7 @@ require ( github.com/creachadair/atomicfile v0.2.5 github.com/creachadair/taskgroup v0.3.2 github.com/golangci/golangci-lint v1.45.2 - github.com/google/go-cmp v0.5.7 + github.com/google/go-cmp v0.5.8 github.com/vektra/mockery/v2 v2.12.1 gotest.tools v2.2.0+incompatible ) diff --git a/go.sum b/go.sum index d8f113b48..07dedbb7b 100644 --- a/go.sum +++ b/go.sum @@ -449,8 +449,9 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= From e741d01231653eaa88a74efebb1e2cfa3dc96845 Mon Sep 17 00:00:00 2001 From: elias-orijtech <103319121+elias-orijtech@users.noreply.github.com> Date: Wed, 27 Apr 2022 16:26:21 +0200 Subject: [PATCH 21/35] fuzz: don't panic on expected errors (#8423) In the conversion to Go 1.18 fuzzing in e4991fd862c8300254417360feb2d66c5861aa54, a `return 0` was converted to a panic. A `return 0` is a hint to the fuzzer, not a failing testcase. While here, clean up the test by folding setup code into it. --- test/fuzz/tests/mempool_test.go | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/test/fuzz/tests/mempool_test.go b/test/fuzz/tests/mempool_test.go index a76b059ca..2c8623036 100644 --- a/test/fuzz/tests/mempool_test.go +++ b/test/fuzz/tests/mempool_test.go @@ -13,10 +13,7 @@ import ( "github.com/tendermint/tendermint/libs/log" ) -var mp *mempool.TxMempool -var getMp func() mempool.Mempool - -func init() { +func FuzzMempool(f *testing.F) { app := kvstore.NewApplication() logger := log.NewNopLogger() conn := abciclient.NewLocalClient(logger, app) @@ -28,19 +25,9 @@ func init() { cfg := config.DefaultMempoolConfig() cfg.Broadcast = false - getMp = func() mempool.Mempool { - if mp == nil { - mp = mempool.NewTxMempool(logger, cfg, conn) - } - return mp - } -} + mp := mempool.NewTxMempool(logger, cfg, conn) -func FuzzMempool(f *testing.F) { f.Fuzz(func(t *testing.T, data []byte) { - err := getMp().CheckTx(context.Background(), data, nil, mempool.TxInfo{}) - if err != nil { - panic(err) - } + _ = mp.CheckTx(context.Background(), data, nil, mempool.TxInfo{}) }) } From da1b871808b352926a24132467ccc5349286d3fa Mon Sep 17 00:00:00 2001 From: "M. J. Fromberger" Date: Wed, 27 Apr 2022 07:53:51 -0700 Subject: [PATCH 22/35] Unify RPC method signatures and parameter decoding (#8397) Pass all parameters from JSON-RPC requests to their corresponding handlers using struct types instead of positional parameters. This allows us to control encoding of arguments using only the standard library, and to eliminate the remaining special-purpose JSON encoding hooks in the server. To support existing use, the server still allows arguments to be encoded in JSON as either an array or an object. Related changes: - Rework the RPCFunc constructor to reduce reflection during RPC call service. - Add request parameter wrappers for each RPC service method. - Update the RPC Environment methods to use these types. - Update the interfaces and shims derived from Environment to the new signatures. - Update and extend test cases. --- internal/inspect/rpc/rpc.go | 20 +- internal/rpc/core/abci.go | 17 +- internal/rpc/core/blocks.go | 68 +++---- internal/rpc/core/blocks_test.go | 4 +- internal/rpc/core/consensus.go | 21 +- internal/rpc/core/events.go | 40 ++-- internal/rpc/core/evidence.go | 13 +- internal/rpc/core/mempool.go | 50 ++--- internal/rpc/core/net.go | 4 +- internal/rpc/core/routes.go | 100 +++++---- internal/rpc/core/tx.go | 37 ++-- light/proxy/routes.go | 150 +++++++++++--- rpc/client/eventstream/eventstream_test.go | 22 +- rpc/client/http/http.go | 81 +++++--- rpc/client/http/request.go | 65 ------ rpc/client/local/local.go | 73 ++++--- rpc/client/mock/client.go | 33 +-- rpc/coretypes/requests.go | 188 +++++++++++++++++ rpc/coretypes/responses.go | 26 --- rpc/jsonrpc/doc.go | 2 +- rpc/jsonrpc/jsonrpc_test.go | 46 +++-- rpc/jsonrpc/server/http_json_handler.go | 115 +---------- rpc/jsonrpc/server/http_json_handler_test.go | 13 +- rpc/jsonrpc/server/http_uri_handler.go | 154 +++----------- rpc/jsonrpc/server/parse_test.go | 202 ++++++++++++++----- rpc/jsonrpc/server/rpc_func.go | 185 +++++++++++++---- rpc/jsonrpc/server/ws_handler.go | 16 +- rpc/jsonrpc/server/ws_handler_test.go | 7 +- rpc/jsonrpc/test/main.go | 2 +- test/fuzz/tests/rpc_jsonrpc_server_test.go | 8 +- 30 files changed, 983 insertions(+), 779 deletions(-) delete mode 100644 rpc/client/http/request.go create mode 100644 rpc/coretypes/requests.go diff --git a/internal/inspect/rpc/rpc.go b/internal/inspect/rpc/rpc.go index 40f0d5d26..00c3e52ef 100644 --- a/internal/inspect/rpc/rpc.go +++ b/internal/inspect/rpc/rpc.go @@ -38,16 +38,16 @@ func Routes(cfg config.RPCConfig, s state.Store, bs state.BlockStore, es []index Logger: logger, } return core.RoutesMap{ - "blockchain": server.NewRPCFunc(env.BlockchainInfo, "minHeight", "maxHeight"), - "consensus_params": server.NewRPCFunc(env.ConsensusParams, "height"), - "block": server.NewRPCFunc(env.Block, "height"), - "block_by_hash": server.NewRPCFunc(env.BlockByHash, "hash"), - "block_results": server.NewRPCFunc(env.BlockResults, "height"), - "commit": server.NewRPCFunc(env.Commit, "height"), - "validators": server.NewRPCFunc(env.Validators, "height", "page", "per_page"), - "tx": server.NewRPCFunc(env.Tx, "hash", "prove"), - "tx_search": server.NewRPCFunc(env.TxSearch, "query", "prove", "page", "per_page", "order_by"), - "block_search": server.NewRPCFunc(env.BlockSearch, "query", "page", "per_page", "order_by"), + "blockchain": server.NewRPCFunc(env.BlockchainInfo), + "consensus_params": server.NewRPCFunc(env.ConsensusParams), + "block": server.NewRPCFunc(env.Block), + "block_by_hash": server.NewRPCFunc(env.BlockByHash), + "block_results": server.NewRPCFunc(env.BlockResults), + "commit": server.NewRPCFunc(env.Commit), + "validators": server.NewRPCFunc(env.Validators), + "tx": server.NewRPCFunc(env.Tx), + "tx_search": server.NewRPCFunc(env.TxSearch), + "block_search": server.NewRPCFunc(env.BlockSearch), } } diff --git a/internal/rpc/core/abci.go b/internal/rpc/core/abci.go index dc7a5bdfe..fa45c6b45 100644 --- a/internal/rpc/core/abci.go +++ b/internal/rpc/core/abci.go @@ -5,24 +5,17 @@ import ( abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/internal/proxy" - "github.com/tendermint/tendermint/libs/bytes" "github.com/tendermint/tendermint/rpc/coretypes" ) // ABCIQuery queries the application for some information. // More: https://docs.tendermint.com/master/rpc/#/ABCI/abci_query -func (env *Environment) ABCIQuery( - ctx context.Context, - path string, - data bytes.HexBytes, - height int64, - prove bool, -) (*coretypes.ResultABCIQuery, error) { +func (env *Environment) ABCIQuery(ctx context.Context, req *coretypes.RequestABCIQuery) (*coretypes.ResultABCIQuery, error) { resQuery, err := env.ProxyApp.Query(ctx, &abci.RequestQuery{ - Path: path, - Data: data, - Height: height, - Prove: prove, + Path: req.Path, + Data: req.Data, + Height: int64(req.Height), + Prove: req.Prove, }) if err != nil { return nil, err diff --git a/internal/rpc/core/blocks.go b/internal/rpc/core/blocks.go index 26044aef7..239344002 100644 --- a/internal/rpc/core/blocks.go +++ b/internal/rpc/core/blocks.go @@ -7,7 +7,6 @@ import ( tmquery "github.com/tendermint/tendermint/internal/pubsub/query" "github.com/tendermint/tendermint/internal/state/indexer" - "github.com/tendermint/tendermint/libs/bytes" tmmath "github.com/tendermint/tendermint/libs/math" "github.com/tendermint/tendermint/rpc/coretypes" "github.com/tendermint/tendermint/types" @@ -23,17 +22,15 @@ import ( // order (highest first). // // More: https://docs.tendermint.com/master/rpc/#/Info/blockchain -func (env *Environment) BlockchainInfo(ctx context.Context, minHeight, maxHeight int64) (*coretypes.ResultBlockchainInfo, error) { - - const limit int64 = 20 - - var err error - minHeight, maxHeight, err = filterMinMax( +func (env *Environment) BlockchainInfo(ctx context.Context, req *coretypes.RequestBlockchainInfo) (*coretypes.ResultBlockchainInfo, error) { + const limit = 20 + minHeight, maxHeight, err := filterMinMax( env.BlockStore.Base(), env.BlockStore.Height(), - minHeight, - maxHeight, - limit) + int64(req.MinHeight), + int64(req.MaxHeight), + limit, + ) if err != nil { return nil, err } @@ -90,8 +87,8 @@ func filterMinMax(base, height, min, max, limit int64) (int64, int64, error) { // Block gets block at a given height. // If no height is provided, it will fetch the latest block. // More: https://docs.tendermint.com/master/rpc/#/Info/block -func (env *Environment) Block(ctx context.Context, heightPtr *int64) (*coretypes.ResultBlock, error) { - height, err := env.getHeight(env.BlockStore.Height(), heightPtr) +func (env *Environment) Block(ctx context.Context, req *coretypes.RequestBlockInfo) (*coretypes.ResultBlock, error) { + height, err := env.getHeight(env.BlockStore.Height(), (*int64)(req.Height)) if err != nil { return nil, err } @@ -107,12 +104,8 @@ func (env *Environment) Block(ctx context.Context, heightPtr *int64) (*coretypes // BlockByHash gets block by hash. // More: https://docs.tendermint.com/master/rpc/#/Info/block_by_hash -func (env *Environment) BlockByHash(ctx context.Context, hash bytes.HexBytes) (*coretypes.ResultBlock, error) { - // N.B. The hash parameter is HexBytes so that the reflective parameter - // decoding logic in the HTTP service will correctly translate from JSON. - // See https://github.com/tendermint/tendermint/issues/6802 for context. - - block := env.BlockStore.LoadBlockByHash(hash) +func (env *Environment) BlockByHash(ctx context.Context, req *coretypes.RequestBlockByHash) (*coretypes.ResultBlock, error) { + block := env.BlockStore.LoadBlockByHash(req.Hash) if block == nil { return &coretypes.ResultBlock{BlockID: types.BlockID{}, Block: nil}, nil } @@ -124,8 +117,8 @@ func (env *Environment) BlockByHash(ctx context.Context, hash bytes.HexBytes) (* // Header gets block header at a given height. // If no height is provided, it will fetch the latest header. // More: https://docs.tendermint.com/master/rpc/#/Info/header -func (env *Environment) Header(ctx context.Context, heightPtr *int64) (*coretypes.ResultHeader, error) { - height, err := env.getHeight(env.BlockStore.Height(), heightPtr) +func (env *Environment) Header(ctx context.Context, req *coretypes.RequestBlockInfo) (*coretypes.ResultHeader, error) { + height, err := env.getHeight(env.BlockStore.Height(), (*int64)(req.Height)) if err != nil { return nil, err } @@ -140,12 +133,8 @@ func (env *Environment) Header(ctx context.Context, heightPtr *int64) (*coretype // HeaderByHash gets header by hash. // More: https://docs.tendermint.com/master/rpc/#/Info/header_by_hash -func (env *Environment) HeaderByHash(ctx context.Context, hash bytes.HexBytes) (*coretypes.ResultHeader, error) { - // N.B. The hash parameter is HexBytes so that the reflective parameter - // decoding logic in the HTTP service will correctly translate from JSON. - // See https://github.com/tendermint/tendermint/issues/6802 for context. - - blockMeta := env.BlockStore.LoadBlockMetaByHash(hash) +func (env *Environment) HeaderByHash(ctx context.Context, req *coretypes.RequestBlockByHash) (*coretypes.ResultHeader, error) { + blockMeta := env.BlockStore.LoadBlockMetaByHash(req.Hash) if blockMeta == nil { return &coretypes.ResultHeader{}, nil } @@ -156,8 +145,8 @@ func (env *Environment) HeaderByHash(ctx context.Context, hash bytes.HexBytes) ( // Commit gets block commit at a given height. // If no height is provided, it will fetch the commit for the latest block. // More: https://docs.tendermint.com/master/rpc/#/Info/commit -func (env *Environment) Commit(ctx context.Context, heightPtr *int64) (*coretypes.ResultCommit, error) { - height, err := env.getHeight(env.BlockStore.Height(), heightPtr) +func (env *Environment) Commit(ctx context.Context, req *coretypes.RequestBlockInfo) (*coretypes.ResultCommit, error) { + height, err := env.getHeight(env.BlockStore.Height(), (*int64)(req.Height)) if err != nil { return nil, err } @@ -192,8 +181,8 @@ func (env *Environment) Commit(ctx context.Context, heightPtr *int64) (*coretype // // Results are for the height of the block containing the txs. // More: https://docs.tendermint.com/master/rpc/#/Info/block_results -func (env *Environment) BlockResults(ctx context.Context, heightPtr *int64) (*coretypes.ResultBlockResults, error) { - height, err := env.getHeight(env.BlockStore.Height(), heightPtr) +func (env *Environment) BlockResults(ctx context.Context, req *coretypes.RequestBlockInfo) (*coretypes.ResultBlockResults, error) { + height, err := env.getHeight(env.BlockStore.Height(), (*int64)(req.Height)) if err != nil { return nil, err } @@ -218,20 +207,13 @@ func (env *Environment) BlockResults(ctx context.Context, heightPtr *int64) (*co }, nil } -// BlockSearch searches for a paginated set of blocks matching the provided -// query. -func (env *Environment) BlockSearch( - ctx context.Context, - query string, - pagePtr, perPagePtr *int, - orderBy string, -) (*coretypes.ResultBlockSearch, error) { - +// BlockSearch searches for a paginated set of blocks matching the provided query. +func (env *Environment) BlockSearch(ctx context.Context, req *coretypes.RequestBlockSearch) (*coretypes.ResultBlockSearch, error) { if !indexer.KVSinkEnabled(env.EventSinks) { return nil, fmt.Errorf("block searching is disabled due to no kvEventSink") } - q, err := tmquery.New(query) + q, err := tmquery.New(req.Query) if err != nil { return nil, err } @@ -249,7 +231,7 @@ func (env *Environment) BlockSearch( } // sort results (must be done before pagination) - switch orderBy { + switch req.OrderBy { case "desc", "": sort.Slice(results, func(i, j int) bool { return results[i] > results[j] }) @@ -262,9 +244,9 @@ func (env *Environment) BlockSearch( // paginate results totalCount := len(results) - perPage := env.validatePerPage(perPagePtr) + perPage := env.validatePerPage(req.PerPage.IntPtr()) - page, err := validatePage(pagePtr, perPage, totalCount) + page, err := validatePage(req.Page.IntPtr(), perPage, totalCount) if err != nil { return nil, err } diff --git a/internal/rpc/core/blocks_test.go b/internal/rpc/core/blocks_test.go index c48ac4c48..d95338332 100644 --- a/internal/rpc/core/blocks_test.go +++ b/internal/rpc/core/blocks_test.go @@ -109,7 +109,9 @@ func TestBlockResults(t *testing.T) { ctx := context.Background() for _, tc := range testCases { - res, err := env.BlockResults(ctx, &tc.height) + res, err := env.BlockResults(ctx, &coretypes.RequestBlockInfo{ + Height: (*coretypes.Int64)(&tc.height), + }) if tc.wantErr { assert.Error(t, err) } else { diff --git a/internal/rpc/core/consensus.go b/internal/rpc/core/consensus.go index f10f37ebc..46e220f05 100644 --- a/internal/rpc/core/consensus.go +++ b/internal/rpc/core/consensus.go @@ -14,10 +14,9 @@ import ( // for the validators in the set as used in computing their Merkle root. // // More: https://docs.tendermint.com/master/rpc/#/Info/validators -func (env *Environment) Validators(ctx context.Context, heightPtr *int64, pagePtr, perPagePtr *int) (*coretypes.ResultValidators, error) { - +func (env *Environment) Validators(ctx context.Context, req *coretypes.RequestValidators) (*coretypes.ResultValidators, error) { // The latest validator that we know is the NextValidator of the last block. - height, err := env.getHeight(env.latestUncommittedHeight(), heightPtr) + height, err := env.getHeight(env.latestUncommittedHeight(), (*int64)(req.Height)) if err != nil { return nil, err } @@ -28,8 +27,8 @@ func (env *Environment) Validators(ctx context.Context, heightPtr *int64, pagePt } totalCount := len(validators.Validators) - perPage := env.validatePerPage(perPagePtr) - page, err := validatePage(pagePtr, perPage, totalCount) + perPage := env.validatePerPage(req.PerPage.IntPtr()) + page, err := validatePage(req.Page.IntPtr(), perPage, totalCount) if err != nil { return nil, err } @@ -42,7 +41,8 @@ func (env *Environment) Validators(ctx context.Context, heightPtr *int64, pagePt BlockHeight: height, Validators: v, Count: len(v), - Total: totalCount}, nil + Total: totalCount, + }, nil } // DumpConsensusState dumps consensus state. @@ -99,11 +99,10 @@ func (env *Environment) GetConsensusState(ctx context.Context) (*coretypes.Resul // ConsensusParams gets the consensus parameters at the given block height. // If no height is provided, it will fetch the latest consensus params. // More: https://docs.tendermint.com/master/rpc/#/Info/consensus_params -func (env *Environment) ConsensusParams(ctx context.Context, heightPtr *int64) (*coretypes.ResultConsensusParams, error) { - - // The latest consensus params that we know is the consensus params after the - // last block. - height, err := env.getHeight(env.latestUncommittedHeight(), heightPtr) +func (env *Environment) ConsensusParams(ctx context.Context, req *coretypes.RequestConsensusParams) (*coretypes.ResultConsensusParams, error) { + // The latest consensus params that we know is the consensus params after + // the last block. + height, err := env.getHeight(env.latestUncommittedHeight(), (*int64)(req.Height)) if err != nil { return nil, err } diff --git a/internal/rpc/core/events.go b/internal/rpc/core/events.go index 4e0d2ac8a..3f289bfa7 100644 --- a/internal/rpc/core/events.go +++ b/internal/rpc/core/events.go @@ -26,7 +26,7 @@ const ( // Subscribe for events via WebSocket. // More: https://docs.tendermint.com/master/rpc/#/Websocket/subscribe -func (env *Environment) Subscribe(ctx context.Context, query string) (*coretypes.ResultSubscribe, error) { +func (env *Environment) Subscribe(ctx context.Context, req *coretypes.RequestSubscribe) (*coretypes.ResultSubscribe, error) { callInfo := rpctypes.GetCallInfo(ctx) addr := callInfo.RemoteAddr() @@ -34,15 +34,15 @@ func (env *Environment) Subscribe(ctx context.Context, query string) (*coretypes return nil, fmt.Errorf("max_subscription_clients %d reached", env.Config.MaxSubscriptionClients) } else if env.EventBus.NumClientSubscriptions(addr) >= env.Config.MaxSubscriptionsPerClient { return nil, fmt.Errorf("max_subscriptions_per_client %d reached", env.Config.MaxSubscriptionsPerClient) - } else if len(query) > maxQueryLength { + } else if len(req.Query) > maxQueryLength { return nil, errors.New("maximum query length exceeded") } env.Logger.Info("WARNING: Websocket subscriptions are deprecated and will be removed " + "in Tendermint v0.37. See https://tinyurl.com/adr075 for more information.") - env.Logger.Info("Subscribe to query", "remote", addr, "query", query) + env.Logger.Info("Subscribe to query", "remote", addr, "query", req.Query) - q, err := tmquery.New(query) + q, err := tmquery.New(req.Query) if err != nil { return nil, fmt.Errorf("failed to parse query: %w", err) } @@ -83,7 +83,7 @@ func (env *Environment) Subscribe(ctx context.Context, query string) (*coretypes // We have a message to deliver to the client. resp := callInfo.RPCRequest.MakeResponse(&coretypes.ResultEvent{ - Query: query, + Query: req.Query, Data: msg.Data(), Events: msg.Events(), }) @@ -102,15 +102,15 @@ func (env *Environment) Subscribe(ctx context.Context, query string) (*coretypes // Unsubscribe from events via WebSocket. // More: https://docs.tendermint.com/master/rpc/#/Websocket/unsubscribe -func (env *Environment) Unsubscribe(ctx context.Context, query string) (*coretypes.ResultUnsubscribe, error) { +func (env *Environment) Unsubscribe(ctx context.Context, req *coretypes.RequestUnsubscribe) (*coretypes.ResultUnsubscribe, error) { args := tmpubsub.UnsubscribeArgs{Subscriber: rpctypes.GetCallInfo(ctx).RemoteAddr()} - env.Logger.Info("Unsubscribe from query", "remote", args.Subscriber, "subscription", query) + env.Logger.Info("Unsubscribe from query", "remote", args.Subscriber, "subscription", req.Query) var err error - args.Query, err = tmquery.New(query) + args.Query, err = tmquery.New(req.Query) if err != nil { - args.ID = query + args.ID = req.Query } err = env.EventBus.Unsubscribe(ctx, args) @@ -148,17 +148,13 @@ func (env *Environment) UnsubscribeAll(ctx context.Context) (*coretypes.ResultUn // If maxItems ≤ 0, a default positive number of events is chosen. The values // of maxItems and waitTime may be capped to sensible internal maxima without // reporting an error to the caller. -func (env *Environment) Events(ctx context.Context, - filter *coretypes.EventFilter, - maxItems int, - before, after cursor.Cursor, - waitTime time.Duration, -) (*coretypes.ResultEvents, error) { +func (env *Environment) Events(ctx context.Context, req *coretypes.RequestEvents) (*coretypes.ResultEvents, error) { if env.EventLog == nil { return nil, errors.New("the event log is not enabled") } // Parse and validate parameters. + maxItems := req.MaxItems if maxItems <= 0 { maxItems = 10 } else if maxItems > 100 { @@ -167,6 +163,8 @@ func (env *Environment) Events(ctx context.Context, const minWaitTime = 1 * time.Second const maxWaitTime = 30 * time.Second + + waitTime := req.WaitTime if waitTime < minWaitTime { waitTime = minWaitTime } else if waitTime > maxWaitTime { @@ -174,14 +172,22 @@ func (env *Environment) Events(ctx context.Context, } query := tmquery.All - if filter != nil && filter.Query != "" { - q, err := tmquery.New(filter.Query) + if req.Filter != nil && req.Filter.Query != "" { + q, err := tmquery.New(req.Filter.Query) if err != nil { return nil, fmt.Errorf("invalid filter query: %w", err) } query = q } + var before, after cursor.Cursor + if err := before.UnmarshalText([]byte(req.Before)); err != nil { + return nil, fmt.Errorf("invalid cursor %q: %w", req.Before, err) + } + if err := after.UnmarshalText([]byte(req.After)); err != nil { + return nil, fmt.Errorf("invalid cursor %q: %w", req.After, err) + } + var info eventlog.Info var items []*eventlog.Item var err error diff --git a/internal/rpc/core/evidence.go b/internal/rpc/core/evidence.go index c7e2bea8a..5de93d2c2 100644 --- a/internal/rpc/core/evidence.go +++ b/internal/rpc/core/evidence.go @@ -9,18 +9,15 @@ import ( // BroadcastEvidence broadcasts evidence of the misbehavior. // More: https://docs.tendermint.com/master/rpc/#/Evidence/broadcast_evidence -func (env *Environment) BroadcastEvidence( - ctx context.Context, - ev coretypes.Evidence, -) (*coretypes.ResultBroadcastEvidence, error) { - if ev.Value == nil { +func (env *Environment) BroadcastEvidence(ctx context.Context, req *coretypes.RequestBroadcastEvidence) (*coretypes.ResultBroadcastEvidence, error) { + if req.Evidence == nil { return nil, fmt.Errorf("%w: no evidence was provided", coretypes.ErrInvalidRequest) } - if err := ev.Value.ValidateBasic(); err != nil { + if err := req.Evidence.ValidateBasic(); err != nil { return nil, fmt.Errorf("evidence.ValidateBasic failed: %w", err) } - if err := env.EvidencePool.AddEvidence(ctx, ev.Value); err != nil { + if err := env.EvidencePool.AddEvidence(ctx, req.Evidence); err != nil { return nil, fmt.Errorf("failed to add evidence: %w", err) } - return &coretypes.ResultBroadcastEvidence{Hash: ev.Value.Hash()}, nil + return &coretypes.ResultBroadcastEvidence{Hash: req.Evidence.Hash()}, nil } diff --git a/internal/rpc/core/mempool.go b/internal/rpc/core/mempool.go index 450adf4d5..5fc2b9fcf 100644 --- a/internal/rpc/core/mempool.go +++ b/internal/rpc/core/mempool.go @@ -12,7 +12,6 @@ import ( "github.com/tendermint/tendermint/internal/state/indexer" tmmath "github.com/tendermint/tendermint/libs/math" "github.com/tendermint/tendermint/rpc/coretypes" - "github.com/tendermint/tendermint/types" ) //----------------------------------------------------------------------------- @@ -21,23 +20,23 @@ import ( // BroadcastTxAsync returns right away, with no response. Does not wait for // CheckTx nor DeliverTx results. // More: https://docs.tendermint.com/master/rpc/#/Tx/broadcast_tx_async -func (env *Environment) BroadcastTxAsync(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTx, error) { - err := env.Mempool.CheckTx(ctx, tx, nil, mempool.TxInfo{}) +func (env *Environment) BroadcastTxAsync(ctx context.Context, req *coretypes.RequestBroadcastTx) (*coretypes.ResultBroadcastTx, error) { + err := env.Mempool.CheckTx(ctx, req.Tx, nil, mempool.TxInfo{}) if err != nil { return nil, err } - return &coretypes.ResultBroadcastTx{Hash: tx.Hash()}, nil + return &coretypes.ResultBroadcastTx{Hash: req.Tx.Hash()}, nil } // BroadcastTxSync returns with the response from CheckTx. Does not wait for // DeliverTx result. // More: https://docs.tendermint.com/master/rpc/#/Tx/broadcast_tx_sync -func (env *Environment) BroadcastTxSync(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTx, error) { +func (env *Environment) BroadcastTxSync(ctx context.Context, req *coretypes.RequestBroadcastTx) (*coretypes.ResultBroadcastTx, error) { resCh := make(chan *abci.ResponseCheckTx, 1) err := env.Mempool.CheckTx( ctx, - tx, + req.Tx, func(res *abci.ResponseCheckTx) { select { case <-ctx.Done(): @@ -60,19 +59,18 @@ func (env *Environment) BroadcastTxSync(ctx context.Context, tx types.Tx) (*core Log: r.Log, Codespace: r.Codespace, MempoolError: r.MempoolError, - Hash: tx.Hash(), + Hash: req.Tx.Hash(), }, nil } - } // BroadcastTxCommit returns with the responses from CheckTx and DeliverTx. // More: https://docs.tendermint.com/master/rpc/#/Tx/broadcast_tx_commit -func (env *Environment) BroadcastTxCommit(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTxCommit, error) { +func (env *Environment) BroadcastTxCommit(ctx context.Context, req *coretypes.RequestBroadcastTx) (*coretypes.ResultBroadcastTxCommit, error) { resCh := make(chan *abci.ResponseCheckTx, 1) err := env.Mempool.CheckTx( ctx, - tx, + req.Tx, func(res *abci.ResponseCheckTx) { select { case <-ctx.Done(): @@ -92,14 +90,14 @@ func (env *Environment) BroadcastTxCommit(ctx context.Context, tx types.Tx) (*co if r.Code != abci.CodeTypeOK { return &coretypes.ResultBroadcastTxCommit{ CheckTx: *r, - Hash: tx.Hash(), + Hash: req.Tx.Hash(), }, fmt.Errorf("transaction encountered error (%s)", r.MempoolError) } if !indexer.KVSinkEnabled(env.EventSinks) { return &coretypes.ResultBroadcastTxCommit{ CheckTx: *r, - Hash: tx.Hash(), + Hash: req.Tx.Hash(), }, errors.New("cannot confirm transaction because kvEventSink is not enabled") } @@ -118,11 +116,14 @@ func (env *Environment) BroadcastTxCommit(ctx context.Context, tx types.Tx) (*co "err", err) return &coretypes.ResultBroadcastTxCommit{ CheckTx: *r, - Hash: tx.Hash(), + Hash: req.Tx.Hash(), }, fmt.Errorf("timeout waiting for commit of tx %s (%s)", - tx.Hash(), time.Since(startAt)) + req.Tx.Hash(), time.Since(startAt)) case <-timer.C: - txres, err := env.Tx(ctx, tx.Hash(), false) + txres, err := env.Tx(ctx, &coretypes.RequestTx{ + Hash: req.Tx.Hash(), + Prove: false, + }) if err != nil { jitter := 100*time.Millisecond + time.Duration(rand.Int63n(int64(time.Second))) // nolint: gosec backoff := 100 * time.Duration(count) * time.Millisecond @@ -133,7 +134,7 @@ func (env *Environment) BroadcastTxCommit(ctx context.Context, tx types.Tx) (*co return &coretypes.ResultBroadcastTxCommit{ CheckTx: *r, TxResult: txres.TxResult, - Hash: tx.Hash(), + Hash: req.Tx.Hash(), Height: txres.Height, }, nil } @@ -143,10 +144,10 @@ func (env *Environment) BroadcastTxCommit(ctx context.Context, tx types.Tx) (*co // UnconfirmedTxs gets unconfirmed transactions from the mempool in order of priority // More: https://docs.tendermint.com/master/rpc/#/Info/unconfirmed_txs -func (env *Environment) UnconfirmedTxs(ctx context.Context, pagePtr, perPagePtr *int) (*coretypes.ResultUnconfirmedTxs, error) { +func (env *Environment) UnconfirmedTxs(ctx context.Context, req *coretypes.RequestUnconfirmedTxs) (*coretypes.ResultUnconfirmedTxs, error) { totalCount := env.Mempool.Size() - perPage := env.validatePerPage(perPagePtr) - page, err := validatePage(pagePtr, perPage, totalCount) + perPage := env.validatePerPage(req.PerPage.IntPtr()) + page, err := validatePage(req.Page.IntPtr(), perPage, totalCount) if err != nil { return nil, err } @@ -160,7 +161,8 @@ func (env *Environment) UnconfirmedTxs(ctx context.Context, pagePtr, perPagePtr Count: len(result), Total: totalCount, TotalBytes: env.Mempool.SizeBytes(), - Txs: result}, nil + Txs: result, + }, nil } // NumUnconfirmedTxs gets number of unconfirmed transactions. @@ -175,14 +177,14 @@ func (env *Environment) NumUnconfirmedTxs(ctx context.Context) (*coretypes.Resul // CheckTx checks the transaction without executing it. The transaction won't // be added to the mempool either. // More: https://docs.tendermint.com/master/rpc/#/Tx/check_tx -func (env *Environment) CheckTx(ctx context.Context, tx types.Tx) (*coretypes.ResultCheckTx, error) { - res, err := env.ProxyApp.CheckTx(ctx, &abci.RequestCheckTx{Tx: tx}) +func (env *Environment) CheckTx(ctx context.Context, req *coretypes.RequestCheckTx) (*coretypes.ResultCheckTx, error) { + res, err := env.ProxyApp.CheckTx(ctx, &abci.RequestCheckTx{Tx: req.Tx}) if err != nil { return nil, err } return &coretypes.ResultCheckTx{ResponseCheckTx: *res}, nil } -func (env *Environment) RemoveTx(ctx context.Context, txkey types.TxKey) error { - return env.Mempool.RemoveTxByKey(txkey) +func (env *Environment) RemoveTx(ctx context.Context, req *coretypes.RequestRemoveTx) error { + return env.Mempool.RemoveTxByKey(req.TxKey) } diff --git a/internal/rpc/core/net.go b/internal/rpc/core/net.go index 5444b77b7..b18f1e2fc 100644 --- a/internal/rpc/core/net.go +++ b/internal/rpc/core/net.go @@ -44,7 +44,7 @@ func (env *Environment) Genesis(ctx context.Context) (*coretypes.ResultGenesis, return &coretypes.ResultGenesis{Genesis: env.GenDoc}, nil } -func (env *Environment) GenesisChunked(ctx context.Context, chunk uint) (*coretypes.ResultGenesisChunk, error) { +func (env *Environment) GenesisChunked(ctx context.Context, req *coretypes.RequestGenesisChunked) (*coretypes.ResultGenesisChunk, error) { if env.genChunks == nil { return nil, fmt.Errorf("service configuration error, genesis chunks are not initialized") } @@ -53,7 +53,7 @@ func (env *Environment) GenesisChunked(ctx context.Context, chunk uint) (*corety return nil, fmt.Errorf("service configuration error, there are no chunks") } - id := int(chunk) + id := int(req.Chunk) if id > len(env.genChunks)-1 { return nil, fmt.Errorf("there are %d chunks, %d is invalid", len(env.genChunks)-1, id) diff --git a/internal/rpc/core/routes.go b/internal/rpc/core/routes.go index 945798ed7..4bc1ca414 100644 --- a/internal/rpc/core/routes.go +++ b/internal/rpc/core/routes.go @@ -2,13 +2,9 @@ package core import ( "context" - "time" - "github.com/tendermint/tendermint/internal/eventlog/cursor" - "github.com/tendermint/tendermint/libs/bytes" "github.com/tendermint/tendermint/rpc/coretypes" rpc "github.com/tendermint/tendermint/rpc/jsonrpc/server" - "github.com/tendermint/tendermint/types" ) // TODO: better system than "unsafe" prefix @@ -32,47 +28,47 @@ func NewRoutesMap(svc RPCService, opts *RouteOptions) RoutesMap { out := RoutesMap{ // Event subscription. Note that subscribe, unsubscribe, and // unsubscribe_all are only available via the websocket endpoint. - "events": rpc.NewRPCFunc(svc.Events, "filter", "maxItems", "before", "after", "waitTime"), - "subscribe": rpc.NewWSRPCFunc(svc.Subscribe, "query"), - "unsubscribe": rpc.NewWSRPCFunc(svc.Unsubscribe, "query"), + "events": rpc.NewRPCFunc(svc.Events), + "subscribe": rpc.NewWSRPCFunc(svc.Subscribe), + "unsubscribe": rpc.NewWSRPCFunc(svc.Unsubscribe), "unsubscribe_all": rpc.NewWSRPCFunc(svc.UnsubscribeAll), // info API "health": rpc.NewRPCFunc(svc.Health), "status": rpc.NewRPCFunc(svc.Status), "net_info": rpc.NewRPCFunc(svc.NetInfo), - "blockchain": rpc.NewRPCFunc(svc.BlockchainInfo, "minHeight", "maxHeight"), + "blockchain": rpc.NewRPCFunc(svc.BlockchainInfo), "genesis": rpc.NewRPCFunc(svc.Genesis), - "genesis_chunked": rpc.NewRPCFunc(svc.GenesisChunked, "chunk"), - "header": rpc.NewRPCFunc(svc.Header, "height"), - "header_by_hash": rpc.NewRPCFunc(svc.HeaderByHash, "hash"), - "block": rpc.NewRPCFunc(svc.Block, "height"), - "block_by_hash": rpc.NewRPCFunc(svc.BlockByHash, "hash"), - "block_results": rpc.NewRPCFunc(svc.BlockResults, "height"), - "commit": rpc.NewRPCFunc(svc.Commit, "height"), - "check_tx": rpc.NewRPCFunc(svc.CheckTx, "tx"), - "remove_tx": rpc.NewRPCFunc(svc.RemoveTx, "txkey"), - "tx": rpc.NewRPCFunc(svc.Tx, "hash", "prove"), - "tx_search": rpc.NewRPCFunc(svc.TxSearch, "query", "prove", "page", "per_page", "order_by"), - "block_search": rpc.NewRPCFunc(svc.BlockSearch, "query", "page", "per_page", "order_by"), - "validators": rpc.NewRPCFunc(svc.Validators, "height", "page", "per_page"), + "genesis_chunked": rpc.NewRPCFunc(svc.GenesisChunked), + "header": rpc.NewRPCFunc(svc.Header), + "header_by_hash": rpc.NewRPCFunc(svc.HeaderByHash), + "block": rpc.NewRPCFunc(svc.Block), + "block_by_hash": rpc.NewRPCFunc(svc.BlockByHash), + "block_results": rpc.NewRPCFunc(svc.BlockResults), + "commit": rpc.NewRPCFunc(svc.Commit), + "check_tx": rpc.NewRPCFunc(svc.CheckTx), + "remove_tx": rpc.NewRPCFunc(svc.RemoveTx), + "tx": rpc.NewRPCFunc(svc.Tx), + "tx_search": rpc.NewRPCFunc(svc.TxSearch), + "block_search": rpc.NewRPCFunc(svc.BlockSearch), + "validators": rpc.NewRPCFunc(svc.Validators), "dump_consensus_state": rpc.NewRPCFunc(svc.DumpConsensusState), "consensus_state": rpc.NewRPCFunc(svc.GetConsensusState), - "consensus_params": rpc.NewRPCFunc(svc.ConsensusParams, "height"), - "unconfirmed_txs": rpc.NewRPCFunc(svc.UnconfirmedTxs, "page", "per_page"), + "consensus_params": rpc.NewRPCFunc(svc.ConsensusParams), + "unconfirmed_txs": rpc.NewRPCFunc(svc.UnconfirmedTxs), "num_unconfirmed_txs": rpc.NewRPCFunc(svc.NumUnconfirmedTxs), // tx broadcast API - "broadcast_tx_commit": rpc.NewRPCFunc(svc.BroadcastTxCommit, "tx"), - "broadcast_tx_sync": rpc.NewRPCFunc(svc.BroadcastTxSync, "tx"), - "broadcast_tx_async": rpc.NewRPCFunc(svc.BroadcastTxAsync, "tx"), + "broadcast_tx_commit": rpc.NewRPCFunc(svc.BroadcastTxCommit), + "broadcast_tx_sync": rpc.NewRPCFunc(svc.BroadcastTxSync), + "broadcast_tx_async": rpc.NewRPCFunc(svc.BroadcastTxAsync), // abci API - "abci_query": rpc.NewRPCFunc(svc.ABCIQuery, "path", "data", "height", "prove"), + "abci_query": rpc.NewRPCFunc(svc.ABCIQuery), "abci_info": rpc.NewRPCFunc(svc.ABCIInfo), // evidence API - "broadcast_evidence": rpc.NewRPCFunc(svc.BroadcastEvidence, "evidence"), + "broadcast_evidence": rpc.NewRPCFunc(svc.BroadcastEvidence), } if u, ok := svc.(RPCUnsafe); ok && opts.Unsafe { out["unsafe_flush_mempool"] = rpc.NewRPCFunc(u.UnsafeFlushMempool) @@ -84,38 +80,38 @@ func NewRoutesMap(svc RPCService, opts *RouteOptions) RoutesMap { // implementation, for use in constructing a routing table. type RPCService interface { ABCIInfo(ctx context.Context) (*coretypes.ResultABCIInfo, error) - ABCIQuery(ctx context.Context, path string, data bytes.HexBytes, height int64, prove bool) (*coretypes.ResultABCIQuery, error) - Block(ctx context.Context, heightPtr *int64) (*coretypes.ResultBlock, error) - BlockByHash(ctx context.Context, hash bytes.HexBytes) (*coretypes.ResultBlock, error) - BlockResults(ctx context.Context, heightPtr *int64) (*coretypes.ResultBlockResults, error) - BlockSearch(ctx context.Context, query string, pagePtr, perPagePtr *int, orderBy string) (*coretypes.ResultBlockSearch, error) - BlockchainInfo(ctx context.Context, minHeight, maxHeight int64) (*coretypes.ResultBlockchainInfo, error) - BroadcastEvidence(ctx context.Context, ev coretypes.Evidence) (*coretypes.ResultBroadcastEvidence, error) - BroadcastTxAsync(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTx, error) - BroadcastTxCommit(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTxCommit, error) - BroadcastTxSync(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTx, error) - CheckTx(ctx context.Context, tx types.Tx) (*coretypes.ResultCheckTx, error) - Commit(ctx context.Context, heightPtr *int64) (*coretypes.ResultCommit, error) - ConsensusParams(ctx context.Context, heightPtr *int64) (*coretypes.ResultConsensusParams, error) + ABCIQuery(ctx context.Context, req *coretypes.RequestABCIQuery) (*coretypes.ResultABCIQuery, error) + Block(ctx context.Context, req *coretypes.RequestBlockInfo) (*coretypes.ResultBlock, error) + BlockByHash(ctx context.Context, req *coretypes.RequestBlockByHash) (*coretypes.ResultBlock, error) + BlockResults(ctx context.Context, req *coretypes.RequestBlockInfo) (*coretypes.ResultBlockResults, error) + BlockSearch(ctx context.Context, req *coretypes.RequestBlockSearch) (*coretypes.ResultBlockSearch, error) + BlockchainInfo(ctx context.Context, req *coretypes.RequestBlockchainInfo) (*coretypes.ResultBlockchainInfo, error) + BroadcastEvidence(ctx context.Context, req *coretypes.RequestBroadcastEvidence) (*coretypes.ResultBroadcastEvidence, error) + BroadcastTxAsync(ctx context.Context, req *coretypes.RequestBroadcastTx) (*coretypes.ResultBroadcastTx, error) + BroadcastTxCommit(ctx context.Context, req *coretypes.RequestBroadcastTx) (*coretypes.ResultBroadcastTxCommit, error) + BroadcastTxSync(ctx context.Context, req *coretypes.RequestBroadcastTx) (*coretypes.ResultBroadcastTx, error) + CheckTx(ctx context.Context, req *coretypes.RequestCheckTx) (*coretypes.ResultCheckTx, error) + Commit(ctx context.Context, req *coretypes.RequestBlockInfo) (*coretypes.ResultCommit, error) + ConsensusParams(ctx context.Context, req *coretypes.RequestConsensusParams) (*coretypes.ResultConsensusParams, error) DumpConsensusState(ctx context.Context) (*coretypes.ResultDumpConsensusState, error) - Events(ctx context.Context, filter *coretypes.EventFilter, maxItems int, before, after cursor.Cursor, waitTime time.Duration) (*coretypes.ResultEvents, error) + Events(ctx context.Context, req *coretypes.RequestEvents) (*coretypes.ResultEvents, error) Genesis(ctx context.Context) (*coretypes.ResultGenesis, error) - GenesisChunked(ctx context.Context, chunk uint) (*coretypes.ResultGenesisChunk, error) + GenesisChunked(ctx context.Context, req *coretypes.RequestGenesisChunked) (*coretypes.ResultGenesisChunk, error) GetConsensusState(ctx context.Context) (*coretypes.ResultConsensusState, error) - Header(ctx context.Context, heightPtr *int64) (*coretypes.ResultHeader, error) - HeaderByHash(ctx context.Context, hash bytes.HexBytes) (*coretypes.ResultHeader, error) + Header(ctx context.Context, req *coretypes.RequestBlockInfo) (*coretypes.ResultHeader, error) + HeaderByHash(ctx context.Context, req *coretypes.RequestBlockByHash) (*coretypes.ResultHeader, error) Health(ctx context.Context) (*coretypes.ResultHealth, error) NetInfo(ctx context.Context) (*coretypes.ResultNetInfo, error) NumUnconfirmedTxs(ctx context.Context) (*coretypes.ResultUnconfirmedTxs, error) - RemoveTx(ctx context.Context, txkey types.TxKey) error + RemoveTx(ctx context.Context, req *coretypes.RequestRemoveTx) error Status(ctx context.Context) (*coretypes.ResultStatus, error) - Subscribe(ctx context.Context, query string) (*coretypes.ResultSubscribe, error) - Tx(ctx context.Context, hash bytes.HexBytes, prove bool) (*coretypes.ResultTx, error) - TxSearch(ctx context.Context, query string, prove bool, pagePtr, perPagePtr *int, orderBy string) (*coretypes.ResultTxSearch, error) - UnconfirmedTxs(ctx context.Context, page, perPage *int) (*coretypes.ResultUnconfirmedTxs, error) - Unsubscribe(ctx context.Context, query string) (*coretypes.ResultUnsubscribe, error) + Subscribe(ctx context.Context, req *coretypes.RequestSubscribe) (*coretypes.ResultSubscribe, error) + Tx(ctx context.Context, req *coretypes.RequestTx) (*coretypes.ResultTx, error) + TxSearch(ctx context.Context, req *coretypes.RequestTxSearch) (*coretypes.ResultTxSearch, error) + UnconfirmedTxs(ctx context.Context, req *coretypes.RequestUnconfirmedTxs) (*coretypes.ResultUnconfirmedTxs, error) + Unsubscribe(ctx context.Context, req *coretypes.RequestUnsubscribe) (*coretypes.ResultUnsubscribe, error) UnsubscribeAll(ctx context.Context) (*coretypes.ResultUnsubscribe, error) - Validators(ctx context.Context, heightPtr *int64, pagePtr, perPagePtr *int) (*coretypes.ResultValidators, error) + Validators(ctx context.Context, req *coretypes.RequestValidators) (*coretypes.ResultValidators, error) } // RPCUnsafe defines the set of "unsafe" methods that may optionally be diff --git a/internal/rpc/core/tx.go b/internal/rpc/core/tx.go index 73fa6d2c8..cd643b844 100644 --- a/internal/rpc/core/tx.go +++ b/internal/rpc/core/tx.go @@ -8,7 +8,6 @@ import ( tmquery "github.com/tendermint/tendermint/internal/pubsub/query" "github.com/tendermint/tendermint/internal/state/indexer" - "github.com/tendermint/tendermint/libs/bytes" tmmath "github.com/tendermint/tendermint/libs/math" "github.com/tendermint/tendermint/rpc/coretypes" "github.com/tendermint/tendermint/types" @@ -18,32 +17,27 @@ import ( // transaction is in the mempool, invalidated, or was not sent in the first // place. // More: https://docs.tendermint.com/master/rpc/#/Info/tx -func (env *Environment) Tx(ctx context.Context, hash bytes.HexBytes, prove bool) (*coretypes.ResultTx, error) { +func (env *Environment) Tx(ctx context.Context, req *coretypes.RequestTx) (*coretypes.ResultTx, error) { // if index is disabled, return error - - // N.B. The hash parameter is HexBytes so that the reflective parameter - // decoding logic in the HTTP service will correctly translate from JSON. - // See https://github.com/tendermint/tendermint/issues/6802 for context. - if !indexer.KVSinkEnabled(env.EventSinks) { return nil, errors.New("transaction querying is disabled due to no kvEventSink") } for _, sink := range env.EventSinks { if sink.Type() == indexer.KV { - r, err := sink.GetTxByHash(hash) + r, err := sink.GetTxByHash(req.Hash) if r == nil { - return nil, fmt.Errorf("tx (%X) not found, err: %w", hash, err) + return nil, fmt.Errorf("tx (%X) not found, err: %w", req.Hash, err) } var proof types.TxProof - if prove { + if req.Prove { block := env.BlockStore.LoadBlock(r.Height) proof = block.Data.Txs.Proof(int(r.Index)) } return &coretypes.ResultTx{ - Hash: hash, + Hash: req.Hash, Height: r.Height, Index: r.Index, TxResult: r.Result, @@ -59,21 +53,14 @@ func (env *Environment) Tx(ctx context.Context, hash bytes.HexBytes, prove bool) // TxSearch allows you to query for multiple transactions results. It returns a // list of transactions (maximum ?per_page entries) and the total count. // More: https://docs.tendermint.com/master/rpc/#/Info/tx_search -func (env *Environment) TxSearch( - ctx context.Context, - query string, - prove bool, - pagePtr, perPagePtr *int, - orderBy string, -) (*coretypes.ResultTxSearch, error) { - +func (env *Environment) TxSearch(ctx context.Context, req *coretypes.RequestTxSearch) (*coretypes.ResultTxSearch, error) { if !indexer.KVSinkEnabled(env.EventSinks) { return nil, fmt.Errorf("transaction searching is disabled due to no kvEventSink") - } else if len(query) > maxQueryLength { + } else if len(req.Query) > maxQueryLength { return nil, errors.New("maximum query length exceeded") } - q, err := tmquery.New(query) + q, err := tmquery.New(req.Query) if err != nil { return nil, err } @@ -86,7 +73,7 @@ func (env *Environment) TxSearch( } // sort results (must be done before pagination) - switch orderBy { + switch req.OrderBy { case "desc", "": sort.Slice(results, func(i, j int) bool { if results[i].Height == results[j].Height { @@ -107,9 +94,9 @@ func (env *Environment) TxSearch( // paginate results totalCount := len(results) - perPage := env.validatePerPage(perPagePtr) + perPage := env.validatePerPage(req.PerPage.IntPtr()) - page, err := validatePage(pagePtr, perPage, totalCount) + page, err := validatePage(req.Page.IntPtr(), perPage, totalCount) if err != nil { return nil, err } @@ -122,7 +109,7 @@ func (env *Environment) TxSearch( r := results[i] var proof types.TxProof - if prove { + if req.Prove { block := env.BlockStore.LoadBlock(r.Height) proof = block.Data.Txs.Proof(int(r.Index)) } diff --git a/light/proxy/routes.go b/light/proxy/routes.go index 5dd934ed1..8331723e7 100644 --- a/light/proxy/routes.go +++ b/light/proxy/routes.go @@ -2,60 +2,148 @@ package proxy import ( "context" - "time" - "github.com/tendermint/tendermint/internal/eventlog/cursor" - tmbytes "github.com/tendermint/tendermint/libs/bytes" lrpc "github.com/tendermint/tendermint/light/rpc" rpcclient "github.com/tendermint/tendermint/rpc/client" "github.com/tendermint/tendermint/rpc/coretypes" ) // proxyService wraps a light RPC client to export the RPC service interfaces. -// This is needed because the service and the client use different signatures -// for some of the methods. +// The interfaces are implemented by delegating to the underlying node via the +// specified client. type proxyService struct { - *lrpc.Client + Client *lrpc.Client } -func (p proxyService) ABCIQuery(ctx context.Context, path string, data tmbytes.HexBytes, height int64, prove bool) (*coretypes.ResultABCIQuery, error) { - return p.ABCIQueryWithOptions(ctx, path, data, rpcclient.ABCIQueryOptions{ - Height: height, - Prove: prove, +func (p proxyService) ABCIInfo(ctx context.Context) (*coretypes.ResultABCIInfo, error) { panic("ok") } + +func (p proxyService) ABCIQuery(ctx context.Context, req *coretypes.RequestABCIQuery) (*coretypes.ResultABCIQuery, error) { + return p.Client.ABCIQueryWithOptions(ctx, req.Path, req.Data, rpcclient.ABCIQueryOptions{ + Height: int64(req.Height), + Prove: req.Prove, }) } +func (p proxyService) Block(ctx context.Context, req *coretypes.RequestBlockInfo) (*coretypes.ResultBlock, error) { + return p.Client.Block(ctx, (*int64)(req.Height)) +} + +func (p proxyService) BlockByHash(ctx context.Context, req *coretypes.RequestBlockByHash) (*coretypes.ResultBlock, error) { + return p.Client.BlockByHash(ctx, req.Hash) +} + +func (p proxyService) BlockResults(ctx context.Context, req *coretypes.RequestBlockInfo) (*coretypes.ResultBlockResults, error) { + return p.Client.BlockResults(ctx, (*int64)(req.Height)) +} + +func (p proxyService) BlockSearch(ctx context.Context, req *coretypes.RequestBlockSearch) (*coretypes.ResultBlockSearch, error) { + return p.Client.BlockSearch(ctx, req.Query, req.Page.IntPtr(), req.PerPage.IntPtr(), req.OrderBy) +} + +func (p proxyService) BlockchainInfo(ctx context.Context, req *coretypes.RequestBlockchainInfo) (*coretypes.ResultBlockchainInfo, error) { + return p.Client.BlockchainInfo(ctx, int64(req.MinHeight), int64(req.MaxHeight)) +} + +func (p proxyService) BroadcastEvidence(ctx context.Context, req *coretypes.RequestBroadcastEvidence) (*coretypes.ResultBroadcastEvidence, error) { + return p.Client.BroadcastEvidence(ctx, req.Evidence) +} + +func (p proxyService) BroadcastTxAsync(ctx context.Context, req *coretypes.RequestBroadcastTx) (*coretypes.ResultBroadcastTx, error) { + return p.Client.BroadcastTxAsync(ctx, req.Tx) +} + +func (p proxyService) BroadcastTxCommit(ctx context.Context, req *coretypes.RequestBroadcastTx) (*coretypes.ResultBroadcastTxCommit, error) { + return p.Client.BroadcastTxCommit(ctx, req.Tx) +} + +func (p proxyService) BroadcastTxSync(ctx context.Context, req *coretypes.RequestBroadcastTx) (*coretypes.ResultBroadcastTx, error) { + return p.Client.BroadcastTxSync(ctx, req.Tx) +} + +func (p proxyService) CheckTx(ctx context.Context, req *coretypes.RequestCheckTx) (*coretypes.ResultCheckTx, error) { + return p.Client.CheckTx(ctx, req.Tx) +} + +func (p proxyService) Commit(ctx context.Context, req *coretypes.RequestBlockInfo) (*coretypes.ResultCommit, error) { + return p.Client.Commit(ctx, (*int64)(req.Height)) +} + +func (p proxyService) ConsensusParams(ctx context.Context, req *coretypes.RequestConsensusParams) (*coretypes.ResultConsensusParams, error) { + return p.Client.ConsensusParams(ctx, (*int64)(req.Height)) +} + +func (p proxyService) DumpConsensusState(ctx context.Context) (*coretypes.ResultDumpConsensusState, error) { + return p.Client.DumpConsensusState(ctx) +} + +func (p proxyService) Events(ctx context.Context, req *coretypes.RequestEvents) (*coretypes.ResultEvents, error) { + return p.Client.Events(ctx, req) +} + +func (p proxyService) Genesis(ctx context.Context) (*coretypes.ResultGenesis, error) { + return p.Client.Genesis(ctx) +} + +func (p proxyService) GenesisChunked(ctx context.Context, req *coretypes.RequestGenesisChunked) (*coretypes.ResultGenesisChunk, error) { + return p.Client.GenesisChunked(ctx, uint(req.Chunk)) +} + func (p proxyService) GetConsensusState(ctx context.Context) (*coretypes.ResultConsensusState, error) { - return p.ConsensusState(ctx) + return p.Client.ConsensusState(ctx) } -func (p proxyService) Events(ctx context.Context, - filter *coretypes.EventFilter, - maxItems int, - before, after cursor.Cursor, - waitTime time.Duration, -) (*coretypes.ResultEvents, error) { - return p.Client.Events(ctx, &coretypes.RequestEvents{ - Filter: filter, - MaxItems: maxItems, - Before: before.String(), - After: after.String(), - WaitTime: waitTime, - }) +func (p proxyService) Header(ctx context.Context, req *coretypes.RequestBlockInfo) (*coretypes.ResultHeader, error) { + return p.Client.Header(ctx, (*int64)(req.Height)) } -func (p proxyService) Subscribe(ctx context.Context, query string) (*coretypes.ResultSubscribe, error) { - return p.SubscribeWS(ctx, query) +func (p proxyService) HeaderByHash(ctx context.Context, req *coretypes.RequestBlockByHash) (*coretypes.ResultHeader, error) { + return p.Client.HeaderByHash(ctx, req.Hash) } -func (p proxyService) Unsubscribe(ctx context.Context, query string) (*coretypes.ResultUnsubscribe, error) { - return p.UnsubscribeWS(ctx, query) +func (p proxyService) Health(ctx context.Context) (*coretypes.ResultHealth, error) { + return p.Client.Health(ctx) +} + +func (p proxyService) NetInfo(ctx context.Context) (*coretypes.ResultNetInfo, error) { + return p.Client.NetInfo(ctx) +} + +func (p proxyService) NumUnconfirmedTxs(ctx context.Context) (*coretypes.ResultUnconfirmedTxs, error) { + return p.Client.NumUnconfirmedTxs(ctx) +} + +func (p proxyService) RemoveTx(ctx context.Context, req *coretypes.RequestRemoveTx) error { + return p.Client.RemoveTx(ctx, req.TxKey) +} + +func (p proxyService) Status(ctx context.Context) (*coretypes.ResultStatus, error) { + return p.Client.Status(ctx) +} + +func (p proxyService) Subscribe(ctx context.Context, req *coretypes.RequestSubscribe) (*coretypes.ResultSubscribe, error) { + return p.Client.SubscribeWS(ctx, req.Query) +} + +func (p proxyService) Tx(ctx context.Context, req *coretypes.RequestTx) (*coretypes.ResultTx, error) { + return p.Client.Tx(ctx, req.Hash, req.Prove) +} + +func (p proxyService) TxSearch(ctx context.Context, req *coretypes.RequestTxSearch) (*coretypes.ResultTxSearch, error) { + return p.Client.TxSearch(ctx, req.Query, req.Prove, req.Page.IntPtr(), req.PerPage.IntPtr(), req.OrderBy) +} + +func (p proxyService) UnconfirmedTxs(ctx context.Context, req *coretypes.RequestUnconfirmedTxs) (*coretypes.ResultUnconfirmedTxs, error) { + return p.Client.UnconfirmedTxs(ctx, req.Page.IntPtr(), req.PerPage.IntPtr()) +} + +func (p proxyService) Unsubscribe(ctx context.Context, req *coretypes.RequestUnsubscribe) (*coretypes.ResultUnsubscribe, error) { + return p.Client.UnsubscribeWS(ctx, req.Query) } func (p proxyService) UnsubscribeAll(ctx context.Context) (*coretypes.ResultUnsubscribe, error) { - return p.UnsubscribeAllWS(ctx) + return p.Client.UnsubscribeAllWS(ctx) } -func (p proxyService) BroadcastEvidence(ctx context.Context, ev coretypes.Evidence) (*coretypes.ResultBroadcastEvidence, error) { - return p.Client.BroadcastEvidence(ctx, ev.Value) +func (p proxyService) Validators(ctx context.Context, req *coretypes.RequestValidators) (*coretypes.ResultValidators, error) { + return p.Client.Validators(ctx, (*int64)(req.Height), req.Page.IntPtr(), req.PerPage.IntPtr()) } diff --git a/rpc/client/eventstream/eventstream_test.go b/rpc/client/eventstream/eventstream_test.go index ca27734e2..8cd9df30f 100644 --- a/rpc/client/eventstream/eventstream_test.go +++ b/rpc/client/eventstream/eventstream_test.go @@ -103,13 +103,16 @@ func TestMinPollTime(t *testing.T) { // wait time and reports no events. ctx := context.Background() filter := &coretypes.EventFilter{Query: `tm.event = 'good'`} - var zero cursor.Cursor t.Run("NoneMatch", func(t *testing.T) { start := time.Now() // Request a very short delay, and affirm we got the server's minimum. - rsp, err := s.env.Events(ctx, filter, 1, zero, zero, 10*time.Millisecond) + rsp, err := s.env.Events(ctx, &coretypes.RequestEvents{ + Filter: filter, + MaxItems: 1, + WaitTime: 10 * time.Millisecond, + }) if err != nil { t.Fatalf("Events failed: %v", err) } else if elapsed := time.Since(start); elapsed < time.Second { @@ -128,7 +131,11 @@ func TestMinPollTime(t *testing.T) { // Request a long-ish delay and affirm we don't block for it. // Check for this by ensuring we return sooner than the minimum delay, // since we don't know the exact timing. - rsp, err := s.env.Events(ctx, filter, 1, zero, zero, 10*time.Second) + rsp, err := s.env.Events(ctx, &coretypes.RequestEvents{ + Filter: filter, + MaxItems: 1, + WaitTime: 10 * time.Second, + }) if err != nil { t.Fatalf("Events failed: %v", err) } else if elapsed := time.Since(start); elapsed > 500*time.Millisecond { @@ -263,12 +270,5 @@ func (s *streamTester) advance(d time.Duration) { s.clock += int64(d) } // environment as if it were a local RPC client. This works because the Events // method only requires the event log, the other fields are unused. func (s *streamTester) Events(ctx context.Context, req *coretypes.RequestEvents) (*coretypes.ResultEvents, error) { - var before, after cursor.Cursor - if err := before.UnmarshalText([]byte(req.Before)); err != nil { - return nil, err - } - if err := after.UnmarshalText([]byte(req.After)); err != nil { - return nil, err - } - return s.env.Events(ctx, req.Filter, req.MaxItems, before, after, req.WaitTime) + return s.env.Events(ctx, req) } diff --git a/rpc/client/http/http.go b/rpc/client/http/http.go index 435f80a5c..50d78d279 100644 --- a/rpc/client/http/http.go +++ b/rpc/client/http/http.go @@ -213,10 +213,10 @@ func (c *baseRPCClient) ABCIQuery(ctx context.Context, path string, data bytes.H func (c *baseRPCClient) ABCIQueryWithOptions(ctx context.Context, path string, data bytes.HexBytes, opts rpcclient.ABCIQueryOptions) (*coretypes.ResultABCIQuery, error) { result := new(coretypes.ResultABCIQuery) - if err := c.caller.Call(ctx, "abci_query", abciQueryArgs{ + if err := c.caller.Call(ctx, "abci_query", &coretypes.RequestABCIQuery{ Path: path, Data: data, - Height: opts.Height, + Height: coretypes.Int64(opts.Height), Prove: opts.Prove, }, result); err != nil { return nil, err @@ -226,7 +226,9 @@ func (c *baseRPCClient) ABCIQueryWithOptions(ctx context.Context, path string, d func (c *baseRPCClient) BroadcastTxCommit(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTxCommit, error) { result := new(coretypes.ResultBroadcastTxCommit) - if err := c.caller.Call(ctx, "broadcast_tx_commit", txArgs{Tx: tx}, result); err != nil { + if err := c.caller.Call(ctx, "broadcast_tx_commit", &coretypes.RequestBroadcastTx{ + Tx: tx, + }, result); err != nil { return nil, err } return result, nil @@ -242,7 +244,7 @@ func (c *baseRPCClient) BroadcastTxSync(ctx context.Context, tx types.Tx) (*core func (c *baseRPCClient) broadcastTX(ctx context.Context, route string, tx types.Tx) (*coretypes.ResultBroadcastTx, error) { result := new(coretypes.ResultBroadcastTx) - if err := c.caller.Call(ctx, route, txArgs{Tx: tx}, result); err != nil { + if err := c.caller.Call(ctx, route, &coretypes.RequestBroadcastTx{Tx: tx}, result); err != nil { return nil, err } return result, nil @@ -251,7 +253,10 @@ func (c *baseRPCClient) broadcastTX(ctx context.Context, route string, tx types. func (c *baseRPCClient) UnconfirmedTxs(ctx context.Context, page *int, perPage *int) (*coretypes.ResultUnconfirmedTxs, error) { result := new(coretypes.ResultUnconfirmedTxs) - if err := c.caller.Call(ctx, "unconfirmed_txs", unconfirmedArgs{Page: page, PerPage: perPage}, result); err != nil { + if err := c.caller.Call(ctx, "unconfirmed_txs", &coretypes.RequestUnconfirmedTxs{ + Page: coretypes.Int64Ptr(page), + PerPage: coretypes.Int64Ptr(perPage), + }, result); err != nil { return nil, err } return result, nil @@ -267,14 +272,14 @@ func (c *baseRPCClient) NumUnconfirmedTxs(ctx context.Context) (*coretypes.Resul func (c *baseRPCClient) CheckTx(ctx context.Context, tx types.Tx) (*coretypes.ResultCheckTx, error) { result := new(coretypes.ResultCheckTx) - if err := c.caller.Call(ctx, "check_tx", txArgs{Tx: tx}, result); err != nil { + if err := c.caller.Call(ctx, "check_tx", &coretypes.RequestCheckTx{Tx: tx}, result); err != nil { return nil, err } return result, nil } func (c *baseRPCClient) RemoveTx(ctx context.Context, txKey types.TxKey) error { - if err := c.caller.Call(ctx, "remove_tx", txKeyArgs{TxKey: txKey[:]}, nil); err != nil { + if err := c.caller.Call(ctx, "remove_tx", &coretypes.RequestRemoveTx{TxKey: txKey}, nil); err != nil { return err } return nil @@ -306,7 +311,9 @@ func (c *baseRPCClient) ConsensusState(ctx context.Context) (*coretypes.ResultCo func (c *baseRPCClient) ConsensusParams(ctx context.Context, height *int64) (*coretypes.ResultConsensusParams, error) { result := new(coretypes.ResultConsensusParams) - if err := c.caller.Call(ctx, "consensus_params", heightArgs{Height: height}, result); err != nil { + if err := c.caller.Call(ctx, "consensus_params", &coretypes.RequestConsensusParams{ + Height: (*coretypes.Int64)(height), + }, result); err != nil { return nil, err } return result, nil @@ -330,9 +337,9 @@ func (c *baseRPCClient) Health(ctx context.Context) (*coretypes.ResultHealth, er func (c *baseRPCClient) BlockchainInfo(ctx context.Context, minHeight, maxHeight int64) (*coretypes.ResultBlockchainInfo, error) { result := new(coretypes.ResultBlockchainInfo) - if err := c.caller.Call(ctx, "blockchain", blockchainInfoArgs{ - MinHeight: minHeight, - MaxHeight: maxHeight, + if err := c.caller.Call(ctx, "blockchain", &coretypes.RequestBlockchainInfo{ + MinHeight: coretypes.Int64(minHeight), + MaxHeight: coretypes.Int64(maxHeight), }, result); err != nil { return nil, err } @@ -349,7 +356,9 @@ func (c *baseRPCClient) Genesis(ctx context.Context) (*coretypes.ResultGenesis, func (c *baseRPCClient) GenesisChunked(ctx context.Context, id uint) (*coretypes.ResultGenesisChunk, error) { result := new(coretypes.ResultGenesisChunk) - if err := c.caller.Call(ctx, "genesis_chunked", genesisChunkArgs{Chunk: id}, result); err != nil { + if err := c.caller.Call(ctx, "genesis_chunked", &coretypes.RequestGenesisChunked{ + Chunk: coretypes.Int64(id), + }, result); err != nil { return nil, err } return result, nil @@ -357,7 +366,9 @@ func (c *baseRPCClient) GenesisChunked(ctx context.Context, id uint) (*coretypes func (c *baseRPCClient) Block(ctx context.Context, height *int64) (*coretypes.ResultBlock, error) { result := new(coretypes.ResultBlock) - if err := c.caller.Call(ctx, "block", heightArgs{Height: height}, result); err != nil { + if err := c.caller.Call(ctx, "block", &coretypes.RequestBlockInfo{ + Height: (*coretypes.Int64)(height), + }, result); err != nil { return nil, err } return result, nil @@ -365,7 +376,7 @@ func (c *baseRPCClient) Block(ctx context.Context, height *int64) (*coretypes.Re func (c *baseRPCClient) BlockByHash(ctx context.Context, hash bytes.HexBytes) (*coretypes.ResultBlock, error) { result := new(coretypes.ResultBlock) - if err := c.caller.Call(ctx, "block_by_hash", hashArgs{Hash: hash}, result); err != nil { + if err := c.caller.Call(ctx, "block_by_hash", &coretypes.RequestBlockByHash{Hash: hash}, result); err != nil { return nil, err } return result, nil @@ -373,7 +384,9 @@ func (c *baseRPCClient) BlockByHash(ctx context.Context, hash bytes.HexBytes) (* func (c *baseRPCClient) BlockResults(ctx context.Context, height *int64) (*coretypes.ResultBlockResults, error) { result := new(coretypes.ResultBlockResults) - if err := c.caller.Call(ctx, "block_results", heightArgs{Height: height}, result); err != nil { + if err := c.caller.Call(ctx, "block_results", &coretypes.RequestBlockInfo{ + Height: (*coretypes.Int64)(height), + }, result); err != nil { return nil, err } return result, nil @@ -381,7 +394,9 @@ func (c *baseRPCClient) BlockResults(ctx context.Context, height *int64) (*coret func (c *baseRPCClient) Header(ctx context.Context, height *int64) (*coretypes.ResultHeader, error) { result := new(coretypes.ResultHeader) - if err := c.caller.Call(ctx, "header", heightArgs{Height: height}, result); err != nil { + if err := c.caller.Call(ctx, "header", &coretypes.RequestBlockInfo{ + Height: (*coretypes.Int64)(height), + }, result); err != nil { return nil, err } return result, nil @@ -389,7 +404,9 @@ func (c *baseRPCClient) Header(ctx context.Context, height *int64) (*coretypes.R func (c *baseRPCClient) HeaderByHash(ctx context.Context, hash bytes.HexBytes) (*coretypes.ResultHeader, error) { result := new(coretypes.ResultHeader) - if err := c.caller.Call(ctx, "header_by_hash", hashArgs{Hash: hash}, result); err != nil { + if err := c.caller.Call(ctx, "header_by_hash", &coretypes.RequestBlockByHash{ + Hash: hash, + }, result); err != nil { return nil, err } return result, nil @@ -397,7 +414,9 @@ func (c *baseRPCClient) HeaderByHash(ctx context.Context, hash bytes.HexBytes) ( func (c *baseRPCClient) Commit(ctx context.Context, height *int64) (*coretypes.ResultCommit, error) { result := new(coretypes.ResultCommit) - if err := c.caller.Call(ctx, "commit", heightArgs{Height: height}, result); err != nil { + if err := c.caller.Call(ctx, "commit", &coretypes.RequestBlockInfo{ + Height: (*coretypes.Int64)(height), + }, result); err != nil { return nil, err } return result, nil @@ -405,7 +424,7 @@ func (c *baseRPCClient) Commit(ctx context.Context, height *int64) (*coretypes.R func (c *baseRPCClient) Tx(ctx context.Context, hash bytes.HexBytes, prove bool) (*coretypes.ResultTx, error) { result := new(coretypes.ResultTx) - if err := c.caller.Call(ctx, "tx", hashArgs{Hash: hash, Prove: prove}, result); err != nil { + if err := c.caller.Call(ctx, "tx", &coretypes.RequestTx{Hash: hash, Prove: prove}, result); err != nil { return nil, err } return result, nil @@ -413,12 +432,12 @@ func (c *baseRPCClient) Tx(ctx context.Context, hash bytes.HexBytes, prove bool) func (c *baseRPCClient) TxSearch(ctx context.Context, query string, prove bool, page, perPage *int, orderBy string) (*coretypes.ResultTxSearch, error) { result := new(coretypes.ResultTxSearch) - if err := c.caller.Call(ctx, "tx_search", searchArgs{ + if err := c.caller.Call(ctx, "tx_search", &coretypes.RequestTxSearch{ Query: query, Prove: prove, OrderBy: orderBy, - Page: page, - PerPage: perPage, + Page: coretypes.Int64Ptr(page), + PerPage: coretypes.Int64Ptr(perPage), }, result); err != nil { return nil, err } @@ -428,11 +447,11 @@ func (c *baseRPCClient) TxSearch(ctx context.Context, query string, prove bool, func (c *baseRPCClient) BlockSearch(ctx context.Context, query string, page, perPage *int, orderBy string) (*coretypes.ResultBlockSearch, error) { result := new(coretypes.ResultBlockSearch) - if err := c.caller.Call(ctx, "block_search", searchArgs{ + if err := c.caller.Call(ctx, "block_search", &coretypes.RequestBlockSearch{ Query: query, OrderBy: orderBy, - Page: page, - PerPage: perPage, + Page: coretypes.Int64Ptr(page), + PerPage: coretypes.Int64Ptr(perPage), }, result); err != nil { return nil, err } @@ -442,10 +461,10 @@ func (c *baseRPCClient) BlockSearch(ctx context.Context, query string, page, per func (c *baseRPCClient) Validators(ctx context.Context, height *int64, page, perPage *int) (*coretypes.ResultValidators, error) { result := new(coretypes.ResultValidators) - if err := c.caller.Call(ctx, "validators", validatorArgs{ - Height: height, - Page: page, - PerPage: perPage, + if err := c.caller.Call(ctx, "validators", &coretypes.RequestValidators{ + Height: (*coretypes.Int64)(height), + Page: coretypes.Int64Ptr(page), + PerPage: coretypes.Int64Ptr(perPage), }, result); err != nil { return nil, err } @@ -454,8 +473,8 @@ func (c *baseRPCClient) Validators(ctx context.Context, height *int64, page, per func (c *baseRPCClient) BroadcastEvidence(ctx context.Context, ev types.Evidence) (*coretypes.ResultBroadcastEvidence, error) { result := new(coretypes.ResultBroadcastEvidence) - if err := c.caller.Call(ctx, "broadcast_evidence", evidenceArgs{ - Evidence: coretypes.Evidence{Value: ev}, + if err := c.caller.Call(ctx, "broadcast_evidence", &coretypes.RequestBroadcastEvidence{ + Evidence: ev, }, result); err != nil { return nil, err } diff --git a/rpc/client/http/request.go b/rpc/client/http/request.go deleted file mode 100644 index 746cb776d..000000000 --- a/rpc/client/http/request.go +++ /dev/null @@ -1,65 +0,0 @@ -package http - -// The types in this file define the JSON encoding for RPC method parameters -// from the client to the server. - -import ( - "github.com/tendermint/tendermint/libs/bytes" - "github.com/tendermint/tendermint/rpc/coretypes" -) - -type abciQueryArgs struct { - Path string `json:"path"` - Data bytes.HexBytes `json:"data"` - Height int64 `json:"height,string"` - Prove bool `json:"prove"` -} - -type txArgs struct { - Tx []byte `json:"tx"` -} - -type txKeyArgs struct { - TxKey []byte `json:"tx_key"` -} - -type unconfirmedArgs struct { - Page *int `json:"page,string,omitempty"` - PerPage *int `json:"per_page,string,omitempty"` -} - -type heightArgs struct { - Height *int64 `json:"height,string,omitempty"` -} - -type hashArgs struct { - Hash bytes.HexBytes `json:"hash"` - Prove bool `json:"prove,omitempty"` -} - -type blockchainInfoArgs struct { - MinHeight int64 `json:"minHeight,string"` - MaxHeight int64 `json:"maxHeight,string"` -} - -type genesisChunkArgs struct { - Chunk uint `json:"chunk,string"` -} - -type searchArgs struct { - Query string `json:"query"` - Prove bool `json:"prove,omitempty"` - OrderBy string `json:"order_by,omitempty"` - Page *int `json:"page,string,omitempty"` - PerPage *int `json:"per_page,string,omitempty"` -} - -type validatorArgs struct { - Height *int64 `json:"height,string,omitempty"` - Page *int `json:"page,string,omitempty"` - PerPage *int `json:"per_page,string,omitempty"` -} - -type evidenceArgs struct { - Evidence coretypes.Evidence `json:"evidence"` -} diff --git a/rpc/client/local/local.go b/rpc/client/local/local.go index 24a9a6d7e..8718ee504 100644 --- a/rpc/client/local/local.go +++ b/rpc/client/local/local.go @@ -7,7 +7,6 @@ import ( "time" "github.com/tendermint/tendermint/internal/eventbus" - "github.com/tendermint/tendermint/internal/eventlog/cursor" "github.com/tendermint/tendermint/internal/pubsub" "github.com/tendermint/tendermint/internal/pubsub/query" rpccore "github.com/tendermint/tendermint/internal/rpc/core" @@ -79,23 +78,28 @@ func (c *Local) ABCIQuery(ctx context.Context, path string, data bytes.HexBytes) } func (c *Local) ABCIQueryWithOptions(ctx context.Context, path string, data bytes.HexBytes, opts rpcclient.ABCIQueryOptions) (*coretypes.ResultABCIQuery, error) { - return c.env.ABCIQuery(ctx, path, data, opts.Height, opts.Prove) + return c.env.ABCIQuery(ctx, &coretypes.RequestABCIQuery{ + Path: path, Data: data, Height: coretypes.Int64(opts.Height), Prove: opts.Prove, + }) } func (c *Local) BroadcastTxCommit(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTxCommit, error) { - return c.env.BroadcastTxCommit(ctx, tx) + return c.env.BroadcastTxCommit(ctx, &coretypes.RequestBroadcastTx{Tx: tx}) } func (c *Local) BroadcastTxAsync(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTx, error) { - return c.env.BroadcastTxAsync(ctx, tx) + return c.env.BroadcastTxAsync(ctx, &coretypes.RequestBroadcastTx{Tx: tx}) } func (c *Local) BroadcastTxSync(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTx, error) { - return c.env.BroadcastTxSync(ctx, tx) + return c.env.BroadcastTxSync(ctx, &coretypes.RequestBroadcastTx{Tx: tx}) } func (c *Local) UnconfirmedTxs(ctx context.Context, page, perPage *int) (*coretypes.ResultUnconfirmedTxs, error) { - return c.env.UnconfirmedTxs(ctx, page, perPage) + return c.env.UnconfirmedTxs(ctx, &coretypes.RequestUnconfirmedTxs{ + Page: coretypes.Int64Ptr(page), + PerPage: coretypes.Int64Ptr(perPage), + }) } func (c *Local) NumUnconfirmedTxs(ctx context.Context) (*coretypes.ResultUnconfirmedTxs, error) { @@ -103,7 +107,7 @@ func (c *Local) NumUnconfirmedTxs(ctx context.Context) (*coretypes.ResultUnconfi } func (c *Local) CheckTx(ctx context.Context, tx types.Tx) (*coretypes.ResultCheckTx, error) { - return c.env.CheckTx(ctx, tx) + return c.env.CheckTx(ctx, &coretypes.RequestCheckTx{Tx: tx}) } func (c *Local) RemoveTx(ctx context.Context, txKey types.TxKey) error { @@ -123,18 +127,11 @@ func (c *Local) ConsensusState(ctx context.Context) (*coretypes.ResultConsensusS } func (c *Local) ConsensusParams(ctx context.Context, height *int64) (*coretypes.ResultConsensusParams, error) { - return c.env.ConsensusParams(ctx, height) + return c.env.ConsensusParams(ctx, &coretypes.RequestConsensusParams{Height: (*coretypes.Int64)(height)}) } func (c *Local) Events(ctx context.Context, req *coretypes.RequestEvents) (*coretypes.ResultEvents, error) { - var before, after cursor.Cursor - if err := before.UnmarshalText([]byte(req.Before)); err != nil { - return nil, err - } - if err := after.UnmarshalText([]byte(req.After)); err != nil { - return nil, err - } - return c.env.Events(ctx, req.Filter, req.MaxItems, before, after, req.WaitTime) + return c.env.Events(ctx, req) } func (c *Local) Health(ctx context.Context) (*coretypes.ResultHealth, error) { @@ -142,7 +139,10 @@ func (c *Local) Health(ctx context.Context) (*coretypes.ResultHealth, error) { } func (c *Local) BlockchainInfo(ctx context.Context, minHeight, maxHeight int64) (*coretypes.ResultBlockchainInfo, error) { - return c.env.BlockchainInfo(ctx, minHeight, maxHeight) + return c.env.BlockchainInfo(ctx, &coretypes.RequestBlockchainInfo{ + MinHeight: coretypes.Int64(minHeight), + MaxHeight: coretypes.Int64(maxHeight), + }) } func (c *Local) Genesis(ctx context.Context) (*coretypes.ResultGenesis, error) { @@ -150,51 +150,66 @@ func (c *Local) Genesis(ctx context.Context) (*coretypes.ResultGenesis, error) { } func (c *Local) GenesisChunked(ctx context.Context, id uint) (*coretypes.ResultGenesisChunk, error) { - return c.env.GenesisChunked(ctx, id) + return c.env.GenesisChunked(ctx, &coretypes.RequestGenesisChunked{Chunk: coretypes.Int64(id)}) } func (c *Local) Block(ctx context.Context, height *int64) (*coretypes.ResultBlock, error) { - return c.env.Block(ctx, height) + return c.env.Block(ctx, &coretypes.RequestBlockInfo{Height: (*coretypes.Int64)(height)}) } func (c *Local) BlockByHash(ctx context.Context, hash bytes.HexBytes) (*coretypes.ResultBlock, error) { - return c.env.BlockByHash(ctx, hash) + return c.env.BlockByHash(ctx, &coretypes.RequestBlockByHash{Hash: hash}) } func (c *Local) BlockResults(ctx context.Context, height *int64) (*coretypes.ResultBlockResults, error) { - return c.env.BlockResults(ctx, height) + return c.env.BlockResults(ctx, &coretypes.RequestBlockInfo{Height: (*coretypes.Int64)(height)}) } func (c *Local) Header(ctx context.Context, height *int64) (*coretypes.ResultHeader, error) { - return c.env.Header(ctx, height) + return c.env.Header(ctx, &coretypes.RequestBlockInfo{Height: (*coretypes.Int64)(height)}) } func (c *Local) HeaderByHash(ctx context.Context, hash bytes.HexBytes) (*coretypes.ResultHeader, error) { - return c.env.HeaderByHash(ctx, hash) + return c.env.HeaderByHash(ctx, &coretypes.RequestBlockByHash{Hash: hash}) } func (c *Local) Commit(ctx context.Context, height *int64) (*coretypes.ResultCommit, error) { - return c.env.Commit(ctx, height) + return c.env.Commit(ctx, &coretypes.RequestBlockInfo{Height: (*coretypes.Int64)(height)}) } func (c *Local) Validators(ctx context.Context, height *int64, page, perPage *int) (*coretypes.ResultValidators, error) { - return c.env.Validators(ctx, height, page, perPage) + return c.env.Validators(ctx, &coretypes.RequestValidators{ + Height: (*coretypes.Int64)(height), + Page: coretypes.Int64Ptr(page), + PerPage: coretypes.Int64Ptr(perPage), + }) } func (c *Local) Tx(ctx context.Context, hash bytes.HexBytes, prove bool) (*coretypes.ResultTx, error) { - return c.env.Tx(ctx, hash, prove) + return c.env.Tx(ctx, &coretypes.RequestTx{Hash: hash, Prove: prove}) } func (c *Local) TxSearch(ctx context.Context, queryString string, prove bool, page, perPage *int, orderBy string) (*coretypes.ResultTxSearch, error) { - return c.env.TxSearch(ctx, queryString, prove, page, perPage, orderBy) + return c.env.TxSearch(ctx, &coretypes.RequestTxSearch{ + Query: queryString, + Prove: prove, + Page: coretypes.Int64Ptr(page), + PerPage: coretypes.Int64Ptr(perPage), + OrderBy: orderBy, + }) } func (c *Local) BlockSearch(ctx context.Context, queryString string, page, perPage *int, orderBy string) (*coretypes.ResultBlockSearch, error) { - return c.env.BlockSearch(ctx, queryString, page, perPage, orderBy) + return c.env.BlockSearch(ctx, &coretypes.RequestBlockSearch{ + Query: queryString, + Page: coretypes.Int64Ptr(page), + PerPage: coretypes.Int64Ptr(perPage), + OrderBy: orderBy, + }) } func (c *Local) BroadcastEvidence(ctx context.Context, ev types.Evidence) (*coretypes.ResultBroadcastEvidence, error) { - return c.env.BroadcastEvidence(ctx, coretypes.Evidence{Value: ev}) + return c.env.BroadcastEvidence(ctx, &coretypes.RequestBroadcastEvidence{Evidence: ev}) } func (c *Local) Subscribe(ctx context.Context, subscriber, queryString string, capacity ...int) (<-chan coretypes.ResultEvent, error) { diff --git a/rpc/client/mock/client.go b/rpc/client/mock/client.go index b47ff1e76..a3272cb17 100644 --- a/rpc/client/mock/client.go +++ b/rpc/client/mock/client.go @@ -91,23 +91,25 @@ func (c Client) ABCIQueryWithOptions( path string, data bytes.HexBytes, opts client.ABCIQueryOptions) (*coretypes.ResultABCIQuery, error) { - return c.env.ABCIQuery(ctx, path, data, opts.Height, opts.Prove) + return c.env.ABCIQuery(ctx, &coretypes.RequestABCIQuery{ + Path: path, Data: data, Height: coretypes.Int64(opts.Height), Prove: opts.Prove, + }) } func (c Client) BroadcastTxCommit(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTxCommit, error) { - return c.env.BroadcastTxCommit(ctx, tx) + return c.env.BroadcastTxCommit(ctx, &coretypes.RequestBroadcastTx{Tx: tx}) } func (c Client) BroadcastTxAsync(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTx, error) { - return c.env.BroadcastTxAsync(ctx, tx) + return c.env.BroadcastTxAsync(ctx, &coretypes.RequestBroadcastTx{Tx: tx}) } func (c Client) BroadcastTxSync(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTx, error) { - return c.env.BroadcastTxSync(ctx, tx) + return c.env.BroadcastTxSync(ctx, &coretypes.RequestBroadcastTx{Tx: tx}) } func (c Client) CheckTx(ctx context.Context, tx types.Tx) (*coretypes.ResultCheckTx, error) { - return c.env.CheckTx(ctx, tx) + return c.env.CheckTx(ctx, &coretypes.RequestCheckTx{Tx: tx}) } func (c Client) NetInfo(ctx context.Context) (*coretypes.ResultNetInfo, error) { @@ -123,7 +125,7 @@ func (c Client) DumpConsensusState(ctx context.Context) (*coretypes.ResultDumpCo } func (c Client) ConsensusParams(ctx context.Context, height *int64) (*coretypes.ResultConsensusParams, error) { - return c.env.ConsensusParams(ctx, height) + return c.env.ConsensusParams(ctx, &coretypes.RequestConsensusParams{Height: (*coretypes.Int64)(height)}) } func (c Client) Health(ctx context.Context) (*coretypes.ResultHealth, error) { @@ -131,7 +133,10 @@ func (c Client) Health(ctx context.Context) (*coretypes.ResultHealth, error) { } func (c Client) BlockchainInfo(ctx context.Context, minHeight, maxHeight int64) (*coretypes.ResultBlockchainInfo, error) { - return c.env.BlockchainInfo(ctx, minHeight, maxHeight) + return c.env.BlockchainInfo(ctx, &coretypes.RequestBlockchainInfo{ + MinHeight: coretypes.Int64(minHeight), + MaxHeight: coretypes.Int64(maxHeight), + }) } func (c Client) Genesis(ctx context.Context) (*coretypes.ResultGenesis, error) { @@ -139,21 +144,25 @@ func (c Client) Genesis(ctx context.Context) (*coretypes.ResultGenesis, error) { } func (c Client) Block(ctx context.Context, height *int64) (*coretypes.ResultBlock, error) { - return c.env.Block(ctx, height) + return c.env.Block(ctx, &coretypes.RequestBlockInfo{Height: (*coretypes.Int64)(height)}) } func (c Client) BlockByHash(ctx context.Context, hash bytes.HexBytes) (*coretypes.ResultBlock, error) { - return c.env.BlockByHash(ctx, hash) + return c.env.BlockByHash(ctx, &coretypes.RequestBlockByHash{Hash: hash}) } func (c Client) Commit(ctx context.Context, height *int64) (*coretypes.ResultCommit, error) { - return c.env.Commit(ctx, height) + return c.env.Commit(ctx, &coretypes.RequestBlockInfo{Height: (*coretypes.Int64)(height)}) } func (c Client) Validators(ctx context.Context, height *int64, page, perPage *int) (*coretypes.ResultValidators, error) { - return c.env.Validators(ctx, height, page, perPage) + return c.env.Validators(ctx, &coretypes.RequestValidators{ + Height: (*coretypes.Int64)(height), + Page: coretypes.Int64Ptr(page), + PerPage: coretypes.Int64Ptr(perPage), + }) } func (c Client) BroadcastEvidence(ctx context.Context, ev types.Evidence) (*coretypes.ResultBroadcastEvidence, error) { - return c.env.BroadcastEvidence(ctx, coretypes.Evidence{Value: ev}) + return c.env.BroadcastEvidence(ctx, &coretypes.RequestBroadcastEvidence{Evidence: ev}) } diff --git a/rpc/coretypes/requests.go b/rpc/coretypes/requests.go new file mode 100644 index 000000000..cd4d22726 --- /dev/null +++ b/rpc/coretypes/requests.go @@ -0,0 +1,188 @@ +package coretypes + +import ( + "encoding/json" + "strconv" + "time" + + "github.com/tendermint/tendermint/internal/jsontypes" + "github.com/tendermint/tendermint/libs/bytes" + "github.com/tendermint/tendermint/types" +) + +type RequestSubscribe struct { + Query string `json:"query"` +} + +type RequestUnsubscribe struct { + Query string `json:"query"` +} + +type RequestBlockchainInfo struct { + MinHeight Int64 `json:"minHeight"` + MaxHeight Int64 `json:"maxHeight"` +} + +type RequestGenesisChunked struct { + Chunk Int64 `json:"chunk"` +} + +type RequestBlockInfo struct { + Height *Int64 `json:"height"` +} + +type RequestBlockByHash struct { + Hash bytes.HexBytes `json:"hash"` +} + +type RequestCheckTx struct { + Tx types.Tx `json:"tx"` +} + +type RequestRemoveTx struct { + TxKey types.TxKey `json:"txkey"` +} + +type RequestTx struct { + Hash bytes.HexBytes `json:"hash"` + Prove bool `json:"prove"` +} + +type RequestTxSearch struct { + Query string `json:"query"` + Prove bool `json:"prove"` + Page *Int64 `json:"page"` + PerPage *Int64 `json:"per_page"` + OrderBy string `json:"order_by"` +} + +type RequestBlockSearch struct { + Query string `json:"query"` + Page *Int64 `json:"page"` + PerPage *Int64 `json:"per_page"` + OrderBy string `json:"order_by"` +} + +type RequestValidators struct { + Height *Int64 `json:"height"` + Page *Int64 `json:"page"` + PerPage *Int64 `json:"per_page"` +} + +type RequestConsensusParams struct { + Height *Int64 `json:"height"` +} + +type RequestUnconfirmedTxs struct { + Page *Int64 `json:"page"` + PerPage *Int64 `json:"per_page"` +} + +type RequestBroadcastTx struct { + Tx types.Tx `json:"tx"` +} + +type RequestABCIQuery struct { + Path string `json:"path"` + Data bytes.HexBytes `json:"data"` + Height Int64 `json:"height"` + Prove bool `json:"prove"` +} + +type RequestBroadcastEvidence struct { + Evidence types.Evidence +} + +type requestBroadcastEvidenceJSON struct { + Evidence json.RawMessage `json:"evidence"` +} + +func (r RequestBroadcastEvidence) MarshalJSON() ([]byte, error) { + ev, err := jsontypes.Marshal(r.Evidence) + if err != nil { + return nil, err + } + return json.Marshal(requestBroadcastEvidenceJSON{ + Evidence: ev, + }) +} + +func (r *RequestBroadcastEvidence) UnmarshalJSON(data []byte) error { + var val requestBroadcastEvidenceJSON + if err := json.Unmarshal(data, &val); err != nil { + return err + } + if err := jsontypes.Unmarshal(val.Evidence, &r.Evidence); err != nil { + return err + } + return nil +} + +// RequestEvents is the argument for the "/events" RPC endpoint. +type RequestEvents struct { + // Optional filter spec. If nil or empty, all items are eligible. + Filter *EventFilter `json:"filter"` + + // The maximum number of eligible items to return. + // If zero or negative, the server will report a default number. + MaxItems int `json:"maxItems"` + + // Return only items after this cursor. If empty, the limit is just + // before the the beginning of the event log. + After string `json:"after"` + + // Return only items before this cursor. If empty, the limit is just + // after the head of the event log. + Before string `json:"before"` + + // Wait for up to this long for events to be available. + WaitTime time.Duration `json:"waitTime"` +} + +// An EventFilter specifies which events are selected by an /events request. +type EventFilter struct { + Query string `json:"query"` +} + +// Int64 is a wrapper for int64 that encodes to JSON as a string and can be +// decoded from either a string or a number value. +type Int64 int64 + +func (z *Int64) UnmarshalJSON(data []byte) error { + var s string + if len(data) != 0 && data[0] == '"' { + if err := json.Unmarshal(data, &s); err != nil { + return err + } + } else { + s = string(data) + } + v, err := strconv.ParseInt(s, 10, 64) + if err != nil { + return err + } + *z = Int64(v) + return nil +} + +func (z Int64) MarshalJSON() ([]byte, error) { + return []byte(strconv.FormatInt(int64(z), 10)), nil +} + +// IntPtr returns a pointer to the value of *z as an int, or nil if z == nil. +func (z *Int64) IntPtr() *int { + if z == nil { + return nil + } + v := int(*z) + return &v +} + +// Int64Ptr returns an *Int64 that points to the same value as v, or nil. +func Int64Ptr(v *int) *Int64 { + if v == nil { + return nil + } + z := Int64(*v) + return &z +} diff --git a/rpc/coretypes/responses.go b/rpc/coretypes/responses.go index 8968f9868..51d988f3a 100644 --- a/rpc/coretypes/responses.go +++ b/rpc/coretypes/responses.go @@ -357,32 +357,6 @@ type Evidence struct { func (e Evidence) MarshalJSON() ([]byte, error) { return jsontypes.Marshal(e.Value) } func (e *Evidence) UnmarshalJSON(data []byte) error { return jsontypes.Unmarshal(data, &e.Value) } -// RequestEvents is the argument for the "/events" RPC endpoint. -type RequestEvents struct { - // Optional filter spec. If nil or empty, all items are eligible. - Filter *EventFilter `json:"filter"` - - // The maximum number of eligible items to return. - // If zero or negative, the server will report a default number. - MaxItems int `json:"maxItems"` - - // Return only items after this cursor. If empty, the limit is just - // before the the beginning of the event log. - After string `json:"after"` - - // Return only items before this cursor. If empty, the limit is just - // after the head of the event log. - Before string `json:"before"` - - // Wait for up to this long for events to be available. - WaitTime time.Duration `json:"waitTime"` -} - -// An EventFilter specifies which events are selected by an /events request. -type EventFilter struct { - Query string `json:"query"` -} - // ResultEvents is the response from the "/events" RPC endpoint. type ResultEvents struct { // The items matching the request parameters, from newest diff --git a/rpc/jsonrpc/doc.go b/rpc/jsonrpc/doc.go index b014fe38d..58b522861 100644 --- a/rpc/jsonrpc/doc.go +++ b/rpc/jsonrpc/doc.go @@ -55,7 +55,7 @@ // Define some routes // // var Routes = map[string]*rpcserver.RPCFunc{ -// "status": rpcserver.NewRPCFunc(Status, "arg"), +// "status": rpcserver.NewRPCFunc(Status), // } // // An rpc function: diff --git a/rpc/jsonrpc/jsonrpc_test.go b/rpc/jsonrpc/jsonrpc_test.go index 1ba853a62..236db9b32 100644 --- a/rpc/jsonrpc/jsonrpc_test.go +++ b/rpc/jsonrpc/jsonrpc_test.go @@ -34,49 +34,65 @@ const ( testVal = "acbd" ) +type RequestEcho struct { + Value string `json:"arg"` +} + type ResultEcho struct { Value string `json:"value"` } +type RequestEchoInt struct { + Value int `json:"arg"` +} + type ResultEchoInt struct { Value int `json:"value"` } +type RequestEchoBytes struct { + Value []byte `json:"arg"` +} + type ResultEchoBytes struct { Value []byte `json:"value"` } +type RequestEchoDataBytes struct { + Value tmbytes.HexBytes `json:"arg"` +} + type ResultEchoDataBytes struct { Value tmbytes.HexBytes `json:"value"` } // Define some routes var Routes = map[string]*server.RPCFunc{ - "echo": server.NewRPCFunc(EchoResult, "arg"), - "echo_ws": server.NewWSRPCFunc(EchoWSResult, "arg"), - "echo_bytes": server.NewRPCFunc(EchoBytesResult, "arg"), - "echo_data_bytes": server.NewRPCFunc(EchoDataBytesResult, "arg"), - "echo_int": server.NewRPCFunc(EchoIntResult, "arg"), + "echo": server.NewRPCFunc(EchoResult), + "echo_ws": server.NewWSRPCFunc(EchoWSResult), + "echo_bytes": server.NewRPCFunc(EchoBytesResult), + "echo_data_bytes": server.NewRPCFunc(EchoDataBytesResult), + "echo_int": server.NewRPCFunc(EchoIntResult), } -func EchoResult(ctx context.Context, v string) (*ResultEcho, error) { - return &ResultEcho{v}, nil +func EchoResult(ctx context.Context, v *RequestEcho) (*ResultEcho, error) { + return &ResultEcho{v.Value}, nil } -func EchoWSResult(ctx context.Context, v string) (*ResultEcho, error) { - return &ResultEcho{v}, nil +func EchoWSResult(ctx context.Context, v *RequestEcho) (*ResultEcho, error) { + return &ResultEcho{v.Value}, nil } -func EchoIntResult(ctx context.Context, v int) (*ResultEchoInt, error) { - return &ResultEchoInt{v}, nil +func EchoIntResult(ctx context.Context, v *RequestEchoInt) (*ResultEchoInt, error) { + return &ResultEchoInt{v.Value}, nil } -func EchoBytesResult(ctx context.Context, v []byte) (*ResultEchoBytes, error) { - return &ResultEchoBytes{v}, nil +func EchoBytesResult(ctx context.Context, v *RequestEchoBytes) (*ResultEchoBytes, error) { + return &ResultEchoBytes{v.Value}, nil } -func EchoDataBytesResult(ctx context.Context, v tmbytes.HexBytes) (*ResultEchoDataBytes, error) { - return &ResultEchoDataBytes{v}, nil +func EchoDataBytesResult(ctx context.Context, v *RequestEchoDataBytes) (*ResultEchoDataBytes, error) { + return &ResultEchoDataBytes{v.Value}, nil } // launch unix and tcp servers diff --git a/rpc/jsonrpc/server/http_json_handler.go b/rpc/jsonrpc/server/http_json_handler.go index 94da974de..defcb7d9c 100644 --- a/rpc/jsonrpc/server/http_json_handler.go +++ b/rpc/jsonrpc/server/http_json_handler.go @@ -2,15 +2,11 @@ package server import ( "bytes" - "context" "encoding/json" - "errors" "fmt" "html/template" "io" "net/http" - "reflect" - "strconv" "strings" "github.com/tendermint/tendermint/libs/log" @@ -70,19 +66,11 @@ func makeJSONRPCHandler(funcMap map[string]*RPCFunc, logger log.Logger) http.Han RPCRequest: &req, HTTPRequest: hreq, }) - args, err := parseParams(ctx, rpcFunc, req.Params) + result, err := rpcFunc.Call(ctx, req.Params) if err != nil { - responses = append(responses, - req.MakeErrorf(rpctypes.CodeInvalidParams, "converting JSON parameters: %v", err)) - continue - } - - returns := rpcFunc.f.Call(args) - result, err := unreflectResult(returns) - if err == nil { - responses = append(responses, req.MakeResponse(result)) - } else { responses = append(responses, req.MakeError(err)) + } else { + responses = append(responses, req.MakeResponse(result)) } } @@ -124,103 +112,6 @@ func parseRequests(data []byte) ([]rpctypes.RPCRequest, error) { return reqs, nil } -// parseParams parses the JSON parameters of rpcReq into the arguments of fn, -// returning the corresponding argument values or an error. -func parseParams(ctx context.Context, fn *RPCFunc, paramData []byte) ([]reflect.Value, error) { - params, err := parseJSONParams(fn, paramData) - if err != nil { - return nil, err - } - - args := make([]reflect.Value, 1+len(params)) - args[0] = reflect.ValueOf(ctx) - for i, param := range params { - ptype := fn.args[i+1] - if len(param) == 0 { - args[i+1] = reflect.Zero(ptype) - continue - } - - var pval reflect.Value - isPtr := ptype.Kind() == reflect.Ptr - if isPtr { - pval = reflect.New(ptype.Elem()) - } else { - pval = reflect.New(ptype) - } - baseType := pval.Type().Elem() - - if isIntType(baseType) && isStringValue(param) { - var z int64String - if err := json.Unmarshal(param, &z); err != nil { - return nil, fmt.Errorf("decoding string %q: %w", fn.argNames[i], err) - } - pval.Elem().Set(reflect.ValueOf(z).Convert(baseType)) - } else if err := json.Unmarshal(param, pval.Interface()); err != nil { - return nil, fmt.Errorf("decoding %q: %w", fn.argNames[i], err) - } - - if isPtr { - args[i+1] = pval - } else { - args[i+1] = pval.Elem() - } - } - return args, nil -} - -// parseJSONParams parses data and returns a slice of JSON values matching the -// positional parameters of fn. It reports an error if data is not "null" and -// does not encode an object or an array, or if the number of array parameters -// does not match the argument list of fn (excluding the context). -func parseJSONParams(fn *RPCFunc, data []byte) ([]json.RawMessage, error) { - base := bytes.TrimSpace(data) - if bytes.HasPrefix(base, []byte("{")) { - var m map[string]json.RawMessage - if err := json.Unmarshal(base, &m); err != nil { - return nil, fmt.Errorf("decoding parameter object: %w", err) - } - out := make([]json.RawMessage, len(fn.argNames)) - for i, name := range fn.argNames { - if p, ok := m[name]; ok { - out[i] = p - } - } - return out, nil - - } else if bytes.HasPrefix(base, []byte("[")) { - var m []json.RawMessage - if err := json.Unmarshal(base, &m); err != nil { - return nil, fmt.Errorf("decoding parameter array: %w", err) - } - if len(m) != len(fn.argNames) { - return nil, fmt.Errorf("got %d parameters, want %d", len(m), len(fn.argNames)) - } - return m, nil - - } else if bytes.Equal(base, []byte("null")) { - return make([]json.RawMessage, len(fn.argNames)), nil - } - - return nil, errors.New("parameters must be an object or an array") -} - -// isStringValue reports whether data is a JSON string value. -func isStringValue(data json.RawMessage) bool { - return len(data) != 0 && data[0] == '"' -} - -type int64String int64 - -func (z *int64String) UnmarshalText(data []byte) error { - v, err := strconv.ParseInt(string(data), 10, 64) - if err != nil { - return err - } - *z = int64String(v) - return nil -} - // writes a list of available rpc endpoints as an html page func writeListOfEndpoints(w http.ResponseWriter, r *http.Request, funcMap map[string]*RPCFunc) { hasArgs := make(map[string]string) diff --git a/rpc/jsonrpc/server/http_json_handler_test.go b/rpc/jsonrpc/server/http_json_handler_test.go index 1f5d2c320..77c74ffbc 100644 --- a/rpc/jsonrpc/server/http_json_handler_test.go +++ b/rpc/jsonrpc/server/http_json_handler_test.go @@ -17,9 +17,16 @@ import ( ) func testMux() *http.ServeMux { + type testArgs struct { + S string `json:"s"` + I json.Number `json:"i"` + } + type blockArgs struct { + H json.Number `json:"h"` + } funcMap := map[string]*RPCFunc{ - "c": NewRPCFunc(func(ctx context.Context, s string, i int) (string, error) { return "foo", nil }, "s", "i"), - "block": NewRPCFunc(func(ctx context.Context, h int) (string, error) { return "block", nil }, "height"), + "c": NewRPCFunc(func(ctx context.Context, arg *testArgs) (string, error) { return "foo", nil }), + "block": NewRPCFunc(func(ctx context.Context, arg *blockArgs) (string, error) { return "block", nil }), } mux := http.NewServeMux() logger := log.NewNopLogger() @@ -46,7 +53,7 @@ func TestRPCParams(t *testing.T) { // id not captured in JSON parsing failures {`{"method": "c", "id": "0", "params": a}`, "invalid character", ""}, {`{"method": "c", "id": "0", "params": ["a"]}`, "got 1", `"0"`}, - {`{"method": "c", "id": "0", "params": ["a", "b"]}`, "invalid syntax", `"0"`}, + {`{"method": "c", "id": "0", "params": ["a", "b"]}`, "invalid number", `"0"`}, {`{"method": "c", "id": "0", "params": [1, 1]}`, "of type string", `"0"`}, // no ID - notification diff --git a/rpc/jsonrpc/server/http_uri_handler.go b/rpc/jsonrpc/server/http_uri_handler.go index ad0fbb7b3..7e1902ac1 100644 --- a/rpc/jsonrpc/server/http_uri_handler.go +++ b/rpc/jsonrpc/server/http_uri_handler.go @@ -1,13 +1,11 @@ package server import ( - "context" - "encoding" "encoding/hex" "encoding/json" + "errors" "fmt" "net/http" - "reflect" "strconv" "strings" @@ -25,7 +23,7 @@ func makeHTTPHandler(rpcFunc *RPCFunc, logger log.Logger) func(http.ResponseWrit ctx := rpctypes.WithCallInfo(req.Context(), &rpctypes.CallInfo{ HTTPRequest: req, }) - args, err := parseURLParams(ctx, rpcFunc, req) + args, err := parseURLParams(rpcFunc.argNames, req) if err != nil { w.Header().Set("Content-Type", "text/plain") w.WriteHeader(http.StatusBadRequest) @@ -33,10 +31,7 @@ func makeHTTPHandler(rpcFunc *RPCFunc, logger log.Logger) func(http.ResponseWrit return } jreq := rpctypes.NewRequest(uriReqID) - outs := rpcFunc.f.Call(args) - - logger.Debug("HTTPRestRPC", "method", req.URL.Path, "args", args, "returns", outs) - result, err := unreflectResult(outs) + result, err := rpcFunc.Call(ctx, args) if err == nil { writeHTTPResponse(w, logger, jreq.MakeResponse(result)) } else { @@ -45,7 +40,7 @@ func makeHTTPHandler(rpcFunc *RPCFunc, logger log.Logger) func(http.ResponseWrit } } -func parseURLParams(ctx context.Context, rf *RPCFunc, req *http.Request) ([]reflect.Value, error) { +func parseURLParams(argNames []string, req *http.Request) ([]byte, error) { if err := req.ParseForm(); err != nil { return nil, fmt.Errorf("invalid HTTP request: %w", err) } @@ -56,112 +51,35 @@ func parseURLParams(ctx context.Context, rf *RPCFunc, req *http.Request) ([]refl return "", false } - vals := make([]reflect.Value, len(rf.argNames)+1) - vals[0] = reflect.ValueOf(ctx) - for i, name := range rf.argNames { - atype := rf.args[i+1] - - text, ok := getArg(name) + params := make(map[string]interface{}) + for _, name := range argNames { + v, ok := getArg(name) if !ok { - vals[i+1] = reflect.Zero(atype) continue } - - val, err := parseArgValue(atype, text) - if err != nil { - return nil, fmt.Errorf("decoding parameter %q: %w", name, err) + if z, err := decodeInteger(v); err == nil { + params[name] = z + } else if b, err := strconv.ParseBool(v); err == nil { + params[name] = b + } else if lc := strings.ToLower(v); strings.HasPrefix(lc, "0x") { + dec, err := hex.DecodeString(lc[2:]) + if err != nil { + return nil, fmt.Errorf("invalid hex string: %w", err) + } else if len(dec) == 0 { + return nil, errors.New("invalid empty hex string") + } + params[name] = dec + } else if isQuotedString(v) { + var dec string + if err := json.Unmarshal([]byte(v), &dec); err != nil { + return nil, fmt.Errorf("invalid quoted string: %w", err) + } + params[name] = dec + } else { + params[name] = v } - vals[i+1] = val - } - return vals, nil -} - -func parseArgValue(atype reflect.Type, text string) (reflect.Value, error) { - // Regardless whether the argument is a pointer type, allocate a pointer so - // we can set the computed value. - var out reflect.Value - isPtr := atype.Kind() == reflect.Ptr - if isPtr { - out = reflect.New(atype.Elem()) - } else { - out = reflect.New(atype) - } - - baseType := out.Type().Elem() - if isIntType(baseType) { - // Integral type: Require a base-10 digit string. For compatibility with - // existing use allow quotation marks. - v, err := decodeInteger(text) - if err != nil { - return reflect.Value{}, fmt.Errorf("invalid integer: %w", err) - } - out.Elem().Set(reflect.ValueOf(v).Convert(baseType)) - - } else if isStringOrBytes(baseType) { - // String or byte slice: Check for quotes, hex encoding. - dec, err := decodeString(text) - if err != nil { - return reflect.Value{}, err - } - out.Elem().Set(reflect.ValueOf(dec).Convert(baseType)) - - } else if baseType.Kind() == reflect.Bool { - b, err := strconv.ParseBool(text) - if err != nil { - return reflect.Value{}, fmt.Errorf("invalid boolean: %w", err) - } - out.Elem().Set(reflect.ValueOf(b)) - - } else if out.Type().Implements(textUnmarshalerType) { - s, err := decodeString(text) - if err != nil { - return reflect.Value{}, err - } - v := reflect.New(baseType) - dec := v.Interface().(encoding.TextUnmarshaler) - if err := dec.UnmarshalText(s); err != nil { - return reflect.Value{}, fmt.Errorf("invalid text: %w", err) - } - out.Elem().Set(v.Elem()) - - } else { - // We don't know how to represent other types. - return reflect.Value{}, fmt.Errorf("unsupported argument type %v", baseType) - } - - // If the argument wants a pointer, return the value as-is, otherwise - // indirect the pointer back off. - if isPtr { - return out, nil - } - return out.Elem(), nil -} - -var ( - uint64Type = reflect.TypeOf(uint64(0)) - textUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem() -) - -// isIntType reports whether atype is an integer-shaped type. -func isIntType(atype reflect.Type) bool { - switch atype.Kind() { - case reflect.Float32, reflect.Float64: - return false - default: - return atype.ConvertibleTo(uint64Type) - } -} - -// isStringOrBytes reports whether atype is a string or []byte. -func isStringOrBytes(atype reflect.Type) bool { - switch atype.Kind() { - case reflect.String: - return true - case reflect.Slice: - return atype.Elem().Kind() == reflect.Uint8 - default: - return false } + return json.Marshal(params) } // isQuotedString reports whether s is enclosed in double quotes. @@ -177,19 +95,3 @@ func decodeInteger(s string) (int64, error) { } return strconv.ParseInt(s, 10, 64) } - -// decodeString decodes s into a byte slice. If s has an 0x prefix, it is -// treated as a hex-encoded string. If it is "double quoted" it is treated as a -// JSON string value. Otherwise, s is converted to bytes directly. -func decodeString(s string) ([]byte, error) { - if lc := strings.ToLower(s); strings.HasPrefix(lc, "0x") { - return hex.DecodeString(lc[2:]) - } else if isQuotedString(s) { - var dec string - if err := json.Unmarshal([]byte(s), &dec); err != nil { - return nil, fmt.Errorf("invalid quoted string: %w", err) - } - return []byte(dec), nil - } - return []byte(s), nil -} diff --git a/rpc/jsonrpc/server/parse_test.go b/rpc/jsonrpc/server/parse_test.go index ee0ab5d79..e6667fb0a 100644 --- a/rpc/jsonrpc/server/parse_test.go +++ b/rpc/jsonrpc/server/parse_test.go @@ -3,7 +3,6 @@ package server import ( "context" "encoding/json" - "fmt" "net/http" "strconv" "testing" @@ -134,8 +133,12 @@ func TestParseJSONArray(t *testing.T) { } func TestParseJSONRPC(t *testing.T) { - demo := func(ctx context.Context, height int, name string) error { return nil } - call := NewRPCFunc(demo, "height", "name") + type demoArgs struct { + Height int `json:"height,string"` + Name string `json:"name"` + } + demo := func(ctx context.Context, _ *demoArgs) error { return nil } + rfunc := NewRPCFunc(demo) cases := []struct { raw string @@ -156,14 +159,16 @@ func TestParseJSONRPC(t *testing.T) { ctx := context.Background() for idx, tc := range cases { i := strconv.Itoa(idx) - vals, err := parseParams(ctx, call, []byte(tc.raw)) + vals, err := rfunc.parseParams(ctx, []byte(tc.raw)) if tc.fail { assert.Error(t, err, i) } else { assert.NoError(t, err, "%s: %+v", i, err) - if assert.Equal(t, 3, len(vals), i) { // ctx, height, name - assert.Equal(t, tc.height, vals[1].Int(), i) - assert.Equal(t, tc.name, vals[2].String(), i) + assert.Equal(t, 2, len(vals), i) + p, ok := vals[1].Interface().(*demoArgs) + if assert.True(t, ok) { + assert.Equal(t, tc.height, int64(p.Height), i) + assert.Equal(t, tc.name, p.Name, i) } } @@ -171,50 +176,147 @@ func TestParseJSONRPC(t *testing.T) { } func TestParseURI(t *testing.T) { - demo := func(ctx context.Context, height int, name string) error { return nil } - call := NewRPCFunc(demo, "height", "name") + // URI parameter parsing happens in two phases: + // + // Phase 1 swizzles the query parameters into JSON. The result of this + // phase must be valid JSON, but may fail the second stage. + // + // Phase 2 decodes the JSON to obtain the actual arguments. A failure at + // this stage means the JSON is not compatible with the target. - cases := []struct { - raw []string - height int64 - name string - fail bool - }{ - // can parse numbers unquoted and strings quoted - {[]string{"7", `"flew"`}, 7, "flew", false}, - {[]string{"22", `"john"`}, 22, "john", false}, - {[]string{"-10", `"bob"`}, -10, "bob", false}, - // can parse numbers quoted, too - {[]string{`"7"`, `"flew"`}, 7, "flew", false}, - {[]string{`"-10"`, `"bob"`}, -10, "bob", false}, - // can parse strings hex-escaped, in either case - {[]string{`-9`, `0x626f62`}, -9, "bob", false}, - {[]string{`-9`, `0X646F7567`}, -9, "doug", false}, - // can parse strings unquoted (as per OpenAPI docs) - {[]string{`0`, `hey you`}, 0, "hey you", false}, - // fail for invalid numbers, strings, hex - {[]string{`"-xx"`, `bob`}, 0, "", true}, // bad number - {[]string{`"95""`, `"bob`}, 0, "", true}, // bad string - {[]string{`15`, `0xa`}, 0, "", true}, // bad hex - } - for idx, tc := range cases { - i := strconv.Itoa(idx) - // data := []byte(tc.raw) - url := fmt.Sprintf( - "test.com/method?height=%v&name=%v", - tc.raw[0], tc.raw[1]) - req, err := http.NewRequest("GET", url, nil) - assert.NoError(t, err) - vals, err := parseURLParams(context.Background(), call, req) - if tc.fail { - assert.Error(t, err, i) - } else { - assert.NoError(t, err, "%s: %+v", i, err) - if assert.Equal(t, 3, len(vals), i) { - assert.Equal(t, tc.height, vals[1].Int(), i) - assert.Equal(t, tc.name, vals[2].String(), i) - } + t.Run("Swizzle", func(t *testing.T) { + tests := []struct { + name string + url string + args []string + want string + fail bool + }{ + { + name: "quoted numbers and strings", + url: `http://localhost?num="7"&str="flew"&neg="-10"`, + args: []string{"neg", "num", "str", "other"}, + want: `{"neg":-10,"num":7,"str":"flew"}`, + }, + { + name: "unquoted numbers and strings", + url: `http://localhost?num1=7&str1=cabbage&num2=-199&str2=hey+you`, + args: []string{"num1", "num2", "str1", "str2", "other"}, + want: `{"num1":7,"num2":-199,"str1":"cabbage","str2":"hey you"}`, + }, + { + name: "byte strings in hex", + url: `http://localhost?lower=0x626f62&upper=0X646F7567`, + args: []string{"upper", "lower", "other"}, + want: `{"lower":"Ym9i","upper":"ZG91Zw=="}`, + }, + { + name: "invalid hex odd length", + url: `http://localhost?bad=0xa`, + args: []string{"bad", "superbad"}, + fail: true, + }, + { + name: "invalid hex empty", + url: `http://localhost?bad=0x`, + args: []string{"bad"}, + fail: true, + }, + { + name: "invalid quoted string", + url: `http://localhost?bad="double""`, + args: []string{"bad"}, + fail: true, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + hreq, err := http.NewRequest("GET", test.url, nil) + if err != nil { + t.Fatalf("NewRequest for %q: %v", test.url, err) + } + + bits, err := parseURLParams(test.args, hreq) + if err != nil && !test.fail { + t.Fatalf("Parse %q: unexpected error: %v", test.url, err) + } else if err == nil && test.fail { + t.Fatalf("Parse %q: got %#q, wanted error", test.url, string(bits)) + } + if got := string(bits); got != test.want { + t.Errorf("Parse %q: got %#q, want %#q", test.url, got, test.want) + } + }) + } + }) + + t.Run("Decode", func(t *testing.T) { + type argValue struct { + Height json.Number `json:"height"` + Name string `json:"name"` + Flag bool `json:"flag"` } - } + echo := NewRPCFunc(func(_ context.Context, arg *argValue) (*argValue, error) { + return arg, nil + }) + + tests := []struct { + name string + url string + fail string + want interface{} + }{ + { + name: "valid all args", + url: `http://localhost?height=235&flag=true&name="bogart"`, + want: &argValue{ + Height: "235", + Flag: true, + Name: "bogart", + }, + }, + { + name: "valid partial args", + url: `http://localhost?height="1987"&name=free+willy`, + want: &argValue{ + Height: "1987", + Name: "free willy", + }, + }, + { + name: "invalid quoted number", + url: `http://localhost?height="-xx"`, + fail: "invalid number literal", + }, + { + name: "invalid unquoted number", + url: `http://localhost?height=25*q`, + fail: "invalid number literal", + }, + { + name: "invalid boolean", + url: `http://localhost?flag="garbage"`, + fail: "flag of type bool", + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + hreq, err := http.NewRequest("GET", test.url, nil) + if err != nil { + t.Fatalf("NewRequest for %q: %v", test.url, err) + } + bits, err := parseURLParams(echo.argNames, hreq) + if err != nil { + t.Fatalf("Parse %#q: unexpected error: %v", test.url, err) + } + rsp, err := echo.Call(context.Background(), bits) + if test.want != nil { + assert.Equal(t, test.want, rsp) + } + if test.fail != "" { + assert.ErrorContains(t, err, test.fail) + } + }) + } + }) } diff --git a/rpc/jsonrpc/server/rpc_func.go b/rpc/jsonrpc/server/rpc_func.go index a58973c6e..456d97bfc 100644 --- a/rpc/jsonrpc/server/rpc_func.go +++ b/rpc/jsonrpc/server/rpc_func.go @@ -1,13 +1,17 @@ package server import ( + "bytes" "context" + "encoding/json" "errors" "fmt" "net/http" "reflect" + "strings" "github.com/tendermint/tendermint/libs/log" + rpctypes "github.com/tendermint/tendermint/rpc/jsonrpc/types" ) // RegisterRPCFuncs adds a route to mux for each non-websocket function in the @@ -28,27 +32,97 @@ func RegisterRPCFuncs(mux *http.ServeMux, funcMap map[string]*RPCFunc, logger lo // RPCFunc contains the introspected type information for a function. type RPCFunc struct { - f reflect.Value // underlying rpc function - args []reflect.Type // type of each function arg - returns []reflect.Type // type of each return arg - argNames []string // name of each argument - ws bool // websocket only + f reflect.Value // underlying rpc function + param reflect.Type // the parameter struct, or nil + result reflect.Type // the non-error result type, or nil + argNames []string // name of each argument (for display) + ws bool // websocket only +} + +// Call parses the given JSON parameters and calls the function wrapped by rf +// with the resulting argument value. It reports an error if parameter parsing +// fails, otherwise it returns the result from the wrapped function. +func (rf *RPCFunc) Call(ctx context.Context, params json.RawMessage) (interface{}, error) { + args, err := rf.parseParams(ctx, params) + if err != nil { + return nil, err + } + returns := rf.f.Call(args) + + // Case 1: There is no non-error result type. + if rf.result == nil { + if oerr := returns[0].Interface(); oerr != nil { + return nil, oerr.(error) + } + return nil, nil + } + + // Case 2: There is a non-error result. + if oerr := returns[1].Interface(); oerr != nil { + // In case of error, report the error and ignore the result. + return nil, oerr.(error) + } + return returns[0].Interface(), nil +} + +// parseParams parses the parameters of a JSON-RPC request and returns the +// corresponding argument values. On success, the first argument value will be +// the value of ctx. +func (rf *RPCFunc) parseParams(ctx context.Context, params json.RawMessage) ([]reflect.Value, error) { + // If rf does not accept parameters, there is no decoding to do, but verify + // that no parameters were passed. + if rf.param == nil { + if !isNullOrEmpty(params) { + return nil, invalidParamsError("no parameters accepted for this method") + } + return []reflect.Value{reflect.ValueOf(ctx)}, nil + } + bits, err := rf.adjustParams(params) + if err != nil { + return nil, invalidParamsError(err.Error()) + } + arg := reflect.New(rf.param) + if err := json.Unmarshal(bits, arg.Interface()); err != nil { + return nil, invalidParamsError(err.Error()) + } + return []reflect.Value{reflect.ValueOf(ctx), arg}, nil +} + +// adjustParams checks whether data is encoded as a JSON array, and if so +// adjusts the values to match the corresponding parameter names. +func (rf *RPCFunc) adjustParams(data []byte) (json.RawMessage, error) { + base := bytes.TrimSpace(data) + if bytes.HasPrefix(base, []byte("[")) { + var args []json.RawMessage + if err := json.Unmarshal(base, &args); err != nil { + return nil, err + } else if len(args) != len(rf.argNames) { + return nil, fmt.Errorf("got %d arguments, want %d", len(args), len(rf.argNames)) + } + m := make(map[string]json.RawMessage) + for i, arg := range args { + m[rf.argNames[i]] = arg + } + return json.Marshal(m) + } else if bytes.HasPrefix(base, []byte("{")) || bytes.Equal(base, []byte("null")) { + return base, nil + } + return nil, errors.New("parameters must be an object or an array") + } // NewRPCFunc constructs an RPCFunc for f, which must be a function whose type // signature matches one of these schemes: // -// func(context.Context, T1, T2, ...) error -// func(context.Context, T1, T2, ...) (R, error) +// func(context.Context) error +// func(context.Context) (R, error) +// func(context.Context, *T) error +// func(context.Context, *T) (R, error) // -// for arbitrary types T_i and R. The number of argNames must exactly match the -// number of non-context arguments to f. Otherwise, NewRPCFunc panics. -// -// The parameter names given are used to map JSON object keys to the -// corresonding parameter of the function. The names do not need to match the -// declared names, but must match what the client sends in a request. -func NewRPCFunc(f interface{}, argNames ...string) *RPCFunc { - rf, err := newRPCFunc(f, argNames) +// for an arbitrary struct type T and type R. NewRPCFunc will panic if f does +// not have one of these forms. +func NewRPCFunc(f interface{}) *RPCFunc { + rf, err := newRPCFunc(f) if err != nil { panic("invalid RPC function: " + err.Error()) } @@ -57,8 +131,8 @@ func NewRPCFunc(f interface{}, argNames ...string) *RPCFunc { // NewWSRPCFunc behaves as NewRPCFunc, but marks the resulting function for use // via websocket. -func NewWSRPCFunc(f interface{}, argNames ...string) *RPCFunc { - rf := NewRPCFunc(f, argNames...) +func NewWSRPCFunc(f interface{}) *RPCFunc { + rf := NewRPCFunc(f) rf.ws = true return rf } @@ -69,7 +143,7 @@ var ( ) // newRPCFunc constructs an RPCFunc for f. See the comment at NewRPCFunc. -func newRPCFunc(f interface{}, argNames []string) (*RPCFunc, error) { +func newRPCFunc(f interface{}) (*RPCFunc, error) { if f == nil { return nil, errors.New("nil function") } @@ -80,49 +154,74 @@ func newRPCFunc(f interface{}, argNames []string) (*RPCFunc, error) { return nil, errors.New("not a function") } + var ptype reflect.Type ft := fv.Type() - if np := ft.NumIn(); np == 0 { + if np := ft.NumIn(); np == 0 || np > 2 { return nil, errors.New("wrong number of parameters") } else if ft.In(0) != ctxType { return nil, errors.New("first parameter is not context.Context") - } else if np-1 != len(argNames) { - return nil, fmt.Errorf("have %d names for %d parameters", len(argNames), np-1) + } else if np == 2 { + ptype = ft.In(1) + if ptype.Kind() != reflect.Ptr { + return nil, errors.New("parameter type is not a pointer") + } + ptype = ptype.Elem() + if ptype.Kind() != reflect.Struct { + return nil, errors.New("parameter type is not a struct") + } } + var rtype reflect.Type if no := ft.NumOut(); no < 1 || no > 2 { return nil, errors.New("wrong number of results") } else if ft.Out(no-1) != errType { return nil, errors.New("last result is not error") + } else if no == 2 { + rtype = ft.Out(0) } - args := make([]reflect.Type, ft.NumIn()) - for i := 0; i < ft.NumIn(); i++ { - args[i] = ft.In(i) - } - outs := make([]reflect.Type, ft.NumOut()) - for i := 0; i < ft.NumOut(); i++ { - outs[i] = ft.Out(i) + var argNames []string + if ptype != nil { + for i := 0; i < ptype.NumField(); i++ { + field := ptype.Field(i) + if tag := strings.SplitN(field.Tag.Get("json"), ",", 2)[0]; tag != "" && tag != "-" { + argNames = append(argNames, tag) + } else if tag == "-" { + // If the tag is "-" the field should explicitly be ignored, even + // if it is otherwise eligible. + } else if field.IsExported() && !field.Anonymous { + // Examples: Name → name, MaxEffort → maxEffort. + // Note that this is an aesthetic choice; the standard decoder will + // match without regard to case anyway. + name := strings.ToLower(field.Name[:1]) + field.Name[1:] + argNames = append(argNames, name) + } + } } + return &RPCFunc{ f: fv, - args: args, - returns: outs, + param: ptype, + result: rtype, argNames: argNames, }, nil } -//------------------------------------------------------------- - -// NOTE: assume returns is result struct and error. If error is not nil, return it -func unreflectResult(returns []reflect.Value) (interface{}, error) { - errV := returns[1] - if err, ok := errV.Interface().(error); ok && err != nil { - return nil, err +// invalidParamsError returns an RPC invalid parameters error with the given +// detail message. +func invalidParamsError(msg string, args ...interface{}) error { + return &rpctypes.RPCError{ + Code: int(rpctypes.CodeInvalidParams), + Message: rpctypes.CodeInvalidParams.String(), + Data: fmt.Sprintf(msg, args...), } - rv := returns[0] - // the result is a registered interface, - // we need a pointer to it so we can marshal with type byte - rvp := reflect.New(rv.Type()) - rvp.Elem().Set(rv) - return rvp.Interface(), nil +} + +// isNullOrEmpty reports whether params is either itself empty or represents an +// empty parameter (null, empty object, or empty array). +func isNullOrEmpty(params json.RawMessage) bool { + return len(params) == 0 || + bytes.Equal(params, []byte("null")) || + bytes.Equal(params, []byte("{}")) || + bytes.Equal(params, []byte("[]")) } diff --git a/rpc/jsonrpc/server/ws_handler.go b/rpc/jsonrpc/server/ws_handler.go index 7f2221b24..3a259757b 100644 --- a/rpc/jsonrpc/server/ws_handler.go +++ b/rpc/jsonrpc/server/ws_handler.go @@ -331,22 +331,8 @@ func (wsc *wsConnection) readRoutine(ctx context.Context) { RPCRequest: &request, WSConn: wsc, }) - args, err := parseParams(fctx, rpcFunc, request.Params) - if err != nil { - if err := wsc.WriteRPCResponse(writeCtx, request.MakeErrorf(rpctypes.CodeInvalidParams, - "converting JSON parameters: %v", err)); err != nil { - wsc.Logger.Error("error writing RPC response", "err", err) - } - continue - } - - returns := rpcFunc.f.Call(args) - - // TODO: Need to encode args/returns to string if we want to log them - wsc.Logger.Info("WSJSONRPC", "method", request.Method) - var resp rpctypes.RPCResponse - result, err := unreflectResult(returns) + result, err := rpcFunc.Call(fctx, request.Params) if err == nil { resp = request.MakeResponse(result) } else { diff --git a/rpc/jsonrpc/server/ws_handler_test.go b/rpc/jsonrpc/server/ws_handler_test.go index ae73a953b..ce1bcd973 100644 --- a/rpc/jsonrpc/server/ws_handler_test.go +++ b/rpc/jsonrpc/server/ws_handler_test.go @@ -2,6 +2,7 @@ package server import ( "context" + "encoding/json" "net/http" "net/http/httptest" "testing" @@ -44,8 +45,12 @@ func TestWebsocketManagerHandler(t *testing.T) { } func newWSServer(t *testing.T, logger log.Logger) *httptest.Server { + type args struct { + S string `json:"s"` + I json.Number `json:"i"` + } funcMap := map[string]*RPCFunc{ - "c": NewWSRPCFunc(func(ctx context.Context, s string, i int) (string, error) { return "foo", nil }, "s", "i"), + "c": NewWSRPCFunc(func(context.Context, *args) (string, error) { return "foo", nil }), } wm := NewWebsocketManager(logger, funcMap) diff --git a/rpc/jsonrpc/test/main.go b/rpc/jsonrpc/test/main.go index 07a3b28f3..2ed013c17 100644 --- a/rpc/jsonrpc/test/main.go +++ b/rpc/jsonrpc/test/main.go @@ -14,7 +14,7 @@ import ( ) var routes = map[string]*rpcserver.RPCFunc{ - "hello_world": rpcserver.NewRPCFunc(HelloWorld, "name", "num"), + "hello_world": rpcserver.NewRPCFunc(HelloWorld), } func HelloWorld(ctx context.Context, name string, num int) (Result, error) { diff --git a/test/fuzz/tests/rpc_jsonrpc_server_test.go b/test/fuzz/tests/rpc_jsonrpc_server_test.go index bc4e90881..67dee9ef2 100644 --- a/test/fuzz/tests/rpc_jsonrpc_server_test.go +++ b/test/fuzz/tests/rpc_jsonrpc_server_test.go @@ -17,10 +17,14 @@ import ( ) func FuzzRPCJSONRPCServer(f *testing.F) { + type args struct { + S string `json:"s"` + I int `json:"i"` + } var rpcFuncMap = map[string]*rpcserver.RPCFunc{ - "c": rpcserver.NewRPCFunc(func(ctx context.Context, s string, i int) (string, error) { + "c": rpcserver.NewRPCFunc(func(context.Context, *args) (string, error) { return "foo", nil - }, "s", "i"), + }), } mux := http.NewServeMux() From 86706782917ed7662baa624c52d140116ccb52dc Mon Sep 17 00:00:00 2001 From: Sam Kleinman Date: Wed, 27 Apr 2022 14:29:19 -0400 Subject: [PATCH 23/35] p2p: remove support for multiple transports and endpoints (#8420) --- internal/p2p/address.go | 8 +-- internal/p2p/address_test.go | 34 ++++++------ internal/p2p/mocks/transport.go | 29 ++++++---- internal/p2p/p2ptest/network.go | 10 ++-- internal/p2p/router.go | 80 +++++++++------------------- internal/p2p/router_test.go | 46 ++++++++-------- internal/p2p/transport.go | 12 ++--- internal/p2p/transport_mconn.go | 18 +++---- internal/p2p/transport_mconn_test.go | 39 +++++++------- internal/p2p/transport_memory.go | 12 ++--- internal/p2p/transport_test.go | 70 +++++++++++++----------- node/setup.go | 4 +- 12 files changed, 178 insertions(+), 184 deletions(-) diff --git a/internal/p2p/address.go b/internal/p2p/address.go index 7c084216e..0f4066faf 100644 --- a/internal/p2p/address.go +++ b/internal/p2p/address.go @@ -97,7 +97,7 @@ func ParseNodeAddress(urlString string) (NodeAddress, error) { // Resolve resolves a NodeAddress into a set of Endpoints, by expanding // out a DNS hostname to IP addresses. -func (a NodeAddress) Resolve(ctx context.Context) ([]Endpoint, error) { +func (a NodeAddress) Resolve(ctx context.Context) ([]*Endpoint, error) { if a.Protocol == "" { return nil, errors.New("address has no protocol") } @@ -109,7 +109,7 @@ func (a NodeAddress) Resolve(ctx context.Context) ([]Endpoint, error) { if a.NodeID == "" { return nil, errors.New("local address has no node ID") } - return []Endpoint{{ + return []*Endpoint{{ Protocol: a.Protocol, Path: string(a.NodeID), }}, nil @@ -119,9 +119,9 @@ func (a NodeAddress) Resolve(ctx context.Context) ([]Endpoint, error) { if err != nil { return nil, err } - endpoints := make([]Endpoint, len(ips)) + endpoints := make([]*Endpoint, len(ips)) for i, ip := range ips { - endpoints[i] = Endpoint{ + endpoints[i] = &Endpoint{ Protocol: a.Protocol, IP: ip, Port: a.Port, diff --git a/internal/p2p/address_test.go b/internal/p2p/address_test.go index d5f9e498e..d4c745d8d 100644 --- a/internal/p2p/address_test.go +++ b/internal/p2p/address_test.go @@ -210,71 +210,71 @@ func TestNodeAddress_Resolve(t *testing.T) { testcases := []struct { address p2p.NodeAddress - expect p2p.Endpoint + expect *p2p.Endpoint ok bool }{ // Valid networked addresses (with hostname). { p2p.NodeAddress{Protocol: "tcp", Hostname: "127.0.0.1", Port: 80, Path: "/path"}, - p2p.Endpoint{Protocol: "tcp", IP: net.IPv4(127, 0, 0, 1), Port: 80, Path: "/path"}, + &p2p.Endpoint{Protocol: "tcp", IP: net.IPv4(127, 0, 0, 1), Port: 80, Path: "/path"}, true, }, { p2p.NodeAddress{Protocol: "tcp", Hostname: "localhost", Port: 80, Path: "/path"}, - p2p.Endpoint{Protocol: "tcp", IP: net.IPv4(127, 0, 0, 1), Port: 80, Path: "/path"}, + &p2p.Endpoint{Protocol: "tcp", IP: net.IPv4(127, 0, 0, 1), Port: 80, Path: "/path"}, true, }, { p2p.NodeAddress{Protocol: "tcp", Hostname: "localhost", Port: 80, Path: "/path"}, - p2p.Endpoint{Protocol: "tcp", IP: net.IPv6loopback, Port: 80, Path: "/path"}, + &p2p.Endpoint{Protocol: "tcp", IP: net.IPv6loopback, Port: 80, Path: "/path"}, true, }, { p2p.NodeAddress{Protocol: "tcp", Hostname: "127.0.0.1"}, - p2p.Endpoint{Protocol: "tcp", IP: net.IPv4(127, 0, 0, 1)}, + &p2p.Endpoint{Protocol: "tcp", IP: net.IPv4(127, 0, 0, 1)}, true, }, { p2p.NodeAddress{Protocol: "tcp", Hostname: "::1"}, - p2p.Endpoint{Protocol: "tcp", IP: net.IPv6loopback}, + &p2p.Endpoint{Protocol: "tcp", IP: net.IPv6loopback}, true, }, { p2p.NodeAddress{Protocol: "tcp", Hostname: "8.8.8.8"}, - p2p.Endpoint{Protocol: "tcp", IP: net.IPv4(8, 8, 8, 8)}, + &p2p.Endpoint{Protocol: "tcp", IP: net.IPv4(8, 8, 8, 8)}, true, }, { p2p.NodeAddress{Protocol: "tcp", Hostname: "2001:0db8::ff00:0042:8329"}, - p2p.Endpoint{Protocol: "tcp", IP: []byte{ + &p2p.Endpoint{Protocol: "tcp", IP: []byte{ 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29}}, true, }, { p2p.NodeAddress{Protocol: "tcp", Hostname: "some.missing.host.tendermint.com"}, - p2p.Endpoint{}, + &p2p.Endpoint{}, false, }, // Valid non-networked addresses. { p2p.NodeAddress{Protocol: "memory", NodeID: id}, - p2p.Endpoint{Protocol: "memory", Path: string(id)}, + &p2p.Endpoint{Protocol: "memory", Path: string(id)}, true, }, { p2p.NodeAddress{Protocol: "memory", NodeID: id, Path: string(id)}, - p2p.Endpoint{Protocol: "memory", Path: string(id)}, + &p2p.Endpoint{Protocol: "memory", Path: string(id)}, true, }, // Invalid addresses. - {p2p.NodeAddress{}, p2p.Endpoint{}, false}, - {p2p.NodeAddress{Hostname: "127.0.0.1"}, p2p.Endpoint{}, false}, - {p2p.NodeAddress{Protocol: "tcp", Hostname: "127.0.0.1:80"}, p2p.Endpoint{}, false}, - {p2p.NodeAddress{Protocol: "memory"}, p2p.Endpoint{}, false}, - {p2p.NodeAddress{Protocol: "memory", Path: string(id)}, p2p.Endpoint{}, false}, - {p2p.NodeAddress{Protocol: "tcp", Hostname: "💥"}, p2p.Endpoint{}, false}, + {p2p.NodeAddress{}, &p2p.Endpoint{}, false}, + {p2p.NodeAddress{Hostname: "127.0.0.1"}, &p2p.Endpoint{}, false}, + {p2p.NodeAddress{Protocol: "tcp", Hostname: "127.0.0.1:80"}, &p2p.Endpoint{}, false}, + {p2p.NodeAddress{Protocol: "memory"}, &p2p.Endpoint{}, false}, + {p2p.NodeAddress{Protocol: "memory", Path: string(id)}, &p2p.Endpoint{}, false}, + {p2p.NodeAddress{Protocol: "tcp", Hostname: "💥"}, &p2p.Endpoint{}, false}, } for _, tc := range testcases { tc := tc diff --git a/internal/p2p/mocks/transport.go b/internal/p2p/mocks/transport.go index d08533186..34ebec20e 100644 --- a/internal/p2p/mocks/transport.go +++ b/internal/p2p/mocks/transport.go @@ -62,11 +62,11 @@ func (_m *Transport) Close() error { } // Dial provides a mock function with given fields: _a0, _a1 -func (_m *Transport) Dial(_a0 context.Context, _a1 p2p.Endpoint) (p2p.Connection, error) { +func (_m *Transport) Dial(_a0 context.Context, _a1 *p2p.Endpoint) (p2p.Connection, error) { ret := _m.Called(_a0, _a1) var r0 p2p.Connection - if rf, ok := ret.Get(0).(func(context.Context, p2p.Endpoint) p2p.Connection); ok { + if rf, ok := ret.Get(0).(func(context.Context, *p2p.Endpoint) p2p.Connection); ok { r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { @@ -75,7 +75,7 @@ func (_m *Transport) Dial(_a0 context.Context, _a1 p2p.Endpoint) (p2p.Connection } var r1 error - if rf, ok := ret.Get(1).(func(context.Context, p2p.Endpoint) error); ok { + if rf, ok := ret.Get(1).(func(context.Context, *p2p.Endpoint) error); ok { r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) @@ -84,28 +84,35 @@ func (_m *Transport) Dial(_a0 context.Context, _a1 p2p.Endpoint) (p2p.Connection return r0, r1 } -// Endpoints provides a mock function with given fields: -func (_m *Transport) Endpoints() []p2p.Endpoint { +// Endpoint provides a mock function with given fields: +func (_m *Transport) Endpoint() (*p2p.Endpoint, error) { ret := _m.Called() - var r0 []p2p.Endpoint - if rf, ok := ret.Get(0).(func() []p2p.Endpoint); ok { + var r0 *p2p.Endpoint + if rf, ok := ret.Get(0).(func() *p2p.Endpoint); ok { r0 = rf() } else { if ret.Get(0) != nil { - r0 = ret.Get(0).([]p2p.Endpoint) + r0 = ret.Get(0).(*p2p.Endpoint) } } - return r0 + var r1 error + if rf, ok := ret.Get(1).(func() error); ok { + r1 = rf() + } else { + r1 = ret.Error(1) + } + + return r0, r1 } // Listen provides a mock function with given fields: _a0 -func (_m *Transport) Listen(_a0 p2p.Endpoint) error { +func (_m *Transport) Listen(_a0 *p2p.Endpoint) error { ret := _m.Called(_a0) var r0 error - if rf, ok := ret.Get(0).(func(p2p.Endpoint) error); ok { + if rf, ok := ret.Get(0).(func(*p2p.Endpoint) error); ok { r0 = rf(_a0) } else { r0 = ret.Error(0) diff --git a/internal/p2p/p2ptest/network.go b/internal/p2p/p2ptest/network.go index cde14e721..73df1e47f 100644 --- a/internal/p2p/p2ptest/network.go +++ b/internal/p2p/p2ptest/network.go @@ -247,7 +247,9 @@ func (n *Network) MakeNode(ctx context.Context, t *testing.T, opts NodeOptions) } transport := n.memoryNetwork.CreateTransport(nodeID) - require.Len(t, transport.Endpoints(), 1, "transport not listening on 1 endpoint") + ep, err := transport.Endpoint() + require.NoError(t, err) + require.NotNil(t, ep, "transport not listening an endpoint") peerManager, err := p2p.NewPeerManager(nodeID, dbm.NewMemDB(), p2p.PeerManagerOptions{ MinRetryTime: 10 * time.Millisecond, @@ -264,8 +266,8 @@ func (n *Network) MakeNode(ctx context.Context, t *testing.T, opts NodeOptions) privKey, peerManager, func() *types.NodeInfo { return &nodeInfo }, - []p2p.Transport{transport}, - transport.Endpoints(), + transport, + ep, p2p.RouterOptions{DialSleep: func(_ context.Context) {}}, ) @@ -284,7 +286,7 @@ func (n *Network) MakeNode(ctx context.Context, t *testing.T, opts NodeOptions) return &Node{ NodeID: nodeID, NodeInfo: nodeInfo, - NodeAddress: transport.Endpoints()[0].NodeAddress(nodeID), + NodeAddress: ep.NodeAddress(nodeID), PrivKey: privKey, Router: router, PeerManager: peerManager, diff --git a/internal/p2p/router.go b/internal/p2p/router.go index ca9536900..830b0091c 100644 --- a/internal/p2p/router.go +++ b/internal/p2p/router.go @@ -148,15 +148,14 @@ type Router struct { *service.BaseService logger log.Logger - metrics *Metrics - options RouterOptions - privKey crypto.PrivKey - peerManager *PeerManager - chDescs []*ChannelDescriptor - transports []Transport - endpoints []Endpoint - connTracker connectionTracker - protocolTransports map[Protocol]Transport + metrics *Metrics + options RouterOptions + privKey crypto.PrivKey + peerManager *PeerManager + chDescs []*ChannelDescriptor + transport Transport + endpoint *Endpoint + connTracker connectionTracker peerMtx sync.RWMutex peerQueues map[types.NodeID]queue // outbound messages per peer for all channels @@ -182,8 +181,8 @@ func NewRouter( privKey crypto.PrivKey, peerManager *PeerManager, nodeInfoProducer func() *types.NodeInfo, - transports []Transport, - endpoints []Endpoint, + transport Transport, + endpoint *Endpoint, options RouterOptions, ) (*Router, error) { @@ -200,28 +199,19 @@ func NewRouter( options.MaxIncomingConnectionAttempts, options.IncomingConnectionWindow, ), - chDescs: make([]*ChannelDescriptor, 0), - transports: transports, - endpoints: endpoints, - protocolTransports: map[Protocol]Transport{}, - peerManager: peerManager, - options: options, - channelQueues: map[ChannelID]queue{}, - channelMessages: map[ChannelID]proto.Message{}, - peerQueues: map[types.NodeID]queue{}, - peerChannels: make(map[types.NodeID]ChannelIDSet), + chDescs: make([]*ChannelDescriptor, 0), + transport: transport, + endpoint: endpoint, + peerManager: peerManager, + options: options, + channelQueues: map[ChannelID]queue{}, + channelMessages: map[ChannelID]proto.Message{}, + peerQueues: map[types.NodeID]queue{}, + peerChannels: make(map[types.NodeID]ChannelIDSet), } router.BaseService = service.NewBaseService(logger, "router", router) - for _, transport := range transports { - for _, protocol := range transport.Protocols() { - if _, ok := router.protocolTransports[protocol]; !ok { - router.protocolTransports[protocol] = transport - } - } - } - return router, nil } @@ -286,9 +276,7 @@ func (r *Router) OpenChannel(ctx context.Context, chDesc *ChannelDescriptor) (*C // add the channel to the nodeInfo if it's not already there. r.nodeInfoProducer().AddChannel(uint16(chDesc.ID)) - for _, t := range r.transports { - t.AddChannelDescriptors([]*ChannelDescriptor{chDesc}) - } + r.transport.AddChannelDescriptors([]*ChannelDescriptor{chDesc}) go func() { defer func() { @@ -670,12 +658,6 @@ func (r *Router) dialPeer(ctx context.Context, address NodeAddress) (Connection, } for _, endpoint := range endpoints { - transport, ok := r.protocolTransports[endpoint.Protocol] - if !ok { - r.logger.Error("no transport found for protocol", "endpoint", endpoint) - continue - } - dialCtx := ctx if r.options.DialTimeout > 0 { var cancel context.CancelFunc @@ -690,7 +672,7 @@ func (r *Router) dialPeer(ctx context.Context, address NodeAddress) (Connection, // by the peer's endpoint, since e.g. a peer on 192.168.0.0 can reach us // on a private address on this endpoint, but a peer on the public // Internet can't and needs a different public address. - conn, err := transport.Dial(dialCtx, endpoint) + conn, err := r.transport.Dial(dialCtx, endpoint) if err != nil { r.logger.Error("failed to dial endpoint", "peer", address.NodeID, "endpoint", endpoint, "err", err) } else { @@ -950,12 +932,8 @@ func (r *Router) OnStart(ctx context.Context) error { return err } - for _, transport := range r.transports { - for _, endpoint := range r.endpoints { - if err := transport.Listen(endpoint); err != nil { - return err - } - } + if err := r.transport.Listen(r.endpoint); err != nil { + return err } nodeInfo := r.nodeInfoProducer() @@ -964,15 +942,11 @@ func (r *Router) OnStart(ctx context.Context) error { "node_id", nodeInfo.NodeID, "channels", nodeInfo.Channels, "listen_addr", nodeInfo.ListenAddr, - "transports", len(r.transports), ) go r.dialPeers(ctx) go r.evictPeers(ctx) - - for _, transport := range r.transports { - go r.acceptPeers(ctx, transport) - } + go r.acceptPeers(ctx, r.transport) return nil } @@ -985,10 +959,8 @@ func (r *Router) OnStart(ctx context.Context) error { // sender's responsibility. func (r *Router) OnStop() { // Close transport listeners (unblocks Accept calls). - for _, transport := range r.transports { - if err := transport.Close(); err != nil { - r.logger.Error("failed to close transport", "transport", transport, "err", err) - } + if err := r.transport.Close(); err != nil { + r.logger.Error("failed to close transport", "err", err) } // Collect all remaining queues, and wait for them to close. diff --git a/internal/p2p/router_test.go b/internal/p2p/router_test.go index 7ef77a16d..f578446e3 100644 --- a/internal/p2p/router_test.go +++ b/internal/p2p/router_test.go @@ -105,14 +105,16 @@ func TestRouter_Channel_Basic(t *testing.T) { peerManager, err := p2p.NewPeerManager(selfID, dbm.NewMemDB(), p2p.PeerManagerOptions{}) require.NoError(t, err) + testnet := p2ptest.MakeNetwork(ctx, t, p2ptest.NetworkOptions{NumNodes: 1}) + router, err := p2p.NewRouter( log.NewNopLogger(), p2p.NopMetrics(), selfKey, peerManager, func() *types.NodeInfo { return &selfInfo }, - nil, - nil, + testnet.RandomNode().Transport, + &p2p.Endpoint{}, p2p.RouterOptions{}, ) require.NoError(t, err) @@ -396,10 +398,10 @@ func TestRouter_AcceptPeers(t *testing.T) { mockTransport := &mocks.Transport{} mockTransport.On("String").Maybe().Return("mock") - mockTransport.On("Protocols").Return([]p2p.Protocol{"mock"}) mockTransport.On("Close").Return(nil).Maybe() mockTransport.On("Accept", mock.Anything).Once().Return(mockConnection, nil) mockTransport.On("Accept", mock.Anything).Maybe().Return(nil, io.EOF) + mockTransport.On("Listen", mock.Anything).Return(nil) // Set up and start the router. peerManager, err := p2p.NewPeerManager(selfID, dbm.NewMemDB(), p2p.PeerManagerOptions{}) @@ -413,7 +415,7 @@ func TestRouter_AcceptPeers(t *testing.T) { selfKey, peerManager, func() *types.NodeInfo { return &selfInfo }, - []p2p.Transport{mockTransport}, + mockTransport, nil, p2p.RouterOptions{}, ) @@ -453,9 +455,9 @@ func TestRouter_AcceptPeers_Error(t *testing.T) { // the router from calling Accept again. mockTransport := &mocks.Transport{} mockTransport.On("String").Maybe().Return("mock") - mockTransport.On("Protocols").Return([]p2p.Protocol{"mock"}) mockTransport.On("Accept", mock.Anything).Once().Return(nil, errors.New("boom")) mockTransport.On("Close").Return(nil) + mockTransport.On("Listen", mock.Anything).Return(nil) // Set up and start the router. peerManager, err := p2p.NewPeerManager(selfID, dbm.NewMemDB(), p2p.PeerManagerOptions{}) @@ -467,7 +469,7 @@ func TestRouter_AcceptPeers_Error(t *testing.T) { selfKey, peerManager, func() *types.NodeInfo { return &selfInfo }, - []p2p.Transport{mockTransport}, + mockTransport, nil, p2p.RouterOptions{}, ) @@ -490,9 +492,9 @@ func TestRouter_AcceptPeers_ErrorEOF(t *testing.T) { // the router from calling Accept again. mockTransport := &mocks.Transport{} mockTransport.On("String").Maybe().Return("mock") - mockTransport.On("Protocols").Return([]p2p.Protocol{"mock"}) mockTransport.On("Accept", mock.Anything).Once().Return(nil, io.EOF) mockTransport.On("Close").Return(nil) + mockTransport.On("Listen", mock.Anything).Return(nil) // Set up and start the router. peerManager, err := p2p.NewPeerManager(selfID, dbm.NewMemDB(), p2p.PeerManagerOptions{}) @@ -504,7 +506,7 @@ func TestRouter_AcceptPeers_ErrorEOF(t *testing.T) { selfKey, peerManager, func() *types.NodeInfo { return &selfInfo }, - []p2p.Transport{mockTransport}, + mockTransport, nil, p2p.RouterOptions{}, ) @@ -538,12 +540,12 @@ func TestRouter_AcceptPeers_HeadOfLineBlocking(t *testing.T) { mockTransport := &mocks.Transport{} mockTransport.On("String").Maybe().Return("mock") - mockTransport.On("Protocols").Return([]p2p.Protocol{"mock"}) mockTransport.On("Close").Return(nil) mockTransport.On("Accept", mock.Anything).Times(3).Run(func(_ mock.Arguments) { acceptCh <- true }).Return(mockConnection, nil) mockTransport.On("Accept", mock.Anything).Once().Return(nil, io.EOF) + mockTransport.On("Listen", mock.Anything).Return(nil) // Set up and start the router. peerManager, err := p2p.NewPeerManager(selfID, dbm.NewMemDB(), p2p.PeerManagerOptions{}) @@ -555,7 +557,7 @@ func TestRouter_AcceptPeers_HeadOfLineBlocking(t *testing.T) { selfKey, peerManager, func() *types.NodeInfo { return &selfInfo }, - []p2p.Transport{mockTransport}, + mockTransport, nil, p2p.RouterOptions{}, ) @@ -611,7 +613,7 @@ func TestRouter_DialPeers(t *testing.T) { defer cancel() address := p2p.NodeAddress{Protocol: "mock", NodeID: tc.dialID} - endpoint := p2p.Endpoint{Protocol: "mock", Path: string(tc.dialID)} + endpoint := &p2p.Endpoint{Protocol: "mock", Path: string(tc.dialID)} // Set up a mock transport that handshakes. connCtx, connCancel := context.WithCancel(context.Background()) @@ -629,8 +631,8 @@ func TestRouter_DialPeers(t *testing.T) { mockTransport := &mocks.Transport{} mockTransport.On("String").Maybe().Return("mock") - mockTransport.On("Protocols").Return([]p2p.Protocol{"mock"}) mockTransport.On("Close").Return(nil).Maybe() + mockTransport.On("Listen", mock.Anything).Return(nil) mockTransport.On("Accept", mock.Anything).Maybe().Return(nil, io.EOF) if tc.dialErr == nil { mockTransport.On("Dial", mock.Anything, endpoint).Once().Return(mockConnection, nil) @@ -658,7 +660,7 @@ func TestRouter_DialPeers(t *testing.T) { selfKey, peerManager, func() *types.NodeInfo { return &selfInfo }, - []p2p.Transport{mockTransport}, + mockTransport, nil, p2p.RouterOptions{}, ) @@ -711,11 +713,11 @@ func TestRouter_DialPeers_Parallel(t *testing.T) { mockTransport := &mocks.Transport{} mockTransport.On("String").Maybe().Return("mock") - mockTransport.On("Protocols").Return([]p2p.Protocol{"mock"}) mockTransport.On("Close").Return(nil) + mockTransport.On("Listen", mock.Anything).Return(nil) mockTransport.On("Accept", mock.Anything).Once().Return(nil, io.EOF) for _, address := range []p2p.NodeAddress{a, b, c} { - endpoint := p2p.Endpoint{Protocol: address.Protocol, Path: string(address.NodeID)} + endpoint := &p2p.Endpoint{Protocol: address.Protocol, Path: string(address.NodeID)} mockTransport.On("Dial", mock.Anything, endpoint).Run(func(_ mock.Arguments) { dialCh <- true }).Return(mockConnection, nil) @@ -743,7 +745,7 @@ func TestRouter_DialPeers_Parallel(t *testing.T) { selfKey, peerManager, func() *types.NodeInfo { return &selfInfo }, - []p2p.Transport{mockTransport}, + mockTransport, nil, p2p.RouterOptions{ DialSleep: func(_ context.Context) {}, @@ -800,10 +802,10 @@ func TestRouter_EvictPeers(t *testing.T) { mockTransport := &mocks.Transport{} mockTransport.On("String").Maybe().Return("mock") - mockTransport.On("Protocols").Return([]p2p.Protocol{"mock"}) mockTransport.On("Close").Return(nil) mockTransport.On("Accept", mock.Anything).Once().Return(mockConnection, nil) mockTransport.On("Accept", mock.Anything).Maybe().Return(nil, io.EOF) + mockTransport.On("Listen", mock.Anything).Return(nil) // Set up and start the router. peerManager, err := p2p.NewPeerManager(selfID, dbm.NewMemDB(), p2p.PeerManagerOptions{}) @@ -817,7 +819,7 @@ func TestRouter_EvictPeers(t *testing.T) { selfKey, peerManager, func() *types.NodeInfo { return &selfInfo }, - []p2p.Transport{mockTransport}, + mockTransport, nil, p2p.RouterOptions{}, ) @@ -864,10 +866,10 @@ func TestRouter_ChannelCompatability(t *testing.T) { mockTransport := &mocks.Transport{} mockTransport.On("String").Maybe().Return("mock") - mockTransport.On("Protocols").Return([]p2p.Protocol{"mock"}) mockTransport.On("Close").Return(nil) mockTransport.On("Accept", mock.Anything).Once().Return(mockConnection, nil) mockTransport.On("Accept", mock.Anything).Once().Return(nil, io.EOF) + mockTransport.On("Listen", mock.Anything).Return(nil) // Set up and start the router. peerManager, err := p2p.NewPeerManager(selfID, dbm.NewMemDB(), p2p.PeerManagerOptions{}) @@ -879,7 +881,7 @@ func TestRouter_ChannelCompatability(t *testing.T) { selfKey, peerManager, func() *types.NodeInfo { return &selfInfo }, - []p2p.Transport{mockTransport}, + mockTransport, nil, p2p.RouterOptions{}, ) @@ -917,10 +919,10 @@ func TestRouter_DontSendOnInvalidChannel(t *testing.T) { mockTransport := &mocks.Transport{} mockTransport.On("AddChannelDescriptors", mock.Anything).Return() mockTransport.On("String").Maybe().Return("mock") - mockTransport.On("Protocols").Return([]p2p.Protocol{"mock"}) mockTransport.On("Close").Return(nil) mockTransport.On("Accept", mock.Anything).Once().Return(mockConnection, nil) mockTransport.On("Accept", mock.Anything).Maybe().Return(nil, io.EOF) + mockTransport.On("Listen", mock.Anything).Return(nil) // Set up and start the router. peerManager, err := p2p.NewPeerManager(selfID, dbm.NewMemDB(), p2p.PeerManagerOptions{}) @@ -934,7 +936,7 @@ func TestRouter_DontSendOnInvalidChannel(t *testing.T) { selfKey, peerManager, func() *types.NodeInfo { return &selfInfo }, - []p2p.Transport{mockTransport}, + mockTransport, nil, p2p.RouterOptions{}, ) diff --git a/internal/p2p/transport.go b/internal/p2p/transport.go index 041bbda3a..7a965260a 100644 --- a/internal/p2p/transport.go +++ b/internal/p2p/transport.go @@ -24,7 +24,7 @@ type Protocol string // Transport is a connection-oriented mechanism for exchanging data with a peer. type Transport interface { // Listen starts the transport on the specified endpoint. - Listen(Endpoint) error + Listen(*Endpoint) error // Protocols returns the protocols supported by the transport. The Router // uses this to pick a transport for an Endpoint. @@ -34,7 +34,7 @@ type Transport interface { // // How to listen is transport-dependent, e.g. MConnTransport uses Listen() while // MemoryTransport starts listening via MemoryNetwork.CreateTransport(). - Endpoints() []Endpoint + Endpoint() (*Endpoint, error) // Accept waits for the next inbound connection on a listening endpoint, blocking // until either a connection is available or the transport is closed. On closure, @@ -42,7 +42,7 @@ type Transport interface { Accept(context.Context) (Connection, error) // Dial creates an outbound connection to an endpoint. - Dial(context.Context, Endpoint) (Connection, error) + Dial(context.Context, *Endpoint) (Connection, error) // Close stops accepting new connections, but does not close active connections. Close() error @@ -129,13 +129,13 @@ type Endpoint struct { } // NewEndpoint constructs an Endpoint from a types.NetAddress structure. -func NewEndpoint(addr string) (Endpoint, error) { +func NewEndpoint(addr string) (*Endpoint, error) { ip, port, err := types.ParseAddressString(addr) if err != nil { - return Endpoint{}, err + return nil, err } - return Endpoint{ + return &Endpoint{ Protocol: MConnProtocol, IP: ip, Port: port, diff --git a/internal/p2p/transport_mconn.go b/internal/p2p/transport_mconn.go index 6e6728f11..7bf17d1a0 100644 --- a/internal/p2p/transport_mconn.go +++ b/internal/p2p/transport_mconn.go @@ -78,25 +78,25 @@ func (m *MConnTransport) Protocols() []Protocol { return []Protocol{MConnProtocol, TCPProtocol} } -// Endpoints implements Transport. -func (m *MConnTransport) Endpoints() []Endpoint { +// Endpoint implements Transport. +func (m *MConnTransport) Endpoint() (*Endpoint, error) { if m.listener == nil { - return []Endpoint{} + return nil, errors.New("listenter not defined") } select { case <-m.doneCh: - return []Endpoint{} + return nil, errors.New("transport closed") default: } - endpoint := Endpoint{ + endpoint := &Endpoint{ Protocol: MConnProtocol, } if addr, ok := m.listener.Addr().(*net.TCPAddr); ok { endpoint.IP = addr.IP endpoint.Port = uint16(addr.Port) } - return []Endpoint{endpoint} + return endpoint, nil } // Listen asynchronously listens for inbound connections on the given endpoint. @@ -106,7 +106,7 @@ func (m *MConnTransport) Endpoints() []Endpoint { // FIXME: Listen currently only supports listening on a single endpoint, it // might be useful to support listening on multiple addresses (e.g. IPv4 and // IPv6, or a private and public address) via multiple Listen() calls. -func (m *MConnTransport) Listen(endpoint Endpoint) error { +func (m *MConnTransport) Listen(endpoint *Endpoint) error { if m.listener != nil { return errors.New("transport is already listening") } @@ -170,7 +170,7 @@ func (m *MConnTransport) Accept(ctx context.Context) (Connection, error) { } // Dial implements Transport. -func (m *MConnTransport) Dial(ctx context.Context, endpoint Endpoint) (Connection, error) { +func (m *MConnTransport) Dial(ctx context.Context, endpoint *Endpoint) (Connection, error) { if err := m.validateEndpoint(endpoint); err != nil { return nil, err } @@ -217,7 +217,7 @@ func (m *MConnTransport) AddChannelDescriptors(channelDesc []*ChannelDescriptor) } // validateEndpoint validates an endpoint. -func (m *MConnTransport) validateEndpoint(endpoint Endpoint) error { +func (m *MConnTransport) validateEndpoint(endpoint *Endpoint) error { if err := endpoint.Validate(); err != nil { return err } diff --git a/internal/p2p/transport_mconn_test.go b/internal/p2p/transport_mconn_test.go index 423f4e930..c478dbe1d 100644 --- a/internal/p2p/transport_mconn_test.go +++ b/internal/p2p/transport_mconn_test.go @@ -25,7 +25,7 @@ func init() { []*p2p.ChannelDescriptor{{ID: chID, Priority: 1}}, p2p.MConnTransportOptions{}, ) - err := transport.Listen(p2p.Endpoint{ + err := transport.Listen(&p2p.Endpoint{ Protocol: p2p.MConnProtocol, IP: net.IPv4(127, 0, 0, 1), Port: 0, // assign a random port @@ -73,13 +73,14 @@ func TestMConnTransport_AcceptMaxAcceptedConnections(t *testing.T) { t.Cleanup(func() { _ = transport.Close() }) - err := transport.Listen(p2p.Endpoint{ + err := transport.Listen(&p2p.Endpoint{ Protocol: p2p.MConnProtocol, IP: net.IPv4(127, 0, 0, 1), }) require.NoError(t, err) - require.NotEmpty(t, transport.Endpoints()) - endpoint := transport.Endpoints()[0] + endpoint, err := transport.Endpoint() + require.NoError(t, err) + require.NotNil(t, endpoint) // Start a goroutine to just accept any connections. acceptCh := make(chan p2p.Connection, 10) @@ -132,20 +133,20 @@ func TestMConnTransport_Listen(t *testing.T) { defer cancel() testcases := []struct { - endpoint p2p.Endpoint + endpoint *p2p.Endpoint ok bool }{ // Valid v4 and v6 addresses, with mconn and tcp protocols. - {p2p.Endpoint{Protocol: p2p.MConnProtocol, IP: net.IPv4zero}, true}, - {p2p.Endpoint{Protocol: p2p.MConnProtocol, IP: net.IPv4(127, 0, 0, 1)}, true}, - {p2p.Endpoint{Protocol: p2p.MConnProtocol, IP: net.IPv6zero}, true}, - {p2p.Endpoint{Protocol: p2p.MConnProtocol, IP: net.IPv6loopback}, true}, - {p2p.Endpoint{Protocol: p2p.TCPProtocol, IP: net.IPv4zero}, true}, + {&p2p.Endpoint{Protocol: p2p.MConnProtocol, IP: net.IPv4zero}, true}, + {&p2p.Endpoint{Protocol: p2p.MConnProtocol, IP: net.IPv4(127, 0, 0, 1)}, true}, + {&p2p.Endpoint{Protocol: p2p.MConnProtocol, IP: net.IPv6zero}, true}, + {&p2p.Endpoint{Protocol: p2p.MConnProtocol, IP: net.IPv6loopback}, true}, + {&p2p.Endpoint{Protocol: p2p.TCPProtocol, IP: net.IPv4zero}, true}, // Invalid endpoints. - {p2p.Endpoint{}, false}, - {p2p.Endpoint{Protocol: p2p.MConnProtocol, Path: "foo"}, false}, - {p2p.Endpoint{Protocol: p2p.MConnProtocol, IP: net.IPv4zero, Path: "foo"}, false}, + {&p2p.Endpoint{}, false}, + {&p2p.Endpoint{Protocol: p2p.MConnProtocol, Path: "foo"}, false}, + {&p2p.Endpoint{Protocol: p2p.MConnProtocol, IP: net.IPv4zero, Path: "foo"}, false}, } for _, tc := range testcases { tc := tc @@ -160,10 +161,12 @@ func TestMConnTransport_Listen(t *testing.T) { ) // Transport should not listen on any endpoints yet. - require.Empty(t, transport.Endpoints()) + endpoint, err := transport.Endpoint() + require.Error(t, err) + require.Nil(t, endpoint) // Start listening, and check any expected errors. - err := transport.Listen(tc.endpoint) + err = transport.Listen(tc.endpoint) if !tc.ok { require.Error(t, err) return @@ -171,9 +174,9 @@ func TestMConnTransport_Listen(t *testing.T) { require.NoError(t, err) // Check the endpoint. - endpoints := transport.Endpoints() - require.Len(t, endpoints, 1) - endpoint := endpoints[0] + endpoint, err = transport.Endpoint() + require.NoError(t, err) + require.NotNil(t, endpoint) require.Equal(t, p2p.MConnProtocol, endpoint.Protocol) if tc.endpoint.IP.IsUnspecified() { diff --git a/internal/p2p/transport_memory.go b/internal/p2p/transport_memory.go index 528ce4bb6..3eb4c5b51 100644 --- a/internal/p2p/transport_memory.go +++ b/internal/p2p/transport_memory.go @@ -119,7 +119,7 @@ func (t *MemoryTransport) String() string { return string(MemoryProtocol) } -func (*MemoryTransport) Listen(Endpoint) error { return nil } +func (*MemoryTransport) Listen(*Endpoint) error { return nil } func (t *MemoryTransport) AddChannelDescriptors([]*ChannelDescriptor) {} @@ -129,19 +129,19 @@ func (t *MemoryTransport) Protocols() []Protocol { } // Endpoints implements Transport. -func (t *MemoryTransport) Endpoints() []Endpoint { +func (t *MemoryTransport) Endpoint() (*Endpoint, error) { if n := t.network.GetTransport(t.nodeID); n == nil { - return []Endpoint{} + return nil, errors.New("node not defined") } - return []Endpoint{{ + return &Endpoint{ Protocol: MemoryProtocol, Path: string(t.nodeID), // An arbitrary IP and port is used in order for the pex // reactor to be able to send addresses to one another. IP: net.IPv4zero, Port: 0, - }} + }, nil } // Accept implements Transport. @@ -158,7 +158,7 @@ func (t *MemoryTransport) Accept(ctx context.Context) (Connection, error) { } // Dial implements Transport. -func (t *MemoryTransport) Dial(ctx context.Context, endpoint Endpoint) (Connection, error) { +func (t *MemoryTransport) Dial(ctx context.Context, endpoint *Endpoint) (Connection, error) { if endpoint.Protocol != MemoryProtocol { return nil, fmt.Errorf("invalid protocol %q", endpoint.Protocol) } diff --git a/internal/p2p/transport_test.go b/internal/p2p/transport_test.go index 8f4f90483..b4edf9bc9 100644 --- a/internal/p2p/transport_test.go +++ b/internal/p2p/transport_test.go @@ -87,9 +87,9 @@ func TestTransport_DialEndpoints(t *testing.T) { withTransports(ctx, t, func(ctx context.Context, t *testing.T, makeTransport transportFactory) { a := makeTransport(t) - endpoints := a.Endpoints() - require.NotEmpty(t, endpoints) - endpoint := endpoints[0] + endpoint, err := a.Endpoint() + require.NoError(t, err) + require.NotNil(t, endpoint) // Spawn a goroutine to simply accept any connections until closed. go func() { @@ -108,19 +108,19 @@ func TestTransport_DialEndpoints(t *testing.T) { require.NoError(t, conn.Close()) // Dialing empty endpoint should error. - _, err = a.Dial(ctx, p2p.Endpoint{}) + _, err = a.Dial(ctx, &p2p.Endpoint{}) require.Error(t, err) // Dialing without protocol should error. - noProtocol := endpoint + noProtocol := *endpoint noProtocol.Protocol = "" - _, err = a.Dial(ctx, noProtocol) + _, err = a.Dial(ctx, &noProtocol) require.Error(t, err) // Dialing with invalid protocol should error. - fooProtocol := endpoint + fooProtocol := *endpoint fooProtocol.Protocol = "foo" - _, err = a.Dial(ctx, fooProtocol) + _, err = a.Dial(ctx, &fooProtocol) require.Error(t, err) // Tests for networked endpoints (with IP). @@ -129,11 +129,12 @@ func TestTransport_DialEndpoints(t *testing.T) { tc := tc t.Run(tc.ip.String(), func(t *testing.T) { e := endpoint + require.NotNil(t, e) e.IP = tc.ip conn, err := a.Dial(ctx, e) if tc.ok { - require.NoError(t, conn.Close()) require.NoError(t, err) + require.NoError(t, conn.Close()) } else { require.Error(t, err, "endpoint=%s", e) } @@ -167,16 +168,18 @@ func TestTransport_Dial(t *testing.T) { a := makeTransport(t) b := makeTransport(t) - require.NotEmpty(t, a.Endpoints()) - require.NotEmpty(t, b.Endpoints()) - aEndpoint := a.Endpoints()[0] - bEndpoint := b.Endpoints()[0] + aEndpoint, err := a.Endpoint() + require.NoError(t, err) + require.NotNil(t, aEndpoint) + bEndpoint, err := b.Endpoint() + require.NoError(t, err) + require.NotNil(t, bEndpoint) // Context cancellation should error. We can't test timeouts since we'd // need a non-responsive endpoint. cancelCtx, cancel := context.WithCancel(ctx) cancel() - _, err := a.Dial(cancelCtx, bEndpoint) + _, err = a.Dial(cancelCtx, bEndpoint) require.Error(t, err) // Unavailable endpoint should error. @@ -210,21 +213,26 @@ func TestTransport_Endpoints(t *testing.T) { b := makeTransport(t) // Both transports return valid and different endpoints. - aEndpoints := a.Endpoints() - bEndpoints := b.Endpoints() - require.NotEmpty(t, aEndpoints) - require.NotEmpty(t, bEndpoints) - require.NotEqual(t, aEndpoints, bEndpoints) - for _, endpoint := range append(aEndpoints, bEndpoints...) { + aEndpoint, err := a.Endpoint() + require.NoError(t, err) + require.NotNil(t, aEndpoint) + bEndpoint, err := b.Endpoint() + require.NoError(t, err) + require.NotNil(t, bEndpoint) + require.NotEqual(t, aEndpoint, bEndpoint) + for _, endpoint := range []*p2p.Endpoint{aEndpoint, bEndpoint} { err := endpoint.Validate() require.NoError(t, err, "invalid endpoint %q", endpoint) } // When closed, the transport should no longer return any endpoints. - err := a.Close() + require.NoError(t, a.Close()) + aEndpoint, err = a.Endpoint() + require.Error(t, err) + require.Nil(t, aEndpoint) + bEndpoint, err = b.Endpoint() require.NoError(t, err) - require.Empty(t, a.Endpoints()) - require.NotEmpty(t, b.Endpoints()) + require.NotNil(t, bEndpoint) }) } @@ -235,13 +243,12 @@ func TestTransport_Protocols(t *testing.T) { withTransports(ctx, t, func(ctx context.Context, t *testing.T, makeTransport transportFactory) { a := makeTransport(t) protocols := a.Protocols() - endpoints := a.Endpoints() + endpoint, err := a.Endpoint() + require.NoError(t, err) require.NotEmpty(t, protocols) - require.NotEmpty(t, endpoints) + require.NotNil(t, endpoint) - for _, endpoint := range endpoints { - require.Contains(t, protocols, endpoint.Protocol) - } + require.Contains(t, protocols, endpoint.Protocol) }) } @@ -595,8 +602,9 @@ func TestEndpoint_Validate(t *testing.T) { func dialAccept(ctx context.Context, t *testing.T, a, b p2p.Transport) (p2p.Connection, p2p.Connection) { t.Helper() - endpoints := b.Endpoints() - require.NotEmpty(t, endpoints, "peer not listening on any endpoints") + endpoint, err := b.Endpoint() + require.NoError(t, err) + require.NotNil(t, endpoint, "peer not listening on any endpoints") ctx, cancel := context.WithTimeout(ctx, time.Second) defer cancel() @@ -609,7 +617,7 @@ func dialAccept(ctx context.Context, t *testing.T, a, b p2p.Transport) (p2p.Conn acceptCh <- conn }() - dialConn, err := a.Dial(ctx, endpoints[0]) + dialConn, err := a.Dial(ctx, endpoint) require.NoError(t, err) acceptConn := <-acceptCh diff --git a/node/setup.go b/node/setup.go index 512b02901..d6966800a 100644 --- a/node/setup.go +++ b/node/setup.go @@ -310,8 +310,8 @@ func createRouter( nodeKey.PrivKey, peerManager, nodeInfoProducer, - []p2p.Transport{transport}, - []p2p.Endpoint{ep}, + transport, + ep, getRouterConfig(cfg, appClient), ) } From 1121698757e86f4e21ac81b5eb19e64439a6f39d Mon Sep 17 00:00:00 2001 From: Sam Kleinman Date: Wed, 27 Apr 2022 15:55:27 -0400 Subject: [PATCH 24/35] node: start rpc service after reactors (#8426) --- node/node.go | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/node/node.go b/node/node.go index 5c63a3253..56379d2e2 100644 --- a/node/node.go +++ b/node/node.go @@ -488,17 +488,6 @@ func (n *nodeImpl) OnStart(ctx context.Context) error { return err } - n.rpcEnv.NodeInfo = n.nodeInfo - // Start the RPC server before the P2P server - // so we can eg. receive txs for the first block - if n.config.RPC.ListenAddress != "" { - var err error - n.rpcListeners, err = n.rpcEnv.StartService(ctx, n.config) - if err != nil { - return err - } - } - if n.config.Instrumentation.Prometheus && n.config.Instrumentation.PrometheusListenAddr != "" { n.prometheusSrv = n.startPrometheusServer(ctx, n.config.Instrumentation.PrometheusListenAddr) } @@ -515,12 +504,31 @@ func (n *nodeImpl) OnStart(ctx context.Context) error { } } + n.rpcEnv.NodeInfo = n.nodeInfo + // Start the RPC server before the P2P server + // so we can eg. receive txs for the first block + if n.config.RPC.ListenAddress != "" { + var err error + n.rpcListeners, err = n.rpcEnv.StartService(ctx, n.config) + if err != nil { + return err + } + } + return nil } // OnStop stops the Node. It implements service.Service. func (n *nodeImpl) OnStop() { n.logger.Info("Stopping Node") + // stop the listeners / external services first + for _, l := range n.rpcListeners { + n.logger.Info("Closing rpc listener", "listener", l) + if err := l.Close(); err != nil { + n.logger.Error("error closing listener", "listener", l, "err", err) + } + } + for _, es := range n.eventSinks { if err := es.Stop(); err != nil { n.logger.Error("failed to stop event sink", "err", err) @@ -534,14 +542,6 @@ func (n *nodeImpl) OnStop() { n.router.Wait() n.rpcEnv.IsListening = false - // finally stop the listeners / external services - for _, l := range n.rpcListeners { - n.logger.Info("Closing rpc listener", "listener", l) - if err := l.Close(); err != nil { - n.logger.Error("error closing listener", "listener", l, "err", err) - } - } - if pvsc, ok := n.privValidator.(service.Service); ok { pvsc.Wait() } From 2a58ea3ab2a30483ccc9fcce7b4d3e6d12b09b64 Mon Sep 17 00:00:00 2001 From: Sam Kleinman Date: Wed, 27 Apr 2022 17:13:38 -0400 Subject: [PATCH 25/35] p2p: use nodeinfo less often (#8427) --- internal/p2p/p2ptest/network.go | 1 - internal/p2p/router.go | 15 +-------------- internal/p2p/router_test.go | 3 --- 3 files changed, 1 insertion(+), 18 deletions(-) diff --git a/internal/p2p/p2ptest/network.go b/internal/p2p/p2ptest/network.go index 73df1e47f..85df029d8 100644 --- a/internal/p2p/p2ptest/network.go +++ b/internal/p2p/p2ptest/network.go @@ -306,7 +306,6 @@ func (n *Node) MakeChannel( ctx, cancel := context.WithCancel(ctx) channel, err := n.Router.OpenChannel(ctx, chDesc) require.NoError(t, err) - require.Contains(t, n.Router.NodeInfo().Channels, byte(chDesc.ID)) t.Cleanup(func() { RequireEmpty(ctx, t, channel) cancel() diff --git a/internal/p2p/router.go b/internal/p2p/router.go index 830b0091c..df096dbb6 100644 --- a/internal/p2p/router.go +++ b/internal/p2p/router.go @@ -713,7 +713,7 @@ func (r *Router) handshakePeer( return peerInfo, fmt.Errorf("expected to connect with peer %q, got %q", expectID, peerInfo.NodeID) } - if err := r.nodeInfoProducer().CompatibleWith(peerInfo); err != nil { + if err := nodeInfo.CompatibleWith(peerInfo); err != nil { return peerInfo, ErrRejected{ err: err, id: peerInfo.ID(), @@ -911,11 +911,6 @@ func (r *Router) evictPeers(ctx context.Context) { } } -// NodeInfo returns a copy of the current NodeInfo. Used for testing. -func (r *Router) NodeInfo() types.NodeInfo { - return r.nodeInfoProducer().Copy() -} - func (r *Router) setupQueueFactory(ctx context.Context) error { qf, err := r.createQueueFactory(ctx) if err != nil { @@ -936,14 +931,6 @@ func (r *Router) OnStart(ctx context.Context) error { return err } - nodeInfo := r.nodeInfoProducer() - r.logger.Info( - "starting router", - "node_id", nodeInfo.NodeID, - "channels", nodeInfo.Channels, - "listen_addr", nodeInfo.ListenAddr, - ) - go r.dialPeers(ctx) go r.evictPeers(ctx) go r.acceptPeers(ctx, r.transport) diff --git a/internal/p2p/router_test.go b/internal/p2p/router_test.go index f578446e3..663e6b81c 100644 --- a/internal/p2p/router_test.go +++ b/internal/p2p/router_test.go @@ -128,7 +128,6 @@ func TestRouter_Channel_Basic(t *testing.T) { channel, err := router.OpenChannel(chctx, chDesc) require.NoError(t, err) - require.Contains(t, router.NodeInfo().Channels, byte(chDesc.ID)) require.NotNil(t, channel) // Opening the same channel again should fail. @@ -138,9 +137,7 @@ func TestRouter_Channel_Basic(t *testing.T) { // Opening a different channel should work. chDesc2 := &p2p.ChannelDescriptor{ID: 2, MessageType: &p2ptest.Message{}} _, err = router.OpenChannel(ctx, chDesc2) - require.NoError(t, err) - require.Contains(t, router.NodeInfo().Channels, byte(chDesc2.ID)) // Closing the channel, then opening it again should be fine. chcancel() From 47d52fc78d6b905785c707fd551f14b54b176686 Mon Sep 17 00:00:00 2001 From: "M. J. Fromberger" Date: Thu, 28 Apr 2022 06:44:56 -0700 Subject: [PATCH 26/35] Use patched link-checker for periodic checks. (#8430) In #8339 we pointed the markdown link checker action to a patched version that has the up-to-date version of the underlying check tool. In doing so, I missed the periodic cron job that runs the same workflow. Update it to use the patched version also. --- .github/workflows/linkchecker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/linkchecker.yml b/.github/workflows/linkchecker.yml index d143fd905..e2ba80861 100644 --- a/.github/workflows/linkchecker.yml +++ b/.github/workflows/linkchecker.yml @@ -7,6 +7,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - uses: gaurav-nelson/github-action-markdown-link-check@1.0.14 + - uses: creachadair/github-action-markdown-link-check@master with: folder-path: "docs" From d69bd64702f9963e2b8106a307fb698062032d81 Mon Sep 17 00:00:00 2001 From: Thane Thomson Date: Thu, 28 Apr 2022 13:53:44 -0400 Subject: [PATCH 27/35] abci++: Vote extension cleanup (#8402) * Split vote verification/validation based on vote extensions Some parts of the code need vote extensions to be verified and validated (mostly in consensus), and other parts of the code don't because its possible that, in some cases (as per RFC 017), we won't have vote extensions. This explicitly facilitates that split. Signed-off-by: Thane Thomson * Only sign extensions in precommits, not prevotes Signed-off-by: Thane Thomson * Update privval/file.go Co-authored-by: M. J. Fromberger * Apply suggestions from code review Co-authored-by: M. J. Fromberger * Temporarily disable extension requirement again for E2E testing Signed-off-by: Thane Thomson * Reorganize comment for clarity Signed-off-by: Thane Thomson * Leave vote validation and pre-call nil check up to caller of VoteToProto Signed-off-by: Thane Thomson * Split complex vote validation test into multiple tests Signed-off-by: Thane Thomson * Universally enforce no vote extensions on any vote type but precommits Signed-off-by: Thane Thomson * Make error messages more generic Signed-off-by: Thane Thomson * Verify with vote extensions when constructing a VoteSet Signed-off-by: Thane Thomson * Expand comment for clarity Signed-off-by: Thane Thomson * Add extension check for prevotes prior to signing votes Signed-off-by: Thane Thomson * Fix supporting test code to only inject extensions into precommits Signed-off-by: Thane Thomson * Separate vote malleation from signing in vote tests for clarity Signed-off-by: Thane Thomson * Add extension signature length check and corresponding test Signed-off-by: Thane Thomson * Perform basic vote validation in CommitToVoteSet Signed-off-by: Thane Thomson Co-authored-by: M. J. Fromberger --- internal/consensus/common_test.go | 6 +- internal/consensus/msgs.go | 10 +- internal/test/factory/vote.go | 1 + privval/file.go | 22 ++-- types/block.go | 6 +- types/evidence.go | 26 +++-- types/priv_validator.go | 13 ++- types/vote.go | 130 ++++++++++++++++-------- types/vote_set.go | 2 +- types/vote_test.go | 162 +++++++++++++++++++++++------- 10 files changed, 278 insertions(+), 100 deletions(-) diff --git a/internal/consensus/common_test.go b/internal/consensus/common_test.go index 515a74d1a..ca1db8425 100644 --- a/internal/consensus/common_test.go +++ b/internal/consensus/common_test.go @@ -159,7 +159,11 @@ func signVote( chainID string, blockID types.BlockID) *types.Vote { - v, err := vs.signVote(ctx, voteType, chainID, blockID, []byte("extension")) + var ext []byte + if voteType == tmproto.PrecommitType { + ext = []byte("extension") + } + v, err := vs.signVote(ctx, voteType, chainID, blockID, ext) require.NoError(t, err, "failed to sign vote") vs.lastVote = v diff --git a/internal/consensus/msgs.go b/internal/consensus/msgs.go index 8b19db423..c59c06a41 100644 --- a/internal/consensus/msgs.go +++ b/internal/consensus/msgs.go @@ -220,9 +220,13 @@ type VoteMessage struct { func (*VoteMessage) TypeTag() string { return "tendermint/Vote" } -// ValidateBasic performs basic validation. +// ValidateBasic checks whether the vote within the message is well-formed. func (m *VoteMessage) ValidateBasic() error { - return m.Vote.ValidateBasic() + // Here we validate votes with vote extensions, since we require vote + // extensions to be sent in precommit messages during consensus. Prevote + // messages should never have vote extensions, and this is also validated + // here. + return m.Vote.ValidateWithExtension() } // String returns a string representation. @@ -534,6 +538,8 @@ func MsgFromProto(msg *tmcons.Message) (Message, error) { Part: parts, } case *tmcons.Message_Vote: + // Vote validation will be handled in the vote message ValidateBasic + // call below. vote, err := types.VoteFromProto(msg.Vote.Vote) if err != nil { return nil, fmt.Errorf("vote msg to proto error: %w", err) diff --git a/internal/test/factory/vote.go b/internal/test/factory/vote.go index fc63e8d68..4e77473c2 100644 --- a/internal/test/factory/vote.go +++ b/internal/test/factory/vote.go @@ -40,5 +40,6 @@ func MakeVote( } v.Signature = vpb.Signature + v.ExtensionSignature = vpb.ExtensionSignature return v, nil } diff --git a/privval/file.go b/privval/file.go index 1e31b8c78..bf5803632 100644 --- a/privval/file.go +++ b/privval/file.go @@ -372,11 +372,20 @@ func (pv *FilePV) signVote(chainID string, vote *tmproto.Vote) error { } signBytes := types.VoteSignBytes(chainID, vote) - extSignBytes := types.VoteExtensionSignBytes(chainID, vote) - // We always sign the vote extension. See below for details. - extSig, err := pv.Key.PrivKey.Sign(extSignBytes) - if err != nil { - return err + + // Vote extensions are non-deterministic, so it is possible that an + // application may have created a different extension. We therefore always + // re-sign the vote extensions of precommits. For prevotes, the extension + // signature will always be empty. + var extSig []byte + if vote.Type == tmproto.PrecommitType { + extSignBytes := types.VoteExtensionSignBytes(chainID, vote) + extSig, err = pv.Key.PrivKey.Sign(extSignBytes) + if err != nil { + return err + } + } else if len(vote.Extension) > 0 { + return errors.New("unexpected vote extension - extensions are only allowed in precommits") } // We might crash before writing to the wal, @@ -402,9 +411,6 @@ func (pv *FilePV) signVote(chainID string, vote *tmproto.Vote) error { vote.Signature = lss.Signature } - // Vote extensions are non-deterministic, so it's possible that an - // application may have created a different extension. We therefore - // always re-sign the vote extension. vote.ExtensionSignature = extSig return nil diff --git a/types/block.go b/types/block.go index 578ac43ee..cb1b43ea5 100644 --- a/types/block.go +++ b/types/block.go @@ -780,7 +780,11 @@ func CommitToVoteSet(chainID string, commit *Commit, vals *ValidatorSet) *VoteSe if commitSig.Absent() { continue // OK, some precommits can be missing. } - added, err := voteSet.AddVote(commit.GetVote(int32(idx))) + vote := commit.GetVote(int32(idx)) + if err := vote.ValidateBasic(); err != nil { + panic(fmt.Errorf("failed to validate vote reconstructed from LastCommit: %w", err)) + } + added, err := voteSet.AddVote(vote) if !added || err != nil { panic(fmt.Errorf("failed to reconstruct LastCommit: %w", err)) } diff --git a/types/evidence.go b/types/evidence.go index c8ea967cf..dc66a6fcf 100644 --- a/types/evidence.go +++ b/types/evidence.go @@ -211,14 +211,28 @@ func DuplicateVoteEvidenceFromProto(pb *tmproto.DuplicateVoteEvidence) (*Duplica return nil, errors.New("nil duplicate vote evidence") } - vA, err := VoteFromProto(pb.VoteA) - if err != nil { - return nil, err + var vA *Vote + if pb.VoteA != nil { + var err error + vA, err = VoteFromProto(pb.VoteA) + if err != nil { + return nil, err + } + if err = vA.ValidateBasic(); err != nil { + return nil, err + } } - vB, err := VoteFromProto(pb.VoteB) - if err != nil { - return nil, err + var vB *Vote + if pb.VoteB != nil { + var err error + vB, err = VoteFromProto(pb.VoteB) + if err != nil { + return nil, err + } + if err = vB.ValidateBasic(); err != nil { + return nil, err + } } dve := &DuplicateVoteEvidence{ diff --git a/types/priv_validator.go b/types/priv_validator.go index 29620f829..72027c622 100644 --- a/types/priv_validator.go +++ b/types/priv_validator.go @@ -96,9 +96,16 @@ func (pv MockPV) SignVote(ctx context.Context, chainID string, vote *tmproto.Vot return err } vote.Signature = sig - extSig, err := pv.PrivKey.Sign(extSignBytes) - if err != nil { - return err + + var extSig []byte + // We only sign vote extensions for precommits + if vote.Type == tmproto.PrecommitType { + extSig, err = pv.PrivKey.Sign(extSignBytes) + if err != nil { + return err + } + } else if len(vote.Extension) > 0 { + return errors.New("unexpected vote extension - vote extensions are only allowed in precommits") } vote.ExtensionSignature = extSig return nil diff --git a/types/vote.go b/types/vote.go index e66f40396..f20ee491e 100644 --- a/types/vote.go +++ b/types/vote.go @@ -61,6 +61,30 @@ type Vote struct { ExtensionSignature []byte `json:"extension_signature"` } +// VoteFromProto attempts to convert the given serialization (Protobuf) type to +// our Vote domain type. No validation is performed on the resulting vote - +// this is left up to the caller to decide whether to call ValidateBasic or +// ValidateWithExtension. +func VoteFromProto(pv *tmproto.Vote) (*Vote, error) { + blockID, err := BlockIDFromProto(&pv.BlockID) + if err != nil { + return nil, err + } + + return &Vote{ + Type: pv.Type, + Height: pv.Height, + Round: pv.Round, + BlockID: *blockID, + Timestamp: pv.Timestamp, + ValidatorAddress: pv.ValidatorAddress, + ValidatorIndex: pv.ValidatorIndex, + Signature: pv.Signature, + Extension: pv.Extension, + ExtensionSignature: pv.ExtensionSignature, + }, nil +} + // CommitSig converts the Vote to a CommitSig. func (vote *Vote) CommitSig() CommitSig { if vote == nil { @@ -164,24 +188,49 @@ func (vote *Vote) String() string { ) } -func (vote *Vote) Verify(chainID string, pubKey crypto.PubKey) error { +func (vote *Vote) verifyAndReturnProto(chainID string, pubKey crypto.PubKey) (*tmproto.Vote, error) { if !bytes.Equal(pubKey.Address(), vote.ValidatorAddress) { - return ErrVoteInvalidValidatorAddress + return nil, ErrVoteInvalidValidatorAddress } v := vote.ToProto() if !pubKey.VerifySignature(VoteSignBytes(chainID, v), vote.Signature) { - return ErrVoteInvalidSignature + return nil, ErrVoteInvalidSignature } - extSignBytes := VoteExtensionSignBytes(chainID, v) - // TODO: Remove extension signature nil check to enforce vote extension - // signing once we resolve https://github.com/tendermint/tendermint/issues/8272 - if vote.ExtensionSignature != nil && !pubKey.VerifySignature(extSignBytes, vote.ExtensionSignature) { - return ErrVoteInvalidSignature + return v, nil +} + +// Verify checks whether the signature associated with this vote corresponds to +// the given chain ID and public key. This function does not validate vote +// extension signatures - to do so, use VerifyWithExtension instead. +func (vote *Vote) Verify(chainID string, pubKey crypto.PubKey) error { + _, err := vote.verifyAndReturnProto(chainID, pubKey) + return err +} + +// VerifyWithExtension performs the same verification as Verify, but +// additionally checks whether the vote extension signature corresponds to the +// given chain ID and public key. We only verify vote extension signatures for +// precommits. +func (vote *Vote) VerifyWithExtension(chainID string, pubKey crypto.PubKey) error { + v, err := vote.verifyAndReturnProto(chainID, pubKey) + if err != nil { + return err + } + // We only verify vote extension signatures for precommits. + if vote.Type == tmproto.PrecommitType { + extSignBytes := VoteExtensionSignBytes(chainID, v) + // TODO: Remove extension signature nil check to enforce vote extension + // signing once we resolve https://github.com/tendermint/tendermint/issues/8272 + if vote.ExtensionSignature != nil && !pubKey.VerifySignature(extSignBytes, vote.ExtensionSignature) { + return ErrVoteInvalidSignature + } } return nil } -// ValidateBasic performs basic validation. +// ValidateBasic checks whether the vote is well-formed. It does not, however, +// check vote extensions - for vote validation with vote extension validation, +// use ValidateWithExtension. func (vote *Vote) ValidateBasic() error { if !IsVoteTypeValid(vote.Type) { return errors.New("invalid Type") @@ -224,10 +273,38 @@ func (vote *Vote) ValidateBasic() error { return fmt.Errorf("signature is too big (max: %d)", MaxSignatureSize) } - // TODO: Remove the extension length check such that we always require - // extension signatures to be present. - if len(vote.Extension) > 0 && len(vote.ExtensionSignature) == 0 { - return errors.New("vote extension signature is missing") + // We should only ever see vote extensions in precommits. + if vote.Type != tmproto.PrecommitType { + if len(vote.Extension) > 0 { + return errors.New("unexpected vote extension") + } + if len(vote.ExtensionSignature) > 0 { + return errors.New("unexpected vote extension signature") + } + } + + return nil +} + +// ValidateWithExtension performs the same validations as ValidateBasic, but +// additionally checks whether a vote extension signature is present. This +// function is used in places where vote extension signatures are expected. +func (vote *Vote) ValidateWithExtension() error { + if err := vote.ValidateBasic(); err != nil { + return err + } + + // We should always see vote extension signatures in precommits + if vote.Type == tmproto.PrecommitType { + // TODO(thane): Remove extension length check once + // https://github.com/tendermint/tendermint/issues/8272 is + // resolved. + if len(vote.Extension) > 0 && len(vote.ExtensionSignature) == 0 { + return errors.New("vote extension signature is missing") + } + if len(vote.ExtensionSignature) > MaxSignatureSize { + return fmt.Errorf("vote extension signature is too big (max: %d)", MaxSignatureSize) + } } return nil @@ -269,30 +346,3 @@ func VotesToProto(votes []*Vote) []*tmproto.Vote { } return res } - -// FromProto converts a proto generetad type to a handwritten type -// return type, nil if everything converts safely, otherwise nil, error -func VoteFromProto(pv *tmproto.Vote) (*Vote, error) { - if pv == nil { - return nil, errors.New("nil vote") - } - - blockID, err := BlockIDFromProto(&pv.BlockID) - if err != nil { - return nil, err - } - - vote := new(Vote) - vote.Type = pv.Type - vote.Height = pv.Height - vote.Round = pv.Round - vote.BlockID = *blockID - vote.Timestamp = pv.Timestamp - vote.ValidatorAddress = pv.ValidatorAddress - vote.ValidatorIndex = pv.ValidatorIndex - vote.Signature = pv.Signature - vote.Extension = pv.Extension - vote.ExtensionSignature = pv.ExtensionSignature - - return vote, vote.ValidateBasic() -} diff --git a/types/vote_set.go b/types/vote_set.go index 142a4130c..b4d149576 100644 --- a/types/vote_set.go +++ b/types/vote_set.go @@ -194,7 +194,7 @@ func (voteSet *VoteSet) addVote(vote *Vote) (added bool, err error) { } // Check signature. - if err := vote.Verify(voteSet.chainID, val.PubKey); err != nil { + if err := vote.VerifyWithExtension(voteSet.chainID, val.PubKey); err != nil { return false, fmt.Errorf("failed to verify vote with ChainID %s and PubKey %s: %w", voteSet.chainID, val.PubKey, err) } diff --git a/types/vote_test.go b/types/vote_test.go index 949c996d0..684422b97 100644 --- a/types/vote_test.go +++ b/types/vote_test.go @@ -24,7 +24,9 @@ func examplePrevote(t *testing.T) *Vote { func examplePrecommit(t testing.TB) *Vote { t.Helper() - return exampleVote(t, byte(tmproto.PrecommitType)) + vote := exampleVote(t, byte(tmproto.PrecommitType)) + vote.ExtensionSignature = []byte("signature") + return vote } func exampleVote(tb testing.TB, t byte) *Vote { @@ -48,6 +50,7 @@ func exampleVote(tb testing.TB, t byte) *Vote { ValidatorIndex: 56789, } } + func TestVoteSignable(t *testing.T) { vote := examplePrecommit(t) v := vote.ToProto() @@ -221,8 +224,8 @@ func TestVoteExtension(t *testing.T) { includeSignature: true, expectError: false, }, - // TODO: Re-enable once - // https://github.com/tendermint/tendermint/issues/8272 is resolved. + // TODO(thane): Re-enable once + // https://github.com/tendermint/tendermint/issues/8272 is resolved //{ // name: "no extension signature", // extension: []byte("extension"), @@ -269,7 +272,7 @@ func TestVoteExtension(t *testing.T) { if tc.includeSignature { vote.ExtensionSignature = v.ExtensionSignature } - err = vote.Verify("test_chain_id", pk) + err = vote.VerifyWithExtension("test_chain_id", pk) if tc.expectError { require.Error(t, err) } else { @@ -336,39 +339,115 @@ func TestVoteString(t *testing.T) { } } -func TestVoteValidateBasic(t *testing.T) { +func signVote(ctx context.Context, t *testing.T, pv PrivValidator, chainID string, vote *Vote) { + t.Helper() + + v := vote.ToProto() + require.NoError(t, pv.SignVote(ctx, chainID, v)) + vote.Signature = v.Signature + vote.ExtensionSignature = v.ExtensionSignature +} + +func TestValidVotes(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() privVal := NewMockPV() testCases := []struct { - testName string + name string + vote *Vote malleateVote func(*Vote) - expectErr bool }{ - {"Good Vote", func(v *Vote) {}, false}, - {"Negative Height", func(v *Vote) { v.Height = -1 }, true}, - {"Negative Round", func(v *Vote) { v.Round = -1 }, true}, - {"Invalid BlockID", func(v *Vote) { - v.BlockID = BlockID{[]byte{1, 2, 3}, PartSetHeader{111, []byte("blockparts")}} - }, true}, - {"Invalid Address", func(v *Vote) { v.ValidatorAddress = make([]byte, 1) }, true}, - {"Invalid ValidatorIndex", func(v *Vote) { v.ValidatorIndex = -1 }, true}, - {"Invalid Signature", func(v *Vote) { v.Signature = nil }, true}, - {"Too big Signature", func(v *Vote) { v.Signature = make([]byte, MaxSignatureSize+1) }, true}, + {"good prevote", examplePrevote(t), func(v *Vote) {}}, + {"good precommit without vote extension", examplePrecommit(t), func(v *Vote) { v.Extension = nil }}, + {"good precommit with vote extension", examplePrecommit(t), func(v *Vote) { v.Extension = []byte("extension") }}, } for _, tc := range testCases { - tc := tc - t.Run(tc.testName, func(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + signVote(ctx, t, privVal, "test_chain_id", tc.vote) + tc.malleateVote(tc.vote) + require.NoError(t, tc.vote.ValidateBasic(), "ValidateBasic for %s", tc.name) + require.NoError(t, tc.vote.ValidateWithExtension(), "ValidateWithExtension for %s", tc.name) + } +} - vote := examplePrecommit(t) - v := vote.ToProto() - err := privVal.SignVote(ctx, "test_chain_id", v) - vote.Signature = v.Signature - require.NoError(t, err) - tc.malleateVote(vote) - assert.Equal(t, tc.expectErr, vote.ValidateBasic() != nil, "Validate Basic had an unexpected result") - }) +func TestInvalidVotes(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + privVal := NewMockPV() + + testCases := []struct { + name string + malleateVote func(*Vote) + }{ + {"negative height", func(v *Vote) { v.Height = -1 }}, + {"negative round", func(v *Vote) { v.Round = -1 }}, + {"invalid block ID", func(v *Vote) { v.BlockID = BlockID{[]byte{1, 2, 3}, PartSetHeader{111, []byte("blockparts")}} }}, + {"invalid address", func(v *Vote) { v.ValidatorAddress = make([]byte, 1) }}, + {"invalid validator index", func(v *Vote) { v.ValidatorIndex = -1 }}, + {"invalid signature", func(v *Vote) { v.Signature = nil }}, + {"oversized signature", func(v *Vote) { v.Signature = make([]byte, MaxSignatureSize+1) }}, + } + for _, tc := range testCases { + prevote := examplePrevote(t) + signVote(ctx, t, privVal, "test_chain_id", prevote) + tc.malleateVote(prevote) + require.Error(t, prevote.ValidateBasic(), "ValidateBasic for %s in invalid prevote", tc.name) + require.Error(t, prevote.ValidateWithExtension(), "ValidateWithExtension for %s in invalid prevote", tc.name) + + precommit := examplePrecommit(t) + signVote(ctx, t, privVal, "test_chain_id", precommit) + tc.malleateVote(precommit) + require.Error(t, precommit.ValidateBasic(), "ValidateBasic for %s in invalid precommit", tc.name) + require.Error(t, precommit.ValidateWithExtension(), "ValidateWithExtension for %s in invalid precommit", tc.name) + } +} + +func TestInvalidPrevotes(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + privVal := NewMockPV() + + testCases := []struct { + name string + malleateVote func(*Vote) + }{ + {"vote extension present", func(v *Vote) { v.Extension = []byte("extension") }}, + {"vote extension signature present", func(v *Vote) { v.ExtensionSignature = []byte("signature") }}, + } + for _, tc := range testCases { + prevote := examplePrevote(t) + signVote(ctx, t, privVal, "test_chain_id", prevote) + tc.malleateVote(prevote) + require.Error(t, prevote.ValidateBasic(), "ValidateBasic for %s", tc.name) + require.Error(t, prevote.ValidateWithExtension(), "ValidateWithExtension for %s", tc.name) + } +} + +func TestInvalidPrecommitExtensions(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + privVal := NewMockPV() + + testCases := []struct { + name string + malleateVote func(*Vote) + }{ + {"vote extension present without signature", func(v *Vote) { + v.Extension = []byte("extension") + v.ExtensionSignature = nil + }}, + // TODO(thane): Re-enable once https://github.com/tendermint/tendermint/issues/8272 is resolved + //{"missing vote extension signature", func(v *Vote) { v.ExtensionSignature = nil }}, + {"oversized vote extension signature", func(v *Vote) { v.ExtensionSignature = make([]byte, MaxSignatureSize+1) }}, + } + for _, tc := range testCases { + precommit := examplePrecommit(t) + signVote(ctx, t, privVal, "test_chain_id", precommit) + tc.malleateVote(precommit) + // We don't expect an error from ValidateBasic, because it doesn't + // handle vote extensions. + require.NoError(t, precommit.ValidateBasic(), "ValidateBasic for %s", tc.name) + require.Error(t, precommit.ValidateWithExtension(), "ValidateWithExtension for %s", tc.name) } } @@ -384,21 +463,28 @@ func TestVoteProtobuf(t *testing.T) { require.NoError(t, err) testCases := []struct { - msg string - v1 *Vote - expPass bool + msg string + vote *Vote + convertsOk bool + passesValidateBasic bool }{ - {"success", vote, true}, - {"fail vote validate basic", &Vote{}, false}, - {"failure nil", nil, false}, + {"success", vote, true, true}, + {"fail vote validate basic", &Vote{}, true, false}, } for _, tc := range testCases { - protoProposal := tc.v1.ToProto() + protoProposal := tc.vote.ToProto() v, err := VoteFromProto(protoProposal) - if tc.expPass { + if tc.convertsOk { require.NoError(t, err) - require.Equal(t, tc.v1, v, tc.msg) + } else { + require.Error(t, err) + } + + err = v.ValidateBasic() + if tc.passesValidateBasic { + require.NoError(t, err) + require.Equal(t, tc.vote, v, tc.msg) } else { require.Error(t, err) } From 6faf506540680e9d6953cfadee349f13f6411fe4 Mon Sep 17 00:00:00 2001 From: "M. J. Fromberger" Date: Thu, 28 Apr 2022 15:18:11 -0700 Subject: [PATCH 28/35] rpc: fix byte string decoding for URL parameters (#8431) In #8397 I tried to remove all the cases where we needed to keep track of the target type of parameters for JSON encoding, but there is one case still left: When decoding parameters from URL query terms, there is no way to tell whether or not we need base64 encoding without knowing whether the underlying type of the target is string or []byte. To fix this, keep track of parameters that are []byte valued when RPCFunc is compiling its argument map, and use that when parsing URL query terms. Update the tests accordingly. --- rpc/jsonrpc/server/http_json_handler.go | 16 ++++---- rpc/jsonrpc/server/http_uri_handler.go | 26 ++++++++----- rpc/jsonrpc/server/parse_test.go | 26 ++++++++----- rpc/jsonrpc/server/rpc_func.go | 50 +++++++++++++++++-------- 4 files changed, 75 insertions(+), 43 deletions(-) diff --git a/rpc/jsonrpc/server/http_json_handler.go b/rpc/jsonrpc/server/http_json_handler.go index defcb7d9c..2eeded2d7 100644 --- a/rpc/jsonrpc/server/http_json_handler.go +++ b/rpc/jsonrpc/server/http_json_handler.go @@ -118,17 +118,15 @@ func writeListOfEndpoints(w http.ResponseWriter, r *http.Request, funcMap map[st noArgs := make(map[string]string) for name, rf := range funcMap { base := fmt.Sprintf("//%s/%s", r.Host, name) - // N.B. Check argNames, not args, since the type list includes the type - // of the leading context argument. - if len(rf.argNames) == 0 { + if len(rf.args) == 0 { noArgs[name] = base - } else { - query := append([]string(nil), rf.argNames...) - for i, arg := range query { - query[i] = arg + "=_" - } - hasArgs[name] = base + "?" + strings.Join(query, "&") + continue } + var query []string + for _, arg := range rf.args { + query = append(query, arg.name+"=_") + } + hasArgs[name] = base + "?" + strings.Join(query, "&") } w.Header().Set("Content-Type", "text/html") _ = listOfEndpoints.Execute(w, map[string]map[string]string{ diff --git a/rpc/jsonrpc/server/http_uri_handler.go b/rpc/jsonrpc/server/http_uri_handler.go index 7e1902ac1..c755bbaf1 100644 --- a/rpc/jsonrpc/server/http_uri_handler.go +++ b/rpc/jsonrpc/server/http_uri_handler.go @@ -23,7 +23,7 @@ func makeHTTPHandler(rpcFunc *RPCFunc, logger log.Logger) func(http.ResponseWrit ctx := rpctypes.WithCallInfo(req.Context(), &rpctypes.CallInfo{ HTTPRequest: req, }) - args, err := parseURLParams(rpcFunc.argNames, req) + args, err := parseURLParams(rpcFunc.args, req) if err != nil { w.Header().Set("Content-Type", "text/plain") w.WriteHeader(http.StatusBadRequest) @@ -40,7 +40,7 @@ func makeHTTPHandler(rpcFunc *RPCFunc, logger log.Logger) func(http.ResponseWrit } } -func parseURLParams(argNames []string, req *http.Request) ([]byte, error) { +func parseURLParams(args []argInfo, req *http.Request) ([]byte, error) { if err := req.ParseForm(); err != nil { return nil, fmt.Errorf("invalid HTTP request: %w", err) } @@ -52,15 +52,15 @@ func parseURLParams(argNames []string, req *http.Request) ([]byte, error) { } params := make(map[string]interface{}) - for _, name := range argNames { - v, ok := getArg(name) + for _, arg := range args { + v, ok := getArg(arg.name) if !ok { continue } if z, err := decodeInteger(v); err == nil { - params[name] = z + params[arg.name] = z } else if b, err := strconv.ParseBool(v); err == nil { - params[name] = b + params[arg.name] = b } else if lc := strings.ToLower(v); strings.HasPrefix(lc, "0x") { dec, err := hex.DecodeString(lc[2:]) if err != nil { @@ -68,15 +68,23 @@ func parseURLParams(argNames []string, req *http.Request) ([]byte, error) { } else if len(dec) == 0 { return nil, errors.New("invalid empty hex string") } - params[name] = dec + if arg.isBinary { + params[arg.name] = dec + } else { + params[arg.name] = string(dec) + } } else if isQuotedString(v) { var dec string if err := json.Unmarshal([]byte(v), &dec); err != nil { return nil, fmt.Errorf("invalid quoted string: %w", err) } - params[name] = dec + if arg.isBinary { + params[arg.name] = []byte(dec) + } else { + params[arg.name] = dec + } } else { - params[name] = v + params[arg.name] = v } } return json.Marshal(params) diff --git a/rpc/jsonrpc/server/parse_test.go b/rpc/jsonrpc/server/parse_test.go index e6667fb0a..4a0e92ad1 100644 --- a/rpc/jsonrpc/server/parse_test.go +++ b/rpc/jsonrpc/server/parse_test.go @@ -188,44 +188,50 @@ func TestParseURI(t *testing.T) { tests := []struct { name string url string - args []string + args []argInfo want string fail bool }{ { name: "quoted numbers and strings", url: `http://localhost?num="7"&str="flew"&neg="-10"`, - args: []string{"neg", "num", "str", "other"}, + args: []argInfo{{name: "neg"}, {name: "num"}, {name: "str"}, {name: "other"}}, want: `{"neg":-10,"num":7,"str":"flew"}`, }, { name: "unquoted numbers and strings", url: `http://localhost?num1=7&str1=cabbage&num2=-199&str2=hey+you`, - args: []string{"num1", "num2", "str1", "str2", "other"}, + args: []argInfo{{name: "num1"}, {name: "num2"}, {name: "str1"}, {name: "str2"}, {name: "other"}}, want: `{"num1":7,"num2":-199,"str1":"cabbage","str2":"hey you"}`, }, { - name: "byte strings in hex", + name: "quoted byte strings", + url: `http://localhost?left="Fahrvergnügen"&right="Applesauce"`, + args: []argInfo{{name: "left", isBinary: true}, {name: "right", isBinary: false}}, + want: `{"left":"RmFocnZlcmduw7xnZW4=","right":"Applesauce"}`, + }, + { + name: "hexadecimal byte strings", url: `http://localhost?lower=0x626f62&upper=0X646F7567`, - args: []string{"upper", "lower", "other"}, - want: `{"lower":"Ym9i","upper":"ZG91Zw=="}`, + args: []argInfo{{name: "upper", isBinary: true}, {name: "lower", isBinary: false}, {name: "other"}}, + want: `{"lower":"bob","upper":"ZG91Zw=="}`, }, { name: "invalid hex odd length", url: `http://localhost?bad=0xa`, - args: []string{"bad", "superbad"}, + args: []argInfo{{name: "bad"}, {name: "superbad"}}, fail: true, }, { name: "invalid hex empty", url: `http://localhost?bad=0x`, - args: []string{"bad"}, + args: []argInfo{{name: "bad"}}, fail: true, }, { name: "invalid quoted string", url: `http://localhost?bad="double""`, - args: []string{"bad"}, + args: []argInfo{{name: "bad"}}, fail: true, }, } @@ -305,7 +311,7 @@ func TestParseURI(t *testing.T) { if err != nil { t.Fatalf("NewRequest for %q: %v", test.url, err) } - bits, err := parseURLParams(echo.argNames, hreq) + bits, err := parseURLParams(echo.args, hreq) if err != nil { t.Fatalf("Parse %#q: unexpected error: %v", test.url, err) } diff --git a/rpc/jsonrpc/server/rpc_func.go b/rpc/jsonrpc/server/rpc_func.go index 456d97bfc..8eba28728 100644 --- a/rpc/jsonrpc/server/rpc_func.go +++ b/rpc/jsonrpc/server/rpc_func.go @@ -32,11 +32,20 @@ func RegisterRPCFuncs(mux *http.ServeMux, funcMap map[string]*RPCFunc, logger lo // RPCFunc contains the introspected type information for a function. type RPCFunc struct { - f reflect.Value // underlying rpc function - param reflect.Type // the parameter struct, or nil - result reflect.Type // the non-error result type, or nil - argNames []string // name of each argument (for display) - ws bool // websocket only + f reflect.Value // underlying rpc function + param reflect.Type // the parameter struct, or nil + result reflect.Type // the non-error result type, or nil + args []argInfo // names and type information (for URL decoding) + ws bool // websocket only +} + +// argInfo records the name of a field, along with a bit to tell whether the +// value of the field requires binary data, having underlying type []byte. The +// flag is needed when decoding URL parameters, where we permit quoted strings +// to be passed for either argument type. +type argInfo struct { + name string + isBinary bool // value wants binary data } // Call parses the given JSON parameters and calls the function wrapped by rf @@ -96,12 +105,12 @@ func (rf *RPCFunc) adjustParams(data []byte) (json.RawMessage, error) { var args []json.RawMessage if err := json.Unmarshal(base, &args); err != nil { return nil, err - } else if len(args) != len(rf.argNames) { - return nil, fmt.Errorf("got %d arguments, want %d", len(args), len(rf.argNames)) + } else if len(args) != len(rf.args) { + return nil, fmt.Errorf("got %d arguments, want %d", len(args), len(rf.args)) } m := make(map[string]json.RawMessage) for i, arg := range args { - m[rf.argNames[i]] = arg + m[rf.args[i].name] = arg } return json.Marshal(m) } else if bytes.HasPrefix(base, []byte("{")) || bytes.Equal(base, []byte("null")) { @@ -180,12 +189,15 @@ func newRPCFunc(f interface{}) (*RPCFunc, error) { rtype = ft.Out(0) } - var argNames []string + var args []argInfo if ptype != nil { for i := 0; i < ptype.NumField(); i++ { field := ptype.Field(i) if tag := strings.SplitN(field.Tag.Get("json"), ",", 2)[0]; tag != "" && tag != "-" { - argNames = append(argNames, tag) + args = append(args, argInfo{ + name: tag, + isBinary: isByteArray(field.Type), + }) } else if tag == "-" { // If the tag is "-" the field should explicitly be ignored, even // if it is otherwise eligible. @@ -194,16 +206,19 @@ func newRPCFunc(f interface{}) (*RPCFunc, error) { // Note that this is an aesthetic choice; the standard decoder will // match without regard to case anyway. name := strings.ToLower(field.Name[:1]) + field.Name[1:] - argNames = append(argNames, name) + args = append(args, argInfo{ + name: name, + isBinary: isByteArray(field.Type), + }) } } } return &RPCFunc{ - f: fv, - param: ptype, - result: rtype, - argNames: argNames, + f: fv, + param: ptype, + result: rtype, + args: args, }, nil } @@ -225,3 +240,8 @@ func isNullOrEmpty(params json.RawMessage) bool { bytes.Equal(params, []byte("{}")) || bytes.Equal(params, []byte("[]")) } + +// isByteArray reports whether t is (equivalent to) []byte. +func isByteArray(t reflect.Type) bool { + return t.Kind() == reflect.Slice && t.Elem().Kind() == reflect.Uint8 +} From 3d448e1ef83685857b12c6ca94162097916c3402 Mon Sep 17 00:00:00 2001 From: Sam Kleinman Date: Thu, 28 Apr 2022 22:21:43 -0400 Subject: [PATCH 29/35] crypto: cleanup tmhash package (#8434) --- CHANGELOG_PENDING.md | 1 + UPGRADING.md | 31 ++- crypto/crypto.go | 21 +- crypto/ed25519/ed25519.go | 3 +- crypto/merkle/hash.go | 8 +- crypto/merkle/proof.go | 10 +- crypto/merkle/rfc6962_test.go | 10 +- crypto/merkle/tree_test.go | 8 +- crypto/sr25519/pubkey.go | 3 +- crypto/tmhash/hash.go | 25 --- internal/consensus/msgs_test.go | 4 +- internal/consensus/state_test.go | 6 +- .../consensus/types/height_vote_set_test.go | 4 +- internal/evidence/reactor_test.go | 5 +- internal/evidence/verify_test.go | 7 +- internal/libs/protoio/writer_test.go | 5 +- internal/state/execution_test.go | 17 +- internal/state/validation_test.go | 4 +- internal/test/factory/block.go | 3 +- light/helpers_test.go | 3 +- light/store/db/db_test.go | 17 +- light/trust_options.go | 6 +- node/node_test.go | 9 +- privval/file_test.go | 18 +- privval/grpc/client_test.go | 5 +- privval/grpc/server_test.go | 5 +- privval/msgs_test.go | 7 +- privval/signer_client_test.go | 13 +- rpc/client/evidence_test.go | 8 +- test/e2e/runner/evidence.go | 23 +- types/block.go | 5 +- types/block_meta_test.go | 10 +- types/block_test.go | 197 +++++++++--------- types/canonical_test.go | 4 +- types/evidence.go | 16 +- types/evidence_test.go | 37 ++-- types/proposal_test.go | 6 +- types/tx.go | 4 +- types/validation.go | 8 +- types/vote_test.go | 5 +- 40 files changed, 288 insertions(+), 293 deletions(-) delete mode 100644 crypto/tmhash/hash.go diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index 6bfc948f8..65ab5ee3b 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -47,6 +47,7 @@ Special thanks to external contributors on this release: - [libs/service] \#7288 Remove SetLogger method on `service.Service` interface. (@tychoish) - [abci/client] \#7607 Simplify client interface (removes most "async" methods). (@creachadair) - [libs/json] \#7673 Remove the libs/json (tmjson) library. (@creachadair) + - [crypto] \#8412 \#8432 Remove `crypto/tmhash` package in favor of small functions in `crypto` package and cleanup of unused functions. (@tychoish) - Blockchain Protocol diff --git a/UPGRADING.md b/UPGRADING.md index a67d9dfb2..28e44e58c 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -145,6 +145,27 @@ subcommands: `blockchain`, `peers`, `unsafe-signer` and `unsafe-all`. - `tendermint reset unsafe-all`: A summation of the other three commands. This will delete the entire `data` directory which may include application data as well. +### Go API Changes + +#### `crypto` Package Cleanup + +The `github.com/tendermint/tendermint/crypto/tmhash` package was removed +to improve clarity. Users are encouraged to use the standard library +`crypto/sha256` package directly. However, as a convenience, some constants +and one function have moved to the Tendermint `crypto` package: + +- The `crypto.Checksum` function returns the sha256 checksum of a + byteslice. This is a wrapper around `sha256.Sum265` from the + standard libary, but provided as a function to ease type + requirements (the library function returns a `[32]byte` rather than + a `[]byte`). +- `tmhash.TruncatedSize` is now `crypto.AddressSize` which was + previously an alias for the same value. +- `tmhash.Size` and `tmhash.BlockSize` are now `crypto.HashSize` and + `crypto.HashSize`. +- `tmhash.SumTruncated` is now available via `crypto.AddressHash` or by + `crypto.Checksum(<...>)[:crypto.AddressSize]` + ## v0.35 ### ABCI Changes @@ -259,11 +280,13 @@ the full RPC interface provided as direct function calls. Import the the node service as in the following: ```go - node := node.NewDefault() //construct the node object - // start and set up the node service +logger := log.NewNopLogger() - client := local.New(node.(local.NodeService)) - // use client object to interact with the node +// Construct and start up a node with default settings. +node := node.NewDefault(logger) + +// Construct a local (in-memory) RPC client to the node. +client := local.New(logger, node.(local.NodeService)) ``` ### gRPC Support diff --git a/crypto/crypto.go b/crypto/crypto.go index 4f0dc05e7..ea24af243 100644 --- a/crypto/crypto.go +++ b/crypto/crypto.go @@ -1,14 +1,18 @@ package crypto import ( - "github.com/tendermint/tendermint/crypto/tmhash" + "crypto/sha256" + "github.com/tendermint/tendermint/internal/jsontypes" "github.com/tendermint/tendermint/libs/bytes" ) const ( + // HashSize is the size in bytes of an AddressHash. + HashSize = sha256.Size + // AddressSize is the size of a pubkey address. - AddressSize = tmhash.TruncatedSize + AddressSize = 20 ) // An address is a []byte, but hex-encoded even in JSON. @@ -16,8 +20,19 @@ const ( // Use an alias so Unmarshal methods (with ptr receivers) are available too. type Address = bytes.HexBytes +// AddressHash computes a truncated SHA-256 hash of bz for use as +// a peer address. +// +// See: https://docs.tendermint.com/master/spec/core/data_structures.html#address func AddressHash(bz []byte) Address { - return Address(tmhash.SumTruncated(bz)) + h := sha256.Sum256(bz) + return Address(h[:AddressSize]) +} + +// Checksum returns the SHA256 of the bz. +func Checksum(bz []byte) []byte { + h := sha256.Sum256(bz) + return h[:] } type PubKey interface { diff --git a/crypto/ed25519/ed25519.go b/crypto/ed25519/ed25519.go index 7282e5c70..ca425d111 100644 --- a/crypto/ed25519/ed25519.go +++ b/crypto/ed25519/ed25519.go @@ -13,7 +13,6 @@ import ( "github.com/oasisprotocol/curve25519-voi/primitives/ed25519/extra/cache" "github.com/tendermint/tendermint/crypto" - "github.com/tendermint/tendermint/crypto/tmhash" "github.com/tendermint/tendermint/internal/jsontypes" ) @@ -163,7 +162,7 @@ func (pubKey PubKey) Address() crypto.Address { if len(pubKey) != PubKeySize { panic("pubkey is incorrect size") } - return crypto.Address(tmhash.SumTruncated(pubKey)) + return crypto.AddressHash(pubKey) } // Bytes returns the PubKey byte format. diff --git a/crypto/merkle/hash.go b/crypto/merkle/hash.go index 9c6df1786..0bb5448d7 100644 --- a/crypto/merkle/hash.go +++ b/crypto/merkle/hash.go @@ -3,7 +3,7 @@ package merkle import ( "hash" - "github.com/tendermint/tendermint/crypto/tmhash" + "github.com/tendermint/tendermint/crypto" ) // TODO: make these have a large predefined capacity @@ -14,12 +14,12 @@ var ( // returns tmhash() func emptyHash() []byte { - return tmhash.Sum([]byte{}) + return crypto.Checksum([]byte{}) } // returns tmhash(0x00 || leaf) func leafHash(leaf []byte) []byte { - return tmhash.Sum(append(leafPrefix, leaf...)) + return crypto.Checksum(append(leafPrefix, leaf...)) } // returns tmhash(0x00 || leaf) @@ -36,7 +36,7 @@ func innerHash(left []byte, right []byte) []byte { n := copy(data, innerPrefix) n += copy(data[n:], left) copy(data[n:], right) - return tmhash.Sum(data) + return crypto.Checksum(data)[:] } func innerHashOpt(s hash.Hash, left []byte, right []byte) []byte { diff --git a/crypto/merkle/proof.go b/crypto/merkle/proof.go index 4f09e4414..8b98d1b21 100644 --- a/crypto/merkle/proof.go +++ b/crypto/merkle/proof.go @@ -5,7 +5,7 @@ import ( "errors" "fmt" - "github.com/tendermint/tendermint/crypto/tmhash" + "github.com/tendermint/tendermint/crypto" tmcrypto "github.com/tendermint/tendermint/proto/tendermint/crypto" ) @@ -102,15 +102,15 @@ func (sp *Proof) ValidateBasic() error { if sp.Index < 0 { return errors.New("negative Index") } - if len(sp.LeafHash) != tmhash.Size { - return fmt.Errorf("expected LeafHash size to be %d, got %d", tmhash.Size, len(sp.LeafHash)) + if len(sp.LeafHash) != crypto.HashSize { + return fmt.Errorf("expected LeafHash size to be %d, got %d", crypto.HashSize, len(sp.LeafHash)) } if len(sp.Aunts) > MaxAunts { return fmt.Errorf("expected no more than %d aunts, got %d", MaxAunts, len(sp.Aunts)) } for i, auntHash := range sp.Aunts { - if len(auntHash) != tmhash.Size { - return fmt.Errorf("expected Aunts#%d size to be %d, got %d", i, tmhash.Size, len(auntHash)) + if len(auntHash) != crypto.HashSize { + return fmt.Errorf("expected Aunts#%d size to be %d, got %d", i, crypto.HashSize, len(auntHash)) } } return nil diff --git a/crypto/merkle/rfc6962_test.go b/crypto/merkle/rfc6962_test.go index c762cda56..7a70dbb91 100644 --- a/crypto/merkle/rfc6962_test.go +++ b/crypto/merkle/rfc6962_test.go @@ -20,7 +20,7 @@ import ( "encoding/hex" "testing" - "github.com/tendermint/tendermint/crypto/tmhash" + "github.com/tendermint/tendermint/crypto" ) func TestRFC6962Hasher(t *testing.T) { @@ -39,7 +39,7 @@ func TestRFC6962Hasher(t *testing.T) { // echo -n '' | sha256sum { desc: "RFC6962 Empty Tree", - want: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"[:tmhash.Size*2], + want: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"[:crypto.HashSize*2], got: emptyTreeHash, }, @@ -47,19 +47,19 @@ func TestRFC6962Hasher(t *testing.T) { // echo -n 00 | xxd -r -p | sha256sum { desc: "RFC6962 Empty Leaf", - want: "6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d"[:tmhash.Size*2], + want: "6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d"[:crypto.HashSize*2], got: emptyLeafHash, }, // echo -n 004C313233343536 | xxd -r -p | sha256sum { desc: "RFC6962 Leaf", - want: "395aa064aa4c29f7010acfe3f25db9485bbd4b91897b6ad7ad547639252b4d56"[:tmhash.Size*2], + want: "395aa064aa4c29f7010acfe3f25db9485bbd4b91897b6ad7ad547639252b4d56"[:crypto.HashSize*2], got: leafHash, }, // echo -n 014E3132334E343536 | xxd -r -p | sha256sum { desc: "RFC6962 Node", - want: "aa217fe888e47007fa15edab33c2b492a722cb106c64667fc2b044444de66bbb"[:tmhash.Size*2], + want: "aa217fe888e47007fa15edab33c2b492a722cb106c64667fc2b044444de66bbb"[:crypto.HashSize*2], got: innerHash([]byte("N123"), []byte("N456")), }, } { diff --git a/crypto/merkle/tree_test.go b/crypto/merkle/tree_test.go index 641c46b76..72b260178 100644 --- a/crypto/merkle/tree_test.go +++ b/crypto/merkle/tree_test.go @@ -7,7 +7,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/tendermint/tendermint/crypto/tmhash" + "github.com/tendermint/tendermint/crypto" ctest "github.com/tendermint/tendermint/internal/libs/test" tmrand "github.com/tendermint/tendermint/libs/rand" ) @@ -53,7 +53,7 @@ func TestProof(t *testing.T) { items := make([][]byte, total) for i := 0; i < total; i++ { - items[i] = testItem(tmrand.Bytes(tmhash.Size)) + items[i] = testItem(tmrand.Bytes(crypto.HashSize)) } rootHash = HashFromByteSlices(items) @@ -106,7 +106,7 @@ func TestHashAlternatives(t *testing.T) { items := make([][]byte, total) for i := 0; i < total; i++ { - items[i] = testItem(tmrand.Bytes(tmhash.Size)) + items[i] = testItem(tmrand.Bytes(crypto.HashSize)) } rootHash1 := HashFromByteSlicesIterative(items) @@ -119,7 +119,7 @@ func BenchmarkHashAlternatives(b *testing.B) { items := make([][]byte, total) for i := 0; i < total; i++ { - items[i] = testItem(tmrand.Bytes(tmhash.Size)) + items[i] = testItem(tmrand.Bytes(crypto.HashSize)) } b.ResetTimer() diff --git a/crypto/sr25519/pubkey.go b/crypto/sr25519/pubkey.go index 717f25c8c..a2c6bb920 100644 --- a/crypto/sr25519/pubkey.go +++ b/crypto/sr25519/pubkey.go @@ -7,7 +7,6 @@ import ( "github.com/oasisprotocol/curve25519-voi/primitives/sr25519" "github.com/tendermint/tendermint/crypto" - "github.com/tendermint/tendermint/crypto/tmhash" ) var _ crypto.PubKey = PubKey{} @@ -31,7 +30,7 @@ func (pubKey PubKey) Address() crypto.Address { if len(pubKey) != PubKeySize { panic("pubkey is incorrect size") } - return crypto.Address(tmhash.SumTruncated(pubKey)) + return crypto.AddressHash(pubKey) } // Bytes returns the PubKey byte format. diff --git a/crypto/tmhash/hash.go b/crypto/tmhash/hash.go deleted file mode 100644 index 91e55bca4..000000000 --- a/crypto/tmhash/hash.go +++ /dev/null @@ -1,25 +0,0 @@ -package tmhash - -import ( - "crypto/sha256" -) - -const ( - Size = sha256.Size - BlockSize = sha256.BlockSize - TruncatedSize = 20 -) - -// Sum returns the SHA256 of the bz. -func Sum(bz []byte) []byte { - h := sha256.Sum256(bz) - return h[:] -} - -//------------------------------------------------------------- - -// SumTruncated returns the first 20 bytes of SHA256 of the bz. -func SumTruncated(bz []byte) []byte { - hash := sha256.Sum256(bz) - return hash[:TruncatedSize] -} diff --git a/internal/consensus/msgs_test.go b/internal/consensus/msgs_test.go index cfbd53ff7..5a6465294 100644 --- a/internal/consensus/msgs_test.go +++ b/internal/consensus/msgs_test.go @@ -12,8 +12,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/merkle" - "github.com/tendermint/tendermint/crypto/tmhash" cstypes "github.com/tendermint/tendermint/internal/consensus/types" "github.com/tendermint/tendermint/internal/test/factory" "github.com/tendermint/tendermint/libs/bits" @@ -667,7 +667,7 @@ func TestProposalPOLMessageValidateBasic(t *testing.T) { func TestBlockPartMessageValidateBasic(t *testing.T) { testPart := new(types.Part) - testPart.Proof.LeafHash = tmhash.Sum([]byte("leaf")) + testPart.Proof.LeafHash = crypto.Checksum([]byte("leaf")) testCases := []struct { testName string messageHeight int64 diff --git a/internal/consensus/state_test.go b/internal/consensus/state_test.go index d4dd83202..93aa4a49d 100644 --- a/internal/consensus/state_test.go +++ b/internal/consensus/state_test.go @@ -13,7 +13,7 @@ import ( "github.com/tendermint/tendermint/abci/example/kvstore" abci "github.com/tendermint/tendermint/abci/types" abcimocks "github.com/tendermint/tendermint/abci/types/mocks" - "github.com/tendermint/tendermint/crypto/tmhash" + "github.com/tendermint/tendermint/crypto" cstypes "github.com/tendermint/tendermint/internal/consensus/types" "github.com/tendermint/tendermint/internal/eventbus" tmpubsub "github.com/tendermint/tendermint/internal/pubsub" @@ -2769,7 +2769,7 @@ func TestStateOutputVoteStats(t *testing.T) { peerID, err := types.NewNodeID("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA") require.NoError(t, err) - randBytes := tmrand.Bytes(tmhash.Size) + randBytes := tmrand.Bytes(crypto.HashSize) blockID := types.BlockID{ Hash: randBytes, } @@ -2807,7 +2807,7 @@ func TestSignSameVoteTwice(t *testing.T) { _, vss := makeState(ctx, t, makeStateArgs{config: config, validators: 2}) - randBytes := tmrand.Bytes(tmhash.Size) + randBytes := tmrand.Bytes(crypto.HashSize) vote := signVote( ctx, diff --git a/internal/consensus/types/height_vote_set_test.go b/internal/consensus/types/height_vote_set_test.go index 8bafc7a90..acffa794c 100644 --- a/internal/consensus/types/height_vote_set_test.go +++ b/internal/consensus/types/height_vote_set_test.go @@ -7,7 +7,7 @@ import ( "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/config" - "github.com/tendermint/tendermint/crypto/tmhash" + "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/internal/test/factory" tmrand "github.com/tendermint/tendermint/libs/rand" tmtime "github.com/tendermint/tendermint/libs/time" @@ -71,7 +71,7 @@ func makeVoteHR( pubKey, err := privVal.GetPubKey(ctx) require.NoError(t, err) - randBytes := tmrand.Bytes(tmhash.Size) + randBytes := tmrand.Bytes(crypto.HashSize) vote := &types.Vote{ ValidatorAddress: pubKey.Address(), diff --git a/internal/evidence/reactor_test.go b/internal/evidence/reactor_test.go index 5575d7f97..f23195fae 100644 --- a/internal/evidence/reactor_test.go +++ b/internal/evidence/reactor_test.go @@ -16,7 +16,6 @@ import ( dbm "github.com/tendermint/tm-db" "github.com/tendermint/tendermint/crypto" - "github.com/tendermint/tendermint/crypto/tmhash" "github.com/tendermint/tendermint/internal/eventbus" "github.com/tendermint/tendermint/internal/evidence" "github.com/tendermint/tendermint/internal/evidence/mocks" @@ -523,10 +522,10 @@ func TestEvidenceListSerialization(t *testing.T) { Round: 2, Timestamp: stamp, BlockID: types.BlockID{ - Hash: tmhash.Sum([]byte("blockID_hash")), + Hash: crypto.Checksum([]byte("blockID_hash")), PartSetHeader: types.PartSetHeader{ Total: 1000000, - Hash: tmhash.Sum([]byte("blockID_part_set_header_hash")), + Hash: crypto.Checksum([]byte("blockID_part_set_header_hash")), }, }, ValidatorAddress: crypto.AddressHash([]byte("validator_address")), diff --git a/internal/evidence/verify_test.go b/internal/evidence/verify_test.go index b7f535657..b2056186f 100644 --- a/internal/evidence/verify_test.go +++ b/internal/evidence/verify_test.go @@ -11,7 +11,6 @@ import ( dbm "github.com/tendermint/tm-db" "github.com/tendermint/tendermint/crypto" - "github.com/tendermint/tendermint/crypto/tmhash" "github.com/tendermint/tendermint/internal/eventbus" "github.com/tendermint/tendermint/internal/evidence" "github.com/tendermint/tendermint/internal/evidence/mocks" @@ -273,7 +272,7 @@ func TestVerifyLightClientAttack_Equivocation(t *testing.T) { // conflicting header has different next validators hash which should have been correctly derived from // the previous round - ev.ConflictingBlock.Header.NextValidatorsHash = crypto.CRandBytes(tmhash.Size) + ev.ConflictingBlock.Header.NextValidatorsHash = crypto.CRandBytes(crypto.HashSize) assert.Error(t, evidence.VerifyLightClientAttack(ev, trustedSignedHeader, trustedSignedHeader, nil, defaultEvidenceTime.Add(1*time.Minute), 2*time.Hour)) @@ -618,8 +617,8 @@ func makeVote( func makeBlockID(hash []byte, partSetSize uint32, partSetHash []byte) types.BlockID { var ( - h = make([]byte, tmhash.Size) - psH = make([]byte, tmhash.Size) + h = make([]byte, crypto.HashSize) + psH = make([]byte, crypto.HashSize) ) copy(h, hash) copy(psH, partSetHash) diff --git a/internal/libs/protoio/writer_test.go b/internal/libs/protoio/writer_test.go index 69867f733..cf1d0a2a4 100644 --- a/internal/libs/protoio/writer_test.go +++ b/internal/libs/protoio/writer_test.go @@ -8,7 +8,6 @@ import ( "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/crypto" - "github.com/tendermint/tendermint/crypto/tmhash" "github.com/tendermint/tendermint/internal/libs/protoio" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" "github.com/tendermint/tendermint/types" @@ -25,10 +24,10 @@ func aVote(t testing.TB) *types.Vote { Round: 2, Timestamp: stamp, BlockID: types.BlockID{ - Hash: tmhash.Sum([]byte("blockID_hash")), + Hash: crypto.Checksum([]byte("blockID_hash")), PartSetHeader: types.PartSetHeader{ Total: 1000000, - Hash: tmhash.Sum([]byte("blockID_part_set_header_hash")), + Hash: crypto.Checksum([]byte("blockID_part_set_header_hash")), }, }, ValidatorAddress: crypto.AddressHash([]byte("validator_address")), diff --git a/internal/state/execution_test.go b/internal/state/execution_test.go index 317f09706..0937b9990 100644 --- a/internal/state/execution_test.go +++ b/internal/state/execution_test.go @@ -18,7 +18,6 @@ import ( "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/ed25519" "github.com/tendermint/tendermint/crypto/encoding" - "github.com/tendermint/tendermint/crypto/tmhash" "github.com/tendermint/tendermint/internal/eventbus" mpmocks "github.com/tendermint/tendermint/internal/mempool/mocks" "github.com/tendermint/tendermint/internal/proxy" @@ -180,14 +179,14 @@ func TestFinalizeBlockByzantineValidators(t *testing.T) { Height: 10, Time: defaultEvidenceTime, LastBlockID: blockID, - LastCommitHash: crypto.CRandBytes(tmhash.Size), - DataHash: crypto.CRandBytes(tmhash.Size), + LastCommitHash: crypto.CRandBytes(crypto.HashSize), + DataHash: crypto.CRandBytes(crypto.HashSize), ValidatorsHash: state.Validators.Hash(), NextValidatorsHash: state.Validators.Hash(), - ConsensusHash: crypto.CRandBytes(tmhash.Size), - AppHash: crypto.CRandBytes(tmhash.Size), - LastResultsHash: crypto.CRandBytes(tmhash.Size), - EvidenceHash: crypto.CRandBytes(tmhash.Size), + ConsensusHash: crypto.CRandBytes(crypto.HashSize), + AppHash: crypto.CRandBytes(crypto.HashSize), + LastResultsHash: crypto.CRandBytes(crypto.HashSize), + EvidenceHash: crypto.CRandBytes(crypto.HashSize), ProposerAddress: crypto.CRandBytes(crypto.AddressSize), } @@ -1003,8 +1002,8 @@ func TestPrepareProposalErrorOnPrepareProposalError(t *testing.T) { func makeBlockID(hash []byte, partSetSize uint32, partSetHash []byte) types.BlockID { var ( - h = make([]byte, tmhash.Size) - psH = make([]byte, tmhash.Size) + h = make([]byte, crypto.HashSize) + psH = make([]byte, crypto.HashSize) ) copy(h, hash) copy(psH, partSetHash) diff --git a/internal/state/validation_test.go b/internal/state/validation_test.go index 4fd0b49bd..376ce61bc 100644 --- a/internal/state/validation_test.go +++ b/internal/state/validation_test.go @@ -12,8 +12,8 @@ import ( abciclient "github.com/tendermint/tendermint/abci/client" abci "github.com/tendermint/tendermint/abci/types" + "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/ed25519" - "github.com/tendermint/tendermint/crypto/tmhash" "github.com/tendermint/tendermint/internal/eventbus" mpmocks "github.com/tendermint/tendermint/internal/mempool/mocks" "github.com/tendermint/tendermint/internal/proxy" @@ -68,7 +68,7 @@ func TestValidateBlockHeader(t *testing.T) { lastCommit := types.NewCommit(0, 0, types.BlockID{}, nil) // some bad values - wrongHash := tmhash.Sum([]byte("this hash is wrong")) + wrongHash := crypto.Checksum([]byte("this hash is wrong")) wrongVersion1 := state.Version.Consensus wrongVersion1.Block += 2 wrongVersion2 := state.Version.Consensus diff --git a/internal/test/factory/block.go b/internal/test/factory/block.go index 1d5709dcc..2cb6a3161 100644 --- a/internal/test/factory/block.go +++ b/internal/test/factory/block.go @@ -7,7 +7,6 @@ import ( "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/crypto" - "github.com/tendermint/tendermint/crypto/tmhash" "github.com/tendermint/tendermint/types" "github.com/tendermint/tendermint/version" ) @@ -25,7 +24,7 @@ func RandomAddress() []byte { } func RandomHash() []byte { - return crypto.CRandBytes(tmhash.Size) + return crypto.CRandBytes(crypto.HashSize) } func MakeBlockID() types.BlockID { diff --git a/light/helpers_test.go b/light/helpers_test.go index 4d002d936..d93735bb7 100644 --- a/light/helpers_test.go +++ b/light/helpers_test.go @@ -9,7 +9,6 @@ import ( "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/ed25519" - "github.com/tendermint/tendermint/crypto/tmhash" tmtime "github.com/tendermint/tendermint/libs/time" provider_mocks "github.com/tendermint/tendermint/light/provider/mocks" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" @@ -222,5 +221,5 @@ func mockNodeFromHeadersAndVals(headers map[int64]*types.SignedHeader, } func hash(s string) []byte { - return tmhash.Sum([]byte(s)) + return crypto.Checksum([]byte(s)) } diff --git a/light/store/db/db_test.go b/light/store/db/db_test.go index 7069eb11d..cae9bbfc5 100644 --- a/light/store/db/db_test.go +++ b/light/store/db/db_test.go @@ -11,7 +11,6 @@ import ( dbm "github.com/tendermint/tm-db" "github.com/tendermint/tendermint/crypto" - "github.com/tendermint/tendermint/crypto/tmhash" "github.com/tendermint/tendermint/internal/test/factory" tmrand "github.com/tendermint/tendermint/libs/rand" "github.com/tendermint/tendermint/types" @@ -205,14 +204,14 @@ func randLightBlock(ctx context.Context, t *testing.T, height int64) *types.Ligh Height: height, Time: time.Now(), LastBlockID: types.BlockID{}, - LastCommitHash: crypto.CRandBytes(tmhash.Size), - DataHash: crypto.CRandBytes(tmhash.Size), - ValidatorsHash: crypto.CRandBytes(tmhash.Size), - NextValidatorsHash: crypto.CRandBytes(tmhash.Size), - ConsensusHash: crypto.CRandBytes(tmhash.Size), - AppHash: crypto.CRandBytes(tmhash.Size), - LastResultsHash: crypto.CRandBytes(tmhash.Size), - EvidenceHash: crypto.CRandBytes(tmhash.Size), + LastCommitHash: crypto.CRandBytes(crypto.HashSize), + DataHash: crypto.CRandBytes(crypto.HashSize), + ValidatorsHash: crypto.CRandBytes(crypto.HashSize), + NextValidatorsHash: crypto.CRandBytes(crypto.HashSize), + ConsensusHash: crypto.CRandBytes(crypto.HashSize), + AppHash: crypto.CRandBytes(crypto.HashSize), + LastResultsHash: crypto.CRandBytes(crypto.HashSize), + EvidenceHash: crypto.CRandBytes(crypto.HashSize), ProposerAddress: crypto.CRandBytes(crypto.AddressSize), }, Commit: &types.Commit{}, diff --git a/light/trust_options.go b/light/trust_options.go index cbf3b1cd8..2bfad9857 100644 --- a/light/trust_options.go +++ b/light/trust_options.go @@ -5,7 +5,7 @@ import ( "fmt" "time" - "github.com/tendermint/tendermint/crypto/tmhash" + "github.com/tendermint/tendermint/crypto" ) // TrustOptions are the trust parameters needed when a new light client @@ -43,9 +43,9 @@ func (opts TrustOptions) ValidateBasic() error { if opts.Height <= 0 { return errors.New("negative or zero height") } - if len(opts.Hash) != tmhash.Size { + if len(opts.Hash) != crypto.HashSize { return fmt.Errorf("expected hash size to be %d bytes, got %d bytes", - tmhash.Size, + crypto.HashSize, len(opts.Hash), ) } diff --git a/node/node_test.go b/node/node_test.go index cb6f65add..c5ff1f014 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -20,7 +20,6 @@ import ( "github.com/tendermint/tendermint/config" "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/ed25519" - "github.com/tendermint/tendermint/crypto/tmhash" "github.com/tendermint/tendermint/internal/eventbus" "github.com/tendermint/tendermint/internal/evidence" "github.com/tendermint/tendermint/internal/mempool" @@ -498,10 +497,10 @@ func TestMaxProposalBlockSize(t *testing.T) { ) blockID := types.BlockID{ - Hash: tmhash.Sum([]byte("blockID_hash")), + Hash: crypto.Checksum([]byte("blockID_hash")), PartSetHeader: types.PartSetHeader{ Total: math.MaxInt32, - Hash: tmhash.Sum([]byte("blockID_part_set_header_hash")), + Hash: crypto.Checksum([]byte("blockID_part_set_header_hash")), }, } @@ -516,8 +515,8 @@ func TestMaxProposalBlockSize(t *testing.T) { state.LastBlockID = blockID state.LastBlockHeight = math.MaxInt64 - 2 state.LastBlockTime = timestamp - state.LastResultsHash = tmhash.Sum([]byte("last_results_hash")) - state.AppHash = tmhash.Sum([]byte("app_hash")) + state.LastResultsHash = crypto.Checksum([]byte("last_results_hash")) + state.AppHash = crypto.Checksum([]byte("app_hash")) state.Version.Consensus.Block = math.MaxInt64 state.Version.Consensus.App = math.MaxInt64 maxChainID := "" diff --git a/privval/file_test.go b/privval/file_test.go index 30df335a2..9f1105441 100644 --- a/privval/file_test.go +++ b/privval/file_test.go @@ -12,8 +12,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/ed25519" - "github.com/tendermint/tendermint/crypto/tmhash" tmrand "github.com/tendermint/tendermint/libs/rand" tmtime "github.com/tendermint/tendermint/libs/time" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" @@ -47,7 +47,7 @@ func TestResetValidator(t *testing.T) { // test vote height, round := int64(10), int32(1) voteType := tmproto.PrevoteType - randBytes := tmrand.Bytes(tmhash.Size) + randBytes := tmrand.Bytes(crypto.HashSize) blockID := types.BlockID{Hash: randBytes, PartSetHeader: types.PartSetHeader{}} vote := newVote(privVal.Key.Address, 0, height, round, voteType, blockID, nil) err := privVal.SignVote(ctx, "mychainid", vote.ToProto()) @@ -150,8 +150,8 @@ func TestSignVote(t *testing.T) { privVal, _, _ := newTestFilePV(t) - randbytes := tmrand.Bytes(tmhash.Size) - randbytes2 := tmrand.Bytes(tmhash.Size) + randbytes := tmrand.Bytes(crypto.HashSize) + randbytes2 := tmrand.Bytes(crypto.HashSize) block1 := types.BlockID{Hash: randbytes, PartSetHeader: types.PartSetHeader{Total: 5, Hash: randbytes}} @@ -199,8 +199,8 @@ func TestSignProposal(t *testing.T) { privVal, _, _ := newTestFilePV(t) - randbytes := tmrand.Bytes(tmhash.Size) - randbytes2 := tmrand.Bytes(tmhash.Size) + randbytes := tmrand.Bytes(crypto.HashSize) + randbytes2 := tmrand.Bytes(crypto.HashSize) block1 := types.BlockID{Hash: randbytes, PartSetHeader: types.PartSetHeader{Total: 5, Hash: randbytes}} @@ -246,7 +246,7 @@ func TestDifferByTimestamp(t *testing.T) { privVal, err := GenFilePV(tempKeyFile.Name(), tempStateFile.Name(), "") require.NoError(t, err) - randbytes := tmrand.Bytes(tmhash.Size) + randbytes := tmrand.Bytes(crypto.HashSize) height, round := int64(10), int32(1) chainID := "mychainid" @@ -285,8 +285,8 @@ func TestVoteExtensionsAreAlwaysSigned(t *testing.T) { assert.NoError(t, err) block := types.BlockID{ - Hash: tmrand.Bytes(tmhash.Size), - PartSetHeader: types.PartSetHeader{Total: 5, Hash: tmrand.Bytes(tmhash.Size)}, + Hash: tmrand.Bytes(crypto.HashSize), + PartSetHeader: types.PartSetHeader{Total: 5, Hash: tmrand.Bytes(crypto.HashSize)}, } height, round := int64(10), int32(1) diff --git a/privval/grpc/client_test.go b/privval/grpc/client_test.go index ac7608274..0b1056d03 100644 --- a/privval/grpc/client_test.go +++ b/privval/grpc/client_test.go @@ -14,7 +14,6 @@ import ( "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/crypto" - "github.com/tendermint/tendermint/crypto/tmhash" "github.com/tendermint/tendermint/libs/log" tmrand "github.com/tendermint/tendermint/libs/rand" tmgrpc "github.com/tendermint/tendermint/privval/grpc" @@ -86,7 +85,7 @@ func TestSignerClient_SignVote(t *testing.T) { require.NoError(t, err) ts := time.Now() - hash := tmrand.Bytes(tmhash.Size) + hash := tmrand.Bytes(crypto.HashSize) valAddr := tmrand.Bytes(crypto.AddressSize) want := &types.Vote{ @@ -141,7 +140,7 @@ func TestSignerClient_SignProposal(t *testing.T) { require.NoError(t, err) ts := time.Now() - hash := tmrand.Bytes(tmhash.Size) + hash := tmrand.Bytes(crypto.HashSize) have := &types.Proposal{ Type: tmproto.ProposalType, diff --git a/privval/grpc/server_test.go b/privval/grpc/server_test.go index 78e9c79ed..db85a42b7 100644 --- a/privval/grpc/server_test.go +++ b/privval/grpc/server_test.go @@ -9,7 +9,6 @@ import ( "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/crypto" - "github.com/tendermint/tendermint/crypto/tmhash" "github.com/tendermint/tendermint/libs/log" tmrand "github.com/tendermint/tendermint/libs/rand" tmgrpc "github.com/tendermint/tendermint/privval/grpc" @@ -57,7 +56,7 @@ func TestGetPubKey(t *testing.T) { func TestSignVote(t *testing.T) { ts := time.Now() - hash := tmrand.Bytes(tmhash.Size) + hash := tmrand.Bytes(crypto.HashSize) valAddr := tmrand.Bytes(crypto.AddressSize) testCases := []struct { @@ -133,7 +132,7 @@ func TestSignVote(t *testing.T) { func TestSignProposal(t *testing.T) { ts := time.Now() - hash := tmrand.Bytes(tmhash.Size) + hash := tmrand.Bytes(crypto.HashSize) testCases := []struct { name string diff --git a/privval/msgs_test.go b/privval/msgs_test.go index 20e73762c..01cef4641 100644 --- a/privval/msgs_test.go +++ b/privval/msgs_test.go @@ -11,7 +11,6 @@ import ( "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/ed25519" "github.com/tendermint/tendermint/crypto/encoding" - "github.com/tendermint/tendermint/crypto/tmhash" cryptoproto "github.com/tendermint/tendermint/proto/tendermint/crypto" privproto "github.com/tendermint/tendermint/proto/tendermint/privval" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" @@ -25,7 +24,7 @@ func exampleVote() *types.Vote { Type: tmproto.PrecommitType, Height: 3, Round: 2, - BlockID: types.BlockID{Hash: tmhash.Sum([]byte("blockID_hash")), PartSetHeader: types.PartSetHeader{Total: 1000000, Hash: tmhash.Sum([]byte("blockID_part_set_header_hash"))}}, + BlockID: types.BlockID{Hash: crypto.Checksum([]byte("blockID_hash")), PartSetHeader: types.PartSetHeader{Total: 1000000, Hash: crypto.Checksum([]byte("blockID_part_set_header_hash"))}}, Timestamp: stamp, ValidatorAddress: crypto.AddressHash([]byte("validator_address")), ValidatorIndex: 56789, @@ -43,10 +42,10 @@ func exampleProposal() *types.Proposal { POLRound: 2, Signature: []byte("it's a signature"), BlockID: types.BlockID{ - Hash: tmhash.Sum([]byte("blockID_hash")), + Hash: crypto.Checksum([]byte("blockID_hash")), PartSetHeader: types.PartSetHeader{ Total: 1000000, - Hash: tmhash.Sum([]byte("blockID_part_set_header_hash")), + Hash: crypto.Checksum([]byte("blockID_part_set_header_hash")), }, }, } diff --git a/privval/signer_client_test.go b/privval/signer_client_test.go index 272902fc9..fef16f2d6 100644 --- a/privval/signer_client_test.go +++ b/privval/signer_client_test.go @@ -11,7 +11,6 @@ import ( "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/crypto" - "github.com/tendermint/tendermint/crypto/tmhash" "github.com/tendermint/tendermint/libs/log" tmrand "github.com/tendermint/tendermint/libs/rand" cryptoproto "github.com/tendermint/tendermint/proto/tendermint/crypto" @@ -143,7 +142,7 @@ func TestSignerProposal(t *testing.T) { defer tc.closer() ts := time.Now() - hash := tmrand.Bytes(tmhash.Size) + hash := tmrand.Bytes(crypto.HashSize) have := &types.Proposal{ Type: tmproto.ProposalType, Height: 1, @@ -183,7 +182,7 @@ func TestSignerVote(t *testing.T) { defer tc.closer() ts := time.Now() - hash := tmrand.Bytes(tmhash.Size) + hash := tmrand.Bytes(crypto.HashSize) valAddr := tmrand.Bytes(crypto.AddressSize) want := &types.Vote{ Type: tmproto.PrecommitType, @@ -224,7 +223,7 @@ func TestSignerVoteResetDeadline(t *testing.T) { for _, tc := range getSignerTestCases(ctx, t, logger) { t.Run(tc.name, func(t *testing.T) { ts := time.Now() - hash := tmrand.Bytes(tmhash.Size) + hash := tmrand.Bytes(crypto.HashSize) valAddr := tmrand.Bytes(crypto.AddressSize) want := &types.Vote{ Type: tmproto.PrecommitType, @@ -277,7 +276,7 @@ func TestSignerVoteKeepAlive(t *testing.T) { defer tc.closer() ts := time.Now() - hash := tmrand.Bytes(tmhash.Size) + hash := tmrand.Bytes(crypto.HashSize) valAddr := tmrand.Bytes(crypto.AddressSize) want := &types.Vote{ Type: tmproto.PrecommitType, @@ -330,7 +329,7 @@ func TestSignerSignProposalErrors(t *testing.T) { tc.mockPV = types.NewErroringMockPV() ts := time.Now() - hash := tmrand.Bytes(tmhash.Size) + hash := tmrand.Bytes(crypto.HashSize) proposal := &types.Proposal{ Type: tmproto.ProposalType, Height: 1, @@ -368,7 +367,7 @@ func TestSignerSignVoteErrors(t *testing.T) { defer tc.closer() ts := time.Now() - hash := tmrand.Bytes(tmhash.Size) + hash := tmrand.Bytes(crypto.HashSize) valAddr := tmrand.Bytes(crypto.AddressSize) vote := &types.Vote{ Type: tmproto.PrecommitType, diff --git a/rpc/client/evidence_test.go b/rpc/client/evidence_test.go index 9187ddc1a..0096d0924 100644 --- a/rpc/client/evidence_test.go +++ b/rpc/client/evidence_test.go @@ -7,7 +7,7 @@ import ( "github.com/stretchr/testify/require" - "github.com/tendermint/tendermint/crypto/tmhash" + "github.com/tendermint/tendermint/crypto" tmrand "github.com/tendermint/tendermint/libs/rand" "github.com/tendermint/tendermint/privval" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" @@ -54,16 +54,16 @@ func makeEvidences( Type: tmproto.PrevoteType, Timestamp: timestamp, BlockID: types.BlockID{ - Hash: tmhash.Sum(tmrand.Bytes(tmhash.Size)), + Hash: crypto.Checksum(tmrand.Bytes(crypto.HashSize)), PartSetHeader: types.PartSetHeader{ Total: 1000, - Hash: tmhash.Sum([]byte("partset")), + Hash: crypto.Checksum([]byte("partset")), }, }, } vote2 := vote - vote2.BlockID.Hash = tmhash.Sum([]byte("blockhash2")) + vote2.BlockID.Hash = crypto.Checksum([]byte("blockhash2")) correct = newEvidence(t, val, &vote, &vote2, chainID, timestamp) fakes = make([]*types.DuplicateVoteEvidence, 0) diff --git a/test/e2e/runner/evidence.go b/test/e2e/runner/evidence.go index 10db5d58b..849e4edc3 100644 --- a/test/e2e/runner/evidence.go +++ b/test/e2e/runner/evidence.go @@ -12,7 +12,6 @@ import ( "time" "github.com/tendermint/tendermint/crypto" - "github.com/tendermint/tendermint/crypto/tmhash" "github.com/tendermint/tendermint/internal/test/factory" "github.com/tendermint/tendermint/libs/log" "github.com/tendermint/tendermint/privval" @@ -256,26 +255,26 @@ func makeHeaderRandom(chainID string, height int64) *types.Header { Height: height, Time: time.Now(), LastBlockID: makeBlockID([]byte("headerhash"), 1000, []byte("partshash")), - LastCommitHash: crypto.CRandBytes(tmhash.Size), - DataHash: crypto.CRandBytes(tmhash.Size), - ValidatorsHash: crypto.CRandBytes(tmhash.Size), - NextValidatorsHash: crypto.CRandBytes(tmhash.Size), - ConsensusHash: crypto.CRandBytes(tmhash.Size), - AppHash: crypto.CRandBytes(tmhash.Size), - LastResultsHash: crypto.CRandBytes(tmhash.Size), - EvidenceHash: crypto.CRandBytes(tmhash.Size), + LastCommitHash: crypto.CRandBytes(crypto.HashSize), + DataHash: crypto.CRandBytes(crypto.HashSize), + ValidatorsHash: crypto.CRandBytes(crypto.HashSize), + NextValidatorsHash: crypto.CRandBytes(crypto.HashSize), + ConsensusHash: crypto.CRandBytes(crypto.HashSize), + AppHash: crypto.CRandBytes(crypto.HashSize), + LastResultsHash: crypto.CRandBytes(crypto.HashSize), + EvidenceHash: crypto.CRandBytes(crypto.HashSize), ProposerAddress: crypto.CRandBytes(crypto.AddressSize), } } func makeRandomBlockID() types.BlockID { - return makeBlockID(crypto.CRandBytes(tmhash.Size), 100, crypto.CRandBytes(tmhash.Size)) + return makeBlockID(crypto.CRandBytes(crypto.HashSize), 100, crypto.CRandBytes(crypto.HashSize)) } func makeBlockID(hash []byte, partSetSize uint32, partSetHash []byte) types.BlockID { var ( - h = make([]byte, tmhash.Size) - psH = make([]byte, tmhash.Size) + h = make([]byte, crypto.HashSize) + psH = make([]byte, crypto.HashSize) ) copy(h, hash) copy(psH, partSetHash) diff --git a/types/block.go b/types/block.go index cb1b43ea5..17e9812cf 100644 --- a/types/block.go +++ b/types/block.go @@ -13,7 +13,6 @@ import ( "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/merkle" - "github.com/tendermint/tendermint/crypto/tmhash" "github.com/tendermint/tendermint/libs/bits" tmbytes "github.com/tendermint/tendermint/libs/bytes" tmmath "github.com/tendermint/tendermint/libs/math" @@ -1126,9 +1125,9 @@ func (blockID BlockID) IsNil() bool { // IsComplete returns true if this is a valid BlockID of a non-nil block. func (blockID BlockID) IsComplete() bool { - return len(blockID.Hash) == tmhash.Size && + return len(blockID.Hash) == crypto.HashSize && blockID.PartSetHeader.Total > 0 && - len(blockID.PartSetHeader.Hash) == tmhash.Size + len(blockID.PartSetHeader.Hash) == crypto.HashSize } // String returns a human readable string representation of the BlockID. diff --git a/types/block_meta_test.go b/types/block_meta_test.go index a1a382ffa..0ce90c40b 100644 --- a/types/block_meta_test.go +++ b/types/block_meta_test.go @@ -5,13 +5,13 @@ import ( "github.com/stretchr/testify/require" - "github.com/tendermint/tendermint/crypto/tmhash" + "github.com/tendermint/tendermint/crypto" tmrand "github.com/tendermint/tendermint/libs/rand" ) func TestBlockMeta_ToProto(t *testing.T) { h := MakeRandHeader() - bi := BlockID{Hash: h.Hash(), PartSetHeader: PartSetHeader{Total: 123, Hash: tmrand.Bytes(tmhash.Size)}} + bi := BlockID{Hash: h.Hash(), PartSetHeader: PartSetHeader{Total: 123, Hash: tmrand.Bytes(crypto.HashSize)}} bm := &BlockMeta{ BlockID: bi, @@ -48,9 +48,9 @@ func TestBlockMeta_ToProto(t *testing.T) { func TestBlockMeta_ValidateBasic(t *testing.T) { h := MakeRandHeader() - bi := BlockID{Hash: h.Hash(), PartSetHeader: PartSetHeader{Total: 123, Hash: tmrand.Bytes(tmhash.Size)}} - bi2 := BlockID{Hash: tmrand.Bytes(tmhash.Size), - PartSetHeader: PartSetHeader{Total: 123, Hash: tmrand.Bytes(tmhash.Size)}} + bi := BlockID{Hash: h.Hash(), PartSetHeader: PartSetHeader{Total: 123, Hash: tmrand.Bytes(crypto.HashSize)}} + bi2 := BlockID{Hash: tmrand.Bytes(crypto.HashSize), + PartSetHeader: PartSetHeader{Total: 123, Hash: tmrand.Bytes(crypto.HashSize)}} bi3 := BlockID{Hash: []byte("incorrect hash"), PartSetHeader: PartSetHeader{Total: 123, Hash: []byte("incorrect hash")}} diff --git a/types/block_test.go b/types/block_test.go index 97b12cdba..7f2378505 100644 --- a/types/block_test.go +++ b/types/block_test.go @@ -19,7 +19,6 @@ import ( "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/merkle" - "github.com/tendermint/tendermint/crypto/tmhash" "github.com/tendermint/tendermint/libs/bits" "github.com/tendermint/tendermint/libs/bytes" tmrand "github.com/tendermint/tendermint/libs/rand" @@ -213,8 +212,8 @@ func TestBlockString(t *testing.T) { func makeBlockIDRandom() BlockID { var ( - blockHash = make([]byte, tmhash.Size) - partSetHash = make([]byte, tmhash.Size) + blockHash = make([]byte, crypto.HashSize) + partSetHash = make([]byte, crypto.HashSize) ) rand.Read(blockHash) //nolint: errcheck // ignore errcheck for read rand.Read(partSetHash) //nolint: errcheck // ignore errcheck for read @@ -223,8 +222,8 @@ func makeBlockIDRandom() BlockID { func makeBlockID(hash []byte, partSetSize uint32, partSetHash []byte) BlockID { var ( - h = make([]byte, tmhash.Size) - psH = make([]byte, tmhash.Size) + h = make([]byte, crypto.HashSize) + psH = make([]byte, crypto.HashSize) ) copy(h, hash) copy(psH, partSetHash) @@ -324,10 +323,10 @@ func TestMaxCommitBytes(t *testing.T) { Height: math.MaxInt64, Round: math.MaxInt32, BlockID: BlockID{ - Hash: tmhash.Sum([]byte("blockID_hash")), + Hash: crypto.Checksum([]byte("blockID_hash")), PartSetHeader: PartSetHeader{ Total: math.MaxInt32, - Hash: tmhash.Sum([]byte("blockID_part_set_header_hash")), + Hash: crypto.Checksum([]byte("blockID_part_set_header_hash")), }, }, Signatures: []CommitSig{cs}, @@ -359,15 +358,15 @@ func TestHeaderHash(t *testing.T) { ChainID: "chainId", Height: 3, Time: time.Date(2019, 10, 13, 16, 14, 44, 0, time.UTC), - LastBlockID: makeBlockID(make([]byte, tmhash.Size), 6, make([]byte, tmhash.Size)), - LastCommitHash: tmhash.Sum([]byte("last_commit_hash")), - DataHash: tmhash.Sum([]byte("data_hash")), - ValidatorsHash: tmhash.Sum([]byte("validators_hash")), - NextValidatorsHash: tmhash.Sum([]byte("next_validators_hash")), - ConsensusHash: tmhash.Sum([]byte("consensus_hash")), - AppHash: tmhash.Sum([]byte("app_hash")), - LastResultsHash: tmhash.Sum([]byte("last_results_hash")), - EvidenceHash: tmhash.Sum([]byte("evidence_hash")), + LastBlockID: makeBlockID(make([]byte, crypto.HashSize), 6, make([]byte, crypto.HashSize)), + LastCommitHash: crypto.Checksum([]byte("last_commit_hash")), + DataHash: crypto.Checksum([]byte("data_hash")), + ValidatorsHash: crypto.Checksum([]byte("validators_hash")), + NextValidatorsHash: crypto.Checksum([]byte("next_validators_hash")), + ConsensusHash: crypto.Checksum([]byte("consensus_hash")), + AppHash: crypto.Checksum([]byte("app_hash")), + LastResultsHash: crypto.Checksum([]byte("last_results_hash")), + EvidenceHash: crypto.Checksum([]byte("evidence_hash")), ProposerAddress: crypto.AddressHash([]byte("proposer_address")), }, hexBytesFromString(t, "F740121F553B5418C3EFBD343C2DBFE9E007BB67B0D020A0741374BAB65242A4")}, {"nil header yields nil", nil, nil}, @@ -376,15 +375,15 @@ func TestHeaderHash(t *testing.T) { ChainID: "chainId", Height: 3, Time: time.Date(2019, 10, 13, 16, 14, 44, 0, time.UTC), - LastBlockID: makeBlockID(make([]byte, tmhash.Size), 6, make([]byte, tmhash.Size)), - LastCommitHash: tmhash.Sum([]byte("last_commit_hash")), - DataHash: tmhash.Sum([]byte("data_hash")), + LastBlockID: makeBlockID(make([]byte, crypto.HashSize), 6, make([]byte, crypto.HashSize)), + LastCommitHash: crypto.Checksum([]byte("last_commit_hash")), + DataHash: crypto.Checksum([]byte("data_hash")), ValidatorsHash: nil, - NextValidatorsHash: tmhash.Sum([]byte("next_validators_hash")), - ConsensusHash: tmhash.Sum([]byte("consensus_hash")), - AppHash: tmhash.Sum([]byte("app_hash")), - LastResultsHash: tmhash.Sum([]byte("last_results_hash")), - EvidenceHash: tmhash.Sum([]byte("evidence_hash")), + NextValidatorsHash: crypto.Checksum([]byte("next_validators_hash")), + ConsensusHash: crypto.Checksum([]byte("consensus_hash")), + AppHash: crypto.Checksum([]byte("app_hash")), + LastResultsHash: crypto.Checksum([]byte("last_results_hash")), + EvidenceHash: crypto.Checksum([]byte("evidence_hash")), ProposerAddress: crypto.AddressHash([]byte("proposer_address")), }, nil}, } @@ -455,15 +454,15 @@ func TestMaxHeaderBytes(t *testing.T) { ChainID: maxChainID, Height: math.MaxInt64, Time: timestamp, - LastBlockID: makeBlockID(make([]byte, tmhash.Size), math.MaxInt32, make([]byte, tmhash.Size)), - LastCommitHash: tmhash.Sum([]byte("last_commit_hash")), - DataHash: tmhash.Sum([]byte("data_hash")), - ValidatorsHash: tmhash.Sum([]byte("validators_hash")), - NextValidatorsHash: tmhash.Sum([]byte("next_validators_hash")), - ConsensusHash: tmhash.Sum([]byte("consensus_hash")), - AppHash: tmhash.Sum([]byte("app_hash")), - LastResultsHash: tmhash.Sum([]byte("last_results_hash")), - EvidenceHash: tmhash.Sum([]byte("evidence_hash")), + LastBlockID: makeBlockID(make([]byte, crypto.HashSize), math.MaxInt32, make([]byte, crypto.HashSize)), + LastCommitHash: crypto.Checksum([]byte("last_commit_hash")), + DataHash: crypto.Checksum([]byte("data_hash")), + ValidatorsHash: crypto.Checksum([]byte("validators_hash")), + NextValidatorsHash: crypto.Checksum([]byte("next_validators_hash")), + ConsensusHash: crypto.Checksum([]byte("consensus_hash")), + AppHash: crypto.Checksum([]byte("app_hash")), + LastResultsHash: crypto.Checksum([]byte("last_results_hash")), + EvidenceHash: crypto.Checksum([]byte("evidence_hash")), ProposerAddress: crypto.AddressHash([]byte("proposer_address")), } @@ -765,7 +764,7 @@ func MakeRandHeader() Header { chainID := "test" t := time.Now() height := mrand.Int63() - randBytes := tmrand.Bytes(tmhash.Size) + randBytes := tmrand.Bytes(crypto.HashSize) randAddress := tmrand.Bytes(crypto.AddressSize) h := Header{ Version: version.Consensus{Block: version.BlockProtocol, App: 1}, @@ -1014,7 +1013,7 @@ func TestHeader_ValidateBasic(t *testing.T) { ChainID: string(make([]byte, MaxChainIDLen)), Height: 1, LastBlockID: BlockID{ - Hash: make([]byte, tmhash.Size+1), + Hash: make([]byte, crypto.HashSize+1), }, }, true, "wrong Hash", @@ -1026,9 +1025,9 @@ func TestHeader_ValidateBasic(t *testing.T) { ChainID: string(make([]byte, MaxChainIDLen)), Height: 1, LastBlockID: BlockID{ - Hash: make([]byte, tmhash.Size), + Hash: make([]byte, crypto.HashSize), PartSetHeader: PartSetHeader{ - Hash: make([]byte, tmhash.Size+1), + Hash: make([]byte, crypto.HashSize+1), }, }, }, @@ -1041,12 +1040,12 @@ func TestHeader_ValidateBasic(t *testing.T) { ChainID: string(make([]byte, MaxChainIDLen)), Height: 1, LastBlockID: BlockID{ - Hash: make([]byte, tmhash.Size), + Hash: make([]byte, crypto.HashSize), PartSetHeader: PartSetHeader{ - Hash: make([]byte, tmhash.Size), + Hash: make([]byte, crypto.HashSize), }, }, - LastCommitHash: make([]byte, tmhash.Size+1), + LastCommitHash: make([]byte, crypto.HashSize+1), }, true, "wrong LastCommitHash", }, @@ -1057,13 +1056,13 @@ func TestHeader_ValidateBasic(t *testing.T) { ChainID: string(make([]byte, MaxChainIDLen)), Height: 1, LastBlockID: BlockID{ - Hash: make([]byte, tmhash.Size), + Hash: make([]byte, crypto.HashSize), PartSetHeader: PartSetHeader{ - Hash: make([]byte, tmhash.Size), + Hash: make([]byte, crypto.HashSize), }, }, - LastCommitHash: make([]byte, tmhash.Size), - DataHash: make([]byte, tmhash.Size+1), + LastCommitHash: make([]byte, crypto.HashSize), + DataHash: make([]byte, crypto.HashSize+1), }, true, "wrong DataHash", }, @@ -1074,14 +1073,14 @@ func TestHeader_ValidateBasic(t *testing.T) { ChainID: string(make([]byte, MaxChainIDLen)), Height: 1, LastBlockID: BlockID{ - Hash: make([]byte, tmhash.Size), + Hash: make([]byte, crypto.HashSize), PartSetHeader: PartSetHeader{ - Hash: make([]byte, tmhash.Size), + Hash: make([]byte, crypto.HashSize), }, }, - LastCommitHash: make([]byte, tmhash.Size), - DataHash: make([]byte, tmhash.Size), - EvidenceHash: make([]byte, tmhash.Size+1), + LastCommitHash: make([]byte, crypto.HashSize), + DataHash: make([]byte, crypto.HashSize), + EvidenceHash: make([]byte, crypto.HashSize+1), }, true, "wrong EvidenceHash", }, @@ -1092,14 +1091,14 @@ func TestHeader_ValidateBasic(t *testing.T) { ChainID: string(make([]byte, MaxChainIDLen)), Height: 1, LastBlockID: BlockID{ - Hash: make([]byte, tmhash.Size), + Hash: make([]byte, crypto.HashSize), PartSetHeader: PartSetHeader{ - Hash: make([]byte, tmhash.Size), + Hash: make([]byte, crypto.HashSize), }, }, - LastCommitHash: make([]byte, tmhash.Size), - DataHash: make([]byte, tmhash.Size), - EvidenceHash: make([]byte, tmhash.Size), + LastCommitHash: make([]byte, crypto.HashSize), + DataHash: make([]byte, crypto.HashSize), + EvidenceHash: make([]byte, crypto.HashSize), ProposerAddress: make([]byte, crypto.AddressSize+1), }, true, "invalid ProposerAddress length", @@ -1111,16 +1110,16 @@ func TestHeader_ValidateBasic(t *testing.T) { ChainID: string(make([]byte, MaxChainIDLen)), Height: 1, LastBlockID: BlockID{ - Hash: make([]byte, tmhash.Size), + Hash: make([]byte, crypto.HashSize), PartSetHeader: PartSetHeader{ - Hash: make([]byte, tmhash.Size), + Hash: make([]byte, crypto.HashSize), }, }, - LastCommitHash: make([]byte, tmhash.Size), - DataHash: make([]byte, tmhash.Size), - EvidenceHash: make([]byte, tmhash.Size), + LastCommitHash: make([]byte, crypto.HashSize), + DataHash: make([]byte, crypto.HashSize), + EvidenceHash: make([]byte, crypto.HashSize), ProposerAddress: make([]byte, crypto.AddressSize), - ValidatorsHash: make([]byte, tmhash.Size+1), + ValidatorsHash: make([]byte, crypto.HashSize+1), }, true, "wrong ValidatorsHash", }, @@ -1131,17 +1130,17 @@ func TestHeader_ValidateBasic(t *testing.T) { ChainID: string(make([]byte, MaxChainIDLen)), Height: 1, LastBlockID: BlockID{ - Hash: make([]byte, tmhash.Size), + Hash: make([]byte, crypto.HashSize), PartSetHeader: PartSetHeader{ - Hash: make([]byte, tmhash.Size), + Hash: make([]byte, crypto.HashSize), }, }, - LastCommitHash: make([]byte, tmhash.Size), - DataHash: make([]byte, tmhash.Size), - EvidenceHash: make([]byte, tmhash.Size), + LastCommitHash: make([]byte, crypto.HashSize), + DataHash: make([]byte, crypto.HashSize), + EvidenceHash: make([]byte, crypto.HashSize), ProposerAddress: make([]byte, crypto.AddressSize), - ValidatorsHash: make([]byte, tmhash.Size), - NextValidatorsHash: make([]byte, tmhash.Size+1), + ValidatorsHash: make([]byte, crypto.HashSize), + NextValidatorsHash: make([]byte, crypto.HashSize+1), }, true, "wrong NextValidatorsHash", }, @@ -1152,18 +1151,18 @@ func TestHeader_ValidateBasic(t *testing.T) { ChainID: string(make([]byte, MaxChainIDLen)), Height: 1, LastBlockID: BlockID{ - Hash: make([]byte, tmhash.Size), + Hash: make([]byte, crypto.HashSize), PartSetHeader: PartSetHeader{ - Hash: make([]byte, tmhash.Size), + Hash: make([]byte, crypto.HashSize), }, }, - LastCommitHash: make([]byte, tmhash.Size), - DataHash: make([]byte, tmhash.Size), - EvidenceHash: make([]byte, tmhash.Size), + LastCommitHash: make([]byte, crypto.HashSize), + DataHash: make([]byte, crypto.HashSize), + EvidenceHash: make([]byte, crypto.HashSize), ProposerAddress: make([]byte, crypto.AddressSize), - ValidatorsHash: make([]byte, tmhash.Size), - NextValidatorsHash: make([]byte, tmhash.Size), - ConsensusHash: make([]byte, tmhash.Size+1), + ValidatorsHash: make([]byte, crypto.HashSize), + NextValidatorsHash: make([]byte, crypto.HashSize), + ConsensusHash: make([]byte, crypto.HashSize+1), }, true, "wrong ConsensusHash", }, @@ -1174,19 +1173,19 @@ func TestHeader_ValidateBasic(t *testing.T) { ChainID: string(make([]byte, MaxChainIDLen)), Height: 1, LastBlockID: BlockID{ - Hash: make([]byte, tmhash.Size), + Hash: make([]byte, crypto.HashSize), PartSetHeader: PartSetHeader{ - Hash: make([]byte, tmhash.Size), + Hash: make([]byte, crypto.HashSize), }, }, - LastCommitHash: make([]byte, tmhash.Size), - DataHash: make([]byte, tmhash.Size), - EvidenceHash: make([]byte, tmhash.Size), + LastCommitHash: make([]byte, crypto.HashSize), + DataHash: make([]byte, crypto.HashSize), + EvidenceHash: make([]byte, crypto.HashSize), ProposerAddress: make([]byte, crypto.AddressSize), - ValidatorsHash: make([]byte, tmhash.Size), - NextValidatorsHash: make([]byte, tmhash.Size), - ConsensusHash: make([]byte, tmhash.Size), - LastResultsHash: make([]byte, tmhash.Size+1), + ValidatorsHash: make([]byte, crypto.HashSize), + NextValidatorsHash: make([]byte, crypto.HashSize), + ConsensusHash: make([]byte, crypto.HashSize), + LastResultsHash: make([]byte, crypto.HashSize+1), }, true, "wrong LastResultsHash", }, @@ -1197,19 +1196,19 @@ func TestHeader_ValidateBasic(t *testing.T) { ChainID: string(make([]byte, MaxChainIDLen)), Height: 1, LastBlockID: BlockID{ - Hash: make([]byte, tmhash.Size), + Hash: make([]byte, crypto.HashSize), PartSetHeader: PartSetHeader{ - Hash: make([]byte, tmhash.Size), + Hash: make([]byte, crypto.HashSize), }, }, - LastCommitHash: make([]byte, tmhash.Size), - DataHash: make([]byte, tmhash.Size), - EvidenceHash: make([]byte, tmhash.Size), + LastCommitHash: make([]byte, crypto.HashSize), + DataHash: make([]byte, crypto.HashSize), + EvidenceHash: make([]byte, crypto.HashSize), ProposerAddress: make([]byte, crypto.AddressSize), - ValidatorsHash: make([]byte, tmhash.Size), - NextValidatorsHash: make([]byte, tmhash.Size), - ConsensusHash: make([]byte, tmhash.Size), - LastResultsHash: make([]byte, tmhash.Size), + ValidatorsHash: make([]byte, crypto.HashSize), + NextValidatorsHash: make([]byte, crypto.HashSize), + ConsensusHash: make([]byte, crypto.HashSize), + LastResultsHash: make([]byte, crypto.HashSize), }, false, "", }, @@ -1262,9 +1261,9 @@ func TestCommit_ValidateBasic(t *testing.T) { Height: 1, Round: 1, BlockID: BlockID{ - Hash: make([]byte, tmhash.Size), + Hash: make([]byte, crypto.HashSize), PartSetHeader: PartSetHeader{ - Hash: make([]byte, tmhash.Size), + Hash: make([]byte, crypto.HashSize), }, }, }, @@ -1276,9 +1275,9 @@ func TestCommit_ValidateBasic(t *testing.T) { Height: 1, Round: 1, BlockID: BlockID{ - Hash: make([]byte, tmhash.Size), + Hash: make([]byte, crypto.HashSize), PartSetHeader: PartSetHeader{ - Hash: make([]byte, tmhash.Size), + Hash: make([]byte, crypto.HashSize), }, }, Signatures: []CommitSig{ @@ -1297,9 +1296,9 @@ func TestCommit_ValidateBasic(t *testing.T) { Height: 1, Round: 1, BlockID: BlockID{ - Hash: make([]byte, tmhash.Size), + Hash: make([]byte, crypto.HashSize), PartSetHeader: PartSetHeader{ - Hash: make([]byte, tmhash.Size), + Hash: make([]byte, crypto.HashSize), }, }, Signatures: []CommitSig{ diff --git a/types/canonical_test.go b/types/canonical_test.go index 53a8ea52f..2ccb80ff7 100644 --- a/types/canonical_test.go +++ b/types/canonical_test.go @@ -4,13 +4,13 @@ import ( "reflect" "testing" - "github.com/tendermint/tendermint/crypto/tmhash" + "github.com/tendermint/tendermint/crypto" tmrand "github.com/tendermint/tendermint/libs/rand" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" ) func TestCanonicalizeBlockID(t *testing.T) { - randhash := tmrand.Bytes(tmhash.Size) + randhash := tmrand.Bytes(crypto.HashSize) block1 := tmproto.BlockID{Hash: randhash, PartSetHeader: tmproto.PartSetHeader{Total: 5, Hash: randhash}} block2 := tmproto.BlockID{Hash: randhash, diff --git a/types/evidence.go b/types/evidence.go index dc66a6fcf..aed954a93 100644 --- a/types/evidence.go +++ b/types/evidence.go @@ -12,8 +12,8 @@ import ( "time" abci "github.com/tendermint/tendermint/abci/types" + "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/merkle" - "github.com/tendermint/tendermint/crypto/tmhash" "github.com/tendermint/tendermint/internal/jsontypes" tmmath "github.com/tendermint/tendermint/libs/math" tmrand "github.com/tendermint/tendermint/libs/rand" @@ -113,7 +113,7 @@ func (dve *DuplicateVoteEvidence) Bytes() []byte { // Hash returns the hash of the evidence. func (dve *DuplicateVoteEvidence) Hash() []byte { - return tmhash.Sum(dve.Bytes()) + return crypto.Checksum(dve.Bytes()) } // Height returns the height of the infraction @@ -374,10 +374,10 @@ func (l *LightClientAttackEvidence) ConflictingHeaderIsInvalid(trustedHeader *He func (l *LightClientAttackEvidence) Hash() []byte { buf := make([]byte, binary.MaxVarintLen64) n := binary.PutVarint(buf, l.CommonHeight) - bz := make([]byte, tmhash.Size+n) - copy(bz[:tmhash.Size-1], l.ConflictingBlock.Hash().Bytes()) - copy(bz[tmhash.Size:], buf) - return tmhash.Sum(bz) + bz := make([]byte, crypto.HashSize+n) + copy(bz[:crypto.HashSize-1], l.ConflictingBlock.Hash().Bytes()) + copy(bz[crypto.HashSize:], buf) + return crypto.Checksum(bz) } // Height returns the last height at which the primary provider and witness provider had the same header. @@ -843,10 +843,10 @@ func makeMockVote(height int64, round, index int32, addr Address, func randBlockID() BlockID { return BlockID{ - Hash: tmrand.Bytes(tmhash.Size), + Hash: tmrand.Bytes(crypto.HashSize), PartSetHeader: PartSetHeader{ Total: 1, - Hash: tmrand.Bytes(tmhash.Size), + Hash: tmrand.Bytes(crypto.HashSize), }, } } diff --git a/types/evidence_test.go b/types/evidence_test.go index e284c2fca..27e346343 100644 --- a/types/evidence_test.go +++ b/types/evidence_test.go @@ -13,7 +13,6 @@ import ( "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/ed25519" - "github.com/tendermint/tendermint/crypto/tmhash" tmrand "github.com/tendermint/tendermint/libs/rand" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" "github.com/tendermint/tendermint/version" @@ -93,15 +92,15 @@ func TestDuplicateVoteEvidence(t *testing.T) { ev, err := NewMockDuplicateVoteEvidence(ctx, height, time.Now(), "mock-chain-id") require.NoError(t, err) - assert.Equal(t, ev.Hash(), tmhash.Sum(ev.Bytes())) + assert.Equal(t, ev.Hash(), crypto.Checksum(ev.Bytes())) assert.NotNil(t, ev.String()) assert.Equal(t, ev.Height(), height) } func TestDuplicateVoteEvidenceValidation(t *testing.T) { val := NewMockPV() - blockID := makeBlockID(tmhash.Sum([]byte("blockhash")), math.MaxInt32, tmhash.Sum([]byte("partshash"))) - blockID2 := makeBlockID(tmhash.Sum([]byte("blockhash2")), math.MaxInt32, tmhash.Sum([]byte("partshash"))) + blockID := makeBlockID(crypto.Checksum([]byte("blockhash")), math.MaxInt32, crypto.Checksum([]byte("partshash"))) + blockID2 := makeBlockID(crypto.Checksum([]byte("blockhash2")), math.MaxInt32, crypto.Checksum([]byte("partshash"))) const chainID = "mychain" ctx, cancel := context.WithCancel(context.Background()) @@ -153,7 +152,7 @@ func TestLightClientAttackEvidenceBasic(t *testing.T) { header := makeHeaderRandom() header.Height = height - blockID := makeBlockID(tmhash.Sum([]byte("blockhash")), math.MaxInt32, tmhash.Sum([]byte("partshash"))) + blockID := makeBlockID(crypto.Checksum([]byte("blockhash")), math.MaxInt32, crypto.Checksum([]byte("partshash"))) commit, err := makeCommit(ctx, blockID, height, 1, voteSet, privVals, defaultVoteTime) require.NoError(t, err) lcae := &LightClientAttackEvidence{ @@ -217,7 +216,7 @@ func TestLightClientAttackEvidenceValidation(t *testing.T) { header := makeHeaderRandom() header.Height = height header.ValidatorsHash = valSet.Hash() - blockID := makeBlockID(header.Hash(), math.MaxInt32, tmhash.Sum([]byte("partshash"))) + blockID := makeBlockID(header.Hash(), math.MaxInt32, crypto.Checksum([]byte("partshash"))) commit, err := makeCommit(ctx, blockID, height, 1, voteSet, privVals, time.Now()) require.NoError(t, err) lcae := &LightClientAttackEvidence{ @@ -332,14 +331,14 @@ func makeHeaderRandom() *Header { Height: int64(mrand.Uint32() + 1), Time: time.Now(), LastBlockID: makeBlockIDRandom(), - LastCommitHash: crypto.CRandBytes(tmhash.Size), - DataHash: crypto.CRandBytes(tmhash.Size), - ValidatorsHash: crypto.CRandBytes(tmhash.Size), - NextValidatorsHash: crypto.CRandBytes(tmhash.Size), - ConsensusHash: crypto.CRandBytes(tmhash.Size), - AppHash: crypto.CRandBytes(tmhash.Size), - LastResultsHash: crypto.CRandBytes(tmhash.Size), - EvidenceHash: crypto.CRandBytes(tmhash.Size), + LastCommitHash: crypto.CRandBytes(crypto.HashSize), + DataHash: crypto.CRandBytes(crypto.HashSize), + ValidatorsHash: crypto.CRandBytes(crypto.HashSize), + NextValidatorsHash: crypto.CRandBytes(crypto.HashSize), + ConsensusHash: crypto.CRandBytes(crypto.HashSize), + AppHash: crypto.CRandBytes(crypto.HashSize), + LastResultsHash: crypto.CRandBytes(crypto.HashSize), + EvidenceHash: crypto.CRandBytes(crypto.HashSize), ProposerAddress: crypto.CRandBytes(crypto.AddressSize), } } @@ -350,8 +349,8 @@ func TestEvidenceProto(t *testing.T) { // -------- Votes -------- val := NewMockPV() - blockID := makeBlockID(tmhash.Sum([]byte("blockhash")), math.MaxInt32, tmhash.Sum([]byte("partshash"))) - blockID2 := makeBlockID(tmhash.Sum([]byte("blockhash2")), math.MaxInt32, tmhash.Sum([]byte("partshash"))) + blockID := makeBlockID(crypto.Checksum([]byte("blockhash")), math.MaxInt32, crypto.Checksum([]byte("partshash"))) + blockID2 := makeBlockID(crypto.Checksum([]byte("blockhash2")), math.MaxInt32, crypto.Checksum([]byte("partshash"))) const chainID = "mychain" v := makeVote(ctx, t, val, chainID, math.MaxInt32, math.MaxInt64, 1, 0x01, blockID, defaultVoteTime) v2 := makeVote(ctx, t, val, chainID, math.MaxInt32, math.MaxInt64, 2, 0x01, blockID2, defaultVoteTime) @@ -395,8 +394,8 @@ func TestEvidenceVectors(t *testing.T) { // Votes for duplicateEvidence val := NewMockPV() val.PrivKey = ed25519.GenPrivKeyFromSecret([]byte("it's a secret")) // deterministic key - blockID := makeBlockID(tmhash.Sum([]byte("blockhash")), math.MaxInt32, tmhash.Sum([]byte("partshash"))) - blockID2 := makeBlockID(tmhash.Sum([]byte("blockhash2")), math.MaxInt32, tmhash.Sum([]byte("partshash"))) + blockID := makeBlockID(crypto.Checksum([]byte("blockhash")), math.MaxInt32, crypto.Checksum([]byte("partshash"))) + blockID2 := makeBlockID(crypto.Checksum([]byte("blockhash2")), math.MaxInt32, crypto.Checksum([]byte("partshash"))) const chainID = "mychain" v := makeVote(ctx, t, val, chainID, math.MaxInt32, math.MaxInt64, 1, 0x01, blockID, defaultVoteTime) v2 := makeVote(ctx, t, val, chainID, math.MaxInt32, math.MaxInt64, 2, 0x01, blockID2, defaultVoteTime) @@ -424,7 +423,7 @@ func TestEvidenceVectors(t *testing.T) { EvidenceHash: []byte("f2564c78071e26643ae9b3e2a19fa0dc10d4d9e873aa0be808660123f11a1e78"), ProposerAddress: []byte("2915b7b15f979e48ebc61774bb1d86ba3136b7eb"), } - blockID3 := makeBlockID(header.Hash(), math.MaxInt32, tmhash.Sum([]byte("partshash"))) + blockID3 := makeBlockID(header.Hash(), math.MaxInt32, crypto.Checksum([]byte("partshash"))) commit, err := makeCommit(ctx, blockID3, height, 1, voteSet, privVals, defaultVoteTime) require.NoError(t, err) lcae := &LightClientAttackEvidence{ diff --git a/types/proposal_test.go b/types/proposal_test.go index b8b8b3a67..6b2b3dd59 100644 --- a/types/proposal_test.go +++ b/types/proposal_test.go @@ -10,7 +10,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/tendermint/tendermint/crypto/tmhash" + "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/internal/libs/protoio" tmrand "github.com/tendermint/tendermint/libs/rand" tmtime "github.com/tendermint/tendermint/libs/time" @@ -61,7 +61,7 @@ func TestProposalVerifySignature(t *testing.T) { prop := NewProposal( 4, 2, 2, - BlockID{tmrand.Bytes(tmhash.Size), PartSetHeader{777, tmrand.Bytes(tmhash.Size)}}, tmtime.Now()) + BlockID{tmrand.Bytes(crypto.HashSize), PartSetHeader{777, tmrand.Bytes(crypto.HashSize)}}, tmtime.Now()) p := prop.ToProto() signBytes := ProposalSignBytes("test_chain_id", p) @@ -163,7 +163,7 @@ func TestProposalValidateBasic(t *testing.T) { p.Signature = make([]byte, MaxSignatureSize+1) }, true}, } - blockID := makeBlockID(tmhash.Sum([]byte("blockhash")), math.MaxInt32, tmhash.Sum([]byte("partshash"))) + blockID := makeBlockID(crypto.Checksum([]byte("blockhash")), math.MaxInt32, crypto.Checksum([]byte("partshash"))) for _, tc := range testCases { tc := tc diff --git a/types/tx.go b/types/tx.go index c879cf3da..1d429ddf1 100644 --- a/types/tx.go +++ b/types/tx.go @@ -8,8 +8,8 @@ import ( "sort" abci "github.com/tendermint/tendermint/abci/types" + "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/merkle" - "github.com/tendermint/tendermint/crypto/tmhash" tmbytes "github.com/tendermint/tendermint/libs/bytes" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" ) @@ -23,7 +23,7 @@ type Tx []byte func (tx Tx) Key() TxKey { return sha256.Sum256(tx) } // Hash computes the TMHASH hash of the wire encoded transaction. -func (tx Tx) Hash() []byte { return tmhash.Sum(tx) } +func (tx Tx) Hash() []byte { return crypto.Checksum(tx) } // String returns the hex-encoded transaction as a string. func (tx Tx) String() string { return fmt.Sprintf("Tx{%X}", []byte(tx)) } diff --git a/types/validation.go b/types/validation.go index 8655bdabd..21c8730f5 100644 --- a/types/validation.go +++ b/types/validation.go @@ -4,8 +4,8 @@ import ( "errors" "fmt" + "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/batch" - "github.com/tendermint/tendermint/crypto/tmhash" tmmath "github.com/tendermint/tendermint/libs/math" ) @@ -132,11 +132,11 @@ func VerifyCommitLightTrusting(chainID string, vals *ValidatorSet, commit *Commi } // ValidateHash returns an error if the hash is not empty, but its -// size != tmhash.Size. +// size != crypto.HashSize. func ValidateHash(h []byte) error { - if len(h) > 0 && len(h) != tmhash.Size { + if len(h) > 0 && len(h) != crypto.HashSize { return fmt.Errorf("expected size to be %d bytes, got %d bytes", - tmhash.Size, + crypto.HashSize, len(h), ) } diff --git a/types/vote_test.go b/types/vote_test.go index 684422b97..5673ccf57 100644 --- a/types/vote_test.go +++ b/types/vote_test.go @@ -11,7 +11,6 @@ import ( "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/ed25519" - "github.com/tendermint/tendermint/crypto/tmhash" "github.com/tendermint/tendermint/internal/libs/protoio" tmtime "github.com/tendermint/tendermint/libs/time" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" @@ -40,10 +39,10 @@ func exampleVote(tb testing.TB, t byte) *Vote { Round: 2, Timestamp: stamp, BlockID: BlockID{ - Hash: tmhash.Sum([]byte("blockID_hash")), + Hash: crypto.Checksum([]byte("blockID_hash")), PartSetHeader: PartSetHeader{ Total: 1000000, - Hash: tmhash.Sum([]byte("blockID_part_set_header_hash")), + Hash: crypto.Checksum([]byte("blockID_part_set_header_hash")), }, }, ValidatorAddress: crypto.AddressHash([]byte("validator_address")), From 297fcc0a7cc749db28fe03e862526eb603f73dd3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 29 Apr 2022 10:59:15 +0000 Subject: [PATCH 30/35] build(deps): Bump github.com/creachadair/tomledit from 0.0.18 to 0.0.19 (#8440) Bumps [github.com/creachadair/tomledit](https://github.com/creachadair/tomledit) from 0.0.18 to 0.0.19.
Commits
  • 0692e41 Release v0.0.19
  • d1160a4 Update default permissions.
  • 56f28f4 Move transform tests to that package.
  • 3b8b380 Add permissions to CI workflow.
  • 409951b Add a quotation test case.
  • f35c8be parser: include line numbers in headings, mappings, and values
  • 26acca1 Regularize location formatting in diagnostics.
  • 3394f59 Add more parser test cases.
  • 5ce10cc Rename test file.
  • 29f3eb3 Allow compliance tests to be skipped with -short.
  • See full diff in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/creachadair/tomledit&package-manager=go_modules&previous-version=0.0.18&new-version=0.0.19)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index f03deab1a..5e678a922 100644 --- a/go.mod +++ b/go.mod @@ -75,7 +75,7 @@ require ( github.com/charithe/durationcheck v0.0.9 // indirect github.com/chavacava/garif v0.0.0-20210405164556-e8a0a408d6af // indirect github.com/containerd/continuity v0.2.1 // indirect - github.com/creachadair/tomledit v0.0.18 + github.com/creachadair/tomledit v0.0.19 github.com/daixiang0/gci v0.3.3 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/denis-tingaikin/go-header v0.4.3 // indirect diff --git a/go.sum b/go.sum index 07dedbb7b..5c5610003 100644 --- a/go.sum +++ b/go.sum @@ -229,8 +229,8 @@ github.com/creachadair/atomicfile v0.2.5 h1:wkOlpsjyJOvJ3Hd8juHKdirJnCSIPacvtY21 github.com/creachadair/atomicfile v0.2.5/go.mod h1:BRq8Une6ckFneYXZQ+kO7p1ZZP3I2fzVzf28JxrIkBc= github.com/creachadair/taskgroup v0.3.2 h1:zlfutDS+5XG40AOxcHDSThxKzns8Tnr9jnr6VqkYlkM= github.com/creachadair/taskgroup v0.3.2/go.mod h1:wieWwecHVzsidg2CsUnFinW1faVN4+kq+TDlRJQ0Wbk= -github.com/creachadair/tomledit v0.0.18 h1:gleeCnEgMPYcaBz5KN/1CN9yycF5n6Q2py7Ahu6yc7A= -github.com/creachadair/tomledit v0.0.18/go.mod h1:gvtfnSZLa+YNQD28vaPq0Nk12bRxEhmUdBzAWn+EGF4= +github.com/creachadair/tomledit v0.0.19 h1:zbpfUtYFYFdpRjwJY9HJlto1iZ4M5YwYB6qqc37F6UM= +github.com/creachadair/tomledit v0.0.19/go.mod h1:gvtfnSZLa+YNQD28vaPq0Nk12bRxEhmUdBzAWn+EGF4= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= From 97b39770e0dcebf02212981b0124fc29685a5832 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 29 Apr 2022 11:21:56 +0000 Subject: [PATCH 31/35] build(deps): Bump github.com/btcsuite/btcd from 0.22.0-beta to 0.22.1 (#8439) Bumps [github.com/btcsuite/btcd](https://github.com/btcsuite/btcd) from 0.22.0-beta to 0.22.1.
Changelog

Sourced from github.com/btcsuite/btcd's changelog.

============================================================================ User visible changes for btcd A full-node bitcoin implementation written in Go

Changes in 0.22.1 (Wed Apr 27 2022)

  • Notable developer-related package changes:
    • Update to use chaincfg/chainhash module and remove conflicting package
  • Contributors (alphabetical order):
    • Dave Collins

Changes in 0.22.0 (Tue Jun 01 2021)

  • Protocol and network-related changes:
    • Add support for witness tx and block in notfound msg (#1625)
    • Add support for receiving sendaddrv2 messages from a peer (#1670)
    • Fix bug in peer package causing last block height to go backwards (#1606)
    • Add chain parameters for connecting to the public Signet network (#1692, #1718)
  • Crypto changes:
    • Fix bug causing panic due to bad R and S signature components in btcec.RecoverCompact (#1691)
    • Set the name (secp256k1) in the CurveParams of the S256 curve (#1565)
  • Notable developer-related package changes:
    • Remove unknown block version warning in the blockchain package, due to false positives triggered by AsicBoost (#1463)
    • Add chaincfg.RegisterHDKeyID function to populate HD key ID pairs (#1617)
    • Add new method mining.AddWitnessCommitment to add the witness commitment as an OP_RETURN output within the coinbase transaction. (#1716)
  • RPC changes:
    • Support Batch JSON-RPC in rpcclient and server (#1583)
    • Add rpcclient method to invoke getdescriptorinfo JSON-RPC command (#1578)
    • Update the rpcserver handler for validateaddress JSON-RPC command to have parity with the bitcoind 0.20.0 interface (#1613)
    • Add rpcclient method to invoke getblockfilter JSON-RPC command (#1579)
    • Add signmessagewithprivkey JSON-RPC command in rpcserver (#1585)
    • Add rpcclient method to invoke importmulti JSON-RPC command (#1579)
    • Add watchOnly argument in rpcclient method to invoke listtransactions JSON-RPC command (#1628)
    • Update btcjson.ListTransactionsResult for compatibility with Bitcoin Core 0.20.0 (#1626)
    • Support nullable optional JSON-RPC parameters (#1594)
    • Add rpcclient and server method to invoke getnodeaddresses JSON-RPC

... (truncated)

Commits
  • 2f508b3 Update CHANGES file for 0.22.1 release.
  • ff92d88 btcd: bump version to v0.22.1.
  • cf5c461 main: Switch to chaincfg/chainhash module.
  • See full diff in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/btcsuite/btcd&package-manager=go_modules&previous-version=0.22.0-beta&new-version=0.22.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- go.mod | 2 +- go.sum | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 5e678a922..ff5b4e11f 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.17 require ( github.com/BurntSushi/toml v1.1.0 github.com/adlio/schema v1.3.0 - github.com/btcsuite/btcd v0.22.0-beta + github.com/btcsuite/btcd v0.22.1 github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce github.com/fortytw2/leaktest v1.3.0 github.com/go-kit/kit v0.12.0 diff --git a/go.sum b/go.sum index 5c5610003..a7b2d7bd8 100644 --- a/go.sum +++ b/go.sum @@ -157,8 +157,10 @@ github.com/breml/bidichk v0.2.2/go.mod h1:zbfeitpevDUGI7V91Uzzuwrn4Vls8MoBMrwtt7 github.com/breml/errchkjson v0.2.3 h1:97eGTmR/w0paL2SwfRPI1jaAZHaH/fXnxWTw2eEIqE0= github.com/breml/errchkjson v0.2.3/go.mod h1:jZEATw/jF69cL1iy7//Yih8yp/mXp2CBoBr9GJwCAsY= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= -github.com/btcsuite/btcd v0.22.0-beta h1:LTDpDKUM5EeOFBPM8IXpinEcmZ6FWfNZbE3lfrfdnWo= -github.com/btcsuite/btcd v0.22.0-beta/go.mod h1:9n5ntfhhHQBIhUvlhDvD3Qg6fRUj4jkN0VB8L8svzOA= +github.com/btcsuite/btcd v0.22.1 h1:CnwP9LM/M9xuRrGSCGeMVs9iv09uMqwsVX7EeIpgV2c= +github.com/btcsuite/btcd v0.22.1/go.mod h1:wqgTSL29+50LRkmOVknEdmt8ZojIzhuWvgu/iptuN7Y= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce h1:YtWJF7RHm2pYCvA5t0RPmAaLUhREsKuKd+SLhxFbFeQ= From eee19e42db5004df1238d57f6875cc65626cd686 Mon Sep 17 00:00:00 2001 From: Sam Kleinman Date: Fri, 29 Apr 2022 10:29:26 -0400 Subject: [PATCH 32/35] consensus: reduce size of validator set changes test (#8442) --- internal/consensus/reactor_test.go | 76 +++++++++--------------------- 1 file changed, 22 insertions(+), 54 deletions(-) diff --git a/internal/consensus/reactor_test.go b/internal/consensus/reactor_test.go index 8a9abdf43..c6a8869db 100644 --- a/internal/consensus/reactor_test.go +++ b/internal/consensus/reactor_test.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "math/rand" "os" "sync" "testing" @@ -776,8 +777,8 @@ func TestReactorValidatorSetChanges(t *testing.T) { cfg := configSetup(t) - nPeers := 7 - nVals := 4 + nPeers := 4 + nVals := 2 states, _, _, cleanup := randConsensusNetWithPeers( ctx, t, @@ -870,60 +871,27 @@ func TestReactorValidatorSetChanges(t *testing.T) { // it includes the commit for block 4, which should have the updated validator set waitForBlockWithUpdatedValsAndValidateIt(ctx, t, nPeers, activeVals, blocksSubs, states) - updateValidatorPubKey1, err := states[nVals].privValidator.GetPubKey(ctx) - require.NoError(t, err) + for i := 2; i <= 32; i *= 2 { + useState := rand.Intn(nVals) + t.Log(useState) + updateValidatorPubKey1, err := states[useState].privValidator.GetPubKey(ctx) + require.NoError(t, err) - updatePubKey1ABCI, err := encoding.PubKeyToProto(updateValidatorPubKey1) - require.NoError(t, err) + updatePubKey1ABCI, err := encoding.PubKeyToProto(updateValidatorPubKey1) + require.NoError(t, err) - updateValidatorTx1 := kvstore.MakeValSetChangeTx(updatePubKey1ABCI, 25) - previousTotalVotingPower := states[nVals].GetRoundState().LastValidators.TotalVotingPower() + previousTotalVotingPower := states[useState].GetRoundState().LastValidators.TotalVotingPower() + updateValidatorTx1 := kvstore.MakeValSetChangeTx(updatePubKey1ABCI, int64(i)) - waitForAndValidateBlock(ctx, t, nPeers, activeVals, blocksSubs, states, updateValidatorTx1) - waitForAndValidateBlockWithTx(ctx, t, nPeers, activeVals, blocksSubs, states, updateValidatorTx1) - waitForAndValidateBlock(ctx, t, nPeers, activeVals, blocksSubs, states) - waitForBlockWithUpdatedValsAndValidateIt(ctx, t, nPeers, activeVals, blocksSubs, states) + waitForAndValidateBlock(ctx, t, nPeers, activeVals, blocksSubs, states, updateValidatorTx1) + waitForAndValidateBlockWithTx(ctx, t, nPeers, activeVals, blocksSubs, states, updateValidatorTx1) + waitForAndValidateBlock(ctx, t, nPeers, activeVals, blocksSubs, states) + waitForBlockWithUpdatedValsAndValidateIt(ctx, t, nPeers, activeVals, blocksSubs, states) - require.NotEqualf( - t, states[nVals].GetRoundState().LastValidators.TotalVotingPower(), previousTotalVotingPower, - "expected voting power to change (before: %d, after: %d)", - previousTotalVotingPower, states[nVals].GetRoundState().LastValidators.TotalVotingPower(), - ) - - newValidatorPubKey2, err := states[nVals+1].privValidator.GetPubKey(ctx) - require.NoError(t, err) - - newVal2ABCI, err := encoding.PubKeyToProto(newValidatorPubKey2) - require.NoError(t, err) - - newValidatorTx2 := kvstore.MakeValSetChangeTx(newVal2ABCI, testMinPower) - - newValidatorPubKey3, err := states[nVals+2].privValidator.GetPubKey(ctx) - require.NoError(t, err) - - newVal3ABCI, err := encoding.PubKeyToProto(newValidatorPubKey3) - require.NoError(t, err) - - newValidatorTx3 := kvstore.MakeValSetChangeTx(newVal3ABCI, testMinPower) - - waitForAndValidateBlock(ctx, t, nPeers, activeVals, blocksSubs, states, newValidatorTx2, newValidatorTx3) - waitForAndValidateBlockWithTx(ctx, t, nPeers, activeVals, blocksSubs, states, newValidatorTx2, newValidatorTx3) - waitForAndValidateBlock(ctx, t, nPeers, activeVals, blocksSubs, states) - - activeVals[string(newValidatorPubKey2.Address())] = struct{}{} - activeVals[string(newValidatorPubKey3.Address())] = struct{}{} - - waitForBlockWithUpdatedValsAndValidateIt(ctx, t, nPeers, activeVals, blocksSubs, states) - - removeValidatorTx2 := kvstore.MakeValSetChangeTx(newVal2ABCI, 0) - removeValidatorTx3 := kvstore.MakeValSetChangeTx(newVal3ABCI, 0) - - waitForAndValidateBlock(ctx, t, nPeers, activeVals, blocksSubs, states, removeValidatorTx2, removeValidatorTx3) - waitForAndValidateBlockWithTx(ctx, t, nPeers, activeVals, blocksSubs, states, removeValidatorTx2, removeValidatorTx3) - waitForAndValidateBlock(ctx, t, nPeers, activeVals, blocksSubs, states) - - delete(activeVals, string(newValidatorPubKey2.Address())) - delete(activeVals, string(newValidatorPubKey3.Address())) - - waitForBlockWithUpdatedValsAndValidateIt(ctx, t, nPeers, activeVals, blocksSubs, states) + require.NotEqualf( + t, states[useState].GetRoundState().LastValidators.TotalVotingPower(), previousTotalVotingPower, + "expected voting power to change (before: %d, after: %d)", + previousTotalVotingPower, states[useState].GetRoundState().LastValidators.TotalVotingPower(), + ) + } } From 89196596f7ca12e8d397e674e73907c5d7ad96da Mon Sep 17 00:00:00 2001 From: Sam Kleinman Date: Fri, 29 Apr 2022 10:56:10 -0400 Subject: [PATCH 33/35] privval/grpc: normalize signature (#8441) --- cmd/priv_val_server/main.go | 2 +- privval/grpc/client_test.go | 2 +- privval/grpc/server.go | 12 ++++-------- privval/grpc/server_test.go | 6 +++--- test/e2e/node/main.go | 2 +- 5 files changed, 10 insertions(+), 14 deletions(-) diff --git a/cmd/priv_val_server/main.go b/cmd/priv_val_server/main.go index e34236acc..901422145 100644 --- a/cmd/priv_val_server/main.go +++ b/cmd/priv_val_server/main.go @@ -113,7 +113,7 @@ func main() { // add prometheus metrics for unary RPC calls opts = append(opts, grpc.UnaryInterceptor(grpc_prometheus.UnaryServerInterceptor)) - ss := grpcprivval.NewSignerServer(*chainID, pv, logger) + ss := grpcprivval.NewSignerServer(logger, *chainID, pv) protocol, address := tmnet.ProtocolAndAddress(*addr) diff --git a/privval/grpc/client_test.go b/privval/grpc/client_test.go index 0b1056d03..a81f6ce07 100644 --- a/privval/grpc/client_test.go +++ b/privval/grpc/client_test.go @@ -29,7 +29,7 @@ func dialer(t *testing.T, pv types.PrivValidator, logger log.Logger) (*grpc.Serv server := grpc.NewServer() - s := tmgrpc.NewSignerServer(chainID, pv, logger) + s := tmgrpc.NewSignerServer(logger, chainID, pv) privvalproto.RegisterPrivValidatorAPIServer(server, s) diff --git a/privval/grpc/server.go b/privval/grpc/server.go index 13e0c9073..40af82479 100644 --- a/privval/grpc/server.go +++ b/privval/grpc/server.go @@ -21,11 +21,9 @@ type SignerServer struct { privVal types.PrivValidator } -func NewSignerServer(chainID string, - privVal types.PrivValidator, log log.Logger) *SignerServer { - +func NewSignerServer(logger log.Logger, chainID string, privVal types.PrivValidator) *SignerServer { return &SignerServer{ - logger: log, + logger: logger, chainID: chainID, privVal: privVal, } @@ -56,8 +54,7 @@ func (ss *SignerServer) GetPubKey(ctx context.Context, req *privvalproto.PubKeyR // SignVote receives a vote sign requests, attempts to sign it // returns SignedVoteResponse on success and error on failure -func (ss *SignerServer) SignVote(ctx context.Context, req *privvalproto.SignVoteRequest) ( - *privvalproto.SignedVoteResponse, error) { +func (ss *SignerServer) SignVote(ctx context.Context, req *privvalproto.SignVoteRequest) (*privvalproto.SignedVoteResponse, error) { vote := req.Vote err := ss.privVal.SignVote(ctx, req.ChainId, vote) @@ -72,8 +69,7 @@ func (ss *SignerServer) SignVote(ctx context.Context, req *privvalproto.SignVote // SignProposal receives a proposal sign requests, attempts to sign it // returns SignedProposalResponse on success and error on failure -func (ss *SignerServer) SignProposal(ctx context.Context, req *privvalproto.SignProposalRequest) ( - *privvalproto.SignedProposalResponse, error) { +func (ss *SignerServer) SignProposal(ctx context.Context, req *privvalproto.SignProposalRequest) (*privvalproto.SignedProposalResponse, error) { proposal := req.Proposal err := ss.privVal.SignProposal(ctx, req.ChainId, proposal) diff --git a/privval/grpc/server_test.go b/privval/grpc/server_test.go index db85a42b7..ad63b87a6 100644 --- a/privval/grpc/server_test.go +++ b/privval/grpc/server_test.go @@ -37,7 +37,7 @@ func TestGetPubKey(t *testing.T) { defer cancel() logger := log.NewTestingLogger(t) - s := tmgrpc.NewSignerServer(ChainID, tc.pv, logger) + s := tmgrpc.NewSignerServer(logger, ChainID, tc.pv) req := &privvalproto.PubKeyRequest{ChainId: ChainID} resp, err := s.GetPubKey(ctx, req) @@ -112,7 +112,7 @@ func TestSignVote(t *testing.T) { defer cancel() logger := log.NewTestingLogger(t) - s := tmgrpc.NewSignerServer(ChainID, tc.pv, logger) + s := tmgrpc.NewSignerServer(logger, ChainID, tc.pv) req := &privvalproto.SignVoteRequest{ChainId: ChainID, Vote: tc.have.ToProto()} resp, err := s.SignVote(ctx, req) @@ -183,7 +183,7 @@ func TestSignProposal(t *testing.T) { defer cancel() logger := log.NewTestingLogger(t) - s := tmgrpc.NewSignerServer(ChainID, tc.pv, logger) + s := tmgrpc.NewSignerServer(logger, ChainID, tc.pv) req := &privvalproto.SignProposalRequest{ChainId: ChainID, Proposal: tc.have.ToProto()} resp, err := s.SignProposal(ctx, req) diff --git a/test/e2e/node/main.go b/test/e2e/node/main.go index 54b9ef533..2cbb9e4b0 100644 --- a/test/e2e/node/main.go +++ b/test/e2e/node/main.go @@ -248,7 +248,7 @@ func startSigner(ctx context.Context, logger log.Logger, cfg *Config) error { if err != nil { return err } - ss := grpcprivval.NewSignerServer(cfg.ChainID, filePV, logger) + ss := grpcprivval.NewSignerServer(logger, cfg.ChainID, filePV) s := grpc.NewServer() From cf2a00b398cded2235247d3cd1378ec433216233 Mon Sep 17 00:00:00 2001 From: Sam Kleinman Date: Fri, 29 Apr 2022 17:21:36 -0400 Subject: [PATCH 34/35] p2p: avoid using p2p.Channel internals (#8444) --- internal/blocksync/reactor.go | 10 +++++----- internal/consensus/reactor.go | 29 +++++++++++++++-------------- internal/evidence/reactor.go | 13 ++++++------- internal/mempool/reactor.go | 13 ++++++------- internal/p2p/p2ptest/require.go | 2 +- internal/p2p/pex/reactor.go | 2 +- internal/statesync/reactor.go | 18 +++++++++++------- 7 files changed, 45 insertions(+), 42 deletions(-) diff --git a/internal/blocksync/reactor.go b/internal/blocksync/reactor.go index fd9bf4d7a..0bf0561d3 100644 --- a/internal/blocksync/reactor.go +++ b/internal/blocksync/reactor.go @@ -209,7 +209,7 @@ func (r *Reactor) respondToPeer(ctx context.Context, msg *bcproto.BlockRequest, // handleMessage handles an Envelope sent from a peer on a specific p2p Channel. // It will handle errors and any possible panics gracefully. A caller can handle // any error returned by sending a PeerError on the respective channel. -func (r *Reactor) handleMessage(ctx context.Context, chID p2p.ChannelID, envelope *p2p.Envelope, blockSyncCh *p2p.Channel) (err error) { +func (r *Reactor) handleMessage(ctx context.Context, envelope *p2p.Envelope, blockSyncCh *p2p.Channel) (err error) { defer func() { if e := recover(); e != nil { err = fmt.Errorf("panic in processing message: %v", e) @@ -223,7 +223,7 @@ func (r *Reactor) handleMessage(ctx context.Context, chID p2p.ChannelID, envelop r.logger.Debug("received message", "message", envelope.Message, "peer", envelope.From) - switch chID { + switch envelope.ChannelID { case BlockSyncChannel: switch msg := envelope.Message.(type) { case *bcproto.BlockRequest: @@ -260,7 +260,7 @@ func (r *Reactor) handleMessage(ctx context.Context, chID p2p.ChannelID, envelop } default: - err = fmt.Errorf("unknown channel ID (%d) for envelope (%v)", chID, envelope) + err = fmt.Errorf("unknown channel ID (%d) for envelope (%v)", envelope.ChannelID, envelope) } return err @@ -275,12 +275,12 @@ func (r *Reactor) processBlockSyncCh(ctx context.Context, blockSyncCh *p2p.Chann iter := blockSyncCh.Receive(ctx) for iter.Next(ctx) { envelope := iter.Envelope() - if err := r.handleMessage(ctx, blockSyncCh.ID, envelope, blockSyncCh); err != nil { + if err := r.handleMessage(ctx, envelope, blockSyncCh); err != nil { if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) { return } - r.logger.Error("failed to process message", "ch_id", blockSyncCh.ID, "envelope", envelope, "err", err) + r.logger.Error("failed to process message", "ch_id", envelope.ChannelID, "envelope", envelope, "err", err) if serr := blockSyncCh.SendError(ctx, p2p.PeerError{ NodeID: envelope.From, Err: err, diff --git a/internal/consensus/reactor.go b/internal/consensus/reactor.go index 53e0b540d..eea74b5e1 100644 --- a/internal/consensus/reactor.go +++ b/internal/consensus/reactor.go @@ -1266,7 +1266,7 @@ func (r *Reactor) handleVoteSetBitsMessage(ctx context.Context, envelope *p2p.En // the p2p channel. // // NOTE: We block on consensus state for proposals, block parts, and votes. -func (r *Reactor) handleMessage(ctx context.Context, chID p2p.ChannelID, envelope *p2p.Envelope, chans channelBundle) (err error) { +func (r *Reactor) handleMessage(ctx context.Context, envelope *p2p.Envelope, chans channelBundle) (err error) { defer func() { if e := recover(); e != nil { err = fmt.Errorf("panic in processing message: %v", e) @@ -1284,18 +1284,19 @@ func (r *Reactor) handleMessage(ctx context.Context, chID p2p.ChannelID, envelop // and because a large part of the core business logic depends on these // domain types opposed to simply working with the Proto types. protoMsg := new(tmcons.Message) - if err := protoMsg.Wrap(envelope.Message); err != nil { + if err = protoMsg.Wrap(envelope.Message); err != nil { return err } - msgI, err := MsgFromProto(protoMsg) + var msgI Message + msgI, err = MsgFromProto(protoMsg) if err != nil { return err } - r.logger.Debug("received message", "ch_id", chID, "message", msgI, "peer", envelope.From) + r.logger.Debug("received message", "ch_id", envelope.ChannelID, "message", msgI, "peer", envelope.From) - switch chID { + switch envelope.ChannelID { case StateChannel: err = r.handleStateMessage(ctx, envelope, msgI, chans.votSet) case DataChannel: @@ -1305,7 +1306,7 @@ func (r *Reactor) handleMessage(ctx context.Context, chID p2p.ChannelID, envelop case VoteSetBitsChannel: err = r.handleVoteSetBitsMessage(ctx, envelope, msgI) default: - err = fmt.Errorf("unknown channel ID (%d) for envelope (%v)", chID, envelope) + err = fmt.Errorf("unknown channel ID (%d) for envelope (%v)", envelope.ChannelID, envelope) } return err @@ -1320,8 +1321,8 @@ func (r *Reactor) processStateCh(ctx context.Context, chans channelBundle) { iter := chans.state.Receive(ctx) for iter.Next(ctx) { envelope := iter.Envelope() - if err := r.handleMessage(ctx, chans.state.ID, envelope, chans); err != nil { - r.logger.Error("failed to process message", "ch_id", chans.state.ID, "envelope", envelope, "err", err) + if err := r.handleMessage(ctx, envelope, chans); err != nil { + r.logger.Error("failed to process message", "ch_id", envelope.ChannelID, "envelope", envelope, "err", err) if serr := chans.state.SendError(ctx, p2p.PeerError{ NodeID: envelope.From, Err: err, @@ -1341,8 +1342,8 @@ func (r *Reactor) processDataCh(ctx context.Context, chans channelBundle) { iter := chans.data.Receive(ctx) for iter.Next(ctx) { envelope := iter.Envelope() - if err := r.handleMessage(ctx, chans.data.ID, envelope, chans); err != nil { - r.logger.Error("failed to process message", "ch_id", chans.data.ID, "envelope", envelope, "err", err) + if err := r.handleMessage(ctx, envelope, chans); err != nil { + r.logger.Error("failed to process message", "ch_id", envelope.ChannelID, "envelope", envelope, "err", err) if serr := chans.data.SendError(ctx, p2p.PeerError{ NodeID: envelope.From, Err: err, @@ -1362,8 +1363,8 @@ func (r *Reactor) processVoteCh(ctx context.Context, chans channelBundle) { iter := chans.vote.Receive(ctx) for iter.Next(ctx) { envelope := iter.Envelope() - if err := r.handleMessage(ctx, chans.vote.ID, envelope, chans); err != nil { - r.logger.Error("failed to process message", "ch_id", chans.vote.ID, "envelope", envelope, "err", err) + if err := r.handleMessage(ctx, envelope, chans); err != nil { + r.logger.Error("failed to process message", "ch_id", envelope.ChannelID, "envelope", envelope, "err", err) if serr := chans.vote.SendError(ctx, p2p.PeerError{ NodeID: envelope.From, Err: err, @@ -1384,12 +1385,12 @@ func (r *Reactor) processVoteSetBitsCh(ctx context.Context, chans channelBundle) for iter.Next(ctx) { envelope := iter.Envelope() - if err := r.handleMessage(ctx, chans.votSet.ID, envelope, chans); err != nil { + if err := r.handleMessage(ctx, envelope, chans); err != nil { if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) { return } - r.logger.Error("failed to process message", "ch_id", chans.votSet.ID, "envelope", envelope, "err", err) + r.logger.Error("failed to process message", "ch_id", envelope.ChannelID, "envelope", envelope, "err", err) if serr := chans.votSet.SendError(ctx, p2p.PeerError{ NodeID: envelope.From, Err: err, diff --git a/internal/evidence/reactor.go b/internal/evidence/reactor.go index 4809df32e..1d952d30e 100644 --- a/internal/evidence/reactor.go +++ b/internal/evidence/reactor.go @@ -133,7 +133,7 @@ func (r *Reactor) handleEvidenceMessage(ctx context.Context, envelope *p2p.Envel // handleMessage handles an Envelope sent from a peer on a specific p2p Channel. // It will handle errors and any possible panics gracefully. A caller can handle // any error returned by sending a PeerError on the respective channel. -func (r *Reactor) handleMessage(ctx context.Context, chID p2p.ChannelID, envelope *p2p.Envelope) (err error) { +func (r *Reactor) handleMessage(ctx context.Context, envelope *p2p.Envelope) (err error) { defer func() { if e := recover(); e != nil { err = fmt.Errorf("panic in processing message: %v", e) @@ -147,15 +147,14 @@ func (r *Reactor) handleMessage(ctx context.Context, chID p2p.ChannelID, envelop r.logger.Debug("received message", "message", envelope.Message, "peer", envelope.From) - switch chID { + switch envelope.ChannelID { case EvidenceChannel: err = r.handleEvidenceMessage(ctx, envelope) - default: - err = fmt.Errorf("unknown channel ID (%d) for envelope (%v)", chID, envelope) + err = fmt.Errorf("unknown channel ID (%d) for envelope (%v)", envelope.ChannelID, envelope) } - return err + return } // processEvidenceCh implements a blocking event loop where we listen for p2p @@ -164,8 +163,8 @@ func (r *Reactor) processEvidenceCh(ctx context.Context, evidenceCh *p2p.Channel iter := evidenceCh.Receive(ctx) for iter.Next(ctx) { envelope := iter.Envelope() - if err := r.handleMessage(ctx, evidenceCh.ID, envelope); err != nil { - r.logger.Error("failed to process message", "ch_id", evidenceCh.ID, "envelope", envelope, "err", err) + if err := r.handleMessage(ctx, envelope); err != nil { + r.logger.Error("failed to process message", "ch_id", envelope.ChannelID, "envelope", envelope, "err", err) if serr := evidenceCh.SendError(ctx, p2p.PeerError{ NodeID: envelope.From, Err: err, diff --git a/internal/mempool/reactor.go b/internal/mempool/reactor.go index 8f83f5006..ae578e70a 100644 --- a/internal/mempool/reactor.go +++ b/internal/mempool/reactor.go @@ -169,7 +169,7 @@ func (r *Reactor) handleMempoolMessage(ctx context.Context, envelope *p2p.Envelo // handleMessage handles an Envelope sent from a peer on a specific p2p Channel. // It will handle errors and any possible panics gracefully. A caller can handle // any error returned by sending a PeerError on the respective channel. -func (r *Reactor) handleMessage(ctx context.Context, chID p2p.ChannelID, envelope *p2p.Envelope) (err error) { +func (r *Reactor) handleMessage(ctx context.Context, envelope *p2p.Envelope) (err error) { defer func() { if e := recover(); e != nil { r.observePanic(e) @@ -184,15 +184,14 @@ func (r *Reactor) handleMessage(ctx context.Context, chID p2p.ChannelID, envelop r.logger.Debug("received message", "peer", envelope.From) - switch chID { + switch envelope.ChannelID { case MempoolChannel: err = r.handleMempoolMessage(ctx, envelope) - default: - err = fmt.Errorf("unknown channel ID (%d) for envelope (%T)", chID, envelope.Message) + err = fmt.Errorf("unknown channel ID (%d) for envelope (%T)", envelope.ChannelID, envelope.Message) } - return err + return } // processMempoolCh implements a blocking event loop where we listen for p2p @@ -201,8 +200,8 @@ func (r *Reactor) processMempoolCh(ctx context.Context, mempoolCh *p2p.Channel) iter := mempoolCh.Receive(ctx) for iter.Next(ctx) { envelope := iter.Envelope() - if err := r.handleMessage(ctx, mempoolCh.ID, envelope); err != nil { - r.logger.Error("failed to process message", "ch_id", mempoolCh.ID, "envelope", envelope, "err", err) + if err := r.handleMessage(ctx, envelope); err != nil { + r.logger.Error("failed to process message", "ch_id", envelope.ChannelID, "envelope", envelope, "err", err) if serr := mempoolCh.SendError(ctx, p2p.PeerError{ NodeID: envelope.From, Err: err, diff --git a/internal/p2p/p2ptest/require.go b/internal/p2p/p2ptest/require.go index f9f3ec40e..885e080d4 100644 --- a/internal/p2p/p2ptest/require.go +++ b/internal/p2p/p2ptest/require.go @@ -123,7 +123,7 @@ func RequireError(ctx context.Context, t *testing.T, channel *p2p.Channel, peerE err := channel.SendError(tctx, peerError) switch { case errors.Is(err, context.DeadlineExceeded): - require.Fail(t, "timed out reporting error", "%v on %v", peerError, channel.ID) + require.Fail(t, "timed out reporting error", "%v for %q", peerError, channel.String()) default: require.NoError(t, err, "unexpected error") } diff --git a/internal/p2p/pex/reactor.go b/internal/p2p/pex/reactor.go index 1c80763ee..bd4737326 100644 --- a/internal/p2p/pex/reactor.go +++ b/internal/p2p/pex/reactor.go @@ -193,7 +193,7 @@ func (r *Reactor) processPexCh(ctx context.Context, pexCh *p2p.Channel) { dur, err := r.handlePexMessage(ctx, envelope, pexCh) if err != nil { r.logger.Error("failed to process message", - "ch_id", pexCh.ID, "envelope", envelope, "err", err) + "ch_id", envelope.ChannelID, "envelope", envelope, "err", err) if serr := pexCh.SendError(ctx, p2p.PeerError{ NodeID: envelope.From, Err: err, diff --git a/internal/statesync/reactor.go b/internal/statesync/reactor.go index fb2749a02..f4d72d017 100644 --- a/internal/statesync/reactor.go +++ b/internal/statesync/reactor.go @@ -305,7 +305,12 @@ func (r *Reactor) OnStart(ctx context.Context) error { return nil } - go r.processChannels(ctx, snapshotCh, chunkCh, blockCh, paramsCh) + go r.processChannels(ctx, map[p2p.ChannelID]*p2p.Channel{ + SnapshotChannel: snapshotCh, + ChunkChannel: chunkCh, + LightBlockChannel: blockCh, + ParamsChannel: paramsCh, + }) go r.processPeerUpdates(ctx, r.peerEvents(ctx)) if r.needsStateSync { @@ -661,7 +666,7 @@ func (r *Reactor) handleSnapshotMessage(ctx context.Context, envelope *p2p.Envel "failed to add snapshot", "height", msg.Height, "format", msg.Format, - "channel", snapshotCh.ID, + "channel", envelope.ChannelID, "err", err, ) return nil @@ -907,15 +912,14 @@ func (r *Reactor) handleMessage(ctx context.Context, envelope *p2p.Envelope, cha // encountered during message execution will result in a PeerError being sent on // the respective channel. When the reactor is stopped, we will catch the signal // and close the p2p Channel gracefully. -func (r *Reactor) processChannels(ctx context.Context, chs ...*p2p.Channel) { +func (r *Reactor) processChannels(ctx context.Context, chanTable map[p2p.ChannelID]*p2p.Channel) { // make sure that the iterator gets cleaned up in case of error ctx, cancel := context.WithCancel(ctx) defer cancel() - chanTable := make(map[p2p.ChannelID]*p2p.Channel, len(chs)) - for idx := range chs { - ch := chs[idx] - chanTable[ch.ID] = ch + chs := make([]*p2p.Channel, 0, len(chanTable)) + for key := range chanTable { + chs = append(chs, chanTable[key]) } iter := p2p.MergedChannelIterator(ctx, chs...) From e7451a43e72ea5cd0cbaba605b8da3269ee3e8a0 Mon Sep 17 00:00:00 2001 From: Thane Thomson Date: Sat, 30 Apr 2022 14:34:59 -0400 Subject: [PATCH 35/35] blocksync: Honor contexts supplied to BlockPool (#8447) * Lift condition into for loop Signed-off-by: Thane Thomson * Honor contexts in BlockPool Signed-off-by: Thane Thomson * Only stop timers when necessary Signed-off-by: Thane Thomson * Optimize timers Signed-off-by: Thane Thomson * Simplify request interval definition Signed-off-by: Thane Thomson * Remove extraneous timer stop Signed-off-by: Thane Thomson * Convert switch into if Signed-off-by: Thane Thomson * Eliminate timers Signed-off-by: Thane Thomson --- internal/blocksync/pool.go | 39 ++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/internal/blocksync/pool.go b/internal/blocksync/pool.go index 7f133a7a1..f00a2fab5 100644 --- a/internal/blocksync/pool.go +++ b/internal/blocksync/pool.go @@ -28,7 +28,7 @@ eg, L = latency = 0.1s */ const ( - requestIntervalMS = 2 + requestInterval = 2 * time.Millisecond maxTotalRequesters = 600 maxPeerErrBuffer = 1000 maxPendingRequests = maxTotalRequesters @@ -130,27 +130,23 @@ func (*BlockPool) OnStop() {} // spawns requesters as needed func (pool *BlockPool) makeRequestersRoutine(ctx context.Context) { - for { - if !pool.IsRunning() { - break + for pool.IsRunning() { + if ctx.Err() != nil { + return } _, numPending, lenRequesters := pool.GetStatus() - switch { - case numPending >= maxPendingRequests: - // sleep for a bit. - time.Sleep(requestIntervalMS * time.Millisecond) - // check for timed out peers + if numPending >= maxPendingRequests || lenRequesters >= maxTotalRequesters { + // This is preferable to using a timer because the request interval + // is so small. Larger request intervals may necessitate using a + // timer/ticker. + time.Sleep(requestInterval) pool.removeTimedoutPeers() - case lenRequesters >= maxTotalRequesters: - // sleep for a bit. - time.Sleep(requestIntervalMS * time.Millisecond) - // check for timed out peers - pool.removeTimedoutPeers() - default: - // request for more blocks. - pool.makeNextRequester(ctx) + continue } + + // request for more blocks. + pool.makeNextRequester(ctx) } } @@ -639,9 +635,16 @@ OUTER_LOOP: if !bpr.IsRunning() || !bpr.pool.IsRunning() { return } + if ctx.Err() != nil { + return + } + peer = bpr.pool.pickIncrAvailablePeer(bpr.height) if peer == nil { - time.Sleep(requestIntervalMS * time.Millisecond) + // This is preferable to using a timer because the request + // interval is so small. Larger request intervals may + // necessitate using a timer/ticker. + time.Sleep(requestInterval) continue PICK_PEER_LOOP } break PICK_PEER_LOOP