Compare commits
32 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
08cc140d4a | ||
|
2120ef5808 | ||
|
c08af09aaa | ||
|
8b12749f02 | ||
|
e343a17ce9 | ||
|
3fd78ac6ea | ||
|
41bbc11a46 | ||
|
68934353f2 | ||
|
92543a3f92 | ||
|
a514aff819 | ||
|
8d8525e4fc | ||
|
2c1cec4e2c | ||
|
7d0a0a26bb | ||
|
73016d3ed2 | ||
|
9b1cb5c1b7 | ||
|
94f4748a34 | ||
|
8963724ed6 | ||
|
65df58c64a | ||
|
380c5da2d0 | ||
|
7d488a6ed8 | ||
|
159cfdae25 | ||
|
1c3d09ed21 | ||
|
2c8cfdb3f3 | ||
|
85570ac207 | ||
|
054b95cbe1 | ||
|
b67a5bb3b9 | ||
|
3e3fb4e296 | ||
|
f66d8551e9 | ||
|
a5cb10666c | ||
|
76384758d8 | ||
|
4eca26ae50 | ||
|
2d144afec5 |
491
Cargo.lock
generated
491
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,6 @@
|
||||
members = [
|
||||
"accountsdb-plugin-interface",
|
||||
"accountsdb-plugin-manager",
|
||||
"accountsdb-plugin-postgres",
|
||||
"accounts-cluster-bench",
|
||||
"bench-streamer",
|
||||
"bench-tps",
|
||||
@@ -49,6 +48,7 @@ members = [
|
||||
"program-test",
|
||||
"programs/address-lookup-table",
|
||||
"programs/address-lookup-table-tests",
|
||||
"programs/ed25519-tests",
|
||||
"programs/bpf_loader",
|
||||
"programs/bpf_loader/gen-syscall-list",
|
||||
"programs/compute-budget",
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-account-decoder"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
description = "Solana account decoder"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -19,9 +19,9 @@ lazy_static = "1.4.0"
|
||||
serde = "1.0.130"
|
||||
serde_derive = "1.0.103"
|
||||
serde_json = "1.0.72"
|
||||
solana-config-program = { path = "../programs/config", version = "=1.9.6" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.6" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.9.6" }
|
||||
solana-config-program = { path = "../programs/config", version = "=1.9.7" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.7" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.9.7" }
|
||||
spl-token = { version = "=3.2.0", features = ["no-entrypoint"] }
|
||||
thiserror = "1.0"
|
||||
zstd = "0.9.0"
|
||||
|
@@ -2,7 +2,7 @@
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2021"
|
||||
name = "solana-accounts-bench"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -11,11 +11,11 @@ publish = false
|
||||
[dependencies]
|
||||
log = "0.4.14"
|
||||
rayon = "1.5.1"
|
||||
solana-logger = { path = "../logger", version = "=1.9.6" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.9.6" }
|
||||
solana-measure = { path = "../measure", version = "=1.9.6" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.6" }
|
||||
solana-version = { path = "../version", version = "=1.9.6" }
|
||||
solana-logger = { path = "../logger", version = "=1.9.7" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.9.7" }
|
||||
solana-measure = { path = "../measure", version = "=1.9.7" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.7" }
|
||||
solana-version = { path = "../version", version = "=1.9.7" }
|
||||
clap = "2.33.1"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
|
@@ -2,7 +2,7 @@
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2021"
|
||||
name = "solana-accounts-cluster-bench"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -13,25 +13,25 @@ clap = "2.33.1"
|
||||
log = "0.4.14"
|
||||
rand = "0.7.0"
|
||||
rayon = "1.5.1"
|
||||
solana-account-decoder = { path = "../account-decoder", version = "=1.9.6" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.9.6" }
|
||||
solana-client = { path = "../client", version = "=1.9.6" }
|
||||
solana-core = { path = "../core", version = "=1.9.6" }
|
||||
solana-faucet = { path = "../faucet", version = "=1.9.6" }
|
||||
solana-gossip = { path = "../gossip", version = "=1.9.6" }
|
||||
solana-logger = { path = "../logger", version = "=1.9.6" }
|
||||
solana-measure = { path = "../measure", version = "=1.9.6" }
|
||||
solana-net-utils = { path = "../net-utils", version = "=1.9.6" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.9.6" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.6" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.9.6" }
|
||||
solana-test-validator = { path = "../test-validator", version = "=1.9.6" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.9.6" }
|
||||
solana-version = { path = "../version", version = "=1.9.6" }
|
||||
solana-account-decoder = { path = "../account-decoder", version = "=1.9.7" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.9.7" }
|
||||
solana-client = { path = "../client", version = "=1.9.7" }
|
||||
solana-core = { path = "../core", version = "=1.9.7" }
|
||||
solana-faucet = { path = "../faucet", version = "=1.9.7" }
|
||||
solana-gossip = { path = "../gossip", version = "=1.9.7" }
|
||||
solana-logger = { path = "../logger", version = "=1.9.7" }
|
||||
solana-measure = { path = "../measure", version = "=1.9.7" }
|
||||
solana-net-utils = { path = "../net-utils", version = "=1.9.7" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.9.7" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.7" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.9.7" }
|
||||
solana-test-validator = { path = "../test-validator", version = "=1.9.7" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.9.7" }
|
||||
solana-version = { path = "../version", version = "=1.9.7" }
|
||||
spl-token = { version = "=3.2.0", features = ["no-entrypoint"] }
|
||||
|
||||
[dev-dependencies]
|
||||
solana-local-cluster = { path = "../local-cluster", version = "=1.9.6" }
|
||||
solana-local-cluster = { path = "../local-cluster", version = "=1.9.7" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2021"
|
||||
name = "solana-accountsdb-plugin-interface"
|
||||
description = "The Solana AccountsDb plugin interface."
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -12,8 +12,8 @@ documentation = "https://docs.rs/solana-accountsdb-plugin-interface"
|
||||
[dependencies]
|
||||
log = "0.4.11"
|
||||
thiserror = "1.0.30"
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.6" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.9.6" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.7" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.9.7" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2021"
|
||||
name = "solana-accountsdb-plugin-manager"
|
||||
description = "The Solana AccountsDb plugin manager."
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -17,14 +17,14 @@ log = "0.4.11"
|
||||
serde = "1.0.130"
|
||||
serde_derive = "1.0.103"
|
||||
serde_json = "1.0.72"
|
||||
solana-accountsdb-plugin-interface = { path = "../accountsdb-plugin-interface", version = "=1.9.6" }
|
||||
solana-logger = { path = "../logger", version = "=1.9.6" }
|
||||
solana-measure = { path = "../measure", version = "=1.9.6" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.9.6" }
|
||||
solana-rpc = { path = "../rpc", version = "=1.9.6" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.9.6" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.6" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.9.6" }
|
||||
solana-accountsdb-plugin-interface = { path = "../accountsdb-plugin-interface", version = "=1.9.7" }
|
||||
solana-logger = { path = "../logger", version = "=1.9.7" }
|
||||
solana-measure = { path = "../measure", version = "=1.9.7" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.9.7" }
|
||||
solana-rpc = { path = "../rpc", version = "=1.9.7" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.9.7" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.7" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.9.7" }
|
||||
thiserror = "1.0.30"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
|
@@ -1,39 +0,0 @@
|
||||
[package]
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2021"
|
||||
name = "solana-accountsdb-plugin-postgres"
|
||||
description = "The Solana AccountsDb plugin for PostgreSQL database."
|
||||
version = "1.9.6"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
documentation = "https://docs.rs/solana-validator"
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib", "rlib"]
|
||||
|
||||
[dependencies]
|
||||
bs58 = "0.4.0"
|
||||
chrono = { version = "0.4.11", features = ["serde"] }
|
||||
crossbeam-channel = "0.5"
|
||||
log = "0.4.14"
|
||||
postgres = { version = "0.19.2", features = ["with-chrono-0_4"] }
|
||||
postgres-types = { version = "0.2.2", features = ["derive"] }
|
||||
serde = "1.0.130"
|
||||
serde_derive = "1.0.103"
|
||||
serde_json = "1.0.72"
|
||||
solana-accountsdb-plugin-interface = { path = "../accountsdb-plugin-interface", version = "=1.9.6" }
|
||||
solana-logger = { path = "../logger", version = "=1.9.6" }
|
||||
solana-measure = { path = "../measure", version = "=1.9.6" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.9.6" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.9.6" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.6" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.9.6" }
|
||||
thiserror = "1.0.30"
|
||||
tokio-postgres = "0.7.4"
|
||||
|
||||
[dev-dependencies]
|
||||
solana-account-decoder = { path = "../account-decoder", version = "=1.9.6" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
@@ -1,5 +0,0 @@
|
||||
This is an example implementing the AccountsDb plugin for PostgreSQL database.
|
||||
Please see the `src/accountsdb_plugin_postgres.rs` for the format of the plugin's configuration file.
|
||||
|
||||
To create the schema objects for the database, please use `scripts/create_schema.sql`.
|
||||
`scripts/drop_schema.sql` can be used to tear down the schema objects.
|
@@ -1,201 +0,0 @@
|
||||
/**
|
||||
* This plugin implementation for PostgreSQL requires the following tables
|
||||
*/
|
||||
-- The table storing accounts
|
||||
|
||||
|
||||
CREATE TABLE account (
|
||||
pubkey BYTEA PRIMARY KEY,
|
||||
owner BYTEA,
|
||||
lamports BIGINT NOT NULL,
|
||||
slot BIGINT NOT NULL,
|
||||
executable BOOL NOT NULL,
|
||||
rent_epoch BIGINT NOT NULL,
|
||||
data BYTEA,
|
||||
write_version BIGINT NOT NULL,
|
||||
updated_on TIMESTAMP NOT NULL
|
||||
);
|
||||
|
||||
-- The table storing slot information
|
||||
CREATE TABLE slot (
|
||||
slot BIGINT PRIMARY KEY,
|
||||
parent BIGINT,
|
||||
status VARCHAR(16) NOT NULL,
|
||||
updated_on TIMESTAMP NOT NULL
|
||||
);
|
||||
|
||||
-- Types for Transactions
|
||||
|
||||
Create TYPE "TransactionErrorCode" AS ENUM (
|
||||
'AccountInUse',
|
||||
'AccountLoadedTwice',
|
||||
'AccountNotFound',
|
||||
'ProgramAccountNotFound',
|
||||
'InsufficientFundsForFee',
|
||||
'InvalidAccountForFee',
|
||||
'AlreadyProcessed',
|
||||
'BlockhashNotFound',
|
||||
'InstructionError',
|
||||
'CallChainTooDeep',
|
||||
'MissingSignatureForFee',
|
||||
'InvalidAccountIndex',
|
||||
'SignatureFailure',
|
||||
'InvalidProgramForExecution',
|
||||
'SanitizeFailure',
|
||||
'ClusterMaintenance',
|
||||
'AccountBorrowOutstanding',
|
||||
'WouldExceedMaxAccountCostLimit',
|
||||
'WouldExceedMaxBlockCostLimit',
|
||||
'UnsupportedVersion',
|
||||
'InvalidWritableAccount',
|
||||
'WouldExceedMaxAccountDataCostLimit',
|
||||
'TooManyAccountLocks',
|
||||
'AddressLookupTableNotFound',
|
||||
'InvalidAddressLookupTableOwner',
|
||||
'InvalidAddressLookupTableData',
|
||||
'InvalidAddressLookupTableIndex',
|
||||
'InvalidRentPayingAccount'
|
||||
);
|
||||
|
||||
CREATE TYPE "TransactionError" AS (
|
||||
error_code "TransactionErrorCode",
|
||||
error_detail VARCHAR(256)
|
||||
);
|
||||
|
||||
CREATE TYPE "CompiledInstruction" AS (
|
||||
program_id_index SMALLINT,
|
||||
accounts SMALLINT[],
|
||||
data BYTEA
|
||||
);
|
||||
|
||||
CREATE TYPE "InnerInstructions" AS (
|
||||
index SMALLINT,
|
||||
instructions "CompiledInstruction"[]
|
||||
);
|
||||
|
||||
CREATE TYPE "TransactionTokenBalance" AS (
|
||||
account_index SMALLINT,
|
||||
mint VARCHAR(44),
|
||||
ui_token_amount DOUBLE PRECISION,
|
||||
owner VARCHAR(44)
|
||||
);
|
||||
|
||||
Create TYPE "RewardType" AS ENUM (
|
||||
'Fee',
|
||||
'Rent',
|
||||
'Staking',
|
||||
'Voting'
|
||||
);
|
||||
|
||||
CREATE TYPE "Reward" AS (
|
||||
pubkey VARCHAR(44),
|
||||
lamports BIGINT,
|
||||
post_balance BIGINT,
|
||||
reward_type "RewardType",
|
||||
commission SMALLINT
|
||||
);
|
||||
|
||||
CREATE TYPE "TransactionStatusMeta" AS (
|
||||
error "TransactionError",
|
||||
fee BIGINT,
|
||||
pre_balances BIGINT[],
|
||||
post_balances BIGINT[],
|
||||
inner_instructions "InnerInstructions"[],
|
||||
log_messages TEXT[],
|
||||
pre_token_balances "TransactionTokenBalance"[],
|
||||
post_token_balances "TransactionTokenBalance"[],
|
||||
rewards "Reward"[]
|
||||
);
|
||||
|
||||
CREATE TYPE "TransactionMessageHeader" AS (
|
||||
num_required_signatures SMALLINT,
|
||||
num_readonly_signed_accounts SMALLINT,
|
||||
num_readonly_unsigned_accounts SMALLINT
|
||||
);
|
||||
|
||||
CREATE TYPE "TransactionMessage" AS (
|
||||
header "TransactionMessageHeader",
|
||||
account_keys BYTEA[],
|
||||
recent_blockhash BYTEA,
|
||||
instructions "CompiledInstruction"[]
|
||||
);
|
||||
|
||||
CREATE TYPE "TransactionMessageAddressTableLookup" AS (
|
||||
account_key BYTEA,
|
||||
writable_indexes SMALLINT[],
|
||||
readonly_indexes SMALLINT[]
|
||||
);
|
||||
|
||||
CREATE TYPE "TransactionMessageV0" AS (
|
||||
header "TransactionMessageHeader",
|
||||
account_keys BYTEA[],
|
||||
recent_blockhash BYTEA,
|
||||
instructions "CompiledInstruction"[],
|
||||
address_table_lookups "TransactionMessageAddressTableLookup"[]
|
||||
);
|
||||
|
||||
CREATE TYPE "LoadedAddresses" AS (
|
||||
writable BYTEA[],
|
||||
readonly BYTEA[]
|
||||
);
|
||||
|
||||
CREATE TYPE "LoadedMessageV0" AS (
|
||||
message "TransactionMessageV0",
|
||||
loaded_addresses "LoadedAddresses"
|
||||
);
|
||||
|
||||
-- The table storing transactions
|
||||
CREATE TABLE transaction (
|
||||
slot BIGINT NOT NULL,
|
||||
signature BYTEA NOT NULL,
|
||||
is_vote BOOL NOT NULL,
|
||||
message_type SMALLINT, -- 0: legacy, 1: v0 message
|
||||
legacy_message "TransactionMessage",
|
||||
v0_loaded_message "LoadedMessageV0",
|
||||
signatures BYTEA[],
|
||||
message_hash BYTEA,
|
||||
meta "TransactionStatusMeta",
|
||||
updated_on TIMESTAMP NOT NULL,
|
||||
CONSTRAINT transaction_pk PRIMARY KEY (slot, signature)
|
||||
);
|
||||
|
||||
-- The table storing block metadata
|
||||
CREATE TABLE block (
|
||||
slot BIGINT PRIMARY KEY,
|
||||
blockhash VARCHAR(44),
|
||||
rewards "Reward"[],
|
||||
block_time BIGINT,
|
||||
block_height BIGINT,
|
||||
updated_on TIMESTAMP NOT NULL
|
||||
);
|
||||
|
||||
/**
|
||||
* The following is for keeping historical data for accounts and is not required for plugin to work.
|
||||
*/
|
||||
-- The table storing historical data for accounts
|
||||
CREATE TABLE account_audit (
|
||||
pubkey BYTEA,
|
||||
owner BYTEA,
|
||||
lamports BIGINT NOT NULL,
|
||||
slot BIGINT NOT NULL,
|
||||
executable BOOL NOT NULL,
|
||||
rent_epoch BIGINT NOT NULL,
|
||||
data BYTEA,
|
||||
write_version BIGINT NOT NULL,
|
||||
updated_on TIMESTAMP NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX account_audit_account_key ON account_audit (pubkey, write_version);
|
||||
|
||||
CREATE FUNCTION audit_account_update() RETURNS trigger AS $audit_account_update$
|
||||
BEGIN
|
||||
INSERT INTO account_audit (pubkey, owner, lamports, slot, executable, rent_epoch, data, write_version, updated_on)
|
||||
VALUES (OLD.pubkey, OLD.owner, OLD.lamports, OLD.slot,
|
||||
OLD.executable, OLD.rent_epoch, OLD.data, OLD.write_version, OLD.updated_on);
|
||||
RETURN NEW;
|
||||
END;
|
||||
|
||||
$audit_account_update$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE TRIGGER account_update_trigger AFTER UPDATE OR DELETE ON account
|
||||
FOR EACH ROW EXECUTE PROCEDURE audit_account_update();
|
@@ -1,26 +0,0 @@
|
||||
/**
|
||||
* Script for cleaning up the schema for PostgreSQL used for the AccountsDb plugin.
|
||||
*/
|
||||
|
||||
DROP TRIGGER account_update_trigger ON account;
|
||||
DROP FUNCTION audit_account_update;
|
||||
DROP TABLE account_audit;
|
||||
DROP TABLE account;
|
||||
DROP TABLE slot;
|
||||
DROP TABLE transaction;
|
||||
DROP TABLE block;
|
||||
|
||||
DROP TYPE "TransactionError" CASCADE;
|
||||
DROP TYPE "TransactionErrorCode" CASCADE;
|
||||
DROP TYPE "LoadedMessageV0" CASCADE;
|
||||
DROP TYPE "LoadedAddresses" CASCADE;
|
||||
DROP TYPE "TransactionMessageV0" CASCADE;
|
||||
DROP TYPE "TransactionMessage" CASCADE;
|
||||
DROP TYPE "TransactionMessageHeader" CASCADE;
|
||||
DROP TYPE "TransactionMessageAddressTableLookup" CASCADE;
|
||||
DROP TYPE "TransactionStatusMeta" CASCADE;
|
||||
DROP TYPE "RewardType" CASCADE;
|
||||
DROP TYPE "Reward" CASCADE;
|
||||
DROP TYPE "TransactionTokenBalance" CASCADE;
|
||||
DROP TYPE "InnerInstructions" CASCADE;
|
||||
DROP TYPE "CompiledInstruction" CASCADE;
|
@@ -1,802 +0,0 @@
|
||||
# This a reference configuration file for the PostgreSQL database version 14.
|
||||
|
||||
# -----------------------------
|
||||
# PostgreSQL configuration file
|
||||
# -----------------------------
|
||||
#
|
||||
# This file consists of lines of the form:
|
||||
#
|
||||
# name = value
|
||||
#
|
||||
# (The "=" is optional.) Whitespace may be used. Comments are introduced with
|
||||
# "#" anywhere on a line. The complete list of parameter names and allowed
|
||||
# values can be found in the PostgreSQL documentation.
|
||||
#
|
||||
# The commented-out settings shown in this file represent the default values.
|
||||
# Re-commenting a setting is NOT sufficient to revert it to the default value;
|
||||
# you need to reload the server.
|
||||
#
|
||||
# This file is read on server startup and when the server receives a SIGHUP
|
||||
# signal. If you edit the file on a running system, you have to SIGHUP the
|
||||
# server for the changes to take effect, run "pg_ctl reload", or execute
|
||||
# "SELECT pg_reload_conf()". Some parameters, which are marked below,
|
||||
# require a server shutdown and restart to take effect.
|
||||
#
|
||||
# Any parameter can also be given as a command-line option to the server, e.g.,
|
||||
# "postgres -c log_connections=on". Some parameters can be changed at run time
|
||||
# with the "SET" SQL command.
|
||||
#
|
||||
# Memory units: B = bytes Time units: us = microseconds
|
||||
# kB = kilobytes ms = milliseconds
|
||||
# MB = megabytes s = seconds
|
||||
# GB = gigabytes min = minutes
|
||||
# TB = terabytes h = hours
|
||||
# d = days
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# FILE LOCATIONS
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
# The default values of these variables are driven from the -D command-line
|
||||
# option or PGDATA environment variable, represented here as ConfigDir.
|
||||
|
||||
data_directory = '/var/lib/postgresql/14/main' # use data in another directory
|
||||
# (change requires restart)
|
||||
|
||||
hba_file = '/etc/postgresql/14/main/pg_hba.conf' # host-based authentication file
|
||||
# (change requires restart)
|
||||
ident_file = '/etc/postgresql/14/main/pg_ident.conf' # ident configuration file
|
||||
# (change requires restart)
|
||||
|
||||
# If external_pid_file is not explicitly set, no extra PID file is written.
|
||||
external_pid_file = '/var/run/postgresql/14-main.pid' # write an extra PID file
|
||||
# (change requires restart)
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# CONNECTIONS AND AUTHENTICATION
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
# - Connection Settings -
|
||||
|
||||
#listen_addresses = 'localhost' # what IP address(es) to listen on;
|
||||
# comma-separated list of addresses;
|
||||
# defaults to 'localhost'; use '*' for all
|
||||
# (change requires restart)
|
||||
listen_addresses = '*'
|
||||
port = 5433 # (change requires restart)
|
||||
max_connections = 200 # (change requires restart)
|
||||
#superuser_reserved_connections = 3 # (change requires restart)
|
||||
unix_socket_directories = '/var/run/postgresql' # comma-separated list of directories
|
||||
# (change requires restart)
|
||||
#unix_socket_group = '' # (change requires restart)
|
||||
#unix_socket_permissions = 0777 # begin with 0 to use octal notation
|
||||
# (change requires restart)
|
||||
#bonjour = off # advertise server via Bonjour
|
||||
# (change requires restart)
|
||||
#bonjour_name = '' # defaults to the computer name
|
||||
# (change requires restart)
|
||||
|
||||
# - TCP settings -
|
||||
# see "man tcp" for details
|
||||
|
||||
#tcp_keepalives_idle = 0 # TCP_KEEPIDLE, in seconds;
|
||||
# 0 selects the system default
|
||||
#tcp_keepalives_interval = 0 # TCP_KEEPINTVL, in seconds;
|
||||
# 0 selects the system default
|
||||
#tcp_keepalives_count = 0 # TCP_KEEPCNT;
|
||||
# 0 selects the system default
|
||||
#tcp_user_timeout = 0 # TCP_USER_TIMEOUT, in milliseconds;
|
||||
# 0 selects the system default
|
||||
|
||||
#client_connection_check_interval = 0 # time between checks for client
|
||||
# disconnection while running queries;
|
||||
# 0 for never
|
||||
|
||||
# - Authentication -
|
||||
|
||||
#authentication_timeout = 1min # 1s-600s
|
||||
#password_encryption = scram-sha-256 # scram-sha-256 or md5
|
||||
#db_user_namespace = off
|
||||
|
||||
# GSSAPI using Kerberos
|
||||
#krb_server_keyfile = 'FILE:${sysconfdir}/krb5.keytab'
|
||||
#krb_caseins_users = off
|
||||
|
||||
# - SSL -
|
||||
|
||||
ssl = on
|
||||
#ssl_ca_file = ''
|
||||
ssl_cert_file = '/etc/ssl/certs/ssl-cert-snakeoil.pem'
|
||||
#ssl_crl_file = ''
|
||||
#ssl_crl_dir = ''
|
||||
ssl_key_file = '/etc/ssl/private/ssl-cert-snakeoil.key'
|
||||
#ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL' # allowed SSL ciphers
|
||||
#ssl_prefer_server_ciphers = on
|
||||
#ssl_ecdh_curve = 'prime256v1'
|
||||
#ssl_min_protocol_version = 'TLSv1.2'
|
||||
#ssl_max_protocol_version = ''
|
||||
#ssl_dh_params_file = ''
|
||||
#ssl_passphrase_command = ''
|
||||
#ssl_passphrase_command_supports_reload = off
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# RESOURCE USAGE (except WAL)
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
# - Memory -
|
||||
|
||||
shared_buffers = 1GB # min 128kB
|
||||
# (change requires restart)
|
||||
#huge_pages = try # on, off, or try
|
||||
# (change requires restart)
|
||||
#huge_page_size = 0 # zero for system default
|
||||
# (change requires restart)
|
||||
#temp_buffers = 8MB # min 800kB
|
||||
#max_prepared_transactions = 0 # zero disables the feature
|
||||
# (change requires restart)
|
||||
# Caution: it is not advisable to set max_prepared_transactions nonzero unless
|
||||
# you actively intend to use prepared transactions.
|
||||
#work_mem = 4MB # min 64kB
|
||||
#hash_mem_multiplier = 1.0 # 1-1000.0 multiplier on hash table work_mem
|
||||
#maintenance_work_mem = 64MB # min 1MB
|
||||
#autovacuum_work_mem = -1 # min 1MB, or -1 to use maintenance_work_mem
|
||||
#logical_decoding_work_mem = 64MB # min 64kB
|
||||
#max_stack_depth = 2MB # min 100kB
|
||||
#shared_memory_type = mmap # the default is the first option
|
||||
# supported by the operating system:
|
||||
# mmap
|
||||
# sysv
|
||||
# windows
|
||||
# (change requires restart)
|
||||
dynamic_shared_memory_type = posix # the default is the first option
|
||||
# supported by the operating system:
|
||||
# posix
|
||||
# sysv
|
||||
# windows
|
||||
# mmap
|
||||
# (change requires restart)
|
||||
#min_dynamic_shared_memory = 0MB # (change requires restart)
|
||||
|
||||
# - Disk -
|
||||
|
||||
#temp_file_limit = -1 # limits per-process temp file space
|
||||
# in kilobytes, or -1 for no limit
|
||||
|
||||
# - Kernel Resources -
|
||||
|
||||
#max_files_per_process = 1000 # min 64
|
||||
# (change requires restart)
|
||||
|
||||
# - Cost-Based Vacuum Delay -
|
||||
|
||||
#vacuum_cost_delay = 0 # 0-100 milliseconds (0 disables)
|
||||
#vacuum_cost_page_hit = 1 # 0-10000 credits
|
||||
#vacuum_cost_page_miss = 2 # 0-10000 credits
|
||||
#vacuum_cost_page_dirty = 20 # 0-10000 credits
|
||||
#vacuum_cost_limit = 200 # 1-10000 credits
|
||||
|
||||
# - Background Writer -
|
||||
|
||||
#bgwriter_delay = 200ms # 10-10000ms between rounds
|
||||
#bgwriter_lru_maxpages = 100 # max buffers written/round, 0 disables
|
||||
#bgwriter_lru_multiplier = 2.0 # 0-10.0 multiplier on buffers scanned/round
|
||||
#bgwriter_flush_after = 512kB # measured in pages, 0 disables
|
||||
|
||||
# - Asynchronous Behavior -
|
||||
|
||||
#backend_flush_after = 0 # measured in pages, 0 disables
|
||||
effective_io_concurrency = 1000 # 1-1000; 0 disables prefetching
|
||||
#maintenance_io_concurrency = 10 # 1-1000; 0 disables prefetching
|
||||
#max_worker_processes = 8 # (change requires restart)
|
||||
#max_parallel_workers_per_gather = 2 # taken from max_parallel_workers
|
||||
#max_parallel_maintenance_workers = 2 # taken from max_parallel_workers
|
||||
#max_parallel_workers = 8 # maximum number of max_worker_processes that
|
||||
# can be used in parallel operations
|
||||
#parallel_leader_participation = on
|
||||
#old_snapshot_threshold = -1 # 1min-60d; -1 disables; 0 is immediate
|
||||
# (change requires restart)
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# WRITE-AHEAD LOG
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
# - Settings -
|
||||
|
||||
wal_level = minimal # minimal, replica, or logical
|
||||
# (change requires restart)
|
||||
fsync = off # flush data to disk for crash safety
|
||||
# (turning this off can cause
|
||||
# unrecoverable data corruption)
|
||||
synchronous_commit = off # synchronization level;
|
||||
# off, local, remote_write, remote_apply, or on
|
||||
#wal_sync_method = fsync # the default is the first option
|
||||
# supported by the operating system:
|
||||
# open_datasync
|
||||
# fdatasync (default on Linux and FreeBSD)
|
||||
# fsync
|
||||
# fsync_writethrough
|
||||
# open_sync
|
||||
full_page_writes = off # recover from partial page writes
|
||||
#wal_log_hints = off # also do full page writes of non-critical updates
|
||||
# (change requires restart)
|
||||
#wal_compression = off # enable compression of full-page writes
|
||||
#wal_init_zero = on # zero-fill new WAL files
|
||||
#wal_recycle = on # recycle WAL files
|
||||
#wal_buffers = -1 # min 32kB, -1 sets based on shared_buffers
|
||||
# (change requires restart)
|
||||
#wal_writer_delay = 200ms # 1-10000 milliseconds
|
||||
#wal_writer_flush_after = 1MB # measured in pages, 0 disables
|
||||
#wal_skip_threshold = 2MB
|
||||
|
||||
#commit_delay = 0 # range 0-100000, in microseconds
|
||||
#commit_siblings = 5 # range 1-1000
|
||||
|
||||
# - Checkpoints -
|
||||
|
||||
#checkpoint_timeout = 5min # range 30s-1d
|
||||
#checkpoint_completion_target = 0.9 # checkpoint target duration, 0.0 - 1.0
|
||||
#checkpoint_flush_after = 256kB # measured in pages, 0 disables
|
||||
#checkpoint_warning = 30s # 0 disables
|
||||
max_wal_size = 1GB
|
||||
min_wal_size = 80MB
|
||||
|
||||
# - Archiving -
|
||||
|
||||
#archive_mode = off # enables archiving; off, on, or always
|
||||
# (change requires restart)
|
||||
#archive_command = '' # command to use to archive a logfile segment
|
||||
# placeholders: %p = path of file to archive
|
||||
# %f = file name only
|
||||
# e.g. 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f'
|
||||
#archive_timeout = 0 # force a logfile segment switch after this
|
||||
# number of seconds; 0 disables
|
||||
|
||||
# - Archive Recovery -
|
||||
|
||||
# These are only used in recovery mode.
|
||||
|
||||
#restore_command = '' # command to use to restore an archived logfile segment
|
||||
# placeholders: %p = path of file to restore
|
||||
# %f = file name only
|
||||
# e.g. 'cp /mnt/server/archivedir/%f %p'
|
||||
#archive_cleanup_command = '' # command to execute at every restartpoint
|
||||
#recovery_end_command = '' # command to execute at completion of recovery
|
||||
|
||||
# - Recovery Target -
|
||||
|
||||
# Set these only when performing a targeted recovery.
|
||||
|
||||
#recovery_target = '' # 'immediate' to end recovery as soon as a
|
||||
# consistent state is reached
|
||||
# (change requires restart)
|
||||
#recovery_target_name = '' # the named restore point to which recovery will proceed
|
||||
# (change requires restart)
|
||||
#recovery_target_time = '' # the time stamp up to which recovery will proceed
|
||||
# (change requires restart)
|
||||
#recovery_target_xid = '' # the transaction ID up to which recovery will proceed
|
||||
# (change requires restart)
|
||||
#recovery_target_lsn = '' # the WAL LSN up to which recovery will proceed
|
||||
# (change requires restart)
|
||||
#recovery_target_inclusive = on # Specifies whether to stop:
|
||||
# just after the specified recovery target (on)
|
||||
# just before the recovery target (off)
|
||||
# (change requires restart)
|
||||
#recovery_target_timeline = 'latest' # 'current', 'latest', or timeline ID
|
||||
# (change requires restart)
|
||||
#recovery_target_action = 'pause' # 'pause', 'promote', 'shutdown'
|
||||
# (change requires restart)
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# REPLICATION
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
# - Sending Servers -
|
||||
|
||||
# Set these on the primary and on any standby that will send replication data.
|
||||
|
||||
max_wal_senders = 0 # max number of walsender processes
|
||||
# (change requires restart)
|
||||
#max_replication_slots = 10 # max number of replication slots
|
||||
# (change requires restart)
|
||||
#wal_keep_size = 0 # in megabytes; 0 disables
|
||||
#max_slot_wal_keep_size = -1 # in megabytes; -1 disables
|
||||
#wal_sender_timeout = 60s # in milliseconds; 0 disables
|
||||
#track_commit_timestamp = off # collect timestamp of transaction commit
|
||||
# (change requires restart)
|
||||
|
||||
# - Primary Server -
|
||||
|
||||
# These settings are ignored on a standby server.
|
||||
|
||||
#synchronous_standby_names = '' # standby servers that provide sync rep
|
||||
# method to choose sync standbys, number of sync standbys,
|
||||
# and comma-separated list of application_name
|
||||
# from standby(s); '*' = all
|
||||
#vacuum_defer_cleanup_age = 0 # number of xacts by which cleanup is delayed
|
||||
|
||||
# - Standby Servers -
|
||||
|
||||
# These settings are ignored on a primary server.
|
||||
|
||||
#primary_conninfo = '' # connection string to sending server
|
||||
#primary_slot_name = '' # replication slot on sending server
|
||||
#promote_trigger_file = '' # file name whose presence ends recovery
|
||||
#hot_standby = on # "off" disallows queries during recovery
|
||||
# (change requires restart)
|
||||
#max_standby_archive_delay = 30s # max delay before canceling queries
|
||||
# when reading WAL from archive;
|
||||
# -1 allows indefinite delay
|
||||
#max_standby_streaming_delay = 30s # max delay before canceling queries
|
||||
# when reading streaming WAL;
|
||||
# -1 allows indefinite delay
|
||||
#wal_receiver_create_temp_slot = off # create temp slot if primary_slot_name
|
||||
# is not set
|
||||
#wal_receiver_status_interval = 10s # send replies at least this often
|
||||
# 0 disables
|
||||
#hot_standby_feedback = off # send info from standby to prevent
|
||||
# query conflicts
|
||||
#wal_receiver_timeout = 60s # time that receiver waits for
|
||||
# communication from primary
|
||||
# in milliseconds; 0 disables
|
||||
#wal_retrieve_retry_interval = 5s # time to wait before retrying to
|
||||
# retrieve WAL after a failed attempt
|
||||
#recovery_min_apply_delay = 0 # minimum delay for applying changes during recovery
|
||||
|
||||
# - Subscribers -
|
||||
|
||||
# These settings are ignored on a publisher.
|
||||
|
||||
#max_logical_replication_workers = 4 # taken from max_worker_processes
|
||||
# (change requires restart)
|
||||
#max_sync_workers_per_subscription = 2 # taken from max_logical_replication_workers
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# QUERY TUNING
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
# - Planner Method Configuration -
|
||||
|
||||
#enable_async_append = on
|
||||
#enable_bitmapscan = on
|
||||
#enable_gathermerge = on
|
||||
#enable_hashagg = on
|
||||
#enable_hashjoin = on
|
||||
#enable_incremental_sort = on
|
||||
#enable_indexscan = on
|
||||
#enable_indexonlyscan = on
|
||||
#enable_material = on
|
||||
#enable_memoize = on
|
||||
#enable_mergejoin = on
|
||||
#enable_nestloop = on
|
||||
#enable_parallel_append = on
|
||||
#enable_parallel_hash = on
|
||||
#enable_partition_pruning = on
|
||||
#enable_partitionwise_join = off
|
||||
#enable_partitionwise_aggregate = off
|
||||
#enable_seqscan = on
|
||||
#enable_sort = on
|
||||
#enable_tidscan = on
|
||||
|
||||
# - Planner Cost Constants -
|
||||
|
||||
#seq_page_cost = 1.0 # measured on an arbitrary scale
|
||||
#random_page_cost = 4.0 # same scale as above
|
||||
#cpu_tuple_cost = 0.01 # same scale as above
|
||||
#cpu_index_tuple_cost = 0.005 # same scale as above
|
||||
#cpu_operator_cost = 0.0025 # same scale as above
|
||||
#parallel_setup_cost = 1000.0 # same scale as above
|
||||
#parallel_tuple_cost = 0.1 # same scale as above
|
||||
#min_parallel_table_scan_size = 8MB
|
||||
#min_parallel_index_scan_size = 512kB
|
||||
#effective_cache_size = 4GB
|
||||
|
||||
#jit_above_cost = 100000 # perform JIT compilation if available
|
||||
# and query more expensive than this;
|
||||
# -1 disables
|
||||
#jit_inline_above_cost = 500000 # inline small functions if query is
|
||||
# more expensive than this; -1 disables
|
||||
#jit_optimize_above_cost = 500000 # use expensive JIT optimizations if
|
||||
# query is more expensive than this;
|
||||
# -1 disables
|
||||
|
||||
# - Genetic Query Optimizer -
|
||||
|
||||
#geqo = on
|
||||
#geqo_threshold = 12
|
||||
#geqo_effort = 5 # range 1-10
|
||||
#geqo_pool_size = 0 # selects default based on effort
|
||||
#geqo_generations = 0 # selects default based on effort
|
||||
#geqo_selection_bias = 2.0 # range 1.5-2.0
|
||||
#geqo_seed = 0.0 # range 0.0-1.0
|
||||
|
||||
# - Other Planner Options -
|
||||
|
||||
#default_statistics_target = 100 # range 1-10000
|
||||
#constraint_exclusion = partition # on, off, or partition
|
||||
#cursor_tuple_fraction = 0.1 # range 0.0-1.0
|
||||
#from_collapse_limit = 8
|
||||
#jit = on # allow JIT compilation
|
||||
#join_collapse_limit = 8 # 1 disables collapsing of explicit
|
||||
# JOIN clauses
|
||||
#plan_cache_mode = auto # auto, force_generic_plan or
|
||||
# force_custom_plan
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# REPORTING AND LOGGING
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
# - Where to Log -
|
||||
|
||||
#log_destination = 'stderr' # Valid values are combinations of
|
||||
# stderr, csvlog, syslog, and eventlog,
|
||||
# depending on platform. csvlog
|
||||
# requires logging_collector to be on.
|
||||
|
||||
# This is used when logging to stderr:
|
||||
#logging_collector = off # Enable capturing of stderr and csvlog
|
||||
# into log files. Required to be on for
|
||||
# csvlogs.
|
||||
# (change requires restart)
|
||||
|
||||
# These are only used if logging_collector is on:
|
||||
#log_directory = 'log' # directory where log files are written,
|
||||
# can be absolute or relative to PGDATA
|
||||
#log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log' # log file name pattern,
|
||||
# can include strftime() escapes
|
||||
#log_file_mode = 0600 # creation mode for log files,
|
||||
# begin with 0 to use octal notation
|
||||
#log_rotation_age = 1d # Automatic rotation of logfiles will
|
||||
# happen after that time. 0 disables.
|
||||
#log_rotation_size = 10MB # Automatic rotation of logfiles will
|
||||
# happen after that much log output.
|
||||
# 0 disables.
|
||||
#log_truncate_on_rotation = off # If on, an existing log file with the
|
||||
# same name as the new log file will be
|
||||
# truncated rather than appended to.
|
||||
# But such truncation only occurs on
|
||||
# time-driven rotation, not on restarts
|
||||
# or size-driven rotation. Default is
|
||||
# off, meaning append to existing files
|
||||
# in all cases.
|
||||
|
||||
# These are relevant when logging to syslog:
|
||||
#syslog_facility = 'LOCAL0'
|
||||
#syslog_ident = 'postgres'
|
||||
#syslog_sequence_numbers = on
|
||||
#syslog_split_messages = on
|
||||
|
||||
# This is only relevant when logging to eventlog (Windows):
|
||||
# (change requires restart)
|
||||
#event_source = 'PostgreSQL'
|
||||
|
||||
# - When to Log -
|
||||
|
||||
#log_min_messages = warning # values in order of decreasing detail:
|
||||
# debug5
|
||||
# debug4
|
||||
# debug3
|
||||
# debug2
|
||||
# debug1
|
||||
# info
|
||||
# notice
|
||||
# warning
|
||||
# error
|
||||
# log
|
||||
# fatal
|
||||
# panic
|
||||
|
||||
#log_min_error_statement = error # values in order of decreasing detail:
|
||||
# debug5
|
||||
# debug4
|
||||
# debug3
|
||||
# debug2
|
||||
# debug1
|
||||
# info
|
||||
# notice
|
||||
# warning
|
||||
# error
|
||||
# log
|
||||
# fatal
|
||||
# panic (effectively off)
|
||||
|
||||
#log_min_duration_statement = -1 # -1 is disabled, 0 logs all statements
|
||||
# and their durations, > 0 logs only
|
||||
# statements running at least this number
|
||||
# of milliseconds
|
||||
|
||||
#log_min_duration_sample = -1 # -1 is disabled, 0 logs a sample of statements
|
||||
# and their durations, > 0 logs only a sample of
|
||||
# statements running at least this number
|
||||
# of milliseconds;
|
||||
# sample fraction is determined by log_statement_sample_rate
|
||||
|
||||
#log_statement_sample_rate = 1.0 # fraction of logged statements exceeding
|
||||
# log_min_duration_sample to be logged;
|
||||
# 1.0 logs all such statements, 0.0 never logs
|
||||
|
||||
|
||||
#log_transaction_sample_rate = 0.0 # fraction of transactions whose statements
|
||||
# are logged regardless of their duration; 1.0 logs all
|
||||
# statements from all transactions, 0.0 never logs
|
||||
|
||||
# - What to Log -
|
||||
|
||||
#debug_print_parse = off
|
||||
#debug_print_rewritten = off
|
||||
#debug_print_plan = off
|
||||
#debug_pretty_print = on
|
||||
#log_autovacuum_min_duration = -1 # log autovacuum activity;
|
||||
# -1 disables, 0 logs all actions and
|
||||
# their durations, > 0 logs only
|
||||
# actions running at least this number
|
||||
# of milliseconds.
|
||||
#log_checkpoints = off
|
||||
#log_connections = off
|
||||
#log_disconnections = off
|
||||
#log_duration = off
|
||||
#log_error_verbosity = default # terse, default, or verbose messages
|
||||
#log_hostname = off
|
||||
log_line_prefix = '%m [%p] %q%u@%d ' # special values:
|
||||
# %a = application name
|
||||
# %u = user name
|
||||
# %d = database name
|
||||
# %r = remote host and port
|
||||
# %h = remote host
|
||||
# %b = backend type
|
||||
# %p = process ID
|
||||
# %P = process ID of parallel group leader
|
||||
# %t = timestamp without milliseconds
|
||||
# %m = timestamp with milliseconds
|
||||
# %n = timestamp with milliseconds (as a Unix epoch)
|
||||
# %Q = query ID (0 if none or not computed)
|
||||
# %i = command tag
|
||||
# %e = SQL state
|
||||
# %c = session ID
|
||||
# %l = session line number
|
||||
# %s = session start timestamp
|
||||
# %v = virtual transaction ID
|
||||
# %x = transaction ID (0 if none)
|
||||
# %q = stop here in non-session
|
||||
# processes
|
||||
# %% = '%'
|
||||
# e.g. '<%u%%%d> '
|
||||
#log_lock_waits = off # log lock waits >= deadlock_timeout
|
||||
#log_recovery_conflict_waits = off # log standby recovery conflict waits
|
||||
# >= deadlock_timeout
|
||||
#log_parameter_max_length = -1 # when logging statements, limit logged
|
||||
# bind-parameter values to N bytes;
|
||||
# -1 means print in full, 0 disables
|
||||
#log_parameter_max_length_on_error = 0 # when logging an error, limit logged
|
||||
# bind-parameter values to N bytes;
|
||||
# -1 means print in full, 0 disables
|
||||
#log_statement = 'none' # none, ddl, mod, all
|
||||
#log_replication_commands = off
|
||||
#log_temp_files = -1 # log temporary files equal or larger
|
||||
# than the specified size in kilobytes;
|
||||
# -1 disables, 0 logs all temp files
|
||||
log_timezone = 'Etc/UTC'
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# PROCESS TITLE
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
cluster_name = '14/main' # added to process titles if nonempty
|
||||
# (change requires restart)
|
||||
#update_process_title = on
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# STATISTICS
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
# - Query and Index Statistics Collector -
|
||||
|
||||
#track_activities = on
|
||||
#track_activity_query_size = 1024 # (change requires restart)
|
||||
#track_counts = on
|
||||
#track_io_timing = off
|
||||
#track_wal_io_timing = off
|
||||
#track_functions = none # none, pl, all
|
||||
stats_temp_directory = '/var/run/postgresql/14-main.pg_stat_tmp'
|
||||
|
||||
|
||||
# - Monitoring -
|
||||
|
||||
#compute_query_id = auto
|
||||
#log_statement_stats = off
|
||||
#log_parser_stats = off
|
||||
#log_planner_stats = off
|
||||
#log_executor_stats = off
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# AUTOVACUUM
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
#autovacuum = on # Enable autovacuum subprocess? 'on'
|
||||
# requires track_counts to also be on.
|
||||
#autovacuum_max_workers = 3 # max number of autovacuum subprocesses
|
||||
# (change requires restart)
|
||||
#autovacuum_naptime = 1min # time between autovacuum runs
|
||||
#autovacuum_vacuum_threshold = 50 # min number of row updates before
|
||||
# vacuum
|
||||
#autovacuum_vacuum_insert_threshold = 1000 # min number of row inserts
|
||||
# before vacuum; -1 disables insert
|
||||
# vacuums
|
||||
#autovacuum_analyze_threshold = 50 # min number of row updates before
|
||||
# analyze
|
||||
#autovacuum_vacuum_scale_factor = 0.2 # fraction of table size before vacuum
|
||||
#autovacuum_vacuum_insert_scale_factor = 0.2 # fraction of inserts over table
|
||||
# size before insert vacuum
|
||||
#autovacuum_analyze_scale_factor = 0.1 # fraction of table size before analyze
|
||||
#autovacuum_freeze_max_age = 200000000 # maximum XID age before forced vacuum
|
||||
# (change requires restart)
|
||||
#autovacuum_multixact_freeze_max_age = 400000000 # maximum multixact age
|
||||
# before forced vacuum
|
||||
# (change requires restart)
|
||||
#autovacuum_vacuum_cost_delay = 2ms # default vacuum cost delay for
|
||||
# autovacuum, in milliseconds;
|
||||
# -1 means use vacuum_cost_delay
|
||||
#autovacuum_vacuum_cost_limit = -1 # default vacuum cost limit for
|
||||
# autovacuum, -1 means use
|
||||
# vacuum_cost_limit
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# CLIENT CONNECTION DEFAULTS
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
# - Statement Behavior -
|
||||
|
||||
#client_min_messages = notice # values in order of decreasing detail:
|
||||
# debug5
|
||||
# debug4
|
||||
# debug3
|
||||
# debug2
|
||||
# debug1
|
||||
# log
|
||||
# notice
|
||||
# warning
|
||||
# error
|
||||
#search_path = '"$user", public' # schema names
|
||||
#row_security = on
|
||||
#default_table_access_method = 'heap'
|
||||
#default_tablespace = '' # a tablespace name, '' uses the default
|
||||
#default_toast_compression = 'pglz' # 'pglz' or 'lz4'
|
||||
#temp_tablespaces = '' # a list of tablespace names, '' uses
|
||||
# only default tablespace
|
||||
#check_function_bodies = on
|
||||
#default_transaction_isolation = 'read committed'
|
||||
#default_transaction_read_only = off
|
||||
#default_transaction_deferrable = off
|
||||
#session_replication_role = 'origin'
|
||||
#statement_timeout = 0 # in milliseconds, 0 is disabled
|
||||
#lock_timeout = 0 # in milliseconds, 0 is disabled
|
||||
#idle_in_transaction_session_timeout = 0 # in milliseconds, 0 is disabled
|
||||
#idle_session_timeout = 0 # in milliseconds, 0 is disabled
|
||||
#vacuum_freeze_table_age = 150000000
|
||||
#vacuum_freeze_min_age = 50000000
|
||||
#vacuum_failsafe_age = 1600000000
|
||||
#vacuum_multixact_freeze_table_age = 150000000
|
||||
#vacuum_multixact_freeze_min_age = 5000000
|
||||
#vacuum_multixact_failsafe_age = 1600000000
|
||||
#bytea_output = 'hex' # hex, escape
|
||||
#xmlbinary = 'base64'
|
||||
#xmloption = 'content'
|
||||
#gin_pending_list_limit = 4MB
|
||||
|
||||
# - Locale and Formatting -
|
||||
|
||||
datestyle = 'iso, mdy'
|
||||
#intervalstyle = 'postgres'
|
||||
timezone = 'Etc/UTC'
|
||||
#timezone_abbreviations = 'Default' # Select the set of available time zone
|
||||
# abbreviations. Currently, there are
|
||||
# Default
|
||||
# Australia (historical usage)
|
||||
# India
|
||||
# You can create your own file in
|
||||
# share/timezonesets/.
|
||||
#extra_float_digits = 1 # min -15, max 3; any value >0 actually
|
||||
# selects precise output mode
|
||||
#client_encoding = sql_ascii # actually, defaults to database
|
||||
# encoding
|
||||
|
||||
# These settings are initialized by initdb, but they can be changed.
|
||||
lc_messages = 'C.UTF-8' # locale for system error message
|
||||
# strings
|
||||
lc_monetary = 'C.UTF-8' # locale for monetary formatting
|
||||
lc_numeric = 'C.UTF-8' # locale for number formatting
|
||||
lc_time = 'C.UTF-8' # locale for time formatting
|
||||
|
||||
# default configuration for text search
|
||||
default_text_search_config = 'pg_catalog.english'
|
||||
|
||||
# - Shared Library Preloading -
|
||||
|
||||
#local_preload_libraries = ''
|
||||
#session_preload_libraries = ''
|
||||
#shared_preload_libraries = '' # (change requires restart)
|
||||
#jit_provider = 'llvmjit' # JIT library to use
|
||||
|
||||
# - Other Defaults -
|
||||
|
||||
#dynamic_library_path = '$libdir'
|
||||
#extension_destdir = '' # prepend path when loading extensions
|
||||
# and shared objects (added by Debian)
|
||||
#gin_fuzzy_search_limit = 0
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# LOCK MANAGEMENT
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
#deadlock_timeout = 1s
|
||||
#max_locks_per_transaction = 64 # min 10
|
||||
# (change requires restart)
|
||||
#max_pred_locks_per_transaction = 64 # min 10
|
||||
# (change requires restart)
|
||||
#max_pred_locks_per_relation = -2 # negative values mean
|
||||
# (max_pred_locks_per_transaction
|
||||
# / -max_pred_locks_per_relation) - 1
|
||||
#max_pred_locks_per_page = 2 # min 0
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# VERSION AND PLATFORM COMPATIBILITY
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
# - Previous PostgreSQL Versions -
|
||||
|
||||
#array_nulls = on
|
||||
#backslash_quote = safe_encoding # on, off, or safe_encoding
|
||||
#escape_string_warning = on
|
||||
#lo_compat_privileges = off
|
||||
#quote_all_identifiers = off
|
||||
#standard_conforming_strings = on
|
||||
#synchronize_seqscans = on
|
||||
|
||||
# - Other Platforms and Clients -
|
||||
|
||||
#transform_null_equals = off
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# ERROR HANDLING
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
#exit_on_error = off # terminate session on any error?
|
||||
#restart_after_crash = on # reinitialize after backend crash?
|
||||
#data_sync_retry = off # retry or panic on failure to fsync
|
||||
# data?
|
||||
# (change requires restart)
|
||||
#recovery_init_sync_method = fsync # fsync, syncfs (Linux 5.8+)
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# CONFIG FILE INCLUDES
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
# These options allow settings to be loaded from files other than the
|
||||
# default postgresql.conf. Note that these are directives, not variable
|
||||
# assignments, so they can usefully be given more than once.
|
||||
|
||||
include_dir = 'conf.d' # include files ending in '.conf' from
|
||||
# a directory, e.g., 'conf.d'
|
||||
#include_if_exists = '...' # include file only if it exists
|
||||
#include = '...' # include file
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# CUSTOMIZED OPTIONS
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
# Add settings for extensions here
|
@@ -1,74 +0,0 @@
|
||||
use {log::*, std::collections::HashSet};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct AccountsSelector {
|
||||
pub accounts: HashSet<Vec<u8>>,
|
||||
pub owners: HashSet<Vec<u8>>,
|
||||
pub select_all_accounts: bool,
|
||||
}
|
||||
|
||||
impl AccountsSelector {
|
||||
pub fn default() -> Self {
|
||||
AccountsSelector {
|
||||
accounts: HashSet::default(),
|
||||
owners: HashSet::default(),
|
||||
select_all_accounts: true,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new(accounts: &[String], owners: &[String]) -> Self {
|
||||
info!(
|
||||
"Creating AccountsSelector from accounts: {:?}, owners: {:?}",
|
||||
accounts, owners
|
||||
);
|
||||
|
||||
let select_all_accounts = accounts.iter().any(|key| key == "*");
|
||||
if select_all_accounts {
|
||||
return AccountsSelector {
|
||||
accounts: HashSet::default(),
|
||||
owners: HashSet::default(),
|
||||
select_all_accounts,
|
||||
};
|
||||
}
|
||||
let accounts = accounts
|
||||
.iter()
|
||||
.map(|key| bs58::decode(key).into_vec().unwrap())
|
||||
.collect();
|
||||
let owners = owners
|
||||
.iter()
|
||||
.map(|key| bs58::decode(key).into_vec().unwrap())
|
||||
.collect();
|
||||
AccountsSelector {
|
||||
accounts,
|
||||
owners,
|
||||
select_all_accounts,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_account_selected(&self, account: &[u8], owner: &[u8]) -> bool {
|
||||
self.select_all_accounts || self.accounts.contains(account) || self.owners.contains(owner)
|
||||
}
|
||||
|
||||
/// Check if any account is of interested at all
|
||||
pub fn is_enabled(&self) -> bool {
|
||||
self.select_all_accounts || !self.accounts.is_empty() || !self.owners.is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_create_accounts_selector() {
|
||||
AccountsSelector::new(
|
||||
&["9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin".to_string()],
|
||||
&[],
|
||||
);
|
||||
|
||||
AccountsSelector::new(
|
||||
&[],
|
||||
&["9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin".to_string()],
|
||||
);
|
||||
}
|
||||
}
|
@@ -1,466 +0,0 @@
|
||||
use solana_measure::measure::Measure;
|
||||
/// Main entry for the PostgreSQL plugin
|
||||
use {
|
||||
crate::{
|
||||
accounts_selector::AccountsSelector,
|
||||
postgres_client::{ParallelPostgresClient, PostgresClientBuilder},
|
||||
transaction_selector::TransactionSelector,
|
||||
},
|
||||
bs58,
|
||||
log::*,
|
||||
serde_derive::{Deserialize, Serialize},
|
||||
serde_json,
|
||||
solana_accountsdb_plugin_interface::accountsdb_plugin_interface::{
|
||||
AccountsDbPlugin, AccountsDbPluginError, ReplicaAccountInfoVersions,
|
||||
ReplicaBlockInfoVersions, ReplicaTransactionInfoVersions, Result, SlotStatus,
|
||||
},
|
||||
solana_metrics::*,
|
||||
std::{fs::File, io::Read},
|
||||
thiserror::Error,
|
||||
};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct AccountsDbPluginPostgres {
|
||||
client: Option<ParallelPostgresClient>,
|
||||
accounts_selector: Option<AccountsSelector>,
|
||||
transaction_selector: Option<TransactionSelector>,
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for AccountsDbPluginPostgres {
|
||||
fn fmt(&self, _: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct AccountsDbPluginPostgresConfig {
|
||||
pub host: Option<String>,
|
||||
pub user: Option<String>,
|
||||
pub port: Option<u16>,
|
||||
pub connection_str: Option<String>,
|
||||
pub threads: Option<usize>,
|
||||
pub batch_size: Option<usize>,
|
||||
pub panic_on_db_errors: Option<bool>,
|
||||
/// Indicates if to store historical data for accounts
|
||||
pub store_account_historical_data: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum AccountsDbPluginPostgresError {
|
||||
#[error("Error connecting to the backend data store. Error message: ({msg})")]
|
||||
DataStoreConnectionError { msg: String },
|
||||
|
||||
#[error("Error preparing data store schema. Error message: ({msg})")]
|
||||
DataSchemaError { msg: String },
|
||||
|
||||
#[error("Error preparing data store schema. Error message: ({msg})")]
|
||||
ConfigurationError { msg: String },
|
||||
}
|
||||
|
||||
impl AccountsDbPlugin for AccountsDbPluginPostgres {
|
||||
fn name(&self) -> &'static str {
|
||||
"AccountsDbPluginPostgres"
|
||||
}
|
||||
|
||||
/// Do initialization for the PostgreSQL plugin.
|
||||
///
|
||||
/// # Format of the config file:
|
||||
/// * The `accounts_selector` section allows the user to controls accounts selections.
|
||||
/// "accounts_selector" : {
|
||||
/// "accounts" : \["pubkey-1", "pubkey-2", ..., "pubkey-n"\],
|
||||
/// }
|
||||
/// or:
|
||||
/// "accounts_selector" = {
|
||||
/// "owners" : \["pubkey-1", "pubkey-2", ..., "pubkey-m"\]
|
||||
/// }
|
||||
/// Accounts either satisyfing the accounts condition or owners condition will be selected.
|
||||
/// When only owners is specified,
|
||||
/// all accounts belonging to the owners will be streamed.
|
||||
/// The accounts field supports wildcard to select all accounts:
|
||||
/// "accounts_selector" : {
|
||||
/// "accounts" : \["*"\],
|
||||
/// }
|
||||
/// * "host", optional, specifies the PostgreSQL server.
|
||||
/// * "user", optional, specifies the PostgreSQL user.
|
||||
/// * "port", optional, specifies the PostgreSQL server's port.
|
||||
/// * "connection_str", optional, the custom PostgreSQL connection string.
|
||||
/// Please refer to https://docs.rs/postgres/0.19.2/postgres/config/struct.Config.html for the connection configuration.
|
||||
/// When `connection_str` is set, the values in "host", "user" and "port" are ignored. If `connection_str` is not given,
|
||||
/// `host` and `user` must be given.
|
||||
/// "store_account_historical_data", optional, set it to 'true', to store historical account data to account_audit
|
||||
/// table.
|
||||
/// * "threads" optional, specifies the number of worker threads for the plugin. A thread
|
||||
/// maintains a PostgreSQL connection to the server. The default is '10'.
|
||||
/// * "batch_size" optional, specifies the batch size of bulk insert when the AccountsDb is created
|
||||
/// from restoring a snapshot. The default is '10'.
|
||||
/// * "panic_on_db_errors", optional, contols if to panic when there are errors replicating data to the
|
||||
/// PostgreSQL database. The default is 'false'.
|
||||
/// * "transaction_selector", optional, controls if and what transaction to store. If this field is missing
|
||||
/// None of the transction is stored.
|
||||
/// "transaction_selector" : {
|
||||
/// "mentions" : \["pubkey-1", "pubkey-2", ..., "pubkey-n"\],
|
||||
/// }
|
||||
/// The `mentions` field support wildcard to select all transaction or all 'vote' transactions:
|
||||
/// For example, to select all transactions:
|
||||
/// "transaction_selector" : {
|
||||
/// "mentions" : \["*"\],
|
||||
/// }
|
||||
/// To select all vote transactions:
|
||||
/// "transaction_selector" : {
|
||||
/// "mentions" : \["all_votes"\],
|
||||
/// }
|
||||
/// # Examples
|
||||
///
|
||||
/// {
|
||||
/// "libpath": "/home/solana/target/release/libsolana_accountsdb_plugin_postgres.so",
|
||||
/// "host": "host_foo",
|
||||
/// "user": "solana",
|
||||
/// "threads": 10,
|
||||
/// "accounts_selector" : {
|
||||
/// "owners" : ["9oT9R5ZyRovSVnt37QvVoBttGpNqR3J7unkb567NP8k3"]
|
||||
/// }
|
||||
/// }
|
||||
|
||||
fn on_load(&mut self, config_file: &str) -> Result<()> {
|
||||
solana_logger::setup_with_default("info");
|
||||
info!(
|
||||
"Loading plugin {:?} from config_file {:?}",
|
||||
self.name(),
|
||||
config_file
|
||||
);
|
||||
let mut file = File::open(config_file)?;
|
||||
let mut contents = String::new();
|
||||
file.read_to_string(&mut contents)?;
|
||||
|
||||
let result: serde_json::Value = serde_json::from_str(&contents).unwrap();
|
||||
self.accounts_selector = Some(Self::create_accounts_selector_from_config(&result));
|
||||
self.transaction_selector = Some(Self::create_transaction_selector_from_config(&result));
|
||||
|
||||
let result: serde_json::Result<AccountsDbPluginPostgresConfig> =
|
||||
serde_json::from_str(&contents);
|
||||
match result {
|
||||
Err(err) => {
|
||||
return Err(AccountsDbPluginError::ConfigFileReadError {
|
||||
msg: format!(
|
||||
"The config file is not in the JSON format expected: {:?}",
|
||||
err
|
||||
),
|
||||
})
|
||||
}
|
||||
Ok(config) => {
|
||||
let client = PostgresClientBuilder::build_pararallel_postgres_client(&config)?;
|
||||
self.client = Some(client);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn on_unload(&mut self) {
|
||||
info!("Unloading plugin: {:?}", self.name());
|
||||
|
||||
match &mut self.client {
|
||||
None => {}
|
||||
Some(client) => {
|
||||
client.join().unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn update_account(
|
||||
&mut self,
|
||||
account: ReplicaAccountInfoVersions,
|
||||
slot: u64,
|
||||
is_startup: bool,
|
||||
) -> Result<()> {
|
||||
let mut measure_all = Measure::start("accountsdb-plugin-postgres-update-account-main");
|
||||
match account {
|
||||
ReplicaAccountInfoVersions::V0_0_1(account) => {
|
||||
let mut measure_select =
|
||||
Measure::start("accountsdb-plugin-postgres-update-account-select");
|
||||
if let Some(accounts_selector) = &self.accounts_selector {
|
||||
if !accounts_selector.is_account_selected(account.pubkey, account.owner) {
|
||||
return Ok(());
|
||||
}
|
||||
} else {
|
||||
return Ok(());
|
||||
}
|
||||
measure_select.stop();
|
||||
inc_new_counter_debug!(
|
||||
"accountsdb-plugin-postgres-update-account-select-us",
|
||||
measure_select.as_us() as usize,
|
||||
100000,
|
||||
100000
|
||||
);
|
||||
|
||||
debug!(
|
||||
"Updating account {:?} with owner {:?} at slot {:?} using account selector {:?}",
|
||||
bs58::encode(account.pubkey).into_string(),
|
||||
bs58::encode(account.owner).into_string(),
|
||||
slot,
|
||||
self.accounts_selector.as_ref().unwrap()
|
||||
);
|
||||
|
||||
match &mut self.client {
|
||||
None => {
|
||||
return Err(AccountsDbPluginError::Custom(Box::new(
|
||||
AccountsDbPluginPostgresError::DataStoreConnectionError {
|
||||
msg: "There is no connection to the PostgreSQL database."
|
||||
.to_string(),
|
||||
},
|
||||
)));
|
||||
}
|
||||
Some(client) => {
|
||||
let mut measure_update =
|
||||
Measure::start("accountsdb-plugin-postgres-update-account-client");
|
||||
let result = { client.update_account(account, slot, is_startup) };
|
||||
measure_update.stop();
|
||||
|
||||
inc_new_counter_debug!(
|
||||
"accountsdb-plugin-postgres-update-account-client-us",
|
||||
measure_update.as_us() as usize,
|
||||
100000,
|
||||
100000
|
||||
);
|
||||
|
||||
if let Err(err) = result {
|
||||
return Err(AccountsDbPluginError::AccountsUpdateError {
|
||||
msg: format!("Failed to persist the update of account to the PostgreSQL database. Error: {:?}", err)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
measure_all.stop();
|
||||
|
||||
inc_new_counter_debug!(
|
||||
"accountsdb-plugin-postgres-update-account-main-us",
|
||||
measure_all.as_us() as usize,
|
||||
100000,
|
||||
100000
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn update_slot_status(
|
||||
&mut self,
|
||||
slot: u64,
|
||||
parent: Option<u64>,
|
||||
status: SlotStatus,
|
||||
) -> Result<()> {
|
||||
info!("Updating slot {:?} at with status {:?}", slot, status);
|
||||
|
||||
match &mut self.client {
|
||||
None => {
|
||||
return Err(AccountsDbPluginError::Custom(Box::new(
|
||||
AccountsDbPluginPostgresError::DataStoreConnectionError {
|
||||
msg: "There is no connection to the PostgreSQL database.".to_string(),
|
||||
},
|
||||
)));
|
||||
}
|
||||
Some(client) => {
|
||||
let result = client.update_slot_status(slot, parent, status);
|
||||
|
||||
if let Err(err) = result {
|
||||
return Err(AccountsDbPluginError::SlotStatusUpdateError{
|
||||
msg: format!("Failed to persist the update of slot to the PostgreSQL database. Error: {:?}", err)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn notify_end_of_startup(&mut self) -> Result<()> {
|
||||
info!("Notifying the end of startup for accounts notifications");
|
||||
match &mut self.client {
|
||||
None => {
|
||||
return Err(AccountsDbPluginError::Custom(Box::new(
|
||||
AccountsDbPluginPostgresError::DataStoreConnectionError {
|
||||
msg: "There is no connection to the PostgreSQL database.".to_string(),
|
||||
},
|
||||
)));
|
||||
}
|
||||
Some(client) => {
|
||||
let result = client.notify_end_of_startup();
|
||||
|
||||
if let Err(err) = result {
|
||||
return Err(AccountsDbPluginError::SlotStatusUpdateError{
|
||||
msg: format!("Failed to notify the end of startup for accounts notifications. Error: {:?}", err)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn notify_transaction(
|
||||
&mut self,
|
||||
transaction_info: ReplicaTransactionInfoVersions,
|
||||
slot: u64,
|
||||
) -> Result<()> {
|
||||
match &mut self.client {
|
||||
None => {
|
||||
return Err(AccountsDbPluginError::Custom(Box::new(
|
||||
AccountsDbPluginPostgresError::DataStoreConnectionError {
|
||||
msg: "There is no connection to the PostgreSQL database.".to_string(),
|
||||
},
|
||||
)));
|
||||
}
|
||||
Some(client) => match transaction_info {
|
||||
ReplicaTransactionInfoVersions::V0_0_1(transaction_info) => {
|
||||
if let Some(transaction_selector) = &self.transaction_selector {
|
||||
if !transaction_selector.is_transaction_selected(
|
||||
transaction_info.is_vote,
|
||||
transaction_info.transaction.message().account_keys_iter(),
|
||||
) {
|
||||
return Ok(());
|
||||
}
|
||||
} else {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let result = client.log_transaction_info(transaction_info, slot);
|
||||
|
||||
if let Err(err) = result {
|
||||
return Err(AccountsDbPluginError::SlotStatusUpdateError{
|
||||
msg: format!("Failed to persist the transaction info to the PostgreSQL database. Error: {:?}", err)
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn notify_block_metadata(&mut self, block_info: ReplicaBlockInfoVersions) -> Result<()> {
|
||||
match &mut self.client {
|
||||
None => {
|
||||
return Err(AccountsDbPluginError::Custom(Box::new(
|
||||
AccountsDbPluginPostgresError::DataStoreConnectionError {
|
||||
msg: "There is no connection to the PostgreSQL database.".to_string(),
|
||||
},
|
||||
)));
|
||||
}
|
||||
Some(client) => match block_info {
|
||||
ReplicaBlockInfoVersions::V0_0_1(block_info) => {
|
||||
let result = client.update_block_metadata(block_info);
|
||||
|
||||
if let Err(err) = result {
|
||||
return Err(AccountsDbPluginError::SlotStatusUpdateError{
|
||||
msg: format!("Failed to persist the update of block metadata to the PostgreSQL database. Error: {:?}", err)
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Check if the plugin is interested in account data
|
||||
/// Default is true -- if the plugin is not interested in
|
||||
/// account data, please return false.
|
||||
fn account_data_notifications_enabled(&self) -> bool {
|
||||
self.accounts_selector
|
||||
.as_ref()
|
||||
.map_or_else(|| false, |selector| selector.is_enabled())
|
||||
}
|
||||
|
||||
/// Check if the plugin is interested in transaction data
|
||||
fn transaction_notifications_enabled(&self) -> bool {
|
||||
self.transaction_selector
|
||||
.as_ref()
|
||||
.map_or_else(|| false, |selector| selector.is_enabled())
|
||||
}
|
||||
}
|
||||
|
||||
impl AccountsDbPluginPostgres {
|
||||
fn create_accounts_selector_from_config(config: &serde_json::Value) -> AccountsSelector {
|
||||
let accounts_selector = &config["accounts_selector"];
|
||||
|
||||
if accounts_selector.is_null() {
|
||||
AccountsSelector::default()
|
||||
} else {
|
||||
let accounts = &accounts_selector["accounts"];
|
||||
let accounts: Vec<String> = if accounts.is_array() {
|
||||
accounts
|
||||
.as_array()
|
||||
.unwrap()
|
||||
.iter()
|
||||
.map(|val| val.as_str().unwrap().to_string())
|
||||
.collect()
|
||||
} else {
|
||||
Vec::default()
|
||||
};
|
||||
let owners = &accounts_selector["owners"];
|
||||
let owners: Vec<String> = if owners.is_array() {
|
||||
owners
|
||||
.as_array()
|
||||
.unwrap()
|
||||
.iter()
|
||||
.map(|val| val.as_str().unwrap().to_string())
|
||||
.collect()
|
||||
} else {
|
||||
Vec::default()
|
||||
};
|
||||
AccountsSelector::new(&accounts, &owners)
|
||||
}
|
||||
}
|
||||
|
||||
fn create_transaction_selector_from_config(config: &serde_json::Value) -> TransactionSelector {
|
||||
let transaction_selector = &config["transaction_selector"];
|
||||
|
||||
if transaction_selector.is_null() {
|
||||
TransactionSelector::default()
|
||||
} else {
|
||||
let accounts = &transaction_selector["mentions"];
|
||||
let accounts: Vec<String> = if accounts.is_array() {
|
||||
accounts
|
||||
.as_array()
|
||||
.unwrap()
|
||||
.iter()
|
||||
.map(|val| val.as_str().unwrap().to_string())
|
||||
.collect()
|
||||
} else {
|
||||
Vec::default()
|
||||
};
|
||||
TransactionSelector::new(&accounts)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
#[allow(improper_ctypes_definitions)]
|
||||
/// # Safety
|
||||
///
|
||||
/// This function returns the AccountsDbPluginPostgres pointer as trait AccountsDbPlugin.
|
||||
pub unsafe extern "C" fn _create_plugin() -> *mut dyn AccountsDbPlugin {
|
||||
let plugin = AccountsDbPluginPostgres::new();
|
||||
let plugin: Box<dyn AccountsDbPlugin> = Box::new(plugin);
|
||||
Box::into_raw(plugin)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) mod tests {
|
||||
use {super::*, serde_json};
|
||||
|
||||
#[test]
|
||||
fn test_accounts_selector_from_config() {
|
||||
let config = "{\"accounts_selector\" : { \
|
||||
\"owners\" : [\"9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin\"] \
|
||||
}}";
|
||||
|
||||
let config: serde_json::Value = serde_json::from_str(config).unwrap();
|
||||
AccountsDbPluginPostgres::create_accounts_selector_from_config(&config);
|
||||
}
|
||||
}
|
@@ -1,4 +0,0 @@
|
||||
pub mod accounts_selector;
|
||||
pub mod accountsdb_plugin_postgres;
|
||||
pub mod postgres_client;
|
||||
pub mod transaction_selector;
|
File diff suppressed because it is too large
Load Diff
@@ -1,97 +0,0 @@
|
||||
use {
|
||||
crate::{
|
||||
accountsdb_plugin_postgres::{
|
||||
AccountsDbPluginPostgresConfig, AccountsDbPluginPostgresError,
|
||||
},
|
||||
postgres_client::{
|
||||
postgres_client_transaction::DbReward, SimplePostgresClient, UpdateBlockMetadataRequest,
|
||||
},
|
||||
},
|
||||
chrono::Utc,
|
||||
log::*,
|
||||
postgres::{Client, Statement},
|
||||
solana_accountsdb_plugin_interface::accountsdb_plugin_interface::{
|
||||
AccountsDbPluginError, ReplicaBlockInfo,
|
||||
},
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct DbBlockInfo {
|
||||
pub slot: i64,
|
||||
pub blockhash: String,
|
||||
pub rewards: Vec<DbReward>,
|
||||
pub block_time: Option<i64>,
|
||||
pub block_height: Option<i64>,
|
||||
}
|
||||
|
||||
impl<'a> From<&ReplicaBlockInfo<'a>> for DbBlockInfo {
|
||||
fn from(block_info: &ReplicaBlockInfo) -> Self {
|
||||
Self {
|
||||
slot: block_info.slot as i64,
|
||||
blockhash: block_info.blockhash.to_string(),
|
||||
rewards: block_info.rewards.iter().map(DbReward::from).collect(),
|
||||
block_time: block_info.block_time,
|
||||
block_height: block_info
|
||||
.block_height
|
||||
.map(|block_height| block_height as i64),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl SimplePostgresClient {
|
||||
pub(crate) fn build_block_metadata_upsert_statement(
|
||||
client: &mut Client,
|
||||
config: &AccountsDbPluginPostgresConfig,
|
||||
) -> Result<Statement, AccountsDbPluginError> {
|
||||
let stmt =
|
||||
"INSERT INTO block (slot, blockhash, rewards, block_time, block_height, updated_on) \
|
||||
VALUES ($1, $2, $3, $4, $5, $6)";
|
||||
|
||||
let stmt = client.prepare(stmt);
|
||||
|
||||
match stmt {
|
||||
Err(err) => {
|
||||
return Err(AccountsDbPluginError::Custom(Box::new(AccountsDbPluginPostgresError::DataSchemaError {
|
||||
msg: format!(
|
||||
"Error in preparing for the block metadata update PostgreSQL database: ({}) host: {:?} user: {:?} config: {:?}",
|
||||
err, config.host, config.user, config
|
||||
),
|
||||
})));
|
||||
}
|
||||
Ok(stmt) => Ok(stmt),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn update_block_metadata_impl(
|
||||
&mut self,
|
||||
block_info: UpdateBlockMetadataRequest,
|
||||
) -> Result<(), AccountsDbPluginError> {
|
||||
let client = self.client.get_mut().unwrap();
|
||||
let statement = &client.update_block_metadata_stmt;
|
||||
let client = &mut client.client;
|
||||
let updated_on = Utc::now().naive_utc();
|
||||
|
||||
let block_info = block_info.block_info;
|
||||
let result = client.query(
|
||||
statement,
|
||||
&[
|
||||
&block_info.slot,
|
||||
&block_info.blockhash,
|
||||
&block_info.rewards,
|
||||
&block_info.block_time,
|
||||
&block_info.block_height,
|
||||
&updated_on,
|
||||
],
|
||||
);
|
||||
|
||||
if let Err(err) = result {
|
||||
let msg = format!(
|
||||
"Failed to persist the update of block metadata to the PostgreSQL database. Error: {:?}",
|
||||
err);
|
||||
error!("{}", msg);
|
||||
return Err(AccountsDbPluginError::AccountsUpdateError { msg });
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@@ -1,194 +0,0 @@
|
||||
/// The transaction selector is responsible for filtering transactions
|
||||
/// in the plugin framework.
|
||||
use {log::*, solana_sdk::pubkey::Pubkey, std::collections::HashSet};
|
||||
|
||||
pub(crate) struct TransactionSelector {
|
||||
pub mentioned_addresses: HashSet<Vec<u8>>,
|
||||
pub select_all_transactions: bool,
|
||||
pub select_all_vote_transactions: bool,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
impl TransactionSelector {
|
||||
pub fn default() -> Self {
|
||||
Self {
|
||||
mentioned_addresses: HashSet::default(),
|
||||
select_all_transactions: false,
|
||||
select_all_vote_transactions: false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a selector based on the mentioned addresses
|
||||
/// To select all transactions use ["*"] or ["all"]
|
||||
/// To select all vote transactions, use ["all_votes"]
|
||||
/// To select transactions mentioning specific addresses use ["<pubkey1>", "<pubkey2>", ...]
|
||||
pub fn new(mentioned_addresses: &[String]) -> Self {
|
||||
info!(
|
||||
"Creating TransactionSelector from addresses: {:?}",
|
||||
mentioned_addresses
|
||||
);
|
||||
|
||||
let select_all_transactions = mentioned_addresses
|
||||
.iter()
|
||||
.any(|key| key == "*" || key == "all");
|
||||
if select_all_transactions {
|
||||
return Self {
|
||||
mentioned_addresses: HashSet::default(),
|
||||
select_all_transactions,
|
||||
select_all_vote_transactions: true,
|
||||
};
|
||||
}
|
||||
let select_all_vote_transactions = mentioned_addresses.iter().any(|key| key == "all_votes");
|
||||
if select_all_vote_transactions {
|
||||
return Self {
|
||||
mentioned_addresses: HashSet::default(),
|
||||
select_all_transactions,
|
||||
select_all_vote_transactions: true,
|
||||
};
|
||||
}
|
||||
|
||||
let mentioned_addresses = mentioned_addresses
|
||||
.iter()
|
||||
.map(|key| bs58::decode(key).into_vec().unwrap())
|
||||
.collect();
|
||||
|
||||
Self {
|
||||
mentioned_addresses,
|
||||
select_all_transactions: false,
|
||||
select_all_vote_transactions: false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if a transaction is of interest.
|
||||
pub fn is_transaction_selected(
|
||||
&self,
|
||||
is_vote: bool,
|
||||
mentioned_addresses: Box<dyn Iterator<Item = &Pubkey> + '_>,
|
||||
) -> bool {
|
||||
if !self.is_enabled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
if self.select_all_transactions || (self.select_all_vote_transactions && is_vote) {
|
||||
return true;
|
||||
}
|
||||
for address in mentioned_addresses {
|
||||
if self.mentioned_addresses.contains(address.as_ref()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
/// Check if any transaction is of interest at all
|
||||
pub fn is_enabled(&self) -> bool {
|
||||
self.select_all_transactions
|
||||
|| self.select_all_vote_transactions
|
||||
|| !self.mentioned_addresses.is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_select_transaction() {
|
||||
let pubkey1 = Pubkey::new_unique();
|
||||
let pubkey2 = Pubkey::new_unique();
|
||||
|
||||
let selector = TransactionSelector::new(&[pubkey1.to_string()]);
|
||||
|
||||
assert!(selector.is_enabled());
|
||||
|
||||
let addresses = [pubkey1];
|
||||
|
||||
assert!(selector.is_transaction_selected(false, Box::new(addresses.iter())));
|
||||
|
||||
let addresses = [pubkey2];
|
||||
assert!(!selector.is_transaction_selected(false, Box::new(addresses.iter())));
|
||||
|
||||
let addresses = [pubkey1, pubkey2];
|
||||
assert!(selector.is_transaction_selected(false, Box::new(addresses.iter())));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_select_all_transaction_using_wildcard() {
|
||||
let pubkey1 = Pubkey::new_unique();
|
||||
let pubkey2 = Pubkey::new_unique();
|
||||
|
||||
let selector = TransactionSelector::new(&["*".to_string()]);
|
||||
|
||||
assert!(selector.is_enabled());
|
||||
|
||||
let addresses = [pubkey1];
|
||||
|
||||
assert!(selector.is_transaction_selected(false, Box::new(addresses.iter())));
|
||||
|
||||
let addresses = [pubkey2];
|
||||
assert!(selector.is_transaction_selected(false, Box::new(addresses.iter())));
|
||||
|
||||
let addresses = [pubkey1, pubkey2];
|
||||
assert!(selector.is_transaction_selected(false, Box::new(addresses.iter())));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_select_all_transaction_all() {
|
||||
let pubkey1 = Pubkey::new_unique();
|
||||
let pubkey2 = Pubkey::new_unique();
|
||||
|
||||
let selector = TransactionSelector::new(&["all".to_string()]);
|
||||
|
||||
assert!(selector.is_enabled());
|
||||
|
||||
let addresses = [pubkey1];
|
||||
|
||||
assert!(selector.is_transaction_selected(false, Box::new(addresses.iter())));
|
||||
|
||||
let addresses = [pubkey2];
|
||||
assert!(selector.is_transaction_selected(false, Box::new(addresses.iter())));
|
||||
|
||||
let addresses = [pubkey1, pubkey2];
|
||||
assert!(selector.is_transaction_selected(false, Box::new(addresses.iter())));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_select_all_vote_transaction() {
|
||||
let pubkey1 = Pubkey::new_unique();
|
||||
let pubkey2 = Pubkey::new_unique();
|
||||
|
||||
let selector = TransactionSelector::new(&["all_votes".to_string()]);
|
||||
|
||||
assert!(selector.is_enabled());
|
||||
|
||||
let addresses = [pubkey1];
|
||||
|
||||
assert!(!selector.is_transaction_selected(false, Box::new(addresses.iter())));
|
||||
|
||||
let addresses = [pubkey2];
|
||||
assert!(selector.is_transaction_selected(true, Box::new(addresses.iter())));
|
||||
|
||||
let addresses = [pubkey1, pubkey2];
|
||||
assert!(selector.is_transaction_selected(true, Box::new(addresses.iter())));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_select_no_transaction() {
|
||||
let pubkey1 = Pubkey::new_unique();
|
||||
let pubkey2 = Pubkey::new_unique();
|
||||
|
||||
let selector = TransactionSelector::new(&[]);
|
||||
|
||||
assert!(!selector.is_enabled());
|
||||
|
||||
let addresses = [pubkey1];
|
||||
|
||||
assert!(!selector.is_transaction_selected(false, Box::new(addresses.iter())));
|
||||
|
||||
let addresses = [pubkey2];
|
||||
assert!(!selector.is_transaction_selected(true, Box::new(addresses.iter())));
|
||||
|
||||
let addresses = [pubkey1, pubkey2];
|
||||
assert!(!selector.is_transaction_selected(true, Box::new(addresses.iter())));
|
||||
}
|
||||
}
|
@@ -2,7 +2,7 @@
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2021"
|
||||
name = "solana-banking-bench"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -14,17 +14,17 @@ crossbeam-channel = "0.5"
|
||||
log = "0.4.14"
|
||||
rand = "0.7.0"
|
||||
rayon = "1.5.1"
|
||||
solana-core = { path = "../core", version = "=1.9.6" }
|
||||
solana-gossip = { path = "../gossip", version = "=1.9.6" }
|
||||
solana-ledger = { path = "../ledger", version = "=1.9.6" }
|
||||
solana-logger = { path = "../logger", version = "=1.9.6" }
|
||||
solana-measure = { path = "../measure", version = "=1.9.6" }
|
||||
solana-perf = { path = "../perf", version = "=1.9.6" }
|
||||
solana-poh = { path = "../poh", version = "=1.9.6" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.9.6" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.9.6" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.6" }
|
||||
solana-version = { path = "../version", version = "=1.9.6" }
|
||||
solana-core = { path = "../core", version = "=1.9.7" }
|
||||
solana-gossip = { path = "../gossip", version = "=1.9.7" }
|
||||
solana-ledger = { path = "../ledger", version = "=1.9.7" }
|
||||
solana-logger = { path = "../logger", version = "=1.9.7" }
|
||||
solana-measure = { path = "../measure", version = "=1.9.7" }
|
||||
solana-perf = { path = "../perf", version = "=1.9.7" }
|
||||
solana-poh = { path = "../poh", version = "=1.9.7" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.9.7" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.9.7" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.7" }
|
||||
solana-version = { path = "../version", version = "=1.9.7" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-banks-client"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
description = "Solana banks client"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -12,17 +12,17 @@ edition = "2021"
|
||||
[dependencies]
|
||||
borsh = "0.9.1"
|
||||
futures = "0.3"
|
||||
solana-banks-interface = { path = "../banks-interface", version = "=1.9.6" }
|
||||
solana-program = { path = "../sdk/program", version = "=1.9.6" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.6" }
|
||||
solana-banks-interface = { path = "../banks-interface", version = "=1.9.7" }
|
||||
solana-program = { path = "../sdk/program", version = "=1.9.7" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.7" }
|
||||
tarpc = { version = "0.27.2", features = ["full"] }
|
||||
thiserror = "1.0"
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
tokio-serde = { version = "0.8", features = ["bincode"] }
|
||||
|
||||
[dev-dependencies]
|
||||
solana-runtime = { path = "../runtime", version = "=1.9.6" }
|
||||
solana-banks-server = { path = "../banks-server", version = "=1.9.6" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.9.7" }
|
||||
solana-banks-server = { path = "../banks-server", version = "=1.9.7" }
|
||||
|
||||
[lib]
|
||||
crate-type = ["lib"]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-banks-interface"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
description = "Solana banks RPC interface"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -11,7 +11,7 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
serde = { version = "1.0.130", features = ["derive"] }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.6" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.7" }
|
||||
tarpc = { version = "0.27.2", features = ["full"] }
|
||||
|
||||
[lib]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-banks-server"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
description = "Solana banks server"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -12,10 +12,10 @@ edition = "2021"
|
||||
[dependencies]
|
||||
bincode = "1.3.3"
|
||||
futures = "0.3"
|
||||
solana-banks-interface = { path = "../banks-interface", version = "=1.9.6" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.9.6" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.6" }
|
||||
solana-send-transaction-service = { path = "../send-transaction-service", version = "=1.9.6" }
|
||||
solana-banks-interface = { path = "../banks-interface", version = "=1.9.7" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.9.7" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.7" }
|
||||
solana-send-transaction-service = { path = "../send-transaction-service", version = "=1.9.7" }
|
||||
tarpc = { version = "0.27.2", features = ["full"] }
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
tokio-serde = { version = "0.8", features = ["bincode"] }
|
||||
|
@@ -2,7 +2,7 @@
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2021"
|
||||
name = "solana-bench-streamer"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -10,11 +10,11 @@ publish = false
|
||||
|
||||
[dependencies]
|
||||
clap = "2.33.1"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.9.6" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.9.6" }
|
||||
solana-logger = { path = "../logger", version = "=1.9.6" }
|
||||
solana-net-utils = { path = "../net-utils", version = "=1.9.6" }
|
||||
solana-version = { path = "../version", version = "=1.9.6" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.9.7" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.9.7" }
|
||||
solana-logger = { path = "../logger", version = "=1.9.7" }
|
||||
solana-net-utils = { path = "../net-utils", version = "=1.9.7" }
|
||||
solana-version = { path = "../version", version = "=1.9.7" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
@@ -2,7 +2,7 @@
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2021"
|
||||
name = "solana-bench-tps"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -14,23 +14,23 @@ log = "0.4.14"
|
||||
rayon = "1.5.1"
|
||||
serde_json = "1.0.72"
|
||||
serde_yaml = "0.8.21"
|
||||
solana-core = { path = "../core", version = "=1.9.6" }
|
||||
solana-genesis = { path = "../genesis", version = "=1.9.6" }
|
||||
solana-client = { path = "../client", version = "=1.9.6" }
|
||||
solana-faucet = { path = "../faucet", version = "=1.9.6" }
|
||||
solana-gossip = { path = "../gossip", version = "=1.9.6" }
|
||||
solana-logger = { path = "../logger", version = "=1.9.6" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.9.6" }
|
||||
solana-measure = { path = "../measure", version = "=1.9.6" }
|
||||
solana-net-utils = { path = "../net-utils", version = "=1.9.6" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.9.6" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.6" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.9.6" }
|
||||
solana-version = { path = "../version", version = "=1.9.6" }
|
||||
solana-core = { path = "../core", version = "=1.9.7" }
|
||||
solana-genesis = { path = "../genesis", version = "=1.9.7" }
|
||||
solana-client = { path = "../client", version = "=1.9.7" }
|
||||
solana-faucet = { path = "../faucet", version = "=1.9.7" }
|
||||
solana-gossip = { path = "../gossip", version = "=1.9.7" }
|
||||
solana-logger = { path = "../logger", version = "=1.9.7" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.9.7" }
|
||||
solana-measure = { path = "../measure", version = "=1.9.7" }
|
||||
solana-net-utils = { path = "../net-utils", version = "=1.9.7" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.9.7" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.7" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.9.7" }
|
||||
solana-version = { path = "../version", version = "=1.9.7" }
|
||||
|
||||
[dev-dependencies]
|
||||
serial_test = "0.5.1"
|
||||
solana-local-cluster = { path = "../local-cluster", version = "=1.9.6" }
|
||||
solana-local-cluster = { path = "../local-cluster", version = "=1.9.7" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
@@ -21,7 +21,7 @@ pub const NUM_SIGNATURES_FOR_TXS: u64 = 100_000 * 60 * 60 * 24 * 7;
|
||||
|
||||
fn main() {
|
||||
solana_logger::setup_with_default("solana=info");
|
||||
solana_metrics::set_panic_hook("bench-tps");
|
||||
solana_metrics::set_panic_hook("bench-tps", /*version:*/ None);
|
||||
|
||||
let matches = cli::build_args(solana_version::version!()).get_matches();
|
||||
let cli_config = cli::extract_args(&matches);
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-bloom"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
description = "Solana bloom filter"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -16,9 +16,9 @@ rand = "0.7.0"
|
||||
serde = { version = "1.0.133", features = ["rc"] }
|
||||
rayon = "1.5.1"
|
||||
serde_derive = "1.0.103"
|
||||
solana-frozen-abi = { path = "../frozen-abi", version = "=1.9.6" }
|
||||
solana-frozen-abi-macro = { path = "../frozen-abi/macro", version = "=1.9.6" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.6" }
|
||||
solana-frozen-abi = { path = "../frozen-abi", version = "=1.9.7" }
|
||||
solana-frozen-abi-macro = { path = "../frozen-abi/macro", version = "=1.9.7" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.7" }
|
||||
log = "0.4.14"
|
||||
|
||||
[lib]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-bucket-map"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
description = "solana-bucket-map"
|
||||
homepage = "https://solana.com/"
|
||||
documentation = "https://docs.rs/solana-bucket-map"
|
||||
@@ -12,11 +12,11 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
rayon = "1.5.0"
|
||||
solana-logger = { path = "../logger", version = "=1.9.6" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.6" }
|
||||
solana-logger = { path = "../logger", version = "=1.9.7" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.7" }
|
||||
memmap2 = "0.5.0"
|
||||
log = { version = "0.4.11" }
|
||||
solana-measure = { path = "../measure", version = "=1.9.6" }
|
||||
solana-measure = { path = "../measure", version = "=1.9.7" }
|
||||
rand = "0.7.0"
|
||||
fs_extra = "1.2.0"
|
||||
tempfile = "3.2.0"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-clap-utils"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
description = "Solana utilities for the clap"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -12,9 +12,9 @@ edition = "2021"
|
||||
[dependencies]
|
||||
clap = "2.33.0"
|
||||
rpassword = "5.0"
|
||||
solana-perf = { path = "../perf", version = "=1.9.6" }
|
||||
solana-remote-wallet = { path = "../remote-wallet", version = "=1.9.6" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.6" }
|
||||
solana-perf = { path = "../perf", version = "=1.9.7" }
|
||||
solana-remote-wallet = { path = "../remote-wallet", version = "=1.9.7" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.7" }
|
||||
thiserror = "1.0.30"
|
||||
tiny-bip39 = "0.8.2"
|
||||
uriparse = "0.6.3"
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2021"
|
||||
name = "solana-cli-config"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2021"
|
||||
name = "solana-cli-output"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -19,12 +19,12 @@ Inflector = "0.11.4"
|
||||
indicatif = "0.16.2"
|
||||
serde = "1.0.130"
|
||||
serde_json = "1.0.72"
|
||||
solana-account-decoder = { path = "../account-decoder", version = "=1.9.6" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.9.6" }
|
||||
solana-client = { path = "../client", version = "=1.9.6" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.6" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.9.6" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.9.6" }
|
||||
solana-account-decoder = { path = "../account-decoder", version = "=1.9.7" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.9.7" }
|
||||
solana-client = { path = "../client", version = "=1.9.7" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.7" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.9.7" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.9.7" }
|
||||
spl-memo = { version = "=3.0.1", features = ["no-entrypoint"] }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2021"
|
||||
name = "solana-cli"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -26,29 +26,29 @@ semver = "1.0.4"
|
||||
serde = "1.0.130"
|
||||
serde_derive = "1.0.103"
|
||||
serde_json = "1.0.72"
|
||||
solana-account-decoder = { path = "../account-decoder", version = "=1.9.6" }
|
||||
solana-bpf-loader-program = { path = "../programs/bpf_loader", version = "=1.9.6" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.9.6" }
|
||||
solana-cli-config = { path = "../cli-config", version = "=1.9.6" }
|
||||
solana-cli-output = { path = "../cli-output", version = "=1.9.6" }
|
||||
solana-client = { path = "../client", version = "=1.9.6" }
|
||||
solana-config-program = { path = "../programs/config", version = "=1.9.6" }
|
||||
solana-faucet = { path = "../faucet", version = "=1.9.6" }
|
||||
solana-logger = { path = "../logger", version = "=1.9.6" }
|
||||
solana-program-runtime = { path = "../program-runtime", version = "=1.9.6" }
|
||||
solana-account-decoder = { path = "../account-decoder", version = "=1.9.7" }
|
||||
solana-bpf-loader-program = { path = "../programs/bpf_loader", version = "=1.9.7" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.9.7" }
|
||||
solana-cli-config = { path = "../cli-config", version = "=1.9.7" }
|
||||
solana-cli-output = { path = "../cli-output", version = "=1.9.7" }
|
||||
solana-client = { path = "../client", version = "=1.9.7" }
|
||||
solana-config-program = { path = "../programs/config", version = "=1.9.7" }
|
||||
solana-faucet = { path = "../faucet", version = "=1.9.7" }
|
||||
solana-logger = { path = "../logger", version = "=1.9.7" }
|
||||
solana-program-runtime = { path = "../program-runtime", version = "=1.9.7" }
|
||||
solana_rbpf = "=0.2.23"
|
||||
solana-remote-wallet = { path = "../remote-wallet", version = "=1.9.6" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.6" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.9.6" }
|
||||
solana-version = { path = "../version", version = "=1.9.6" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.9.6" }
|
||||
solana-remote-wallet = { path = "../remote-wallet", version = "=1.9.7" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.7" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.9.7" }
|
||||
solana-version = { path = "../version", version = "=1.9.7" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.9.7" }
|
||||
spl-memo = { version = "=3.0.1", features = ["no-entrypoint"] }
|
||||
thiserror = "1.0.30"
|
||||
tiny-bip39 = "0.8.2"
|
||||
|
||||
[dev-dependencies]
|
||||
solana-streamer = { path = "../streamer", version = "=1.9.6" }
|
||||
solana-test-validator = { path = "../test-validator", version = "=1.9.6" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.9.7" }
|
||||
solana-test-validator = { path = "../test-validator", version = "=1.9.7" }
|
||||
tempfile = "3.2.0"
|
||||
|
||||
[[bin]]
|
||||
|
@@ -83,7 +83,6 @@ pub enum CliCommand {
|
||||
filter: RpcTransactionLogsFilter,
|
||||
},
|
||||
Ping {
|
||||
lamports: u64,
|
||||
interval: Duration,
|
||||
count: Option<u64>,
|
||||
timeout: Duration,
|
||||
@@ -973,7 +972,6 @@ pub fn process_command(config: &CliConfig) -> ProcessResult {
|
||||
CliCommand::LiveSlots => process_live_slots(config),
|
||||
CliCommand::Logs { filter } => process_logs(config, filter),
|
||||
CliCommand::Ping {
|
||||
lamports,
|
||||
interval,
|
||||
count,
|
||||
timeout,
|
||||
@@ -982,7 +980,6 @@ pub fn process_command(config: &CliConfig) -> ProcessResult {
|
||||
} => process_ping(
|
||||
&rpc_client,
|
||||
config,
|
||||
*lamports,
|
||||
interval,
|
||||
count,
|
||||
timeout,
|
||||
|
@@ -43,13 +43,13 @@ use {
|
||||
message::Message,
|
||||
native_token::lamports_to_sol,
|
||||
nonce::State as NonceState,
|
||||
pubkey::{self, Pubkey},
|
||||
pubkey::Pubkey,
|
||||
rent::Rent,
|
||||
rpc_port::DEFAULT_RPC_PORT_STR,
|
||||
signature::Signature,
|
||||
slot_history,
|
||||
stake::{self, state::StakeState},
|
||||
system_instruction, system_program,
|
||||
system_instruction,
|
||||
sysvar::{
|
||||
self,
|
||||
slot_history::SlotHistory,
|
||||
@@ -259,15 +259,6 @@ impl ClusterQuerySubCommands for App<'_, '_> {
|
||||
.takes_value(false)
|
||||
.help("Print timestamp (unix time + microseconds as in gettimeofday) before each line"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("lamports")
|
||||
.long("lamports")
|
||||
.value_name("NUMBER")
|
||||
.takes_value(true)
|
||||
.default_value("1")
|
||||
.validator(is_amount)
|
||||
.help("Number of lamports to transfer for each transaction"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("timeout")
|
||||
.short("t")
|
||||
@@ -512,7 +503,6 @@ pub fn parse_cluster_ping(
|
||||
default_signer: &DefaultSigner,
|
||||
wallet_manager: &mut Option<Arc<RemoteWalletManager>>,
|
||||
) -> Result<CliCommandInfo, CliError> {
|
||||
let lamports = value_t_or_exit!(matches, "lamports", u64);
|
||||
let interval = Duration::from_secs(value_t_or_exit!(matches, "interval", u64));
|
||||
let count = if matches.is_present("count") {
|
||||
Some(value_t_or_exit!(matches, "count", u64))
|
||||
@@ -524,7 +514,6 @@ pub fn parse_cluster_ping(
|
||||
let print_timestamp = matches.is_present("print_timestamp");
|
||||
Ok(CliCommandInfo {
|
||||
command: CliCommand::Ping {
|
||||
lamports,
|
||||
interval,
|
||||
count,
|
||||
timeout,
|
||||
@@ -1355,7 +1344,6 @@ pub fn process_get_transaction_count(rpc_client: &RpcClient, _config: &CliConfig
|
||||
pub fn process_ping(
|
||||
rpc_client: &RpcClient,
|
||||
config: &CliConfig,
|
||||
lamports: u64,
|
||||
interval: &Duration,
|
||||
count: &Option<u64>,
|
||||
timeout: &Duration,
|
||||
@@ -1375,7 +1363,7 @@ pub fn process_ping(
|
||||
let mut confirmation_time: VecDeque<u64> = VecDeque::with_capacity(1024);
|
||||
|
||||
let mut blockhash = rpc_client.get_latest_blockhash()?;
|
||||
let mut blockhash_transaction_count = 0;
|
||||
let mut lamports = 0;
|
||||
let mut blockhash_acquired = Instant::now();
|
||||
let mut blockhash_from_cluster = false;
|
||||
if let Some(fixed_blockhash) = fixed_blockhash {
|
||||
@@ -1391,15 +1379,12 @@ pub fn process_ping(
|
||||
// Fetch a new blockhash every minute
|
||||
let new_blockhash = rpc_client.get_new_latest_blockhash(&blockhash)?;
|
||||
blockhash = new_blockhash;
|
||||
blockhash_transaction_count = 0;
|
||||
lamports = 0;
|
||||
blockhash_acquired = Instant::now();
|
||||
}
|
||||
|
||||
let seed =
|
||||
&format!("{}{}", blockhash_transaction_count, blockhash)[0..pubkey::MAX_SEED_LEN];
|
||||
let to = Pubkey::create_with_seed(&config.signers[0].pubkey(), seed, &system_program::id())
|
||||
.unwrap();
|
||||
blockhash_transaction_count += 1;
|
||||
let to = config.signers[0].pubkey();
|
||||
lamports += 1;
|
||||
|
||||
let build_message = |lamports| {
|
||||
let ix = system_instruction::transfer(&config.signers[0].pubkey(), &to, lamports);
|
||||
@@ -2319,7 +2304,6 @@ mod tests {
|
||||
parse_command(&test_ping, &default_signer, &mut None).unwrap(),
|
||||
CliCommandInfo {
|
||||
command: CliCommand::Ping {
|
||||
lamports: 1,
|
||||
interval: Duration::from_secs(1),
|
||||
count: Some(2),
|
||||
timeout: Duration::from_secs(3),
|
||||
|
@@ -1384,7 +1384,13 @@ pub fn process_stake_authorize(
|
||||
if let Some(authorized) = authorized {
|
||||
match authorization_type {
|
||||
StakeAuthorize::Staker => {
|
||||
check_current_authority(&authorized.staker, &authority.pubkey())?;
|
||||
// first check authorized withdrawer
|
||||
check_current_authority(&authorized.withdrawer, &authority.pubkey())
|
||||
.or_else(|_| {
|
||||
// ...then check authorized staker. If neither matches, error will
|
||||
// print the stake key as `expected`
|
||||
check_current_authority(&authorized.staker, &authority.pubkey())
|
||||
})?;
|
||||
}
|
||||
StakeAuthorize::Withdrawer => {
|
||||
check_current_authority(&authorized.withdrawer, &authority.pubkey())?;
|
||||
|
@@ -238,6 +238,7 @@ fn full_battery_tests(
|
||||
#[test]
|
||||
#[allow(clippy::redundant_closure)]
|
||||
fn test_create_account_with_seed() {
|
||||
const ONE_SIG_FEE: f64 = 0.000005;
|
||||
solana_logger::setup();
|
||||
let mint_keypair = Keypair::new();
|
||||
let mint_pubkey = mint_keypair.pubkey();
|
||||
@@ -310,7 +311,7 @@ fn test_create_account_with_seed() {
|
||||
&offline_nonce_authority_signer.pubkey(),
|
||||
);
|
||||
check_balance!(
|
||||
sol_to_lamports(4000.999999999),
|
||||
sol_to_lamports(4001.0 - ONE_SIG_FEE),
|
||||
&rpc_client,
|
||||
&online_nonce_creator_signer.pubkey(),
|
||||
);
|
||||
@@ -381,12 +382,12 @@ fn test_create_account_with_seed() {
|
||||
process_command(&submit_config).unwrap();
|
||||
check_balance!(sol_to_lamports(241.0), &rpc_client, &nonce_address);
|
||||
check_balance!(
|
||||
sol_to_lamports(31.999999999),
|
||||
sol_to_lamports(32.0 - ONE_SIG_FEE),
|
||||
&rpc_client,
|
||||
&offline_nonce_authority_signer.pubkey(),
|
||||
);
|
||||
check_balance!(
|
||||
sol_to_lamports(4000.999999999),
|
||||
sol_to_lamports(4001.0 - ONE_SIG_FEE),
|
||||
&rpc_client,
|
||||
&online_nonce_creator_signer.pubkey(),
|
||||
);
|
||||
|
@@ -18,6 +18,7 @@ use {
|
||||
solana_sdk::{
|
||||
account_utils::StateMut,
|
||||
commitment_config::CommitmentConfig,
|
||||
fee::FeeStructure,
|
||||
nonce::State as NonceState,
|
||||
pubkey::Pubkey,
|
||||
signature::{keypair_from_seed, Keypair, Signer},
|
||||
@@ -876,14 +877,15 @@ fn test_stake_authorize() {
|
||||
#[test]
|
||||
fn test_stake_authorize_with_fee_payer() {
|
||||
solana_logger::setup();
|
||||
const SIG_FEE: u64 = 42;
|
||||
let fee_one_sig = FeeStructure::default().get_max_fee(1, 0);
|
||||
let fee_two_sig = FeeStructure::default().get_max_fee(2, 0);
|
||||
|
||||
let mint_keypair = Keypair::new();
|
||||
let mint_pubkey = mint_keypair.pubkey();
|
||||
let faucet_addr = run_local_faucet(mint_keypair, None);
|
||||
let test_validator = TestValidator::with_custom_fees(
|
||||
mint_pubkey,
|
||||
SIG_FEE,
|
||||
1,
|
||||
Some(faucet_addr),
|
||||
SocketAddrSpace::Unspecified,
|
||||
);
|
||||
@@ -912,14 +914,14 @@ fn test_stake_authorize_with_fee_payer() {
|
||||
config_offline.command = CliCommand::ClusterVersion;
|
||||
process_command(&config_offline).unwrap_err();
|
||||
|
||||
request_and_confirm_airdrop(&rpc_client, &config, &default_pubkey, 100_000).unwrap();
|
||||
check_balance!(100_000, &rpc_client, &config.signers[0].pubkey());
|
||||
request_and_confirm_airdrop(&rpc_client, &config, &default_pubkey, 5_000_000).unwrap();
|
||||
check_balance!(5_000_000, &rpc_client, &config.signers[0].pubkey());
|
||||
|
||||
request_and_confirm_airdrop(&rpc_client, &config_payer, &payer_pubkey, 100_000).unwrap();
|
||||
check_balance!(100_000, &rpc_client, &payer_pubkey);
|
||||
request_and_confirm_airdrop(&rpc_client, &config_payer, &payer_pubkey, 5_000_000).unwrap();
|
||||
check_balance!(5_000_000, &rpc_client, &payer_pubkey);
|
||||
|
||||
request_and_confirm_airdrop(&rpc_client, &config_offline, &offline_pubkey, 100_000).unwrap();
|
||||
check_balance!(100_000, &rpc_client, &offline_pubkey);
|
||||
request_and_confirm_airdrop(&rpc_client, &config_offline, &offline_pubkey, 5_000_000).unwrap();
|
||||
check_balance!(5_000_000, &rpc_client, &offline_pubkey);
|
||||
|
||||
check_ready(&rpc_client);
|
||||
|
||||
@@ -934,7 +936,7 @@ fn test_stake_authorize_with_fee_payer() {
|
||||
withdrawer: None,
|
||||
withdrawer_signer: None,
|
||||
lockup: Lockup::default(),
|
||||
amount: SpendAmount::Some(50_000),
|
||||
amount: SpendAmount::Some(1_000_000),
|
||||
sign_only: false,
|
||||
dump_transaction_message: false,
|
||||
blockhash_query: BlockhashQuery::All(blockhash_query::Source::Cluster),
|
||||
@@ -945,8 +947,7 @@ fn test_stake_authorize_with_fee_payer() {
|
||||
from: 0,
|
||||
};
|
||||
process_command(&config).unwrap();
|
||||
// `config` balance should be 50,000 - 1 stake account sig - 1 fee sig
|
||||
check_balance!(50_000 - SIG_FEE - SIG_FEE, &rpc_client, &default_pubkey);
|
||||
check_balance!(4_000_000 - fee_two_sig, &rpc_client, &default_pubkey);
|
||||
|
||||
// Assign authority with separate fee payer
|
||||
config.signers = vec![&default_signer, &payer_keypair];
|
||||
@@ -970,10 +971,10 @@ fn test_stake_authorize_with_fee_payer() {
|
||||
};
|
||||
process_command(&config).unwrap();
|
||||
// `config` balance has not changed, despite submitting the TX
|
||||
check_balance!(50_000 - SIG_FEE - SIG_FEE, &rpc_client, &default_pubkey);
|
||||
check_balance!(4_000_000 - fee_two_sig, &rpc_client, &default_pubkey);
|
||||
// `config_payer` however has paid `config`'s authority sig
|
||||
// and `config_payer`'s fee sig
|
||||
check_balance!(100_000 - SIG_FEE - SIG_FEE, &rpc_client, &payer_pubkey);
|
||||
check_balance!(5_000_000 - fee_two_sig, &rpc_client, &payer_pubkey);
|
||||
|
||||
// Assign authority with offline fee payer
|
||||
let blockhash = rpc_client.get_latest_blockhash().unwrap();
|
||||
@@ -1021,10 +1022,10 @@ fn test_stake_authorize_with_fee_payer() {
|
||||
};
|
||||
process_command(&config).unwrap();
|
||||
// `config`'s balance again has not changed
|
||||
check_balance!(50_000 - SIG_FEE - SIG_FEE, &rpc_client, &default_pubkey);
|
||||
check_balance!(4_000_000 - fee_two_sig, &rpc_client, &default_pubkey);
|
||||
// `config_offline` however has paid 1 sig due to being both authority
|
||||
// and fee payer
|
||||
check_balance!(100_000 - SIG_FEE, &rpc_client, &offline_pubkey);
|
||||
check_balance!(5_000_000 - fee_one_sig, &rpc_client, &offline_pubkey);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -1058,12 +1059,17 @@ fn test_stake_split() {
|
||||
config_offline.command = CliCommand::ClusterVersion;
|
||||
process_command(&config_offline).unwrap_err();
|
||||
|
||||
request_and_confirm_airdrop(&rpc_client, &config, &config.signers[0].pubkey(), 500_000)
|
||||
.unwrap();
|
||||
check_balance!(500_000, &rpc_client, &config.signers[0].pubkey());
|
||||
request_and_confirm_airdrop(
|
||||
&rpc_client,
|
||||
&config,
|
||||
&config.signers[0].pubkey(),
|
||||
50_000_000,
|
||||
)
|
||||
.unwrap();
|
||||
check_balance!(50_000_000, &rpc_client, &config.signers[0].pubkey());
|
||||
|
||||
request_and_confirm_airdrop(&rpc_client, &config_offline, &offline_pubkey, 100_000).unwrap();
|
||||
check_balance!(100_000, &rpc_client, &offline_pubkey);
|
||||
request_and_confirm_airdrop(&rpc_client, &config_offline, &offline_pubkey, 1_000_000).unwrap();
|
||||
check_balance!(1_000_000, &rpc_client, &offline_pubkey);
|
||||
|
||||
// Create stake account, identity is authority
|
||||
let minimum_stake_balance = rpc_client
|
||||
@@ -1207,12 +1213,12 @@ fn test_stake_set_lockup() {
|
||||
config_offline.command = CliCommand::ClusterVersion;
|
||||
process_command(&config_offline).unwrap_err();
|
||||
|
||||
request_and_confirm_airdrop(&rpc_client, &config, &config.signers[0].pubkey(), 500_000)
|
||||
request_and_confirm_airdrop(&rpc_client, &config, &config.signers[0].pubkey(), 5_000_000)
|
||||
.unwrap();
|
||||
check_balance!(500_000, &rpc_client, &config.signers[0].pubkey());
|
||||
check_balance!(5_000_000, &rpc_client, &config.signers[0].pubkey());
|
||||
|
||||
request_and_confirm_airdrop(&rpc_client, &config_offline, &offline_pubkey, 100_000).unwrap();
|
||||
check_balance!(100_000, &rpc_client, &offline_pubkey);
|
||||
request_and_confirm_airdrop(&rpc_client, &config_offline, &offline_pubkey, 1_000_000).unwrap();
|
||||
check_balance!(1_000_000, &rpc_client, &offline_pubkey);
|
||||
|
||||
// Create stake account, identity is authority
|
||||
let minimum_stake_balance = rpc_client
|
||||
|
@@ -16,6 +16,7 @@ use {
|
||||
solana_faucet::faucet::run_local_faucet,
|
||||
solana_sdk::{
|
||||
commitment_config::CommitmentConfig,
|
||||
fee::FeeStructure,
|
||||
native_token::sol_to_lamports,
|
||||
nonce::State as NonceState,
|
||||
pubkey::Pubkey,
|
||||
@@ -29,6 +30,8 @@ use {
|
||||
#[test]
|
||||
fn test_transfer() {
|
||||
solana_logger::setup();
|
||||
let fee_one_sig = FeeStructure::default().get_max_fee(1, 0);
|
||||
let fee_two_sig = FeeStructure::default().get_max_fee(2, 0);
|
||||
let mint_keypair = Keypair::new();
|
||||
let mint_pubkey = mint_keypair.pubkey();
|
||||
let faucet_addr = run_local_faucet(mint_keypair, None);
|
||||
@@ -77,7 +80,11 @@ fn test_transfer() {
|
||||
derived_address_program_id: None,
|
||||
};
|
||||
process_command(&config).unwrap();
|
||||
check_balance!(sol_to_lamports(4.0) - 1, &rpc_client, &sender_pubkey);
|
||||
check_balance!(
|
||||
sol_to_lamports(4.0) - fee_one_sig,
|
||||
&rpc_client,
|
||||
&sender_pubkey
|
||||
);
|
||||
check_balance!(sol_to_lamports(1.0), &rpc_client, &recipient_pubkey);
|
||||
|
||||
// Plain ole transfer, failure due to InsufficientFundsForSpendAndFee
|
||||
@@ -98,7 +105,11 @@ fn test_transfer() {
|
||||
derived_address_program_id: None,
|
||||
};
|
||||
assert!(process_command(&config).is_err());
|
||||
check_balance!(sol_to_lamports(4.0) - 1, &rpc_client, &sender_pubkey);
|
||||
check_balance!(
|
||||
sol_to_lamports(4.0) - fee_one_sig,
|
||||
&rpc_client,
|
||||
&sender_pubkey
|
||||
);
|
||||
check_balance!(sol_to_lamports(1.0), &rpc_client, &recipient_pubkey);
|
||||
|
||||
let mut offline = CliConfig::recent_for_tests();
|
||||
@@ -154,7 +165,11 @@ fn test_transfer() {
|
||||
derived_address_program_id: None,
|
||||
};
|
||||
process_command(&config).unwrap();
|
||||
check_balance!(sol_to_lamports(0.5) - 1, &rpc_client, &offline_pubkey);
|
||||
check_balance!(
|
||||
sol_to_lamports(0.5) - fee_one_sig,
|
||||
&rpc_client,
|
||||
&offline_pubkey
|
||||
);
|
||||
check_balance!(sol_to_lamports(1.5), &rpc_client, &recipient_pubkey);
|
||||
|
||||
// Create nonce account
|
||||
@@ -172,7 +187,7 @@ fn test_transfer() {
|
||||
};
|
||||
process_command(&config).unwrap();
|
||||
check_balance!(
|
||||
sol_to_lamports(4.0) - 3 - minimum_nonce_balance,
|
||||
sol_to_lamports(4.0) - fee_one_sig - fee_two_sig - minimum_nonce_balance,
|
||||
&rpc_client,
|
||||
&sender_pubkey,
|
||||
);
|
||||
@@ -210,7 +225,7 @@ fn test_transfer() {
|
||||
};
|
||||
process_command(&config).unwrap();
|
||||
check_balance!(
|
||||
sol_to_lamports(3.0) - 4 - minimum_nonce_balance,
|
||||
sol_to_lamports(3.0) - 2 * fee_one_sig - fee_two_sig - minimum_nonce_balance,
|
||||
&rpc_client,
|
||||
&sender_pubkey,
|
||||
);
|
||||
@@ -235,7 +250,7 @@ fn test_transfer() {
|
||||
};
|
||||
process_command(&config).unwrap();
|
||||
check_balance!(
|
||||
sol_to_lamports(3.0) - 5 - minimum_nonce_balance,
|
||||
sol_to_lamports(3.0) - 3 * fee_one_sig - fee_two_sig - minimum_nonce_balance,
|
||||
&rpc_client,
|
||||
&sender_pubkey,
|
||||
);
|
||||
@@ -293,13 +308,18 @@ fn test_transfer() {
|
||||
derived_address_program_id: None,
|
||||
};
|
||||
process_command(&config).unwrap();
|
||||
check_balance!(sol_to_lamports(0.1) - 2, &rpc_client, &offline_pubkey);
|
||||
check_balance!(
|
||||
sol_to_lamports(0.1) - 2 * fee_one_sig,
|
||||
&rpc_client,
|
||||
&offline_pubkey
|
||||
);
|
||||
check_balance!(sol_to_lamports(2.9), &rpc_client, &recipient_pubkey);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_transfer_multisession_signing() {
|
||||
solana_logger::setup();
|
||||
let fee = FeeStructure::default().get_max_fee(2, 0);
|
||||
let mint_keypair = Keypair::new();
|
||||
let mint_pubkey = mint_keypair.pubkey();
|
||||
let faucet_addr = run_local_faucet(mint_keypair, None);
|
||||
@@ -329,7 +349,7 @@ fn test_transfer_multisession_signing() {
|
||||
&rpc_client,
|
||||
&CliConfig::recent_for_tests(),
|
||||
&offline_fee_payer_signer.pubkey(),
|
||||
sol_to_lamports(1.0) + 3,
|
||||
sol_to_lamports(1.0) + 2 * fee,
|
||||
)
|
||||
.unwrap();
|
||||
check_balance!(
|
||||
@@ -338,7 +358,7 @@ fn test_transfer_multisession_signing() {
|
||||
&offline_from_signer.pubkey(),
|
||||
);
|
||||
check_balance!(
|
||||
sol_to_lamports(1.0) + 3,
|
||||
sol_to_lamports(1.0) + 2 * fee,
|
||||
&rpc_client,
|
||||
&offline_fee_payer_signer.pubkey(),
|
||||
);
|
||||
@@ -438,7 +458,7 @@ fn test_transfer_multisession_signing() {
|
||||
&offline_from_signer.pubkey(),
|
||||
);
|
||||
check_balance!(
|
||||
sol_to_lamports(1.0) + 1,
|
||||
sol_to_lamports(1.0) + fee,
|
||||
&rpc_client,
|
||||
&offline_fee_payer_signer.pubkey(),
|
||||
);
|
||||
@@ -448,6 +468,7 @@ fn test_transfer_multisession_signing() {
|
||||
#[test]
|
||||
fn test_transfer_all() {
|
||||
solana_logger::setup();
|
||||
let fee = FeeStructure::default().get_max_fee(1, 0);
|
||||
let mint_keypair = Keypair::new();
|
||||
let mint_pubkey = mint_keypair.pubkey();
|
||||
let faucet_addr = run_local_faucet(mint_keypair, None);
|
||||
@@ -470,8 +491,8 @@ fn test_transfer_all() {
|
||||
let sender_pubkey = config.signers[0].pubkey();
|
||||
let recipient_pubkey = Pubkey::new(&[1u8; 32]);
|
||||
|
||||
request_and_confirm_airdrop(&rpc_client, &config, &sender_pubkey, 50_000).unwrap();
|
||||
check_balance!(50_000, &rpc_client, &sender_pubkey);
|
||||
request_and_confirm_airdrop(&rpc_client, &config, &sender_pubkey, 500_000).unwrap();
|
||||
check_balance!(500_000, &rpc_client, &sender_pubkey);
|
||||
check_balance!(0, &rpc_client, &recipient_pubkey);
|
||||
|
||||
check_ready(&rpc_client);
|
||||
@@ -495,7 +516,7 @@ fn test_transfer_all() {
|
||||
};
|
||||
process_command(&config).unwrap();
|
||||
check_balance!(0, &rpc_client, &sender_pubkey);
|
||||
check_balance!(49_999, &rpc_client, &recipient_pubkey);
|
||||
check_balance!(500_000 - fee, &rpc_client, &recipient_pubkey);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -554,6 +575,7 @@ fn test_transfer_unfunded_recipient() {
|
||||
#[test]
|
||||
fn test_transfer_with_seed() {
|
||||
solana_logger::setup();
|
||||
let fee = FeeStructure::default().get_max_fee(1, 0);
|
||||
let mint_keypair = Keypair::new();
|
||||
let mint_pubkey = mint_keypair.pubkey();
|
||||
let faucet_addr = run_local_faucet(mint_keypair, None);
|
||||
@@ -612,7 +634,7 @@ fn test_transfer_with_seed() {
|
||||
derived_address_program_id: Some(derived_address_program_id),
|
||||
};
|
||||
process_command(&config).unwrap();
|
||||
check_balance!(sol_to_lamports(1.0) - 1, &rpc_client, &sender_pubkey);
|
||||
check_balance!(sol_to_lamports(1.0) - fee, &rpc_client, &sender_pubkey);
|
||||
check_balance!(sol_to_lamports(5.0), &rpc_client, &recipient_pubkey);
|
||||
check_balance!(0, &rpc_client, &derived_address);
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-client-test"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
description = "Solana RPC Test"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -12,24 +12,24 @@ edition = "2021"
|
||||
[dependencies]
|
||||
serde_json = "1.0.72"
|
||||
serial_test = "0.5.1"
|
||||
solana-client = { path = "../client", version = "=1.9.6" }
|
||||
solana-ledger = { path = "../ledger", version = "=1.9.6" }
|
||||
solana-measure = { path = "../measure", version = "=1.9.6" }
|
||||
solana-merkle-tree = { path = "../merkle-tree", version = "=1.9.6" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.9.6" }
|
||||
solana-perf = { path = "../perf", version = "=1.9.6" }
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "=1.9.6" }
|
||||
solana-rpc = { path = "../rpc", version = "=1.9.6" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.9.6" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.6" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.9.6" }
|
||||
solana-test-validator = { path = "../test-validator", version = "=1.9.6" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.9.6" }
|
||||
solana-version = { path = "../version", version = "=1.9.6" }
|
||||
solana-client = { path = "../client", version = "=1.9.7" }
|
||||
solana-ledger = { path = "../ledger", version = "=1.9.7" }
|
||||
solana-measure = { path = "../measure", version = "=1.9.7" }
|
||||
solana-merkle-tree = { path = "../merkle-tree", version = "=1.9.7" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.9.7" }
|
||||
solana-perf = { path = "../perf", version = "=1.9.7" }
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "=1.9.7" }
|
||||
solana-rpc = { path = "../rpc", version = "=1.9.7" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.9.7" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.7" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.9.7" }
|
||||
solana-test-validator = { path = "../test-validator", version = "=1.9.7" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.9.7" }
|
||||
solana-version = { path = "../version", version = "=1.9.7" }
|
||||
systemstat = "0.1.10"
|
||||
|
||||
[dev-dependencies]
|
||||
solana-logger = { path = "../logger", version = "=1.9.6" }
|
||||
solana-logger = { path = "../logger", version = "=1.9.7" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-client"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
description = "Solana Client"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -23,15 +23,15 @@ semver = "1.0.4"
|
||||
serde = "1.0.130"
|
||||
serde_derive = "1.0.103"
|
||||
serde_json = "1.0.72"
|
||||
solana-account-decoder = { path = "../account-decoder", version = "=1.9.6" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.9.6" }
|
||||
solana-faucet = { path = "../faucet", version = "=1.9.6" }
|
||||
solana-net-utils = { path = "../net-utils", version = "=1.9.6" }
|
||||
solana-measure = { path = "../measure", version = "=1.9.6" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.6" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.9.6" }
|
||||
solana-version = { path = "../version", version = "=1.9.6" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.9.6" }
|
||||
solana-account-decoder = { path = "../account-decoder", version = "=1.9.7" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.9.7" }
|
||||
solana-faucet = { path = "../faucet", version = "=1.9.7" }
|
||||
solana-net-utils = { path = "../net-utils", version = "=1.9.7" }
|
||||
solana-measure = { path = "../measure", version = "=1.9.7" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.7" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.9.7" }
|
||||
solana-version = { path = "../version", version = "=1.9.7" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.9.7" }
|
||||
thiserror = "1.0"
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
tungstenite = { version = "0.16.0", features = ["rustls-tls-webpki-roots"] }
|
||||
@@ -40,7 +40,7 @@ url = "2.2.2"
|
||||
[dev-dependencies]
|
||||
assert_matches = "1.5.0"
|
||||
jsonrpc-http-server = "18.0.0"
|
||||
solana-logger = { path = "../logger", version = "=1.9.6" }
|
||||
solana-logger = { path = "../logger", version = "=1.9.7" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
@@ -37,14 +37,14 @@ impl HttpSender {
|
||||
///
|
||||
/// The URL is an HTTP URL, usually for port 8899, as in
|
||||
/// "http://localhost:8899". The sender has a default timeout of 30 seconds.
|
||||
pub fn new(url: String) -> Self {
|
||||
pub fn new<U: ToString>(url: U) -> Self {
|
||||
Self::new_with_timeout(url, Duration::from_secs(30))
|
||||
}
|
||||
|
||||
/// Create an HTTP RPC sender.
|
||||
///
|
||||
/// The URL is an HTTP URL, usually for port 8899.
|
||||
pub fn new_with_timeout(url: String, timeout: Duration) -> Self {
|
||||
pub fn new_with_timeout<U: ToString>(url: U, timeout: Duration) -> Self {
|
||||
// `reqwest::blocking::Client` panics if run in a tokio async context. Shuttle the
|
||||
// request to a different tokio thread to avoid this
|
||||
let client = Arc::new(
|
||||
@@ -58,7 +58,7 @@ impl HttpSender {
|
||||
|
||||
Self {
|
||||
client,
|
||||
url,
|
||||
url: url.to_string(),
|
||||
request_id: AtomicU64::new(0),
|
||||
stats: RwLock::new(RpcTransportStats::default()),
|
||||
}
|
||||
|
@@ -75,13 +75,13 @@ pub struct MockSender {
|
||||
/// from [`RpcRequest`] to a JSON [`Value`] response, Any entries in this map
|
||||
/// override the default behavior for the given request.
|
||||
impl MockSender {
|
||||
pub fn new(url: String) -> Self {
|
||||
pub fn new<U: ToString>(url: U) -> Self {
|
||||
Self::new_with_mocks(url, Mocks::default())
|
||||
}
|
||||
|
||||
pub fn new_with_mocks(url: String, mocks: Mocks) -> Self {
|
||||
pub fn new_with_mocks<U: ToString>(url: U, mocks: Mocks) -> Self {
|
||||
Self {
|
||||
url,
|
||||
url: url.to_string(),
|
||||
mocks: RwLock::new(mocks),
|
||||
}
|
||||
}
|
||||
|
@@ -191,7 +191,7 @@ impl RpcClient {
|
||||
/// let url = "http://localhost:8899".to_string();
|
||||
/// let client = RpcClient::new(url);
|
||||
/// ```
|
||||
pub fn new(url: String) -> Self {
|
||||
pub fn new<U: ToString>(url: U) -> Self {
|
||||
Self::new_with_commitment(url, CommitmentConfig::default())
|
||||
}
|
||||
|
||||
@@ -214,7 +214,7 @@ impl RpcClient {
|
||||
/// let commitment_config = CommitmentConfig::processed();
|
||||
/// let client = RpcClient::new_with_commitment(url, commitment_config);
|
||||
/// ```
|
||||
pub fn new_with_commitment(url: String, commitment_config: CommitmentConfig) -> Self {
|
||||
pub fn new_with_commitment<U: ToString>(url: U, commitment_config: CommitmentConfig) -> Self {
|
||||
Self::new_sender(
|
||||
HttpSender::new(url),
|
||||
RpcClientConfig::with_commitment(commitment_config),
|
||||
@@ -240,7 +240,7 @@ impl RpcClient {
|
||||
/// let timeout = Duration::from_secs(1);
|
||||
/// let client = RpcClient::new_with_timeout(url, timeout);
|
||||
/// ```
|
||||
pub fn new_with_timeout(url: String, timeout: Duration) -> Self {
|
||||
pub fn new_with_timeout<U: ToString>(url: U, timeout: Duration) -> Self {
|
||||
Self::new_sender(
|
||||
HttpSender::new_with_timeout(url, timeout),
|
||||
RpcClientConfig::with_commitment(CommitmentConfig::default()),
|
||||
@@ -269,8 +269,8 @@ impl RpcClient {
|
||||
/// commitment_config,
|
||||
/// );
|
||||
/// ```
|
||||
pub fn new_with_timeout_and_commitment(
|
||||
url: String,
|
||||
pub fn new_with_timeout_and_commitment<U: ToString>(
|
||||
url: U,
|
||||
timeout: Duration,
|
||||
commitment_config: CommitmentConfig,
|
||||
) -> Self {
|
||||
@@ -312,8 +312,8 @@ impl RpcClient {
|
||||
/// confirm_transaction_initial_timeout,
|
||||
/// );
|
||||
/// ```
|
||||
pub fn new_with_timeouts_and_commitment(
|
||||
url: String,
|
||||
pub fn new_with_timeouts_and_commitment<U: ToString>(
|
||||
url: U,
|
||||
timeout: Duration,
|
||||
commitment_config: CommitmentConfig,
|
||||
confirm_transaction_initial_timeout: Duration,
|
||||
@@ -347,7 +347,7 @@ impl RpcClient {
|
||||
/// let url = "fails".to_string();
|
||||
/// let successful_client = RpcClient::new_mock(url);
|
||||
/// ```
|
||||
pub fn new_mock(url: String) -> Self {
|
||||
pub fn new_mock<U: ToString>(url: U) -> Self {
|
||||
Self::new_sender(
|
||||
MockSender::new(url),
|
||||
RpcClientConfig::with_commitment(CommitmentConfig::default()),
|
||||
@@ -381,7 +381,7 @@ impl RpcClient {
|
||||
/// let url = "succeeds".to_string();
|
||||
/// let client = RpcClient::new_mock_with_mocks(url, mocks);
|
||||
/// ```
|
||||
pub fn new_mock_with_mocks(url: String, mocks: Mocks) -> Self {
|
||||
pub fn new_mock_with_mocks<U: ToString>(url: U, mocks: Mocks) -> Self {
|
||||
Self::new_sender(
|
||||
MockSender::new_with_mocks(url, mocks),
|
||||
RpcClientConfig::with_commitment(CommitmentConfig::default()),
|
||||
|
@@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "solana-core"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
homepage = "https://solana.com/"
|
||||
documentation = "https://docs.rs/solana-core"
|
||||
readme = "../README.md"
|
||||
@@ -34,32 +34,32 @@ rayon = "1.5.1"
|
||||
retain_mut = "0.1.5"
|
||||
serde = "1.0.130"
|
||||
serde_derive = "1.0.103"
|
||||
solana-accountsdb-plugin-manager = { path = "../accountsdb-plugin-manager", version = "=1.9.6" }
|
||||
solana-bloom = { path = "../bloom", version = "=1.9.6" }
|
||||
solana-client = { path = "../client", version = "=1.9.6" }
|
||||
solana-entry = { path = "../entry", version = "=1.9.6" }
|
||||
solana-gossip = { path = "../gossip", version = "=1.9.6" }
|
||||
solana-ledger = { path = "../ledger", version = "=1.9.6" }
|
||||
solana-logger = { path = "../logger", version = "=1.9.6" }
|
||||
solana-measure = { path = "../measure", version = "=1.9.6" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.9.6" }
|
||||
solana-net-utils = { path = "../net-utils", version = "=1.9.6" }
|
||||
solana-perf = { path = "../perf", version = "=1.9.6" }
|
||||
solana-poh = { path = "../poh", version = "=1.9.6" }
|
||||
solana-program-runtime = { path = "../program-runtime", version = "=1.9.6" }
|
||||
solana-rpc = { path = "../rpc", version = "=1.9.6" }
|
||||
solana-replica-lib = { path = "../replica-lib", version = "=1.9.6" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.9.6" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.6" }
|
||||
solana-frozen-abi = { path = "../frozen-abi", version = "=1.9.6" }
|
||||
solana-frozen-abi-macro = { path = "../frozen-abi/macro", version = "=1.9.6" }
|
||||
solana-send-transaction-service = { path = "../send-transaction-service", version = "=1.9.6" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.9.6" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.9.6" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.9.6" }
|
||||
solana-accountsdb-plugin-manager = { path = "../accountsdb-plugin-manager", version = "=1.9.7" }
|
||||
solana-bloom = { path = "../bloom", version = "=1.9.7" }
|
||||
solana-client = { path = "../client", version = "=1.9.7" }
|
||||
solana-entry = { path = "../entry", version = "=1.9.7" }
|
||||
solana-gossip = { path = "../gossip", version = "=1.9.7" }
|
||||
solana-ledger = { path = "../ledger", version = "=1.9.7" }
|
||||
solana-logger = { path = "../logger", version = "=1.9.7" }
|
||||
solana-measure = { path = "../measure", version = "=1.9.7" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.9.7" }
|
||||
solana-net-utils = { path = "../net-utils", version = "=1.9.7" }
|
||||
solana-perf = { path = "../perf", version = "=1.9.7" }
|
||||
solana-poh = { path = "../poh", version = "=1.9.7" }
|
||||
solana-program-runtime = { path = "../program-runtime", version = "=1.9.7" }
|
||||
solana-rpc = { path = "../rpc", version = "=1.9.7" }
|
||||
solana-replica-lib = { path = "../replica-lib", version = "=1.9.7" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.9.7" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.7" }
|
||||
solana-frozen-abi = { path = "../frozen-abi", version = "=1.9.7" }
|
||||
solana-frozen-abi-macro = { path = "../frozen-abi/macro", version = "=1.9.7" }
|
||||
solana-send-transaction-service = { path = "../send-transaction-service", version = "=1.9.7" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.9.7" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.9.7" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.9.7" }
|
||||
tempfile = "3.2.0"
|
||||
thiserror = "1.0"
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "=1.9.6" }
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "=1.9.7" }
|
||||
sys-info = "0.9.1"
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
trees = "0.4.2"
|
||||
@@ -73,9 +73,9 @@ matches = "0.1.9"
|
||||
reqwest = { version = "0.11.6", default-features = false, features = ["blocking", "rustls-tls", "json"] }
|
||||
serde_json = "1.0.72"
|
||||
serial_test = "0.5.1"
|
||||
solana-program-runtime = { path = "../program-runtime", version = "=1.9.6" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "=1.9.6" }
|
||||
solana-version = { path = "../version", version = "=1.9.6" }
|
||||
solana-program-runtime = { path = "../program-runtime", version = "=1.9.7" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "=1.9.7" }
|
||||
solana-version = { path = "../version", version = "=1.9.7" }
|
||||
static_assertions = "1.1.0"
|
||||
systemstat = "0.1.10"
|
||||
|
||||
|
@@ -10,6 +10,7 @@ use {
|
||||
rayon::prelude::*,
|
||||
solana_core::{
|
||||
banking_stage::{BankingStage, BankingStageStats},
|
||||
leader_slot_banking_stage_metrics::LeaderSlotMetricsTracker,
|
||||
qos_service::QosService,
|
||||
},
|
||||
solana_entry::entry::{next_hash, Entry},
|
||||
@@ -98,6 +99,7 @@ fn bench_consume_buffered(bencher: &mut Bencher) {
|
||||
&BankingStageStats::default(),
|
||||
&recorder,
|
||||
&Arc::new(QosService::new(Arc::new(RwLock::new(CostModel::default())))),
|
||||
&mut LeaderSlotMetricsTracker::new(0),
|
||||
);
|
||||
});
|
||||
|
||||
|
@@ -9,7 +9,7 @@ use {
|
||||
log::*,
|
||||
rand::{thread_rng, Rng},
|
||||
solana_core::{sigverify::TransactionSigVerifier, sigverify_stage::SigVerifyStage},
|
||||
solana_perf::{packet::to_packet_batches, test_tx::test_tx},
|
||||
solana_perf::{packet::to_packet_batches, packet::PacketBatch, test_tx::test_tx},
|
||||
solana_sdk::{
|
||||
hash::Hash,
|
||||
signature::{Keypair, Signer},
|
||||
@@ -112,19 +112,10 @@ fn bench_packet_discard_mixed_senders(bencher: &mut Bencher) {
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_sigverify_stage(bencher: &mut Bencher) {
|
||||
solana_logger::setup();
|
||||
let (packet_s, packet_r) = channel();
|
||||
let (verified_s, verified_r) = unbounded();
|
||||
let verifier = TransactionSigVerifier::default();
|
||||
let stage = SigVerifyStage::new(packet_r, verified_s, verifier);
|
||||
|
||||
let now = Instant::now();
|
||||
fn gen_batches(use_same_tx: bool) -> Vec<PacketBatch> {
|
||||
let len = 4096;
|
||||
let use_same_tx = true;
|
||||
let chunk_size = 1024;
|
||||
let mut batches = if use_same_tx {
|
||||
if use_same_tx {
|
||||
let tx = test_tx();
|
||||
to_packet_batches(&vec![tx; len], chunk_size)
|
||||
} else {
|
||||
@@ -142,14 +133,28 @@ fn bench_sigverify_stage(bencher: &mut Bencher) {
|
||||
})
|
||||
.collect();
|
||||
to_packet_batches(&txs, chunk_size)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
trace!(
|
||||
"starting... generation took: {} ms batches: {}",
|
||||
duration_as_ms(&now.elapsed()),
|
||||
batches.len()
|
||||
);
|
||||
#[bench]
|
||||
fn bench_sigverify_stage(bencher: &mut Bencher) {
|
||||
solana_logger::setup();
|
||||
trace!("start");
|
||||
let (packet_s, packet_r) = channel();
|
||||
let (verified_s, verified_r) = unbounded();
|
||||
let verifier = TransactionSigVerifier::default();
|
||||
let stage = SigVerifyStage::new(packet_r, verified_s, verifier);
|
||||
|
||||
let use_same_tx = true;
|
||||
bencher.iter(move || {
|
||||
let now = Instant::now();
|
||||
let mut batches = gen_batches(use_same_tx);
|
||||
trace!(
|
||||
"starting... generation took: {} ms batches: {}",
|
||||
duration_as_ms(&now.elapsed()),
|
||||
batches.len()
|
||||
);
|
||||
|
||||
let mut sent_len = 0;
|
||||
for _ in 0..batches.len() {
|
||||
if let Some(batch) = batches.pop() {
|
||||
@@ -165,7 +170,7 @@ fn bench_sigverify_stage(bencher: &mut Bencher) {
|
||||
received += v.packets.len();
|
||||
batches.push(v);
|
||||
}
|
||||
if received >= sent_len {
|
||||
if use_same_tx || received >= sent_len {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@@ -2,7 +2,10 @@
|
||||
//! to contruct a software pipeline. The stage uses all available CPU cores and
|
||||
//! can do its processing in parallel with signature verification on the GPU.
|
||||
use {
|
||||
crate::qos_service::QosService,
|
||||
crate::{
|
||||
leader_slot_banking_stage_metrics::{LeaderSlotMetricsTracker, ProcessTransactionsSummary},
|
||||
qos_service::QosService,
|
||||
},
|
||||
crossbeam_channel::{Receiver as CrossbeamReceiver, RecvTimeoutError},
|
||||
histogram::Histogram,
|
||||
itertools::Itertools,
|
||||
@@ -86,47 +89,6 @@ const MAX_NUM_TRANSACTIONS_PER_BATCH: usize = 128;
|
||||
const NUM_VOTE_PROCESSING_THREADS: u32 = 2;
|
||||
const MIN_THREADS_BANKING: u32 = 1;
|
||||
|
||||
/// A summary of what happened to transactions passed to the execution pipeline.
|
||||
/// Transactions can
|
||||
/// 1) Did not even make it to execution due to being filtered out by things like AccountInUse
|
||||
/// lock conflictss or CostModel compute limits. These types of errors are retryable and
|
||||
/// counted in `Self::retryable_transaction_indexes`.
|
||||
/// 2) Did not execute due to some fatal error like too old, or duplicate signature. These
|
||||
/// will be dropped from the transactions queue and not counted in `Self::retryable_transaction_indexes`
|
||||
/// 3) Were executed and committed, captured by `committed_transactions_count` below.
|
||||
/// 4) Were executed and failed commit, captured by `failed_commit_count` below.
|
||||
struct ProcessTransactionsSummary {
|
||||
// Returns true if we hit the end of the block/max PoH height for the block before
|
||||
// processing all the transactions in the batch.
|
||||
reached_max_poh_height: bool,
|
||||
|
||||
// Total number of transactions that were passed as candidates for execution. See description
|
||||
// of struct above for possible outcomes for these transactions
|
||||
#[allow(dead_code)]
|
||||
transactions_attempted_execution_count: usize,
|
||||
|
||||
// Total number of transactions that made it into the block
|
||||
#[allow(dead_code)]
|
||||
committed_transactions_count: usize,
|
||||
|
||||
// Total number of transactions that made it into the block where the transactions
|
||||
// output from execution was success/no error.
|
||||
#[allow(dead_code)]
|
||||
committed_transactions_with_successful_result_count: usize,
|
||||
|
||||
// All transactions that were executed but then failed record because the
|
||||
// slot ended
|
||||
#[allow(dead_code)]
|
||||
failed_commit_count: usize,
|
||||
|
||||
// Indexes of transactions in the transactions slice that were not committed but are retryable
|
||||
retryable_transaction_indexes: Vec<usize>,
|
||||
|
||||
// The number of transactions filtered out by the cost model
|
||||
#[allow(dead_code)]
|
||||
cost_model_throttled_transactions_count: usize,
|
||||
}
|
||||
|
||||
pub struct ProcessTransactionBatchOutput {
|
||||
// The number of transactions filtered out by the cost model
|
||||
cost_model_throttled_transactions_count: usize,
|
||||
@@ -164,6 +126,7 @@ pub struct BankingStageStats {
|
||||
current_buffered_packet_batches_count: AtomicUsize,
|
||||
rebuffered_packets_count: AtomicUsize,
|
||||
consumed_buffered_packets_count: AtomicUsize,
|
||||
end_of_slot_filtered_invalid_count: AtomicUsize,
|
||||
batch_packet_indexes_len: Histogram,
|
||||
|
||||
// Timing
|
||||
@@ -272,6 +235,12 @@ impl BankingStageStats {
|
||||
.swap(0, Ordering::Relaxed) as i64,
|
||||
i64
|
||||
),
|
||||
(
|
||||
"end_of_slot_filtered_invalid_count",
|
||||
self.end_of_slot_filtered_invalid_count
|
||||
.swap(0, Ordering::Relaxed) as i64,
|
||||
i64
|
||||
),
|
||||
(
|
||||
"consume_buffered_packets_elapsed",
|
||||
self.consume_buffered_packets_elapsed
|
||||
@@ -347,6 +316,12 @@ pub struct BatchedTransactionCostDetails {
|
||||
pub batched_execute_cost: u64,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
struct EndOfSlot {
|
||||
next_slot_leader: Option<Pubkey>,
|
||||
working_bank: Option<Arc<Bank>>,
|
||||
}
|
||||
|
||||
/// Stores the stage's thread handle and output receiver.
|
||||
pub struct BankingStage {
|
||||
bank_thread_hdls: Vec<JoinHandle<()>>,
|
||||
@@ -468,13 +443,14 @@ impl BankingStage {
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Forwards all valid, unprocessed packets in the buffer, up to a rate limit. Returns
|
||||
/// the number of successfully forwarded packets in second part of tuple
|
||||
fn forward_buffered_packets(
|
||||
socket: &std::net::UdpSocket,
|
||||
tpu_forwards: &std::net::SocketAddr,
|
||||
buffered_packet_batches: &UnprocessedPacketBatches,
|
||||
packets: Vec<&Packet>,
|
||||
data_budget: &DataBudget,
|
||||
) -> std::io::Result<()> {
|
||||
let packets = Self::filter_valid_packets_for_forwarding(buffered_packet_batches.iter());
|
||||
) -> (std::io::Result<()>, usize) {
|
||||
const INTERVAL_MS: u64 = 100;
|
||||
const MAX_BYTES_PER_SECOND: usize = 10_000 * 1200;
|
||||
const MAX_BYTES_PER_INTERVAL: usize = MAX_BYTES_PER_SECOND * INTERVAL_MS as usize / 1000;
|
||||
@@ -499,13 +475,13 @@ impl BankingStage {
|
||||
|
||||
if !packet_vec.is_empty() {
|
||||
inc_new_counter_info!("banking_stage-forwarded_packets", packet_vec.len());
|
||||
if let Err(SendPktsError::IoError(ioerr, _num_failed)) = batch_send(socket, &packet_vec)
|
||||
if let Err(SendPktsError::IoError(ioerr, num_failed)) = batch_send(socket, &packet_vec)
|
||||
{
|
||||
return Err(ioerr);
|
||||
return (Err(ioerr), packet_vec.len().saturating_sub(num_failed));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
(Ok(()), packet_vec.len())
|
||||
}
|
||||
|
||||
// Returns whether the given `PacketBatch` has any more remaining unprocessed
|
||||
@@ -534,31 +510,50 @@ impl BankingStage {
|
||||
banking_stage_stats: &BankingStageStats,
|
||||
recorder: &TransactionRecorder,
|
||||
qos_service: &Arc<QosService>,
|
||||
slot_metrics_tracker: &mut LeaderSlotMetricsTracker,
|
||||
) {
|
||||
let mut rebuffered_packet_count = 0;
|
||||
let mut consumed_buffered_packets_count = 0;
|
||||
let buffered_packet_batches_len = buffered_packet_batches.len();
|
||||
let mut proc_start = Measure::start("consume_buffered_process");
|
||||
let mut reached_end_of_slot = None;
|
||||
let mut reached_end_of_slot: Option<EndOfSlot> = None;
|
||||
|
||||
buffered_packet_batches.retain_mut(|buffered_packet_batch_and_offsets| {
|
||||
let (packet_batch, ref mut original_unprocessed_indexes, _forwarded) =
|
||||
buffered_packet_batch_and_offsets;
|
||||
if let Some((next_leader, bank)) = &reached_end_of_slot {
|
||||
if let Some(end_of_slot) = &reached_end_of_slot {
|
||||
// We've hit the end of this slot, no need to perform more processing,
|
||||
// just filter the remaining packets for the invalid (e.g. too old) ones
|
||||
let new_unprocessed_indexes = Self::filter_unprocessed_packets(
|
||||
bank,
|
||||
packet_batch,
|
||||
original_unprocessed_indexes,
|
||||
my_pubkey,
|
||||
*next_leader,
|
||||
banking_stage_stats,
|
||||
);
|
||||
Self::update_buffered_packets_with_new_unprocessed(
|
||||
original_unprocessed_indexes,
|
||||
new_unprocessed_indexes,
|
||||
)
|
||||
// if the working_bank is available
|
||||
if let Some(bank) = &end_of_slot.working_bank {
|
||||
let new_unprocessed_indexes = Self::filter_unprocessed_packets_at_end_of_slot(
|
||||
bank,
|
||||
packet_batch,
|
||||
original_unprocessed_indexes,
|
||||
my_pubkey,
|
||||
end_of_slot.next_slot_leader,
|
||||
banking_stage_stats,
|
||||
);
|
||||
|
||||
let end_of_slot_filtered_invalid_count = original_unprocessed_indexes
|
||||
.len()
|
||||
.saturating_sub(new_unprocessed_indexes.len());
|
||||
|
||||
slot_metrics_tracker.increment_end_of_slot_filtered_invalid_count(
|
||||
end_of_slot_filtered_invalid_count as u64,
|
||||
);
|
||||
|
||||
banking_stage_stats
|
||||
.end_of_slot_filtered_invalid_count
|
||||
.fetch_add(end_of_slot_filtered_invalid_count, Ordering::Relaxed);
|
||||
|
||||
Self::update_buffered_packets_with_new_unprocessed(
|
||||
original_unprocessed_indexes,
|
||||
new_unprocessed_indexes,
|
||||
)
|
||||
} else {
|
||||
true
|
||||
}
|
||||
} else {
|
||||
let bank_start = poh_recorder.lock().unwrap().bank_start();
|
||||
if let Some(BankStart {
|
||||
@@ -576,6 +571,7 @@ impl BankingStage {
|
||||
gossip_vote_sender,
|
||||
banking_stage_stats,
|
||||
qos_service,
|
||||
slot_metrics_tracker,
|
||||
);
|
||||
let ProcessTransactionsSummary {
|
||||
reached_max_poh_height,
|
||||
@@ -589,10 +585,10 @@ impl BankingStage {
|
||||
max_tx_ingestion_ns,
|
||||
)
|
||||
{
|
||||
reached_end_of_slot = Some((
|
||||
poh_recorder.lock().unwrap().next_slot_leader(),
|
||||
working_bank,
|
||||
));
|
||||
reached_end_of_slot = Some(EndOfSlot {
|
||||
next_slot_leader: poh_recorder.lock().unwrap().next_slot_leader(),
|
||||
working_bank: Some(working_bank),
|
||||
});
|
||||
}
|
||||
|
||||
// The difference between all transactions passed to execution and the ones that
|
||||
@@ -619,6 +615,13 @@ impl BankingStage {
|
||||
}
|
||||
has_more_unprocessed_transactions
|
||||
} else {
|
||||
// mark as end-of-slot to avoid aggressively lock poh for the remaining for
|
||||
// packet batches in buffer
|
||||
reached_end_of_slot = Some(EndOfSlot {
|
||||
next_slot_leader: poh_recorder.lock().unwrap().next_slot_leader(),
|
||||
working_bank: None,
|
||||
});
|
||||
|
||||
// `original_unprocessed_indexes` must have remaining packets to process
|
||||
// if not yet processed.
|
||||
assert!(Self::packet_has_more_unprocessed_transactions(
|
||||
@@ -698,6 +701,7 @@ impl BankingStage {
|
||||
recorder: &TransactionRecorder,
|
||||
data_budget: &DataBudget,
|
||||
qos_service: &Arc<QosService>,
|
||||
slot_metrics_tracker: &mut LeaderSlotMetricsTracker,
|
||||
) -> BufferedPacketsDecision {
|
||||
let bank_start;
|
||||
let (
|
||||
@@ -739,6 +743,7 @@ impl BankingStage {
|
||||
banking_stage_stats,
|
||||
recorder,
|
||||
qos_service,
|
||||
slot_metrics_tracker,
|
||||
);
|
||||
}
|
||||
BufferedPacketsDecision::Forward => {
|
||||
@@ -750,6 +755,7 @@ impl BankingStage {
|
||||
socket,
|
||||
false,
|
||||
data_budget,
|
||||
slot_metrics_tracker,
|
||||
);
|
||||
}
|
||||
BufferedPacketsDecision::ForwardAndHold => {
|
||||
@@ -761,10 +767,12 @@ impl BankingStage {
|
||||
socket,
|
||||
true,
|
||||
data_budget,
|
||||
slot_metrics_tracker,
|
||||
);
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
||||
decision
|
||||
}
|
||||
|
||||
@@ -776,6 +784,7 @@ impl BankingStage {
|
||||
socket: &UdpSocket,
|
||||
hold: bool,
|
||||
data_budget: &DataBudget,
|
||||
slot_metrics_tracker: &mut LeaderSlotMetricsTracker,
|
||||
) {
|
||||
let addr = match forward_option {
|
||||
ForwardOption::NotForward => {
|
||||
@@ -793,13 +802,35 @@ impl BankingStage {
|
||||
Some(addr) => addr,
|
||||
None => return,
|
||||
};
|
||||
let _ = Self::forward_buffered_packets(socket, &addr, buffered_packet_batches, data_budget);
|
||||
|
||||
let forwardable_packets =
|
||||
Self::filter_valid_packets_for_forwarding(buffered_packet_batches.iter());
|
||||
let forwardable_packets_len = forwardable_packets.len();
|
||||
let (_forward_result, sucessful_forwarded_packets_count) =
|
||||
Self::forward_buffered_packets(socket, &addr, forwardable_packets, data_budget);
|
||||
let failed_forwarded_packets_count =
|
||||
forwardable_packets_len.saturating_sub(sucessful_forwarded_packets_count);
|
||||
|
||||
if failed_forwarded_packets_count > 0 {
|
||||
slot_metrics_tracker
|
||||
.increment_failed_forwarded_packets_count(failed_forwarded_packets_count as u64);
|
||||
slot_metrics_tracker.increment_packet_batch_forward_failure_count(1);
|
||||
}
|
||||
|
||||
if sucessful_forwarded_packets_count > 0 {
|
||||
slot_metrics_tracker.increment_successful_forwarded_packets_count(
|
||||
sucessful_forwarded_packets_count as u64,
|
||||
);
|
||||
}
|
||||
|
||||
if hold {
|
||||
buffered_packet_batches.retain(|(_, index, _)| !index.is_empty());
|
||||
for (_, _, forwarded) in buffered_packet_batches.iter_mut() {
|
||||
*forwarded = true;
|
||||
}
|
||||
} else {
|
||||
slot_metrics_tracker
|
||||
.increment_cleared_from_buffer_after_forward_count(forwardable_packets_len as u64);
|
||||
buffered_packet_batches.clear();
|
||||
}
|
||||
}
|
||||
@@ -822,6 +853,7 @@ impl BankingStage {
|
||||
let socket = UdpSocket::bind("0.0.0.0:0").unwrap();
|
||||
let mut buffered_packet_batches = VecDeque::with_capacity(batch_limit);
|
||||
let mut banking_stage_stats = BankingStageStats::new(id);
|
||||
let mut slot_metrics_tracker = LeaderSlotMetricsTracker::new(id);
|
||||
loop {
|
||||
let my_pubkey = cluster_info.id();
|
||||
while !buffered_packet_batches.is_empty() {
|
||||
@@ -838,6 +870,7 @@ impl BankingStage {
|
||||
&recorder,
|
||||
data_budget,
|
||||
&qos_service,
|
||||
&mut slot_metrics_tracker,
|
||||
);
|
||||
if matches!(decision, BufferedPacketsDecision::Hold)
|
||||
|| matches!(decision, BufferedPacketsDecision::ForwardAndHold)
|
||||
@@ -848,6 +881,12 @@ impl BankingStage {
|
||||
}
|
||||
}
|
||||
|
||||
let current_poh_bank = {
|
||||
let poh = poh_recorder.lock().unwrap();
|
||||
poh.bank_start()
|
||||
};
|
||||
slot_metrics_tracker.update_on_leader_slot_boundary(¤t_poh_bank);
|
||||
|
||||
let recv_timeout = if !buffered_packet_batches.is_empty() {
|
||||
// If packets are buffered, let's wait for less time on recv from the channel.
|
||||
// This helps detect the next leader faster, and processing the buffered
|
||||
@@ -866,6 +905,7 @@ impl BankingStage {
|
||||
batch_limit,
|
||||
&mut buffered_packet_batches,
|
||||
&mut banking_stage_stats,
|
||||
&mut slot_metrics_tracker,
|
||||
) {
|
||||
Ok(()) | Err(RecvTimeoutError::Timeout) => (),
|
||||
Err(RecvTimeoutError::Disconnected) => break,
|
||||
@@ -1444,6 +1484,7 @@ impl BankingStage {
|
||||
gossip_vote_sender: &ReplayVoteSender,
|
||||
banking_stage_stats: &BankingStageStats,
|
||||
qos_service: &Arc<QosService>,
|
||||
slot_metrics_tracker: &mut LeaderSlotMetricsTracker,
|
||||
) -> ProcessTransactionsSummary {
|
||||
let mut packet_conversion_time = Measure::start("packet_conversion");
|
||||
let (transactions, transaction_to_packet_indexes) = Self::transactions_from_packets(
|
||||
@@ -1474,6 +1515,11 @@ impl BankingStage {
|
||||
..
|
||||
} = process_transactions_summary;
|
||||
|
||||
slot_metrics_tracker.accumulate_process_transactions_summary(&process_transactions_summary);
|
||||
|
||||
let retryable_tx_count = retryable_transaction_indexes.len();
|
||||
inc_new_counter_info!("banking_stage-unprocessed_transactions", retryable_tx_count);
|
||||
|
||||
let mut filter_pending_packets_time = Measure::start("filter_pending_packets_time");
|
||||
let filtered_retryable_tx_indexes = Self::filter_pending_packets_from_pending_txs(
|
||||
bank,
|
||||
@@ -1483,6 +1529,12 @@ impl BankingStage {
|
||||
);
|
||||
filter_pending_packets_time.stop();
|
||||
|
||||
let retryable_packets_filtered_count = retryable_transaction_indexes
|
||||
.len()
|
||||
.saturating_sub(filtered_retryable_tx_indexes.len());
|
||||
slot_metrics_tracker
|
||||
.increment_retryable_packets_filtered_count(retryable_packets_filtered_count as u64);
|
||||
|
||||
inc_new_counter_info!(
|
||||
"banking_stage-dropped_tx_before_forwarding",
|
||||
retryable_transaction_indexes
|
||||
@@ -1505,7 +1557,7 @@ impl BankingStage {
|
||||
process_transactions_summary
|
||||
}
|
||||
|
||||
fn filter_unprocessed_packets(
|
||||
fn filter_unprocessed_packets_at_end_of_slot(
|
||||
bank: &Arc<Bank>,
|
||||
packet_batch: &PacketBatch,
|
||||
transaction_indexes: &[usize],
|
||||
@@ -1575,6 +1627,7 @@ impl BankingStage {
|
||||
batch_limit: usize,
|
||||
buffered_packet_batches: &mut UnprocessedPacketBatches,
|
||||
banking_stage_stats: &mut BankingStageStats,
|
||||
slot_metrics_tracker: &mut LeaderSlotMetricsTracker,
|
||||
) -> Result<(), RecvTimeoutError> {
|
||||
let mut recv_time = Measure::start("receive_and_buffer_packets_recv");
|
||||
let packet_batches = verified_receiver.recv_timeout(recv_timeout)?;
|
||||
@@ -1598,6 +1651,15 @@ impl BankingStage {
|
||||
let mut newly_buffered_packets_count = 0;
|
||||
for packet_batch in packet_batch_iter {
|
||||
let packet_indexes = Self::generate_packet_indexes(&packet_batch.packets);
|
||||
// Track all the packets incoming from sigverify, both valid and invalid
|
||||
slot_metrics_tracker.increment_total_new_valid_packets(packet_indexes.len() as u64);
|
||||
slot_metrics_tracker.increment_newly_failed_sigverify_count(
|
||||
packet_batch
|
||||
.packets
|
||||
.len()
|
||||
.saturating_sub(packet_indexes.len()) as u64,
|
||||
);
|
||||
|
||||
Self::push_unprocessed(
|
||||
buffered_packet_batches,
|
||||
packet_batch,
|
||||
@@ -1607,6 +1669,7 @@ impl BankingStage {
|
||||
&mut newly_buffered_packets_count,
|
||||
batch_limit,
|
||||
banking_stage_stats,
|
||||
slot_metrics_tracker,
|
||||
);
|
||||
}
|
||||
proc_start.stop();
|
||||
@@ -1657,12 +1720,16 @@ impl BankingStage {
|
||||
newly_buffered_packets_count: &mut usize,
|
||||
batch_limit: usize,
|
||||
banking_stage_stats: &mut BankingStageStats,
|
||||
slot_metrics_tracker: &mut LeaderSlotMetricsTracker,
|
||||
) {
|
||||
if Self::packet_has_more_unprocessed_transactions(&packet_indexes) {
|
||||
if unprocessed_packet_batches.len() >= batch_limit {
|
||||
*dropped_packet_batches_count += 1;
|
||||
if let Some(dropped_batch) = unprocessed_packet_batches.pop_front() {
|
||||
*dropped_packets_count += dropped_batch.1.len();
|
||||
slot_metrics_tracker.increment_exceeded_buffer_limit_dropped_packets_count(
|
||||
dropped_batch.1.len() as u64,
|
||||
);
|
||||
}
|
||||
}
|
||||
let _ = banking_stage_stats
|
||||
@@ -1670,6 +1737,8 @@ impl BankingStage {
|
||||
.increment(packet_indexes.len() as u64);
|
||||
|
||||
*newly_buffered_packets_count += packet_indexes.len();
|
||||
slot_metrics_tracker
|
||||
.increment_newly_buffered_packets_count(packet_indexes.len() as u64);
|
||||
unprocessed_packet_batches.push_back((packet_batch, packet_indexes, false));
|
||||
}
|
||||
}
|
||||
@@ -3122,6 +3191,7 @@ mod tests {
|
||||
&BankingStageStats::default(),
|
||||
&recorder,
|
||||
&Arc::new(QosService::new(Arc::new(RwLock::new(CostModel::default())))),
|
||||
&mut LeaderSlotMetricsTracker::new(0),
|
||||
);
|
||||
assert_eq!(
|
||||
buffered_packet_batches[0].1.len(),
|
||||
@@ -3142,6 +3212,7 @@ mod tests {
|
||||
&BankingStageStats::default(),
|
||||
&recorder,
|
||||
&Arc::new(QosService::new(Arc::new(RwLock::new(CostModel::default())))),
|
||||
&mut LeaderSlotMetricsTracker::new(0),
|
||||
);
|
||||
if num_expected_unprocessed == 0 {
|
||||
assert!(buffered_packet_batches.is_empty())
|
||||
@@ -3208,6 +3279,7 @@ mod tests {
|
||||
&BankingStageStats::default(),
|
||||
&recorder,
|
||||
&Arc::new(QosService::new(Arc::new(RwLock::new(CostModel::default())))),
|
||||
&mut LeaderSlotMetricsTracker::new(0),
|
||||
);
|
||||
|
||||
// Check everything is correct. All indexes after `interrupted_iteration`
|
||||
@@ -3305,6 +3377,7 @@ mod tests {
|
||||
&send_socket,
|
||||
true,
|
||||
&data_budget,
|
||||
&mut LeaderSlotMetricsTracker::new(0),
|
||||
);
|
||||
|
||||
recv_socket
|
||||
@@ -3404,6 +3477,7 @@ mod tests {
|
||||
&send_socket,
|
||||
hold,
|
||||
&DataBudget::default(),
|
||||
&mut LeaderSlotMetricsTracker::new(0),
|
||||
);
|
||||
|
||||
recv_socket
|
||||
@@ -3465,6 +3539,7 @@ mod tests {
|
||||
&mut newly_buffered_packets_count,
|
||||
batch_limit,
|
||||
&mut banking_stage_stats,
|
||||
&mut LeaderSlotMetricsTracker::new(0),
|
||||
);
|
||||
assert_eq!(unprocessed_packets.len(), 1);
|
||||
assert_eq!(dropped_packet_batches_count, 0);
|
||||
@@ -3483,6 +3558,7 @@ mod tests {
|
||||
&mut newly_buffered_packets_count,
|
||||
batch_limit,
|
||||
&mut banking_stage_stats,
|
||||
&mut LeaderSlotMetricsTracker::new(0),
|
||||
);
|
||||
assert_eq!(unprocessed_packets.len(), 2);
|
||||
assert_eq!(dropped_packet_batches_count, 0);
|
||||
@@ -3506,6 +3582,7 @@ mod tests {
|
||||
&mut newly_buffered_packets_count,
|
||||
batch_limit,
|
||||
&mut banking_stage_stats,
|
||||
&mut LeaderSlotMetricsTracker::new(0),
|
||||
);
|
||||
assert_eq!(unprocessed_packets.len(), 2);
|
||||
assert_eq!(
|
||||
|
723
core/src/leader_slot_banking_stage_metrics.rs
Normal file
723
core/src/leader_slot_banking_stage_metrics.rs
Normal file
@@ -0,0 +1,723 @@
|
||||
use {
|
||||
solana_poh::poh_recorder::BankStart,
|
||||
solana_sdk::{clock::Slot, saturating_add_assign},
|
||||
std::time::Instant,
|
||||
};
|
||||
|
||||
/// A summary of what happened to transactions passed to the execution pipeline.
|
||||
/// Transactions can
|
||||
/// 1) Did not even make it to execution due to being filtered out by things like AccountInUse
|
||||
/// lock conflicts or CostModel compute limits. These types of errors are retryable and
|
||||
/// counted in `Self::retryable_transaction_indexes`.
|
||||
/// 2) Did not execute due to some fatal error like too old, or duplicate signature. These
|
||||
/// will be dropped from the transactions queue and not counted in `Self::retryable_transaction_indexes`
|
||||
/// 3) Were executed and committed, captured by `committed_transactions_count` below.
|
||||
/// 4) Were executed and failed commit, captured by `failed_commit_count` below.
|
||||
pub(crate) struct ProcessTransactionsSummary {
|
||||
// Returns true if we hit the end of the block/max PoH height for the block before
|
||||
// processing all the transactions in the batch.
|
||||
pub reached_max_poh_height: bool,
|
||||
|
||||
// Total number of transactions that were passed as candidates for execution. See description
|
||||
// of struct above for possible outcomes for these transactions
|
||||
pub transactions_attempted_execution_count: usize,
|
||||
|
||||
// Total number of transactions that made it into the block
|
||||
pub committed_transactions_count: usize,
|
||||
|
||||
// Total number of transactions that made it into the block where the transactions
|
||||
// output from execution was success/no error.
|
||||
pub committed_transactions_with_successful_result_count: usize,
|
||||
|
||||
// All transactions that were executed but then failed record because the
|
||||
// slot ended
|
||||
pub failed_commit_count: usize,
|
||||
|
||||
// Indexes of transactions in the transactions slice that were not committed but are retryable
|
||||
pub retryable_transaction_indexes: Vec<usize>,
|
||||
|
||||
// The number of transactions filtered out by the cost model
|
||||
pub cost_model_throttled_transactions_count: usize,
|
||||
}
|
||||
|
||||
// Metrics capturing wallclock time spent in various parts of BankingStage during this
|
||||
// validator's leader slot
|
||||
#[derive(Debug)]
|
||||
struct LeaderSlotTimingMetrics {
|
||||
bank_detected_time: Instant,
|
||||
|
||||
// Delay from when the bank was created to when this thread detected it
|
||||
bank_detected_delay_us: u64,
|
||||
}
|
||||
|
||||
impl LeaderSlotTimingMetrics {
|
||||
fn new(bank_creation_time: &Instant) -> Self {
|
||||
Self {
|
||||
bank_detected_time: Instant::now(),
|
||||
bank_detected_delay_us: bank_creation_time.elapsed().as_micros() as u64,
|
||||
}
|
||||
}
|
||||
|
||||
fn report(&self, id: u32, slot: Slot) {
|
||||
let bank_detected_to_now = self.bank_detected_time.elapsed().as_micros() as u64;
|
||||
datapoint_info!(
|
||||
"banking_stage-leader_slot_loop_timings",
|
||||
("id", id as i64, i64),
|
||||
("slot", slot as i64, i64),
|
||||
("bank_detected_to_now_us", bank_detected_to_now, i64),
|
||||
(
|
||||
"bank_creation_to_now_us",
|
||||
bank_detected_to_now + self.bank_detected_delay_us,
|
||||
i64
|
||||
),
|
||||
("bank_detected_delay_us", self.bank_detected_delay_us, i64),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Metrics describing packets ingested/processed in various parts of BankingStage during this
|
||||
// validator's leader slot
|
||||
#[derive(Debug, Default)]
|
||||
struct LeaderSlotPacketCountMetrics {
|
||||
// total number of live packets TPU received from verified receiver for processing.
|
||||
total_new_valid_packets: u64,
|
||||
|
||||
// total number of packets TPU received from sigverify that failed signature verification.
|
||||
newly_failed_sigverify_count: u64,
|
||||
|
||||
// total number of dropped packet due to the thread's buffered packets capacity being reached.
|
||||
exceeded_buffer_limit_dropped_packets_count: u64,
|
||||
|
||||
// total number of packets that got added to the pending buffer after arriving to BankingStage
|
||||
newly_buffered_packets_count: u64,
|
||||
|
||||
// total number of transactions in the buffer that were filtered out due to things like age and
|
||||
// duplicate signature checks
|
||||
retryable_packets_filtered_count: u64,
|
||||
|
||||
// total number of transactions that attempted execution in this slot. Should equal the sum
|
||||
// of `committed_transactions_count`, `retryable_errored_transaction_count`, and
|
||||
// `nonretryable_errored_transactions_count`.
|
||||
transactions_attempted_execution_count: u64,
|
||||
|
||||
// total number of transactions that were executed and committed into the block
|
||||
// on this thread
|
||||
committed_transactions_count: u64,
|
||||
|
||||
// total number of transactions that were executed, got a successful execution output/no error,
|
||||
// and were then committed into the block
|
||||
committed_transactions_with_successful_result_count: u64,
|
||||
|
||||
// total number of transactions that were not executed or failed commit, BUT were added back to the buffered
|
||||
// queue becaus they were retryable errors
|
||||
retryable_errored_transaction_count: u64,
|
||||
|
||||
// total number of transactions that attempted execution due to some fatal error (too old, duplicate signature, etc.)
|
||||
// AND were dropped from the buffered queue
|
||||
nonretryable_errored_transactions_count: u64,
|
||||
|
||||
// total number of transactions that were executed, but failed to be committed into the Poh stream because
|
||||
// the block ended. Some of these may be already counted in `nonretryable_errored_transactions_count` if they
|
||||
// then hit the age limit after failing to be comitted.
|
||||
executed_transactions_failed_commit_count: u64,
|
||||
|
||||
// total number of transactions that were excluded from the block because they were too expensive
|
||||
// according to the cost model. These transactions are added back to the buffered queue and are
|
||||
// already counted in `self.retrayble_errored_transaction_count`.
|
||||
cost_model_throttled_transactions_count: u64,
|
||||
|
||||
// total number of forwardsable packets that failed forwarding
|
||||
failed_forwarded_packets_count: u64,
|
||||
|
||||
// total number of forwardsable packets that were successfully forwarded
|
||||
successful_forwarded_packets_count: u64,
|
||||
|
||||
// total number of attempted forwards that failed. Note this is not a count of the number of packets
|
||||
// that failed, just the total number of batches of packets that failed forwarding
|
||||
packet_batch_forward_failure_count: u64,
|
||||
|
||||
// total number of valid unprocessed packets in the buffer that were removed after being forwarded
|
||||
cleared_from_buffer_after_forward_count: u64,
|
||||
|
||||
// total number of packets removed at the end of the slot due to being too old, duplicate, etc.
|
||||
end_of_slot_filtered_invalid_count: u64,
|
||||
}
|
||||
|
||||
impl LeaderSlotPacketCountMetrics {
|
||||
fn new() -> Self {
|
||||
Self { ..Self::default() }
|
||||
}
|
||||
|
||||
fn report(&self, id: u32, slot: Slot) {
|
||||
datapoint_info!(
|
||||
"banking_stage-leader_slot_packet_counts",
|
||||
("id", id as i64, i64),
|
||||
("slot", slot as i64, i64),
|
||||
(
|
||||
"total_new_valid_packets",
|
||||
self.total_new_valid_packets as i64,
|
||||
i64
|
||||
),
|
||||
(
|
||||
"newly_failed_sigverify_count",
|
||||
self.newly_failed_sigverify_count as i64,
|
||||
i64
|
||||
),
|
||||
(
|
||||
"exceeded_buffer_limit_dropped_packets_count",
|
||||
self.exceeded_buffer_limit_dropped_packets_count as i64,
|
||||
i64
|
||||
),
|
||||
(
|
||||
"newly_buffered_packets_count",
|
||||
self.newly_buffered_packets_count as i64,
|
||||
i64
|
||||
),
|
||||
(
|
||||
"retryable_packets_filtered_count",
|
||||
self.retryable_packets_filtered_count as i64,
|
||||
i64
|
||||
),
|
||||
(
|
||||
"transactions_attempted_execution_count",
|
||||
self.transactions_attempted_execution_count as i64,
|
||||
i64
|
||||
),
|
||||
(
|
||||
"committed_transactions_count",
|
||||
self.committed_transactions_count as i64,
|
||||
i64
|
||||
),
|
||||
(
|
||||
"committed_transactions_with_successful_result_count",
|
||||
self.committed_transactions_with_successful_result_count as i64,
|
||||
i64
|
||||
),
|
||||
(
|
||||
"retryable_errored_transaction_count",
|
||||
self.retryable_errored_transaction_count as i64,
|
||||
i64
|
||||
),
|
||||
(
|
||||
"nonretryable_errored_transactions_count",
|
||||
self.nonretryable_errored_transactions_count as i64,
|
||||
i64
|
||||
),
|
||||
(
|
||||
"executed_transactions_failed_commit_count",
|
||||
self.executed_transactions_failed_commit_count as i64,
|
||||
i64
|
||||
),
|
||||
(
|
||||
"cost_model_throttled_transactions_count",
|
||||
self.cost_model_throttled_transactions_count as i64,
|
||||
i64
|
||||
),
|
||||
(
|
||||
"failed_forwarded_packets_count",
|
||||
self.failed_forwarded_packets_count as i64,
|
||||
i64
|
||||
),
|
||||
(
|
||||
"successful_forwarded_packets_count",
|
||||
self.successful_forwarded_packets_count as i64,
|
||||
i64
|
||||
),
|
||||
(
|
||||
"packet_batch_forward_failure_count",
|
||||
self.packet_batch_forward_failure_count as i64,
|
||||
i64
|
||||
),
|
||||
(
|
||||
"cleared_from_buffer_after_forward_count",
|
||||
self.cleared_from_buffer_after_forward_count as i64,
|
||||
i64
|
||||
),
|
||||
(
|
||||
"end_of_slot_filtered_invalid_count",
|
||||
self.end_of_slot_filtered_invalid_count as i64,
|
||||
i64
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct LeaderSlotMetrics {
|
||||
// banking_stage creates one QosService instance per working threads, that is uniquely
|
||||
// identified by id. This field allows to categorize metrics for gossip votes, TPU votes
|
||||
// and other transactions.
|
||||
id: u32,
|
||||
|
||||
// aggregate metrics per slot
|
||||
slot: Slot,
|
||||
|
||||
packet_count_metrics: LeaderSlotPacketCountMetrics,
|
||||
|
||||
timing_metrics: LeaderSlotTimingMetrics,
|
||||
|
||||
// Used by tests to check if the `self.report()` method was called
|
||||
is_reported: bool,
|
||||
}
|
||||
|
||||
impl LeaderSlotMetrics {
|
||||
pub(crate) fn new(id: u32, slot: Slot, bank_creation_time: &Instant) -> Self {
|
||||
Self {
|
||||
id,
|
||||
slot,
|
||||
packet_count_metrics: LeaderSlotPacketCountMetrics::new(),
|
||||
timing_metrics: LeaderSlotTimingMetrics::new(bank_creation_time),
|
||||
is_reported: false,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn report(&mut self) {
|
||||
self.is_reported = true;
|
||||
|
||||
self.timing_metrics.report(self.id, self.slot);
|
||||
self.packet_count_metrics.report(self.id, self.slot);
|
||||
}
|
||||
|
||||
/// Returns `Some(self.slot)` if the metrics have been reported, otherwise returns None
|
||||
fn reported_slot(&self) -> Option<Slot> {
|
||||
if self.is_reported {
|
||||
Some(self.slot)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct LeaderSlotMetricsTracker {
|
||||
// Only `Some` if BankingStage detects it's time to construct our leader slot,
|
||||
// otherwise `None`
|
||||
leader_slot_metrics: Option<LeaderSlotMetrics>,
|
||||
id: u32,
|
||||
}
|
||||
|
||||
impl LeaderSlotMetricsTracker {
|
||||
pub fn new(id: u32) -> Self {
|
||||
Self {
|
||||
leader_slot_metrics: None,
|
||||
id,
|
||||
}
|
||||
}
|
||||
|
||||
// Returns reported slot if metrics were reported
|
||||
pub(crate) fn update_on_leader_slot_boundary(
|
||||
&mut self,
|
||||
bank_start: &Option<BankStart>,
|
||||
) -> Option<Slot> {
|
||||
match (self.leader_slot_metrics.as_mut(), bank_start) {
|
||||
(None, None) => None,
|
||||
|
||||
(Some(leader_slot_metrics), None) => {
|
||||
leader_slot_metrics.report();
|
||||
// Ensure tests catch that `report()` method was called
|
||||
let reported_slot = leader_slot_metrics.reported_slot();
|
||||
// Slot has ended, time to report metrics
|
||||
self.leader_slot_metrics = None;
|
||||
reported_slot
|
||||
}
|
||||
|
||||
(None, Some(bank_start)) => {
|
||||
// Our leader slot has begain, time to create a new slot tracker
|
||||
self.leader_slot_metrics = Some(LeaderSlotMetrics::new(
|
||||
self.id,
|
||||
bank_start.working_bank.slot(),
|
||||
&bank_start.bank_creation_time,
|
||||
));
|
||||
self.leader_slot_metrics.as_ref().unwrap().reported_slot()
|
||||
}
|
||||
|
||||
(Some(leader_slot_metrics), Some(bank_start)) => {
|
||||
if leader_slot_metrics.slot != bank_start.working_bank.slot() {
|
||||
// Last slot has ended, new slot has began
|
||||
leader_slot_metrics.report();
|
||||
// Ensure tests catch that `report()` method was called
|
||||
let reported_slot = leader_slot_metrics.reported_slot();
|
||||
self.leader_slot_metrics = Some(LeaderSlotMetrics::new(
|
||||
self.id,
|
||||
bank_start.working_bank.slot(),
|
||||
&bank_start.bank_creation_time,
|
||||
));
|
||||
reported_slot
|
||||
} else {
|
||||
leader_slot_metrics.reported_slot()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn accumulate_process_transactions_summary(
|
||||
&mut self,
|
||||
process_transactions_summary: &ProcessTransactionsSummary,
|
||||
) {
|
||||
if let Some(leader_slot_metrics) = &mut self.leader_slot_metrics {
|
||||
let ProcessTransactionsSummary {
|
||||
transactions_attempted_execution_count,
|
||||
committed_transactions_count,
|
||||
committed_transactions_with_successful_result_count,
|
||||
failed_commit_count,
|
||||
ref retryable_transaction_indexes,
|
||||
cost_model_throttled_transactions_count,
|
||||
..
|
||||
} = process_transactions_summary;
|
||||
|
||||
saturating_add_assign!(
|
||||
leader_slot_metrics
|
||||
.packet_count_metrics
|
||||
.transactions_attempted_execution_count,
|
||||
*transactions_attempted_execution_count as u64
|
||||
);
|
||||
|
||||
saturating_add_assign!(
|
||||
leader_slot_metrics
|
||||
.packet_count_metrics
|
||||
.committed_transactions_count,
|
||||
*committed_transactions_count as u64
|
||||
);
|
||||
|
||||
saturating_add_assign!(
|
||||
leader_slot_metrics
|
||||
.packet_count_metrics
|
||||
.committed_transactions_with_successful_result_count,
|
||||
*committed_transactions_with_successful_result_count as u64
|
||||
);
|
||||
|
||||
saturating_add_assign!(
|
||||
leader_slot_metrics
|
||||
.packet_count_metrics
|
||||
.executed_transactions_failed_commit_count,
|
||||
*failed_commit_count as u64
|
||||
);
|
||||
|
||||
saturating_add_assign!(
|
||||
leader_slot_metrics
|
||||
.packet_count_metrics
|
||||
.retryable_errored_transaction_count,
|
||||
retryable_transaction_indexes.len() as u64
|
||||
);
|
||||
|
||||
saturating_add_assign!(
|
||||
leader_slot_metrics
|
||||
.packet_count_metrics
|
||||
.nonretryable_errored_transactions_count,
|
||||
transactions_attempted_execution_count
|
||||
.saturating_sub(*committed_transactions_count)
|
||||
.saturating_sub(retryable_transaction_indexes.len()) as u64
|
||||
);
|
||||
|
||||
saturating_add_assign!(
|
||||
leader_slot_metrics
|
||||
.packet_count_metrics
|
||||
.cost_model_throttled_transactions_count,
|
||||
*cost_model_throttled_transactions_count as u64
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn increment_total_new_valid_packets(&mut self, count: u64) {
|
||||
if let Some(leader_slot_metrics) = &mut self.leader_slot_metrics {
|
||||
saturating_add_assign!(
|
||||
leader_slot_metrics
|
||||
.packet_count_metrics
|
||||
.total_new_valid_packets,
|
||||
count
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn increment_newly_failed_sigverify_count(&mut self, count: u64) {
|
||||
if let Some(leader_slot_metrics) = &mut self.leader_slot_metrics {
|
||||
saturating_add_assign!(
|
||||
leader_slot_metrics
|
||||
.packet_count_metrics
|
||||
.newly_failed_sigverify_count,
|
||||
count
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn increment_exceeded_buffer_limit_dropped_packets_count(&mut self, count: u64) {
|
||||
if let Some(leader_slot_metrics) = &mut self.leader_slot_metrics {
|
||||
saturating_add_assign!(
|
||||
leader_slot_metrics
|
||||
.packet_count_metrics
|
||||
.exceeded_buffer_limit_dropped_packets_count,
|
||||
count
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn increment_newly_buffered_packets_count(&mut self, count: u64) {
|
||||
if let Some(leader_slot_metrics) = &mut self.leader_slot_metrics {
|
||||
saturating_add_assign!(
|
||||
leader_slot_metrics
|
||||
.packet_count_metrics
|
||||
.newly_buffered_packets_count,
|
||||
count
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn increment_retryable_packets_filtered_count(&mut self, count: u64) {
|
||||
if let Some(leader_slot_metrics) = &mut self.leader_slot_metrics {
|
||||
saturating_add_assign!(
|
||||
leader_slot_metrics
|
||||
.packet_count_metrics
|
||||
.retryable_packets_filtered_count,
|
||||
count
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn increment_failed_forwarded_packets_count(&mut self, count: u64) {
|
||||
if let Some(leader_slot_metrics) = &mut self.leader_slot_metrics {
|
||||
saturating_add_assign!(
|
||||
leader_slot_metrics
|
||||
.packet_count_metrics
|
||||
.failed_forwarded_packets_count,
|
||||
count
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn increment_successful_forwarded_packets_count(&mut self, count: u64) {
|
||||
if let Some(leader_slot_metrics) = &mut self.leader_slot_metrics {
|
||||
saturating_add_assign!(
|
||||
leader_slot_metrics
|
||||
.packet_count_metrics
|
||||
.successful_forwarded_packets_count,
|
||||
count
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn increment_packet_batch_forward_failure_count(&mut self, count: u64) {
|
||||
if let Some(leader_slot_metrics) = &mut self.leader_slot_metrics {
|
||||
saturating_add_assign!(
|
||||
leader_slot_metrics
|
||||
.packet_count_metrics
|
||||
.packet_batch_forward_failure_count,
|
||||
count
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn increment_cleared_from_buffer_after_forward_count(&mut self, count: u64) {
|
||||
if let Some(leader_slot_metrics) = &mut self.leader_slot_metrics {
|
||||
saturating_add_assign!(
|
||||
leader_slot_metrics
|
||||
.packet_count_metrics
|
||||
.cleared_from_buffer_after_forward_count,
|
||||
count
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn increment_end_of_slot_filtered_invalid_count(&mut self, count: u64) {
|
||||
if let Some(leader_slot_metrics) = &mut self.leader_slot_metrics {
|
||||
saturating_add_assign!(
|
||||
leader_slot_metrics
|
||||
.packet_count_metrics
|
||||
.end_of_slot_filtered_invalid_count,
|
||||
count
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use {
|
||||
super::*,
|
||||
solana_runtime::{bank::Bank, genesis_utils::create_genesis_config},
|
||||
solana_sdk::pubkey::Pubkey,
|
||||
std::sync::Arc,
|
||||
};
|
||||
|
||||
struct TestSlotBoundaryComponents {
|
||||
first_bank: Arc<Bank>,
|
||||
first_poh_recorder_bank: BankStart,
|
||||
next_bank: Arc<Bank>,
|
||||
next_poh_recorder_bank: BankStart,
|
||||
leader_slot_metrics_tracker: LeaderSlotMetricsTracker,
|
||||
}
|
||||
|
||||
fn setup_test_slot_boundary_banks() -> TestSlotBoundaryComponents {
|
||||
let genesis = create_genesis_config(10);
|
||||
let first_bank = Arc::new(Bank::new_for_tests(&genesis.genesis_config));
|
||||
let first_poh_recorder_bank = BankStart {
|
||||
working_bank: first_bank.clone(),
|
||||
bank_creation_time: Arc::new(Instant::now()),
|
||||
};
|
||||
|
||||
// Create a child descended from the first bank
|
||||
let next_bank = Arc::new(Bank::new_from_parent(
|
||||
&first_bank,
|
||||
&Pubkey::new_unique(),
|
||||
first_bank.slot() + 1,
|
||||
));
|
||||
let next_poh_recorder_bank = BankStart {
|
||||
working_bank: next_bank.clone(),
|
||||
bank_creation_time: Arc::new(Instant::now()),
|
||||
};
|
||||
|
||||
let banking_stage_thread_id = 0;
|
||||
let leader_slot_metrics_tracker = LeaderSlotMetricsTracker::new(banking_stage_thread_id);
|
||||
|
||||
TestSlotBoundaryComponents {
|
||||
first_bank,
|
||||
first_poh_recorder_bank,
|
||||
next_bank,
|
||||
next_poh_recorder_bank,
|
||||
leader_slot_metrics_tracker,
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_update_on_leader_slot_boundary_not_leader_to_not_leader() {
|
||||
let TestSlotBoundaryComponents {
|
||||
mut leader_slot_metrics_tracker,
|
||||
..
|
||||
} = setup_test_slot_boundary_banks();
|
||||
// Test that with no bank being tracked, and no new bank being tracked, nothing is reported
|
||||
assert!(leader_slot_metrics_tracker
|
||||
.update_on_leader_slot_boundary(&None)
|
||||
.is_none());
|
||||
assert!(leader_slot_metrics_tracker.leader_slot_metrics.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_update_on_leader_slot_boundary_not_leader_to_leader() {
|
||||
let TestSlotBoundaryComponents {
|
||||
first_poh_recorder_bank,
|
||||
mut leader_slot_metrics_tracker,
|
||||
..
|
||||
} = setup_test_slot_boundary_banks();
|
||||
|
||||
// Test case where the thread has not detected a leader bank, and now sees a leader bank.
|
||||
// Metrics should not be reported because leader slot has not ended
|
||||
assert!(leader_slot_metrics_tracker.leader_slot_metrics.is_none());
|
||||
assert!(leader_slot_metrics_tracker
|
||||
.update_on_leader_slot_boundary(&Some(first_poh_recorder_bank))
|
||||
.is_none());
|
||||
assert!(leader_slot_metrics_tracker.leader_slot_metrics.is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_update_on_leader_slot_boundary_leader_to_not_leader() {
|
||||
let TestSlotBoundaryComponents {
|
||||
first_bank,
|
||||
first_poh_recorder_bank,
|
||||
mut leader_slot_metrics_tracker,
|
||||
..
|
||||
} = setup_test_slot_boundary_banks();
|
||||
|
||||
// Test case where the thread has a leader bank, and now detects there's no more leader bank,
|
||||
// implying the slot has ended. Metrics should be reported for `first_bank.slot()`,
|
||||
// because that leader slot has just ended.
|
||||
assert!(leader_slot_metrics_tracker
|
||||
.update_on_leader_slot_boundary(&Some(first_poh_recorder_bank))
|
||||
.is_none());
|
||||
assert_eq!(
|
||||
leader_slot_metrics_tracker
|
||||
.update_on_leader_slot_boundary(&None)
|
||||
.unwrap(),
|
||||
first_bank.slot()
|
||||
);
|
||||
assert!(leader_slot_metrics_tracker.leader_slot_metrics.is_none());
|
||||
assert!(leader_slot_metrics_tracker
|
||||
.update_on_leader_slot_boundary(&None)
|
||||
.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_update_on_leader_slot_boundary_leader_to_leader_same_slot() {
|
||||
let TestSlotBoundaryComponents {
|
||||
first_bank,
|
||||
first_poh_recorder_bank,
|
||||
mut leader_slot_metrics_tracker,
|
||||
..
|
||||
} = setup_test_slot_boundary_banks();
|
||||
|
||||
// Test case where the thread has a leader bank, and now detects the same leader bank,
|
||||
// implying the slot is still running. Metrics should not be reported
|
||||
assert!(leader_slot_metrics_tracker
|
||||
.update_on_leader_slot_boundary(&Some(first_poh_recorder_bank.clone()))
|
||||
.is_none());
|
||||
assert!(leader_slot_metrics_tracker
|
||||
.update_on_leader_slot_boundary(&Some(first_poh_recorder_bank))
|
||||
.is_none());
|
||||
assert_eq!(
|
||||
leader_slot_metrics_tracker
|
||||
.update_on_leader_slot_boundary(&None)
|
||||
.unwrap(),
|
||||
first_bank.slot()
|
||||
);
|
||||
assert!(leader_slot_metrics_tracker.leader_slot_metrics.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_update_on_leader_slot_boundary_leader_to_leader_bigger_slot() {
|
||||
let TestSlotBoundaryComponents {
|
||||
first_bank,
|
||||
first_poh_recorder_bank,
|
||||
next_bank,
|
||||
next_poh_recorder_bank,
|
||||
mut leader_slot_metrics_tracker,
|
||||
} = setup_test_slot_boundary_banks();
|
||||
|
||||
// Test case where the thread has a leader bank, and now detects there's a new leader bank
|
||||
// for a bigger slot, implying the slot has ended. Metrics should be reported for the
|
||||
// smaller slot
|
||||
assert!(leader_slot_metrics_tracker
|
||||
.update_on_leader_slot_boundary(&Some(first_poh_recorder_bank))
|
||||
.is_none());
|
||||
assert_eq!(
|
||||
leader_slot_metrics_tracker
|
||||
.update_on_leader_slot_boundary(&Some(next_poh_recorder_bank))
|
||||
.unwrap(),
|
||||
first_bank.slot()
|
||||
);
|
||||
assert_eq!(
|
||||
leader_slot_metrics_tracker
|
||||
.update_on_leader_slot_boundary(&None)
|
||||
.unwrap(),
|
||||
next_bank.slot()
|
||||
);
|
||||
assert!(leader_slot_metrics_tracker.leader_slot_metrics.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_update_on_leader_slot_boundary_leader_to_leader_smaller_slot() {
|
||||
let TestSlotBoundaryComponents {
|
||||
first_bank,
|
||||
first_poh_recorder_bank,
|
||||
next_bank,
|
||||
next_poh_recorder_bank,
|
||||
mut leader_slot_metrics_tracker,
|
||||
} = setup_test_slot_boundary_banks();
|
||||
// Test case where the thread has a leader bank, and now detects there's a new leader bank
|
||||
// for a samller slot, implying the slot has ended. Metrics should be reported for the
|
||||
// bigger slot
|
||||
assert!(leader_slot_metrics_tracker
|
||||
.update_on_leader_slot_boundary(&Some(next_poh_recorder_bank))
|
||||
.is_none());
|
||||
assert_eq!(
|
||||
leader_slot_metrics_tracker
|
||||
.update_on_leader_slot_boundary(&Some(first_poh_recorder_bank))
|
||||
.unwrap(),
|
||||
next_bank.slot()
|
||||
);
|
||||
assert_eq!(
|
||||
leader_slot_metrics_tracker
|
||||
.update_on_leader_slot_boundary(&None)
|
||||
.unwrap(),
|
||||
first_bank.slot()
|
||||
);
|
||||
assert!(leader_slot_metrics_tracker.leader_slot_metrics.is_none());
|
||||
}
|
||||
}
|
@@ -28,6 +28,7 @@ pub mod fork_choice;
|
||||
pub mod gen_keys;
|
||||
pub mod heaviest_subtree_fork_choice;
|
||||
pub mod latest_validator_votes_for_frozen_banks;
|
||||
pub mod leader_slot_banking_stage_metrics;
|
||||
pub mod ledger_cleanup_service;
|
||||
pub mod optimistic_confirmation_verifier;
|
||||
pub mod outstanding_requests;
|
||||
|
@@ -104,8 +104,9 @@ impl QosService {
|
||||
txs_costs
|
||||
}
|
||||
|
||||
// Given a list of transactions and their costs, this function returns a corresponding
|
||||
// list of Results that indicate if a transaction is selected to be included in the current block,
|
||||
/// Given a list of transactions and their costs, this function returns a corresponding
|
||||
/// list of Results that indicate if a transaction is selected to be included in the current block,
|
||||
/// and a count of the number of transactions that would fit in the block
|
||||
pub fn select_transactions_per_cost<'a>(
|
||||
&self,
|
||||
transactions: impl Iterator<Item = &'a SanitizedTransaction>,
|
||||
|
@@ -12,7 +12,7 @@ use {
|
||||
itertools::Itertools,
|
||||
solana_measure::measure::Measure,
|
||||
solana_perf::packet::PacketBatch,
|
||||
solana_perf::sigverify::Deduper,
|
||||
solana_perf::sigverify::{count_valid_packets, shrink_batches, Deduper},
|
||||
solana_sdk::timing,
|
||||
solana_streamer::streamer::{self, PacketBatchReceiver, StreamerError},
|
||||
std::{
|
||||
@@ -59,6 +59,9 @@ struct SigVerifierStats {
|
||||
total_packets: usize,
|
||||
total_dedup: usize,
|
||||
total_excess_fail: usize,
|
||||
total_shrink_time: usize,
|
||||
total_shrinks: usize,
|
||||
total_valid_packets: usize,
|
||||
}
|
||||
|
||||
impl SigVerifierStats {
|
||||
@@ -167,6 +170,9 @@ impl SigVerifierStats {
|
||||
("total_packets", self.total_packets, i64),
|
||||
("total_dedup", self.total_dedup, i64),
|
||||
("total_excess_fail", self.total_excess_fail, i64),
|
||||
("total_shrink_time", self.total_shrink_time, i64),
|
||||
("total_shrinks", self.total_shrinks, i64),
|
||||
("total_valid_packets", self.total_valid_packets, i64),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -242,7 +248,20 @@ impl SigVerifyStage {
|
||||
discard_time.stop();
|
||||
|
||||
let mut verify_batch_time = Measure::start("sigverify_batch_time");
|
||||
let batches = verifier.verify_batches(batches);
|
||||
let mut batches = verifier.verify_batches(batches);
|
||||
verify_batch_time.stop();
|
||||
|
||||
let mut shrink_time = Measure::start("sigverify_shrink_time");
|
||||
let num_valid_packets = count_valid_packets(&batches);
|
||||
let start_len = batches.len();
|
||||
const MAX_EMPTY_BATCH_RATIO: usize = 4;
|
||||
if num_packets > num_valid_packets.saturating_mul(MAX_EMPTY_BATCH_RATIO) {
|
||||
let valid = shrink_batches(&mut batches);
|
||||
batches.truncate(valid);
|
||||
}
|
||||
let total_shrinks = start_len.saturating_sub(batches.len());
|
||||
shrink_time.stop();
|
||||
|
||||
sendr.send(batches)?;
|
||||
verify_batch_time.stop();
|
||||
|
||||
@@ -276,7 +295,10 @@ impl SigVerifyStage {
|
||||
stats.total_batches += batches_len;
|
||||
stats.total_packets += num_packets;
|
||||
stats.total_dedup += dedup_fail;
|
||||
stats.total_valid_packets += num_valid_packets;
|
||||
stats.total_excess_fail += excess_fail;
|
||||
stats.total_shrink_time += shrink_time.as_us() as usize;
|
||||
stats.total_shrinks += total_shrinks;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -342,6 +364,12 @@ impl SigVerifyStage {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::sigverify::TransactionSigVerifier;
|
||||
use crate::sigverify_stage::timing::duration_as_ms;
|
||||
use crossbeam_channel::unbounded;
|
||||
use solana_perf::packet::to_packet_batches;
|
||||
use solana_perf::test_tx::test_tx;
|
||||
use std::sync::mpsc::channel;
|
||||
use {super::*, solana_perf::packet::Packet};
|
||||
|
||||
fn count_non_discard(packet_batches: &[PacketBatch]) -> usize {
|
||||
@@ -370,4 +398,58 @@ mod tests {
|
||||
assert!(!batches[0].packets[0].meta.discard());
|
||||
assert!(!batches[0].packets[3].meta.discard());
|
||||
}
|
||||
fn gen_batches(use_same_tx: bool) -> Vec<PacketBatch> {
|
||||
let len = 4096;
|
||||
let chunk_size = 1024;
|
||||
if use_same_tx {
|
||||
let tx = test_tx();
|
||||
to_packet_batches(&vec![tx; len], chunk_size)
|
||||
} else {
|
||||
let txs: Vec<_> = (0..len).map(|_| test_tx()).collect();
|
||||
to_packet_batches(&txs, chunk_size)
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sigverify_stage() {
|
||||
solana_logger::setup();
|
||||
trace!("start");
|
||||
let (packet_s, packet_r) = channel();
|
||||
let (verified_s, verified_r) = unbounded();
|
||||
let verifier = TransactionSigVerifier::default();
|
||||
let stage = SigVerifyStage::new(packet_r, verified_s, verifier);
|
||||
|
||||
let use_same_tx = true;
|
||||
let now = Instant::now();
|
||||
let mut batches = gen_batches(use_same_tx);
|
||||
trace!(
|
||||
"starting... generation took: {} ms batches: {}",
|
||||
duration_as_ms(&now.elapsed()),
|
||||
batches.len()
|
||||
);
|
||||
|
||||
let mut sent_len = 0;
|
||||
for _ in 0..batches.len() {
|
||||
if let Some(batch) = batches.pop() {
|
||||
sent_len += batch.packets.len();
|
||||
packet_s.send(batch).unwrap();
|
||||
}
|
||||
}
|
||||
let mut received = 0;
|
||||
trace!("sent: {}", sent_len);
|
||||
loop {
|
||||
if let Ok(mut verifieds) = verified_r.recv_timeout(Duration::from_millis(10)) {
|
||||
while let Some(v) = verifieds.pop() {
|
||||
received += v.packets.len();
|
||||
batches.push(v);
|
||||
}
|
||||
if use_same_tx || received >= sent_len {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
trace!("received: {}", received);
|
||||
drop(packet_s);
|
||||
stage.join().unwrap();
|
||||
}
|
||||
}
|
||||
|
@@ -294,6 +294,7 @@ pub struct Validator {
|
||||
tvu: Tvu,
|
||||
ip_echo_server: Option<solana_net_utils::IpEchoServer>,
|
||||
pub cluster_info: Arc<ClusterInfo>,
|
||||
pub bank_forks: Arc<RwLock<BankForks>>,
|
||||
accountsdb_repl_service: Option<AccountsDbReplService>,
|
||||
accountsdb_plugin_service: Option<AccountsDbPluginService>,
|
||||
}
|
||||
@@ -911,7 +912,7 @@ impl Validator {
|
||||
&exit,
|
||||
node.info.shred_version,
|
||||
vote_tracker,
|
||||
bank_forks,
|
||||
bank_forks.clone(),
|
||||
verified_vote_sender,
|
||||
gossip_verified_vote_hash_sender,
|
||||
replay_vote_receiver,
|
||||
@@ -947,6 +948,7 @@ impl Validator {
|
||||
ip_echo_server,
|
||||
validator_exit: config.validator_exit.clone(),
|
||||
cluster_info,
|
||||
bank_forks,
|
||||
accountsdb_repl_service,
|
||||
accountsdb_plugin_service,
|
||||
}
|
||||
@@ -988,6 +990,7 @@ impl Validator {
|
||||
}
|
||||
|
||||
pub fn join(self) {
|
||||
drop(self.bank_forks);
|
||||
drop(self.cluster_info);
|
||||
|
||||
self.poh_service.join().expect("poh_service");
|
||||
|
@@ -147,7 +147,7 @@ sendAndConfirmTransaction(
|
||||
);
|
||||
```
|
||||
|
||||
The above code takes in a `TransactionInstruction` using `SystemProgram`, creates a `Transaction`, and sends it over the network. You use `Connection` in order to define with Solana network you are connecting to, namely `mainnet-beta`, `testnet`, or `devnet`.
|
||||
The above code takes in a `TransactionInstruction` using `SystemProgram`, creates a `Transaction`, and sends it over the network. You use `Connection` in order to define which Solana network you are connecting to, namely `mainnet-beta`, `testnet`, or `devnet`.
|
||||
|
||||
### Interacting with Custom Programs
|
||||
|
||||
|
@@ -98,7 +98,7 @@ Unstable methods may see breaking changes in patch releases and may not be suppo
|
||||
- [getConfirmedBlocks](jsonrpc-api.md#getconfirmedblocks)
|
||||
- [getConfirmedBlocksWithLimit](jsonrpc-api.md#getconfirmedblockswithlimit)
|
||||
- [getConfirmedSignaturesForAddress2](jsonrpc-api.md#getconfirmedsignaturesforaddress2)
|
||||
- [getConfirmedTransaction](jsonrpc-api.md#getconfirmedtransact)
|
||||
- [getConfirmedTransaction](jsonrpc-api.md#getconfirmedtransaction)
|
||||
- [getFeeCalculatorForBlockhash](jsonrpc-api.md#getfeecalculatorforblockhash)
|
||||
- [getFeeRateGovernor](jsonrpc-api.md#getfeerategovernor)
|
||||
- [getFees](jsonrpc-api.md#getfees)
|
||||
@@ -2949,7 +2949,7 @@ curl http://localhost:8899 -X POST -H "Content-Type: application/json" -d '
|
||||
|
||||
Result:
|
||||
```json
|
||||
{"jsonrpc":"2.0","result":{"solana-core": "1.9.6"},"id":1}
|
||||
{"jsonrpc":"2.0","result":{"solana-core": "1.9.7"},"id":1}
|
||||
```
|
||||
|
||||
### getVoteAccounts
|
||||
@@ -3191,7 +3191,7 @@ Before submitting, the following preflight checks are performed:
|
||||
preflight commitment to avoid confusing behavior.
|
||||
|
||||
The returned signature is the first signature in the transaction, which
|
||||
is used to identify the transaction ([transaction id](../../terminology.md#transanction-id)).
|
||||
is used to identify the transaction ([transaction id](../../terminology.md#transaction-id)).
|
||||
This identifier can be easily extracted from the transaction data before
|
||||
submission.
|
||||
|
||||
@@ -3207,7 +3207,7 @@ submission.
|
||||
|
||||
#### Results:
|
||||
|
||||
- `<string>` - First Transaction Signature embedded in the transaction, as base-58 encoded string ([transaction id](../../terminology.md#transanction-id))
|
||||
- `<string>` - First Transaction Signature embedded in the transaction, as base-58 encoded string ([transaction id](../../terminology.md#transaction-id))
|
||||
|
||||
#### Example:
|
||||
|
||||
@@ -5093,7 +5093,7 @@ Result:
|
||||
|
||||
### getRecentBlockhash
|
||||
|
||||
**DEPRECATED: Please use [getFeeForMessage](jsonrpc-api.md#getfeeformessage) instead**
|
||||
**DEPRECATED: Please use [getLatestBlockhash](jsonrpc-api.md#getlatestblockhash) instead**
|
||||
This method is expected to be removed in solana-core v2.0
|
||||
|
||||
Returns a recent block hash from the ledger, and a fee schedule that can be used to compute the cost of submitting a transaction using it.
|
||||
|
@@ -140,7 +140,7 @@ the [runtime enforcement
|
||||
policy](developing/programming-model/accounts.md#policy). When an instruction
|
||||
reference the same account multiple times there may be duplicate
|
||||
`SolAccountInfo` entries in the array but they both point back to the original
|
||||
input byte array. A program should handle these case delicately to avoid
|
||||
input byte array. A program should handle these cases delicately to avoid
|
||||
overlapping read/writes to the same buffer. If a program implements their own
|
||||
deserialization function care should be taken to handle duplicate accounts
|
||||
appropriately.
|
||||
|
@@ -48,8 +48,12 @@ The policy is as follows:
|
||||
To prevent a program from abusing computation resources each instruction in a
|
||||
transaction is given a compute budget. The budget consists of computation units
|
||||
that are consumed as the program performs various operations and bounds that the
|
||||
program may not exceed. When the program consumes its entire budget or exceeds
|
||||
a bound then the runtime halts the program and returns an error.
|
||||
program may not exceed. When the program consumes its entire budget or exceeds a
|
||||
bound then the runtime halts the program and returns an error.
|
||||
|
||||
Note: The compute budget currently applies per-instruction but is moving toward
|
||||
a per-transaction model. For more information see [Transaction-wide Compute
|
||||
Budget](#transaction-wide-compute-buget).
|
||||
|
||||
The following operations incur a compute cost:
|
||||
|
||||
@@ -60,12 +64,12 @@ The following operations incur a compute cost:
|
||||
- cross-program invocations
|
||||
- ...
|
||||
|
||||
For cross-program invocations the programs invoked inherit the budget of their
|
||||
For cross-program invocations, the programs invoked inherit the budget of their
|
||||
parent. If an invoked program consume the budget or exceeds a bound the entire
|
||||
invocation chain and the parent are halted.
|
||||
invocation chain is halted.
|
||||
|
||||
The current [compute
|
||||
budget](https://github.com/solana-labs/solana/blob/d3a3a7548c857f26ec2cb10e270da72d373020ec/sdk/src/process_instruction.rs#L65)
|
||||
budget](https://github.com/solana-labs/solana/blob/0224a8b127ace4c6453dd6492a38c66cb999abd2/sdk/src/compute_budget.rs#L102)
|
||||
can be found in the Solana SDK.
|
||||
|
||||
For example, if the current budget is:
|
||||
@@ -80,6 +84,7 @@ max_invoke_depth: 4,
|
||||
max_call_depth: 64,
|
||||
stack_frame_size: 4096,
|
||||
log_pubkey_units: 100,
|
||||
...
|
||||
```
|
||||
|
||||
Then the program
|
||||
@@ -90,7 +95,7 @@ Then the program
|
||||
- Can not exceed a BPF call depth of 64
|
||||
- Cannot exceed 4 levels of cross-program invocations.
|
||||
|
||||
Since the compute budget is consumed incrementally as the program executes the
|
||||
Since the compute budget is consumed incrementally as the program executes, the
|
||||
total budget consumption will be a combination of the various costs of the
|
||||
operations it performs.
|
||||
|
||||
@@ -98,12 +103,38 @@ At runtime a program may log how much of the compute budget remains. See
|
||||
[debugging](developing/on-chain-programs/debugging.md#monitoring-compute-budget-consumption)
|
||||
for more information.
|
||||
|
||||
The budget values are conditional on feature enablement, take a look at the
|
||||
compute budget's
|
||||
[new](https://github.com/solana-labs/solana/blob/d3a3a7548c857f26ec2cb10e270da72d373020ec/sdk/src/process_instruction.rs#L97)
|
||||
function to find out how the budget is constructed. An understanding of how
|
||||
[features](runtime.md#features) work and what features are enabled on the
|
||||
cluster being used are required to determine the current budget's values.
|
||||
## Transaction-wide Compute Budget
|
||||
|
||||
Transactions are processed as a single entity and are the primary unit of block
|
||||
scheduling. In order to facilitate better block scheduling and account for the
|
||||
computational cost of each transaction, the compute budget is moving to a
|
||||
transaction-wide budget rather than per-instruction.
|
||||
|
||||
For information on what the compute budget is and how it is applied see [Compute
|
||||
Budget](#compute-budget).
|
||||
|
||||
With a transaction-wide compute budget the `max_units` cap is applied to the
|
||||
entire transaction rather than to each instruction within the transaction. The
|
||||
default number of maximum units remains at 200k which means the sum of the
|
||||
compute units used by each instruction in the transaction must not exceed that
|
||||
value. The number of maximum units allows is intentionally kept small to
|
||||
facilitate optimized programs and form the bases for a minimum fee level.
|
||||
|
||||
There are a lot of uses cases that require more than 200k units
|
||||
transaction-wide. To enable these uses cases transactions can include a
|
||||
[``ComputeBudgetInstruction`](https://github.com/solana-labs/solana/blob/0224a8b127ace4c6453dd6492a38c66cb999abd2/sdk/src/compute_budget.rs#L44)
|
||||
requesting a higher compute unit cap. Higher compute caps will be charged
|
||||
higher fees.
|
||||
|
||||
Compute Budget instructions don't require any accounts and must lie in the first
|
||||
3 instructions of a transaction otherwise they will be ignored.
|
||||
|
||||
The `ComputeBudgetInstruction::request_units` function can be used to crate
|
||||
these instructions:
|
||||
|
||||
```rust
|
||||
let instruction = ComputeBudgetInstruction::request_units(300_000);
|
||||
```
|
||||
|
||||
## New Features
|
||||
|
||||
|
@@ -150,7 +150,7 @@ found in the [Accounts](accounts.md) section.
|
||||
|
||||
### Instruction data
|
||||
|
||||
Each instruction caries a general purpose byte array that is passed to the
|
||||
Each instruction carries a general purpose byte array that is passed to the
|
||||
program along with the accounts. The contents of the instruction data is program
|
||||
specific and typically used to convey what operations the program should
|
||||
perform, and any additional information those operations may need above and
|
||||
|
@@ -181,21 +181,21 @@ To track all the deposit accounts for your exchange, poll for each confirmed
|
||||
block and inspect for addresses of interest, using the JSON-RPC service of your
|
||||
Solana API node.
|
||||
|
||||
- To identify which blocks are available, send a [`getConfirmedBlocks` request](developing/clients/jsonrpc-api.md#getconfirmedblocks),
|
||||
- To identify which blocks are available, send a [`getBlocks` request](developing/clients/jsonrpc-api.md#getblocks),
|
||||
passing the last block you have already processed as the start-slot parameter:
|
||||
|
||||
```bash
|
||||
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0","id":1,"method":"getConfirmedBlocks","params":[5]}' localhost:8899
|
||||
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0","id":1,"method":"getBlocks","params":[5]}' localhost:8899
|
||||
|
||||
{"jsonrpc":"2.0","result":[5,6,8,9,11],"id":1}
|
||||
```
|
||||
|
||||
Not every slot produces a block, so there may be gaps in the sequence of integers.
|
||||
|
||||
- For each block, request its contents with a [`getConfirmedBlock` request](developing/clients/jsonrpc-api.md#getconfirmedblock):
|
||||
- For each block, request its contents with a [`getBlock` request](developing/clients/jsonrpc-api.md#getblock):
|
||||
|
||||
```bash
|
||||
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0","id":1,"method":"getConfirmedBlock","params":[5, "json"]}' localhost:8899
|
||||
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0","id":1,"method":"getBlock","params":[5, "json"]}' localhost:8899
|
||||
|
||||
{
|
||||
"jsonrpc": "2.0",
|
||||
@@ -278,11 +278,11 @@ generally _not_ a viable method for tracking all your deposit addresses over all
|
||||
slots, but may be useful for examining a few accounts for a specific period of
|
||||
time.
|
||||
|
||||
- Send a [`getConfirmedSignaturesForAddress2`](developing/clients/jsonrpc-api.md#getconfirmedsignaturesforaddress2)
|
||||
- Send a [`getSignaturesForAddress`](developing/clients/jsonrpc-api.md#getsignaturesforaddress)
|
||||
request to the api node:
|
||||
|
||||
```bash
|
||||
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0","id":1,"method":"getConfirmedSignaturesForAddress2","params":["6H94zdiaYfRfPfKjYLjyr2VFBg6JHXygy84r3qhc3NsC", {"limit": 3}]}' localhost:8899
|
||||
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0","id":1,"method":"getSignaturesForAddress","params":["6H94zdiaYfRfPfKjYLjyr2VFBg6JHXygy84r3qhc3NsC", {"limit": 3}]}' localhost:8899
|
||||
|
||||
{
|
||||
"jsonrpc": "2.0",
|
||||
@@ -311,10 +311,10 @@ curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0","id":1,"m
|
||||
```
|
||||
|
||||
- For each signature returned, get the transaction details by sending a
|
||||
[`getConfirmedTransaction`](developing/clients/jsonrpc-api.md#getconfirmedtransaction) request:
|
||||
[`getTransaction`](developing/clients/jsonrpc-api.md#gettransaction) request:
|
||||
|
||||
```bash
|
||||
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0","id":1,"method":"getConfirmedTransaction","params":["dhjhJp2V2ybQGVfELWM1aZy98guVVsxRCB5KhNiXFjCBMK5KEyzV8smhkVvs3xwkAug31KnpzJpiNPtcD5bG1t6", "json"]}' localhost:8899
|
||||
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0","id":1,"method":"getTransaction","params":["dhjhJp2V2ybQGVfELWM1aZy98guVVsxRCB5KhNiXFjCBMK5KEyzV8smhkVvs3xwkAug31KnpzJpiNPtcD5bG1t6", "json"]}' localhost:8899
|
||||
|
||||
// Result
|
||||
{
|
||||
@@ -714,14 +714,12 @@ wallets using the
|
||||
scheme and that _only_ deposits from ATA addresses be accepted.
|
||||
|
||||
Monitoring for deposit transactions should follow the [block polling](#poll-for-blocks)
|
||||
method described above. Each new block should be scanned for successful transactions
|
||||
issuing SPL Token [Transfer](https://github.com/solana-labs/solana-program-library/blob/fc0d6a2db79bd6499f04b9be7ead0c400283845e/token/program/src/instruction.rs#L105)
|
||||
or [TransferChecked](https://github.com/solana-labs/solana-program-library/blob/fc0d6a2db79bd6499f04b9be7ead0c400283845e/token/program/src/instruction.rs#L268)
|
||||
instructions referencing user accounts. It is possible that a transfer is initiated
|
||||
by a smart contract via [Cross Program Invocation](/developing/programming-model/calling-between-programs#cross-program-invocations),
|
||||
so [inner instructions](/terminology#inner-instruction) must be checked as well.
|
||||
The `preTokenBalance` and `postTokenBalance` fields from the transaction's metadata
|
||||
must then be used to determine the effective balance change.
|
||||
method described above. Each new block should be scanned for successful
|
||||
transactions referencing user token-account derived addresses. The
|
||||
`preTokenBalance` and `postTokenBalance` fields from the transaction's metadata
|
||||
must then be used to determine the effective balance change. These fields will
|
||||
identify the token mint and account owner (main wallet address) of the affected
|
||||
account.
|
||||
|
||||
### Withdrawing
|
||||
|
||||
@@ -730,7 +728,10 @@ The withdrawal address a user provides must be the that of their SOL wallet.
|
||||
Before executing a withdrawal [transfer](#token-transfers),
|
||||
the exchange should check the address as
|
||||
[described above](#validating-user-supplied-account-addresses-for-withdrawals).
|
||||
Additionally this address must be owned by the System Program and have no account data. If the address has no SOL balance, user confirmation should be obtained before proceeding with the withdrawal. All other withdrawal addresses must be rejected.
|
||||
Additionally this address must be owned by the System Program and have no
|
||||
account data. If the address has no SOL balance, user confirmation should be
|
||||
obtained before proceeding with the withdrawal. All other withdrawal addresses
|
||||
must be rejected.
|
||||
|
||||
From the withdrawal address, the [Associated Token Account](https://spl.solana.com/associated-token-account)
|
||||
(ATA) for the correct mint is derived and the transfer issued to that account via a
|
||||
|
@@ -100,7 +100,7 @@ any traversal issues on their own.
|
||||
|
||||
#### Required
|
||||
- 8000-10000 TCP/UDP - P2P protocols (gossip, turbine, repair, etc). This can
|
||||
be limited to any free 12 port range with `--dynamic-port-range`
|
||||
be limited to any free 13 port range with `--dynamic-port-range`
|
||||
|
||||
#### Optional
|
||||
For security purposes, it is not suggested that the following ports be open to
|
||||
|
@@ -2,7 +2,7 @@
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2021"
|
||||
name = "solana-dos"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -13,15 +13,15 @@ bincode = "1.3.3"
|
||||
clap = "2.33.1"
|
||||
log = "0.4.14"
|
||||
rand = "0.7.0"
|
||||
solana-core = { path = "../core", version = "=1.9.6" }
|
||||
solana-gossip = { path = "../gossip", version = "=1.9.6" }
|
||||
solana-logger = { path = "../logger", version = "=1.9.6" }
|
||||
solana-net-utils = { path = "../net-utils", version = "=1.9.6" }
|
||||
solana-perf = { path = "../perf", version = "=1.9.6" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.6" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.9.6" }
|
||||
solana-version = { path = "../version", version = "=1.9.6" }
|
||||
solana-client = { path = "../client", version = "=1.9.6" }
|
||||
solana-core = { path = "../core", version = "=1.9.7" }
|
||||
solana-gossip = { path = "../gossip", version = "=1.9.7" }
|
||||
solana-logger = { path = "../logger", version = "=1.9.7" }
|
||||
solana-net-utils = { path = "../net-utils", version = "=1.9.7" }
|
||||
solana-perf = { path = "../perf", version = "=1.9.7" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.7" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.9.7" }
|
||||
solana-version = { path = "../version", version = "=1.9.7" }
|
||||
solana-client = { path = "../client", version = "=1.9.7" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-download-utils"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
description = "Solana Download Utils"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -14,8 +14,8 @@ console = "0.15.0"
|
||||
indicatif = "0.16.2"
|
||||
log = "0.4.14"
|
||||
reqwest = { version = "0.11.6", default-features = false, features = ["blocking", "rustls-tls", "json"] }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.6" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.9.6" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.7" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.9.7" }
|
||||
|
||||
[lib]
|
||||
crate-type = ["lib"]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-entry"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
description = "Solana Entry"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -16,17 +16,17 @@ log = "0.4.11"
|
||||
rand = "0.7.0"
|
||||
rayon = "1.5.1"
|
||||
serde = "1.0.130"
|
||||
solana-measure = { path = "../measure", version = "=1.9.6" }
|
||||
solana-merkle-tree = { path = "../merkle-tree", version = "=1.9.6" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.9.6" }
|
||||
solana-perf = { path = "../perf", version = "=1.9.6" }
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "=1.9.6" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.6" }
|
||||
solana-measure = { path = "../measure", version = "=1.9.7" }
|
||||
solana-merkle-tree = { path = "../merkle-tree", version = "=1.9.7" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.9.7" }
|
||||
solana-perf = { path = "../perf", version = "=1.9.7" }
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "=1.9.7" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.7" }
|
||||
bincode = "1.3.3"
|
||||
|
||||
[dev-dependencies]
|
||||
matches = "0.1.9"
|
||||
solana-logger = { path = "../logger", version = "=1.9.6" }
|
||||
solana-logger = { path = "../logger", version = "=1.9.7" }
|
||||
|
||||
[lib]
|
||||
crate-type = ["lib"]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-faucet"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
description = "Solana Faucet"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -16,12 +16,12 @@ clap = "2.33"
|
||||
log = "0.4.14"
|
||||
serde = "1.0.130"
|
||||
serde_derive = "1.0.103"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.9.6" }
|
||||
solana-cli-config = { path = "../cli-config", version = "=1.9.6" }
|
||||
solana-logger = { path = "../logger", version = "=1.9.6" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.9.6" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.6" }
|
||||
solana-version = { path = "../version", version = "=1.9.6" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.9.7" }
|
||||
solana-cli-config = { path = "../cli-config", version = "=1.9.7" }
|
||||
solana-logger = { path = "../logger", version = "=1.9.7" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.9.7" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.7" }
|
||||
solana-version = { path = "../version", version = "=1.9.7" }
|
||||
spl-memo = { version = "=3.0.1", features = ["no-entrypoint"] }
|
||||
thiserror = "1.0"
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
|
@@ -20,7 +20,7 @@ async fn main() {
|
||||
let default_keypair = solana_cli_config::Config::default().keypair_path;
|
||||
|
||||
solana_logger::setup_with_default("solana=info");
|
||||
solana_metrics::set_panic_hook("faucet");
|
||||
solana_metrics::set_panic_hook("faucet", /*version:*/ None);
|
||||
let matches = App::new(crate_name!())
|
||||
.about(crate_description!())
|
||||
.version(solana_version::version!())
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-frozen-abi"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
description = "Solana Frozen ABI"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -16,11 +16,11 @@ log = "0.4.14"
|
||||
serde = "1.0.130"
|
||||
serde_derive = "1.0.103"
|
||||
sha2 = "0.9.8"
|
||||
solana-frozen-abi-macro = { path = "macro", version = "=1.9.6" }
|
||||
solana-frozen-abi-macro = { path = "macro", version = "=1.9.7" }
|
||||
thiserror = "1.0"
|
||||
|
||||
[target.'cfg(not(target_arch = "bpf"))'.dependencies]
|
||||
solana-logger = { path = "../logger", version = "=1.9.6" }
|
||||
solana-logger = { path = "../logger", version = "=1.9.7" }
|
||||
generic-array = { version = "0.14.4", default-features = false, features = ["serde", "more_lengths"]}
|
||||
memmap2 = "0.5.0"
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-frozen-abi-macro"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
description = "Solana Frozen ABI Macro"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-genesis-utils"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
description = "Solana Genesis Utils"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -10,9 +10,9 @@ documentation = "https://docs.rs/solana-download-utils"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.6" }
|
||||
solana-download-utils = { path = "../download-utils", version = "=1.9.6" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.9.6" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.7" }
|
||||
solana-download-utils = { path = "../download-utils", version = "=1.9.7" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.9.7" }
|
||||
|
||||
[lib]
|
||||
crate-type = ["lib"]
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2021"
|
||||
name = "solana-genesis"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -15,16 +15,16 @@ clap = "2.33.1"
|
||||
serde = "1.0.130"
|
||||
serde_json = "1.0.72"
|
||||
serde_yaml = "0.8.21"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.9.6" }
|
||||
solana-cli-config = { path = "../cli-config", version = "=1.9.6" }
|
||||
solana-entry = { path = "../entry", version = "=1.9.6" }
|
||||
solana-ledger = { path = "../ledger", version = "=1.9.6" }
|
||||
solana-logger = { path = "../logger", version = "=1.9.6" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.9.6" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.6" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "=1.9.6" }
|
||||
solana-version = { path = "../version", version = "=1.9.6" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.9.6" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.9.7" }
|
||||
solana-cli-config = { path = "../cli-config", version = "=1.9.7" }
|
||||
solana-entry = { path = "../entry", version = "=1.9.7" }
|
||||
solana-ledger = { path = "../ledger", version = "=1.9.7" }
|
||||
solana-logger = { path = "../logger", version = "=1.9.7" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.9.7" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.7" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "=1.9.7" }
|
||||
solana-version = { path = "../version", version = "=1.9.7" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.9.7" }
|
||||
tempfile = "3.2.0"
|
||||
|
||||
[[bin]]
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2021"
|
||||
name = "solana-gossip"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -26,24 +26,24 @@ rayon = "1.5.1"
|
||||
serde = "1.0.130"
|
||||
serde_bytes = "0.11"
|
||||
serde_derive = "1.0.103"
|
||||
solana-bloom = { path = "../bloom", version = "=1.9.6" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.9.6" }
|
||||
solana-client = { path = "../client", version = "=1.9.6" }
|
||||
solana-entry = { path = "../entry", version = "=1.9.6" }
|
||||
solana-frozen-abi = { path = "../frozen-abi", version = "=1.9.6" }
|
||||
solana-frozen-abi-macro = { path = "../frozen-abi/macro", version = "=1.9.6" }
|
||||
solana-ledger = { path = "../ledger", version = "=1.9.6" }
|
||||
solana-logger = { path = "../logger", version = "=1.9.6" }
|
||||
solana-measure = { path = "../measure", version = "=1.9.6" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.9.6" }
|
||||
solana-net-utils = { path = "../net-utils", version = "=1.9.6" }
|
||||
solana-perf = { path = "../perf", version = "=1.9.6" }
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "=1.9.6" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.9.6" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.9.6" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.6" }
|
||||
solana-version = { path = "../version", version = "=1.9.6" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.9.6" }
|
||||
solana-bloom = { path = "../bloom", version = "=1.9.7" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.9.7" }
|
||||
solana-client = { path = "../client", version = "=1.9.7" }
|
||||
solana-entry = { path = "../entry", version = "=1.9.7" }
|
||||
solana-frozen-abi = { path = "../frozen-abi", version = "=1.9.7" }
|
||||
solana-frozen-abi-macro = { path = "../frozen-abi/macro", version = "=1.9.7" }
|
||||
solana-ledger = { path = "../ledger", version = "=1.9.7" }
|
||||
solana-logger = { path = "../logger", version = "=1.9.7" }
|
||||
solana-measure = { path = "../measure", version = "=1.9.7" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.9.7" }
|
||||
solana-net-utils = { path = "../net-utils", version = "=1.9.7" }
|
||||
solana-perf = { path = "../perf", version = "=1.9.7" }
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "=1.9.7" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.9.7" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.9.7" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.7" }
|
||||
solana-version = { path = "../version", version = "=1.9.7" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.9.7" }
|
||||
thiserror = "1.0"
|
||||
|
||||
[dev-dependencies]
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2021"
|
||||
name = "solana-install"
|
||||
description = "The solana cluster software installer"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -24,12 +24,12 @@ nix = "0.23.0"
|
||||
reqwest = { version = "0.11.6", default-features = false, features = ["blocking", "rustls-tls", "json"] }
|
||||
serde = { version = "1.0.130", features = ["derive"] }
|
||||
serde_yaml = "0.8.21"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.9.6" }
|
||||
solana-client = { path = "../client", version = "=1.9.6" }
|
||||
solana-config-program = { path = "../programs/config", version = "=1.9.6" }
|
||||
solana-logger = { path = "../logger", version = "=1.9.6" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.6" }
|
||||
solana-version = { path = "../version", version = "=1.9.6" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.9.7" }
|
||||
solana-client = { path = "../client", version = "=1.9.7" }
|
||||
solana-config-program = { path = "../programs/config", version = "=1.9.7" }
|
||||
solana-logger = { path = "../logger", version = "=1.9.7" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.7" }
|
||||
solana-version = { path = "../version", version = "=1.9.7" }
|
||||
semver = "1.0.4"
|
||||
tar = "0.4.37"
|
||||
tempfile = "3.2.0"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-keygen"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
description = "Solana key generation utility"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -14,11 +14,11 @@ bs58 = "0.4.0"
|
||||
clap = "2.33"
|
||||
dirs-next = "2.0.0"
|
||||
num_cpus = "1.13.0"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.9.6" }
|
||||
solana-cli-config = { path = "../cli-config", version = "=1.9.6" }
|
||||
solana-remote-wallet = { path = "../remote-wallet", version = "=1.9.6" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.6" }
|
||||
solana-version = { path = "../version", version = "=1.9.6" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.9.7" }
|
||||
solana-cli-config = { path = "../cli-config", version = "=1.9.7" }
|
||||
solana-remote-wallet = { path = "../remote-wallet", version = "=1.9.7" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.7" }
|
||||
solana-version = { path = "../version", version = "=1.9.7" }
|
||||
tiny-bip39 = "0.8.2"
|
||||
|
||||
[[bin]]
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2021"
|
||||
name = "solana-ledger-tool"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -22,20 +22,20 @@ regex = "1"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0.72"
|
||||
serde_yaml = "0.8.21"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.9.6" }
|
||||
solana-cli-output = { path = "../cli-output", version = "=1.9.6" }
|
||||
solana-core = { path = "../core", version = "=1.9.6" }
|
||||
solana-entry = { path = "../entry", version = "=1.9.6" }
|
||||
solana-ledger = { path = "../ledger", version = "=1.9.6" }
|
||||
solana-logger = { path = "../logger", version = "=1.9.6" }
|
||||
solana-measure = { path = "../measure", version = "=1.9.6" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.9.6" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.6" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "=1.9.6" }
|
||||
solana-storage-bigtable = { path = "../storage-bigtable", version = "=1.9.6" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.9.6" }
|
||||
solana-version = { path = "../version", version = "=1.9.6" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.9.6" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.9.7" }
|
||||
solana-cli-output = { path = "../cli-output", version = "=1.9.7" }
|
||||
solana-core = { path = "../core", version = "=1.9.7" }
|
||||
solana-entry = { path = "../entry", version = "=1.9.7" }
|
||||
solana-ledger = { path = "../ledger", version = "=1.9.7" }
|
||||
solana-logger = { path = "../logger", version = "=1.9.7" }
|
||||
solana-measure = { path = "../measure", version = "=1.9.7" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.9.7" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.7" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "=1.9.7" }
|
||||
solana-storage-bigtable = { path = "../storage-bigtable", version = "=1.9.7" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.9.7" }
|
||||
solana-version = { path = "../version", version = "=1.9.7" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.9.7" }
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
|
||||
[target.'cfg(not(target_env = "msvc"))'.dependencies]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-ledger"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
description = "Solana ledger"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -31,22 +31,22 @@ rayon = "1.5.1"
|
||||
serde = "1.0.130"
|
||||
serde_bytes = "0.11.5"
|
||||
sha2 = "0.9.8"
|
||||
solana-bpf-loader-program = { path = "../programs/bpf_loader", version = "=1.9.6" }
|
||||
solana-entry = { path = "../entry", version = "=1.9.6" }
|
||||
solana-frozen-abi = { path = "../frozen-abi", version = "=1.9.6" }
|
||||
solana-frozen-abi-macro = { path = "../frozen-abi/macro", version = "=1.9.6" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.9.6" }
|
||||
solana-logger = { path = "../logger", version = "=1.9.6" }
|
||||
solana-measure = { path = "../measure", version = "=1.9.6" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.9.6" }
|
||||
solana-perf = { path = "../perf", version = "=1.9.6" }
|
||||
solana-program-runtime = { path = "../program-runtime", version = "=1.9.6" }
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "=1.9.6" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.9.6" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.6" }
|
||||
solana-storage-bigtable = { path = "../storage-bigtable", version = "=1.9.6" }
|
||||
solana-storage-proto = { path = "../storage-proto", version = "=1.9.6" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.9.6" }
|
||||
solana-bpf-loader-program = { path = "../programs/bpf_loader", version = "=1.9.7" }
|
||||
solana-entry = { path = "../entry", version = "=1.9.7" }
|
||||
solana-frozen-abi = { path = "../frozen-abi", version = "=1.9.7" }
|
||||
solana-frozen-abi-macro = { path = "../frozen-abi/macro", version = "=1.9.7" }
|
||||
solana-transaction-status = { path = "../transaction-status", version = "=1.9.7" }
|
||||
solana-logger = { path = "../logger", version = "=1.9.7" }
|
||||
solana-measure = { path = "../measure", version = "=1.9.7" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.9.7" }
|
||||
solana-perf = { path = "../perf", version = "=1.9.7" }
|
||||
solana-program-runtime = { path = "../program-runtime", version = "=1.9.7" }
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "=1.9.7" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.9.7" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.7" }
|
||||
solana-storage-bigtable = { path = "../storage-bigtable", version = "=1.9.7" }
|
||||
solana-storage-proto = { path = "../storage-proto", version = "=1.9.7" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.9.7" }
|
||||
tempfile = "3.2.0"
|
||||
thiserror = "1.0"
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
@@ -64,7 +64,7 @@ features = ["lz4"]
|
||||
[dev-dependencies]
|
||||
assert_matches = "1.5.0"
|
||||
matches = "0.1.9"
|
||||
solana-account-decoder = { path = "../account-decoder", version = "=1.9.6" }
|
||||
solana-account-decoder = { path = "../account-decoder", version = "=1.9.7" }
|
||||
|
||||
[build-dependencies]
|
||||
rustc_version = "0.4"
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2021"
|
||||
name = "solana-local-cluster"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -17,19 +17,19 @@ fs_extra = "1.2.0"
|
||||
log = "0.4.14"
|
||||
rand = "0.7.0"
|
||||
rayon = "1.5.1"
|
||||
solana-config-program = { path = "../programs/config", version = "=1.9.6" }
|
||||
solana-core = { path = "../core", version = "=1.9.6" }
|
||||
solana-client = { path = "../client", version = "=1.9.6" }
|
||||
solana-download-utils = { path = "../download-utils", version = "=1.9.6" }
|
||||
solana-entry = { path = "../entry", version = "=1.9.6" }
|
||||
solana-gossip = { path = "../gossip", version = "=1.9.6" }
|
||||
solana-ledger = { path = "../ledger", version = "=1.9.6" }
|
||||
solana-logger = { path = "../logger", version = "=1.9.6" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.9.6" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.6" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "=1.9.6" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.9.6" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.9.6" }
|
||||
solana-config-program = { path = "../programs/config", version = "=1.9.7" }
|
||||
solana-core = { path = "../core", version = "=1.9.7" }
|
||||
solana-client = { path = "../client", version = "=1.9.7" }
|
||||
solana-download-utils = { path = "../download-utils", version = "=1.9.7" }
|
||||
solana-entry = { path = "../entry", version = "=1.9.7" }
|
||||
solana-gossip = { path = "../gossip", version = "=1.9.7" }
|
||||
solana-ledger = { path = "../ledger", version = "=1.9.7" }
|
||||
solana-logger = { path = "../logger", version = "=1.9.7" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.9.7" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.7" }
|
||||
solana-stake-program = { path = "../programs/stake", version = "=1.9.7" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.9.7" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.9.7" }
|
||||
tempfile = "3.2.0"
|
||||
|
||||
[dev-dependencies]
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
edition = "2021"
|
||||
name = "solana-log-analyzer"
|
||||
description = "The solana cluster network analysis tool"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -14,8 +14,8 @@ byte-unit = "4.0.13"
|
||||
clap = "2.33.1"
|
||||
serde = "1.0.130"
|
||||
serde_json = "1.0.72"
|
||||
solana-logger = { path = "../logger", version = "=1.9.6" }
|
||||
solana-version = { path = "../version", version = "=1.9.6" }
|
||||
solana-logger = { path = "../logger", version = "=1.9.7" }
|
||||
solana-version = { path = "../version", version = "=1.9.7" }
|
||||
|
||||
[[bin]]
|
||||
name = "solana-log-analyzer"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-logger"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
description = "Solana Logger"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
|
@@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "solana-measure"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
homepage = "https://solana.com/"
|
||||
documentation = "https://docs.rs/solana-measure"
|
||||
readme = "../README.md"
|
||||
@@ -12,7 +12,7 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
log = "0.4.14"
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.6" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.7" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
@@ -2,7 +2,7 @@
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2021"
|
||||
name = "solana-merkle-root-bench"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -10,11 +10,11 @@ publish = false
|
||||
|
||||
[dependencies]
|
||||
log = "0.4.14"
|
||||
solana-logger = { path = "../logger", version = "=1.9.6" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.9.6" }
|
||||
solana-measure = { path = "../measure", version = "=1.9.6" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.6" }
|
||||
solana-version = { path = "../version", version = "=1.9.6" }
|
||||
solana-logger = { path = "../logger", version = "=1.9.7" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.9.7" }
|
||||
solana-measure = { path = "../measure", version = "=1.9.7" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.7" }
|
||||
solana-version = { path = "../version", version = "=1.9.7" }
|
||||
clap = "2.33.1"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-merkle-tree"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
description = "Solana Merkle Tree"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -10,7 +10,7 @@ documentation = "https://docs.rs/solana-merkle-tree"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
solana-program = { path = "../sdk/program", version = "=1.9.6" }
|
||||
solana-program = { path = "../sdk/program", version = "=1.9.7" }
|
||||
fast-math = "0.1"
|
||||
|
||||
# This can go once the BPF toolchain target Rust 1.42.0+
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-metrics"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
description = "Solana Metrics"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -15,7 +15,7 @@ gethostname = "0.2.1"
|
||||
lazy_static = "1.4.0"
|
||||
log = "0.4.14"
|
||||
reqwest = { version = "0.11.6", default-features = false, features = ["blocking", "rustls-tls", "json"] }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.6" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.7" }
|
||||
|
||||
[dev-dependencies]
|
||||
rand = "0.7.0"
|
||||
|
@@ -431,7 +431,7 @@ pub fn flush() {
|
||||
}
|
||||
|
||||
/// Hook the panic handler to generate a data point on each panic
|
||||
pub fn set_panic_hook(program: &'static str) {
|
||||
pub fn set_panic_hook(program: &'static str, version: Option<String>) {
|
||||
static SET_HOOK: Once = Once::new();
|
||||
SET_HOOK.call_once(|| {
|
||||
let default_hook = std::panic::take_hook();
|
||||
@@ -450,6 +450,7 @@ pub fn set_panic_hook(program: &'static str) {
|
||||
.add_field_i64("one", 1)
|
||||
.add_field_str("message", &ono.to_string())
|
||||
.add_field_str("location", &location)
|
||||
.add_field_str("version", version.as_ref().unwrap_or(&"".to_string()))
|
||||
.to_owned(),
|
||||
Level::Error,
|
||||
);
|
||||
|
@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2021"
|
||||
name = "solana-net-shaper"
|
||||
description = "The solana cluster network shaping tool"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -13,8 +13,8 @@ publish = false
|
||||
clap = "2.33.1"
|
||||
serde = "1.0.130"
|
||||
serde_json = "1.0.72"
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.9.6" }
|
||||
solana-logger = { path = "../logger", version = "=1.9.6" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "=1.9.7" }
|
||||
solana-logger = { path = "../logger", version = "=1.9.7" }
|
||||
rand = "0.7.0"
|
||||
|
||||
[[bin]]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-net-utils"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
description = "Solana Network Utilities"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -18,9 +18,9 @@ rand = "0.7.0"
|
||||
serde = "1.0.130"
|
||||
serde_derive = "1.0.103"
|
||||
socket2 = "0.4.2"
|
||||
solana-logger = { path = "../logger", version = "=1.9.6" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.6" }
|
||||
solana-version = { path = "../version", version = "=1.9.6" }
|
||||
solana-logger = { path = "../logger", version = "=1.9.7" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.7" }
|
||||
solana-version = { path = "../version", version = "=1.9.7" }
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
url = "2.2.2"
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-notifier"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
description = "Solana Notifier"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-perf"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
description = "Solana Performance APIs"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -22,12 +22,12 @@ log = "0.4.14"
|
||||
rand = "0.7.0"
|
||||
rayon = "1.5.1"
|
||||
serde = "1.0.130"
|
||||
solana-bloom = { path = "../bloom", version = "=1.9.6" }
|
||||
solana-logger = { path = "../logger", version = "=1.9.6" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.9.6" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.6" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.9.6" }
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "=1.9.6" }
|
||||
solana-bloom = { path = "../bloom", version = "=1.9.7" }
|
||||
solana-logger = { path = "../logger", version = "=1.9.7" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.9.7" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.7" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.9.7" }
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "=1.9.7" }
|
||||
|
||||
[target."cfg(target_os = \"linux\")".dependencies]
|
||||
caps = "0.5.3"
|
||||
|
86
perf/benches/shrink.rs
Normal file
86
perf/benches/shrink.rs
Normal file
@@ -0,0 +1,86 @@
|
||||
#![allow(clippy::integer_arithmetic)]
|
||||
#![feature(test)]
|
||||
|
||||
extern crate test;
|
||||
|
||||
use {
|
||||
rand::prelude::*,
|
||||
solana_perf::{
|
||||
packet::{to_packet_batches, PacketBatch, PACKETS_PER_BATCH},
|
||||
sigverify,
|
||||
},
|
||||
test::Bencher,
|
||||
};
|
||||
|
||||
const NUM_PACKETS: usize = 1024 * 4;
|
||||
|
||||
fn test_packet_with_size(size: usize, rng: &mut ThreadRng) -> Vec<u8> {
|
||||
// subtract 8 bytes because the length will get serialized as well
|
||||
(0..size.checked_sub(8).unwrap())
|
||||
.map(|_| rng.gen())
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn do_bench_shrink_packets(bencher: &mut Bencher, mut batches: Vec<PacketBatch>) {
|
||||
// verify packets
|
||||
bencher.iter(|| {
|
||||
let _ans = sigverify::shrink_batches(&mut batches);
|
||||
batches.iter_mut().for_each(|b| {
|
||||
b.packets
|
||||
.iter_mut()
|
||||
.for_each(|p| p.meta.set_discard(thread_rng().gen()))
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
#[ignore]
|
||||
fn bench_shrink_diff_small_packets(bencher: &mut Bencher) {
|
||||
let mut rng = rand::thread_rng();
|
||||
|
||||
let batches = to_packet_batches(
|
||||
&(0..NUM_PACKETS)
|
||||
.map(|_| test_packet_with_size(128, &mut rng))
|
||||
.collect::<Vec<_>>(),
|
||||
PACKETS_PER_BATCH,
|
||||
);
|
||||
|
||||
do_bench_shrink_packets(bencher, batches);
|
||||
}
|
||||
|
||||
#[bench]
|
||||
#[ignore]
|
||||
fn bench_shrink_diff_big_packets(bencher: &mut Bencher) {
|
||||
let mut rng = rand::thread_rng();
|
||||
|
||||
let batches = to_packet_batches(
|
||||
&(0..NUM_PACKETS)
|
||||
.map(|_| test_packet_with_size(1024, &mut rng))
|
||||
.collect::<Vec<_>>(),
|
||||
PACKETS_PER_BATCH,
|
||||
);
|
||||
|
||||
do_bench_shrink_packets(bencher, batches);
|
||||
}
|
||||
|
||||
#[bench]
|
||||
#[ignore]
|
||||
fn bench_shrink_count_packets(bencher: &mut Bencher) {
|
||||
let mut rng = rand::thread_rng();
|
||||
|
||||
let mut batches = to_packet_batches(
|
||||
&(0..NUM_PACKETS)
|
||||
.map(|_| test_packet_with_size(128, &mut rng))
|
||||
.collect::<Vec<_>>(),
|
||||
PACKETS_PER_BATCH,
|
||||
);
|
||||
batches.iter_mut().for_each(|b| {
|
||||
b.packets
|
||||
.iter_mut()
|
||||
.for_each(|p| p.meta.set_discard(thread_rng().gen()))
|
||||
});
|
||||
|
||||
bencher.iter(|| {
|
||||
let _ = sigverify::count_valid_packets(&batches);
|
||||
});
|
||||
}
|
@@ -167,6 +167,13 @@ pub fn count_packets_in_batches(batches: &[PacketBatch]) -> usize {
|
||||
batches.iter().map(|batch| batch.packets.len()).sum()
|
||||
}
|
||||
|
||||
pub fn count_valid_packets(batches: &[PacketBatch]) -> usize {
|
||||
batches
|
||||
.iter()
|
||||
.map(|batch| batch.packets.iter().filter(|p| !p.meta.discard()).count())
|
||||
.sum()
|
||||
}
|
||||
|
||||
// internal function to be unit-tested; should be used only by get_packet_offsets
|
||||
fn do_get_packet_offsets(
|
||||
packet: &Packet,
|
||||
@@ -492,6 +499,43 @@ impl Deduper {
|
||||
}
|
||||
}
|
||||
|
||||
//inplace shrink a batch of packets
|
||||
pub fn shrink_batches(batches: &mut Vec<PacketBatch>) -> usize {
|
||||
let mut valid_batch_ix = 0;
|
||||
let mut valid_packet_ix = 0;
|
||||
let mut last_valid_batch = 0;
|
||||
for batch_ix in 0..batches.len() {
|
||||
for packet_ix in 0..batches[batch_ix].packets.len() {
|
||||
if batches[batch_ix].packets[packet_ix].meta.discard() {
|
||||
continue;
|
||||
}
|
||||
last_valid_batch = batch_ix.saturating_add(1);
|
||||
let mut found_spot = false;
|
||||
while valid_batch_ix < batch_ix && !found_spot {
|
||||
while valid_packet_ix < batches[valid_batch_ix].packets.len() {
|
||||
if batches[valid_batch_ix].packets[valid_packet_ix]
|
||||
.meta
|
||||
.discard()
|
||||
{
|
||||
batches[valid_batch_ix].packets[valid_packet_ix] =
|
||||
batches[batch_ix].packets[packet_ix].clone();
|
||||
batches[batch_ix].packets[packet_ix].meta.set_discard(true);
|
||||
last_valid_batch = valid_batch_ix.saturating_add(1);
|
||||
found_spot = true;
|
||||
break;
|
||||
}
|
||||
valid_packet_ix = valid_packet_ix.saturating_add(1);
|
||||
}
|
||||
if valid_packet_ix >= batches[valid_batch_ix].packets.len() {
|
||||
valid_packet_ix = 0;
|
||||
valid_batch_ix = valid_batch_ix.saturating_add(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
last_valid_batch
|
||||
}
|
||||
|
||||
pub fn ed25519_verify_cpu(batches: &mut [PacketBatch], reject_non_vote: bool) {
|
||||
use rayon::prelude::*;
|
||||
let packet_count = count_packets_in_batches(batches);
|
||||
@@ -671,7 +715,7 @@ mod tests {
|
||||
use {
|
||||
super::*,
|
||||
crate::{
|
||||
packet::{to_packet_batches, Packet, PacketBatch},
|
||||
packet::{to_packet_batches, Packet, PacketBatch, PACKETS_PER_BATCH},
|
||||
sigverify::{self, PacketOffsets},
|
||||
test_tx::{new_test_vote_tx, test_multisig_tx, test_tx},
|
||||
},
|
||||
@@ -1393,4 +1437,223 @@ mod tests {
|
||||
//allow for 1 false positive even if extremely unlikely
|
||||
assert!(discard < 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_shrink_fuzz() {
|
||||
for _ in 0..5 {
|
||||
let mut batches = to_packet_batches(
|
||||
&(0..PACKETS_PER_BATCH * 3)
|
||||
.map(|_| test_tx())
|
||||
.collect::<Vec<_>>(),
|
||||
PACKETS_PER_BATCH,
|
||||
);
|
||||
batches.iter_mut().for_each(|b| {
|
||||
b.packets
|
||||
.iter_mut()
|
||||
.for_each(|p| p.meta.set_discard(thread_rng().gen()))
|
||||
});
|
||||
//find all the non discarded packets
|
||||
let mut start = vec![];
|
||||
batches.iter_mut().for_each(|b| {
|
||||
b.packets
|
||||
.iter_mut()
|
||||
.filter(|p| !p.meta.discard())
|
||||
.for_each(|p| start.push(p.clone()))
|
||||
});
|
||||
start.sort_by_key(|p| p.data);
|
||||
|
||||
let packet_count = count_valid_packets(&batches);
|
||||
let res = shrink_batches(&mut batches);
|
||||
batches.truncate(res);
|
||||
|
||||
//make sure all the non discarded packets are the same
|
||||
let mut end = vec![];
|
||||
batches.iter_mut().for_each(|b| {
|
||||
b.packets
|
||||
.iter_mut()
|
||||
.filter(|p| !p.meta.discard())
|
||||
.for_each(|p| end.push(p.clone()))
|
||||
});
|
||||
end.sort_by_key(|p| p.data);
|
||||
let packet_count2 = count_valid_packets(&batches);
|
||||
assert_eq!(packet_count, packet_count2);
|
||||
assert_eq!(start, end);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_shrink_empty() {
|
||||
const PACKET_COUNT: usize = 1024;
|
||||
const BATCH_COUNT: usize = PACKET_COUNT / PACKETS_PER_BATCH;
|
||||
|
||||
// No batches
|
||||
// truncate of 1 on len 0 is a noop
|
||||
assert_eq!(shrink_batches(&mut vec![]), 0);
|
||||
// One empty batch
|
||||
assert_eq!(shrink_batches(&mut vec![PacketBatch::with_capacity(0)]), 0);
|
||||
// Many empty batches
|
||||
let mut batches = (0..BATCH_COUNT)
|
||||
.map(|_| PacketBatch::with_capacity(0))
|
||||
.collect::<Vec<_>>();
|
||||
assert_eq!(shrink_batches(&mut batches), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_shrink_vectors() {
|
||||
const PACKET_COUNT: usize = 1024;
|
||||
const BATCH_COUNT: usize = PACKET_COUNT / PACKETS_PER_BATCH;
|
||||
|
||||
let set_discards = [
|
||||
// contiguous
|
||||
// 0
|
||||
// No discards
|
||||
|_, _| false,
|
||||
// All discards
|
||||
|_, _| true,
|
||||
// single partitions
|
||||
// discard last half of packets
|
||||
|b, p| ((b * PACKETS_PER_BATCH) + p) >= (PACKET_COUNT / 2),
|
||||
// discard first half of packets
|
||||
|b, p| ((b * PACKETS_PER_BATCH) + p) < (PACKET_COUNT / 2),
|
||||
// discard last half of each batch
|
||||
|_, p| p >= (PACKETS_PER_BATCH / 2),
|
||||
// 5
|
||||
// discard first half of each batch
|
||||
|_, p| p < (PACKETS_PER_BATCH / 2),
|
||||
// uniform sparse
|
||||
// discard even packets
|
||||
|b, p| ((b * PACKETS_PER_BATCH) + p) % 2 == 0,
|
||||
// discard odd packets
|
||||
|b, p| ((b * PACKETS_PER_BATCH) + p) % 2 == 1,
|
||||
// discard even batches
|
||||
|b, _| b % 2 == 0,
|
||||
// discard odd batches
|
||||
|b, _| b % 2 == 1,
|
||||
// edges
|
||||
// 10
|
||||
// discard first batch
|
||||
|b, _| b == 0,
|
||||
// discard last batch
|
||||
|b, _| b == BATCH_COUNT - 1,
|
||||
// discard first and last batches
|
||||
|b, _| b == 0 || b == BATCH_COUNT - 1,
|
||||
// discard all but first and last batches
|
||||
|b, _| b != 0 && b != BATCH_COUNT - 1,
|
||||
// discard first packet
|
||||
|b, p| ((b * PACKETS_PER_BATCH) + p) == 0,
|
||||
// 15
|
||||
// discard all but first packet
|
||||
|b, p| ((b * PACKETS_PER_BATCH) + p) != 0,
|
||||
// discard last packet
|
||||
|b, p| ((b * PACKETS_PER_BATCH) + p) == PACKET_COUNT - 1,
|
||||
// discard all but last packet
|
||||
|b, p| ((b * PACKETS_PER_BATCH) + p) != PACKET_COUNT - 1,
|
||||
// discard first packet of each batch
|
||||
|_, p| p == 0,
|
||||
// discard all but first packet of each batch
|
||||
|_, p| p != 0,
|
||||
// 20
|
||||
// discard last packet of each batch
|
||||
|_, p| p == PACKETS_PER_BATCH - 1,
|
||||
// discard all but last packet of each batch
|
||||
|_, p| p != PACKETS_PER_BATCH - 1,
|
||||
// discard first and last packet of each batch
|
||||
|_, p| p == 0 || p == PACKETS_PER_BATCH - 1,
|
||||
// discard all but first and last packet of each batch
|
||||
|_, p| p != 0 && p != PACKETS_PER_BATCH - 1,
|
||||
// discard all after first packet in second to last batch
|
||||
|b, p| (b == BATCH_COUNT - 2 && p > 0) || b == BATCH_COUNT - 1,
|
||||
// 25
|
||||
];
|
||||
|
||||
let expect_valids = [
|
||||
// (expected_batches, expected_valid_packets)
|
||||
//
|
||||
// contiguous
|
||||
// 0
|
||||
(BATCH_COUNT, PACKET_COUNT),
|
||||
(0, 0),
|
||||
// single partitions
|
||||
(BATCH_COUNT / 2, PACKET_COUNT / 2),
|
||||
(BATCH_COUNT / 2, PACKET_COUNT / 2),
|
||||
(BATCH_COUNT / 2, PACKET_COUNT / 2),
|
||||
// 5
|
||||
(BATCH_COUNT / 2, PACKET_COUNT / 2),
|
||||
// uniform sparse
|
||||
(BATCH_COUNT / 2, PACKET_COUNT / 2),
|
||||
(BATCH_COUNT / 2, PACKET_COUNT / 2),
|
||||
(BATCH_COUNT / 2, PACKET_COUNT / 2),
|
||||
(BATCH_COUNT / 2, PACKET_COUNT / 2),
|
||||
// edges
|
||||
// 10
|
||||
(BATCH_COUNT - 1, PACKET_COUNT - PACKETS_PER_BATCH),
|
||||
(BATCH_COUNT - 1, PACKET_COUNT - PACKETS_PER_BATCH),
|
||||
(BATCH_COUNT - 2, PACKET_COUNT - 2 * PACKETS_PER_BATCH),
|
||||
(2, 2 * PACKETS_PER_BATCH),
|
||||
(BATCH_COUNT, PACKET_COUNT - 1),
|
||||
// 15
|
||||
(1, 1),
|
||||
(BATCH_COUNT, PACKET_COUNT - 1),
|
||||
(1, 1),
|
||||
(
|
||||
(BATCH_COUNT * (PACKETS_PER_BATCH - 1) + PACKETS_PER_BATCH) / PACKETS_PER_BATCH,
|
||||
(PACKETS_PER_BATCH - 1) * BATCH_COUNT,
|
||||
),
|
||||
(
|
||||
(BATCH_COUNT + PACKETS_PER_BATCH) / PACKETS_PER_BATCH,
|
||||
BATCH_COUNT,
|
||||
),
|
||||
// 20
|
||||
(
|
||||
(BATCH_COUNT * (PACKETS_PER_BATCH - 1) + PACKETS_PER_BATCH) / PACKETS_PER_BATCH,
|
||||
(PACKETS_PER_BATCH - 1) * BATCH_COUNT,
|
||||
),
|
||||
(
|
||||
(BATCH_COUNT + PACKETS_PER_BATCH) / PACKETS_PER_BATCH,
|
||||
BATCH_COUNT,
|
||||
),
|
||||
(
|
||||
(BATCH_COUNT * (PACKETS_PER_BATCH - 2) + PACKETS_PER_BATCH) / PACKETS_PER_BATCH,
|
||||
(PACKETS_PER_BATCH - 2) * BATCH_COUNT,
|
||||
),
|
||||
(
|
||||
(2 * BATCH_COUNT + PACKETS_PER_BATCH) / PACKETS_PER_BATCH,
|
||||
PACKET_COUNT - (PACKETS_PER_BATCH - 2) * BATCH_COUNT,
|
||||
),
|
||||
(BATCH_COUNT - 1, PACKET_COUNT - 2 * PACKETS_PER_BATCH + 1),
|
||||
// 25
|
||||
];
|
||||
|
||||
let test_cases = set_discards.iter().zip(&expect_valids).enumerate();
|
||||
for (i, (set_discard, (expect_batch_count, expect_valid_packets))) in test_cases {
|
||||
println!("test_shrink case: {}", i);
|
||||
let mut batches = to_packet_batches(
|
||||
&(0..PACKET_COUNT).map(|_| test_tx()).collect::<Vec<_>>(),
|
||||
PACKETS_PER_BATCH,
|
||||
);
|
||||
assert_eq!(batches.len(), BATCH_COUNT);
|
||||
assert_eq!(count_valid_packets(&batches), PACKET_COUNT);
|
||||
batches.iter_mut().enumerate().for_each(|(i, b)| {
|
||||
b.packets
|
||||
.iter_mut()
|
||||
.enumerate()
|
||||
.for_each(|(j, p)| p.meta.set_discard(set_discard(i, j)))
|
||||
});
|
||||
assert_eq!(count_valid_packets(&batches), *expect_valid_packets);
|
||||
println!("show valid packets for case {}", i);
|
||||
batches.iter_mut().enumerate().for_each(|(i, b)| {
|
||||
b.packets.iter_mut().enumerate().for_each(|(j, p)| {
|
||||
if !p.meta.discard() {
|
||||
println!("{} {}", i, j)
|
||||
}
|
||||
})
|
||||
});
|
||||
println!("done show valid packets for case {}", i);
|
||||
let shrunken_batch_count = shrink_batches(&mut batches);
|
||||
println!("shrunk batch test {} count: {}", i, shrunken_batch_count);
|
||||
assert_eq!(shrunken_batch_count, *expect_batch_count);
|
||||
batches.truncate(shrunken_batch_count);
|
||||
assert_eq!(count_valid_packets(&batches), *expect_valid_packets);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -2,7 +2,7 @@
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
edition = "2021"
|
||||
name = "solana-poh-bench"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
@@ -14,12 +14,12 @@ clap = "2.33.1"
|
||||
log = "0.4.14"
|
||||
rand = "0.7.0"
|
||||
rayon = "1.5.1"
|
||||
solana-logger = { path = "../logger", version = "=1.9.6" }
|
||||
solana-entry = { path = "../entry", version = "=1.9.6" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.6" }
|
||||
solana-measure = { path = "../measure", version = "=1.9.6" }
|
||||
solana-version = { path = "../version", version = "=1.9.6" }
|
||||
solana-perf = { path = "../perf", version = "=1.9.6" }
|
||||
solana-logger = { path = "../logger", version = "=1.9.7" }
|
||||
solana-entry = { path = "../entry", version = "=1.9.7" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.7" }
|
||||
solana-measure = { path = "../measure", version = "=1.9.7" }
|
||||
solana-version = { path = "../version", version = "=1.9.7" }
|
||||
solana-perf = { path = "../perf", version = "=1.9.7" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-poh"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
description = "Solana PoH"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -13,21 +13,21 @@ edition = "2021"
|
||||
core_affinity = "0.5.10"
|
||||
crossbeam-channel = "0.5"
|
||||
log = "0.4.14"
|
||||
solana-entry = { path = "../entry", version = "=1.9.6" }
|
||||
solana-ledger = { path = "../ledger", version = "=1.9.6" }
|
||||
solana-measure = { path = "../measure", version = "=1.9.6" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.9.6" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.9.6" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.6" }
|
||||
solana-sys-tuner = { path = "../sys-tuner", version = "=1.9.6" }
|
||||
solana-entry = { path = "../entry", version = "=1.9.7" }
|
||||
solana-ledger = { path = "../ledger", version = "=1.9.7" }
|
||||
solana-measure = { path = "../measure", version = "=1.9.7" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.9.7" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.9.7" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.7" }
|
||||
solana-sys-tuner = { path = "../sys-tuner", version = "=1.9.7" }
|
||||
thiserror = "1.0"
|
||||
|
||||
[dev-dependencies]
|
||||
bincode = "1.3.3"
|
||||
matches = "0.1.9"
|
||||
rand = "0.7.0"
|
||||
solana-logger = { path = "../logger", version = "=1.9.6" }
|
||||
solana-perf = { path = "../perf", version = "=1.9.6" }
|
||||
solana-logger = { path = "../logger", version = "=1.9.7" }
|
||||
solana-perf = { path = "../perf", version = "=1.9.7" }
|
||||
|
||||
[lib]
|
||||
crate-type = ["lib"]
|
||||
|
@@ -63,6 +63,7 @@ type Result<T> = std::result::Result<T, PohRecorderError>;
|
||||
|
||||
pub type WorkingBankEntry = (Arc<Bank>, (Entry, u64));
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct BankStart {
|
||||
pub working_bank: Arc<Bank>,
|
||||
pub bank_creation_time: Arc<Instant>,
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-program-runtime"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
description = "Solana program runtime"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -19,11 +19,11 @@ log = "0.4.14"
|
||||
num-derive = { version = "0.3" }
|
||||
num-traits = { version = "0.2" }
|
||||
serde = { version = "1.0.129", features = ["derive", "rc"] }
|
||||
solana-frozen-abi = { path = "../frozen-abi", version = "=1.9.6" }
|
||||
solana-frozen-abi-macro = { path = "../frozen-abi/macro", version = "=1.9.6" }
|
||||
solana-logger = { path = "../logger", version = "=1.9.6" }
|
||||
solana-measure = { path = "../measure", version = "=1.9.6" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.6" }
|
||||
solana-frozen-abi = { path = "../frozen-abi", version = "=1.9.7" }
|
||||
solana-frozen-abi-macro = { path = "../frozen-abi/macro", version = "=1.9.7" }
|
||||
solana-logger = { path = "../logger", version = "=1.9.7" }
|
||||
solana-measure = { path = "../measure", version = "=1.9.7" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.7" }
|
||||
thiserror = "1.0"
|
||||
|
||||
[lib]
|
||||
|
@@ -1,16 +1,13 @@
|
||||
use {
|
||||
solana_sdk::{
|
||||
borsh::try_from_slice_unchecked,
|
||||
compute_budget::{self, ComputeBudgetInstruction},
|
||||
entrypoint::HEAP_LENGTH as MIN_HEAP_FRAME_BYTES,
|
||||
feature_set::{requestable_heap_size, FeatureSet},
|
||||
instruction::InstructionError,
|
||||
transaction::{SanitizedTransaction, TransactionError},
|
||||
},
|
||||
std::sync::Arc,
|
||||
use solana_sdk::{
|
||||
borsh::try_from_slice_unchecked,
|
||||
compute_budget::{self, ComputeBudgetInstruction},
|
||||
entrypoint::HEAP_LENGTH as MIN_HEAP_FRAME_BYTES,
|
||||
instruction::InstructionError,
|
||||
message::SanitizedMessage,
|
||||
transaction::TransactionError,
|
||||
};
|
||||
|
||||
const MAX_UNITS: u32 = 1_000_000;
|
||||
const MAX_UNITS: u32 = 1_400_000;
|
||||
const MAX_HEAP_FRAME_BYTES: u32 = 256 * 1024;
|
||||
|
||||
#[cfg(RUSTC_WITH_SPECIALIZATION)]
|
||||
@@ -66,14 +63,19 @@ pub struct ComputeBudget {
|
||||
|
||||
impl Default for ComputeBudget {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
Self::new(true)
|
||||
}
|
||||
}
|
||||
|
||||
impl ComputeBudget {
|
||||
pub fn new() -> Self {
|
||||
pub fn new(use_max_units_default: bool) -> Self {
|
||||
let max_units = if use_max_units_default {
|
||||
MAX_UNITS
|
||||
} else {
|
||||
200_000
|
||||
} as u64;
|
||||
ComputeBudget {
|
||||
max_units: 200_000,
|
||||
max_units,
|
||||
log_64_units: 100,
|
||||
create_program_address_units: 1500,
|
||||
invoke_units: 1000,
|
||||
@@ -94,25 +96,27 @@ impl ComputeBudget {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn process_transaction(
|
||||
pub fn process_message(
|
||||
&mut self,
|
||||
tx: &SanitizedTransaction,
|
||||
feature_set: Arc<FeatureSet>,
|
||||
) -> Result<(), TransactionError> {
|
||||
message: &SanitizedMessage,
|
||||
requestable_heap_size: bool,
|
||||
) -> Result<u64, TransactionError> {
|
||||
let mut requested_additional_fee = 0;
|
||||
let error = TransactionError::InstructionError(0, InstructionError::InvalidInstructionData);
|
||||
// Compute budget instruction must be in the 1st 3 instructions (avoid
|
||||
// nonce marker), otherwise ignored
|
||||
for (program_id, instruction) in tx.message().program_instructions_iter().take(3) {
|
||||
for (program_id, instruction) in message.program_instructions_iter().take(3) {
|
||||
if compute_budget::check_id(program_id) {
|
||||
match try_from_slice_unchecked(&instruction.data) {
|
||||
Ok(ComputeBudgetInstruction::RequestUnits(units)) => {
|
||||
if units > MAX_UNITS {
|
||||
return Err(error);
|
||||
}
|
||||
self.max_units = units as u64;
|
||||
Ok(ComputeBudgetInstruction::RequestUnits {
|
||||
units,
|
||||
additional_fee,
|
||||
}) => {
|
||||
self.max_units = units.min(MAX_UNITS) as u64;
|
||||
requested_additional_fee = additional_fee as u64;
|
||||
}
|
||||
Ok(ComputeBudgetInstruction::RequestHeapFrame(bytes)) => {
|
||||
if !feature_set.is_active(&requestable_heap_size::id())
|
||||
if !requestable_heap_size
|
||||
|| bytes > MAX_HEAP_FRAME_BYTES
|
||||
|| bytes < MIN_HEAP_FRAME_BYTES as u32
|
||||
|| bytes % 1024 != 0
|
||||
@@ -125,7 +129,7 @@ impl ComputeBudget {
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
Ok(requested_additional_fee)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,8 +138,13 @@ mod tests {
|
||||
use {
|
||||
super::*,
|
||||
solana_sdk::{
|
||||
hash::Hash, instruction::Instruction, message::Message, pubkey::Pubkey,
|
||||
signature::Keypair, signer::Signer, transaction::Transaction,
|
||||
hash::Hash,
|
||||
instruction::Instruction,
|
||||
message::Message,
|
||||
pubkey::Pubkey,
|
||||
signature::Keypair,
|
||||
signer::Signer,
|
||||
transaction::{SanitizedTransaction, Transaction},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -147,24 +156,23 @@ mod tests {
|
||||
Message::new($instructions, Some(&payer_keypair.pubkey())),
|
||||
Hash::default(),
|
||||
));
|
||||
let feature_set = Arc::new(FeatureSet::all_enabled());
|
||||
let mut compute_budget = ComputeBudget::default();
|
||||
let result = compute_budget.process_transaction(&tx, feature_set);
|
||||
assert_eq!($expected_error as Result<(), TransactionError>, result);
|
||||
let result = compute_budget.process_message(&tx.message(), true);
|
||||
assert_eq!($expected_error, result);
|
||||
assert_eq!(compute_budget, $expected_budget);
|
||||
};
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_process_transaction() {
|
||||
fn test_process_mesage() {
|
||||
// Units
|
||||
test!(&[], Ok(()), ComputeBudget::default());
|
||||
test!(&[], Ok(0), ComputeBudget::default());
|
||||
test!(
|
||||
&[
|
||||
ComputeBudgetInstruction::request_units(1),
|
||||
ComputeBudgetInstruction::request_units(1, 0),
|
||||
Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]),
|
||||
],
|
||||
Ok(()),
|
||||
Ok(0),
|
||||
ComputeBudget {
|
||||
max_units: 1,
|
||||
..ComputeBudget::default()
|
||||
@@ -172,21 +180,18 @@ mod tests {
|
||||
);
|
||||
test!(
|
||||
&[
|
||||
ComputeBudgetInstruction::request_units(MAX_UNITS + 1),
|
||||
ComputeBudgetInstruction::request_units(MAX_UNITS + 1, 0),
|
||||
Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]),
|
||||
],
|
||||
Err(TransactionError::InstructionError(
|
||||
0,
|
||||
InstructionError::InvalidInstructionData,
|
||||
)),
|
||||
Ok(0),
|
||||
ComputeBudget::default()
|
||||
);
|
||||
test!(
|
||||
&[
|
||||
Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]),
|
||||
ComputeBudgetInstruction::request_units(MAX_UNITS),
|
||||
ComputeBudgetInstruction::request_units(MAX_UNITS, 0),
|
||||
],
|
||||
Ok(()),
|
||||
Ok(0),
|
||||
ComputeBudget {
|
||||
max_units: MAX_UNITS as u64,
|
||||
..ComputeBudget::default()
|
||||
@@ -197,20 +202,20 @@ mod tests {
|
||||
Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]),
|
||||
Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]),
|
||||
Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]),
|
||||
ComputeBudgetInstruction::request_units(1),
|
||||
ComputeBudgetInstruction::request_units(1, 0),
|
||||
],
|
||||
Ok(()),
|
||||
Ok(0),
|
||||
ComputeBudget::default()
|
||||
);
|
||||
|
||||
// HeapFrame
|
||||
test!(&[], Ok(()), ComputeBudget::default());
|
||||
test!(&[], Ok(0), ComputeBudget::default());
|
||||
test!(
|
||||
&[
|
||||
ComputeBudgetInstruction::request_heap_frame(40 * 1024),
|
||||
Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]),
|
||||
],
|
||||
Ok(()),
|
||||
Ok(0),
|
||||
ComputeBudget {
|
||||
heap_size: Some(40 * 1024),
|
||||
..ComputeBudget::default()
|
||||
@@ -254,7 +259,7 @@ mod tests {
|
||||
Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]),
|
||||
ComputeBudgetInstruction::request_heap_frame(MAX_HEAP_FRAME_BYTES),
|
||||
],
|
||||
Ok(()),
|
||||
Ok(0),
|
||||
ComputeBudget {
|
||||
heap_size: Some(MAX_HEAP_FRAME_BYTES as usize),
|
||||
..ComputeBudget::default()
|
||||
@@ -267,7 +272,7 @@ mod tests {
|
||||
Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]),
|
||||
ComputeBudgetInstruction::request_heap_frame(1), // ignored
|
||||
],
|
||||
Ok(()),
|
||||
Ok(0),
|
||||
ComputeBudget::default()
|
||||
);
|
||||
|
||||
@@ -276,9 +281,9 @@ mod tests {
|
||||
&[
|
||||
Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]),
|
||||
ComputeBudgetInstruction::request_heap_frame(MAX_HEAP_FRAME_BYTES),
|
||||
ComputeBudgetInstruction::request_units(MAX_UNITS),
|
||||
ComputeBudgetInstruction::request_units(MAX_UNITS, 0),
|
||||
],
|
||||
Ok(()),
|
||||
Ok(0),
|
||||
ComputeBudget {
|
||||
max_units: MAX_UNITS as u64,
|
||||
heap_size: Some(MAX_HEAP_FRAME_BYTES as usize),
|
||||
|
@@ -1670,13 +1670,14 @@ mod tests {
|
||||
feature_set.deactivate(&requestable_heap_size::id());
|
||||
let mut invoke_context = InvokeContext::new_mock(&accounts, &[]);
|
||||
invoke_context.feature_set = Arc::new(feature_set);
|
||||
invoke_context.compute_budget = ComputeBudget::new(false);
|
||||
|
||||
invoke_context
|
||||
.push(&noop_message, &noop_message.instructions()[0], &[0], &[])
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
*invoke_context.get_compute_budget(),
|
||||
ComputeBudget::default()
|
||||
ComputeBudget::new(false)
|
||||
);
|
||||
invoke_context.pop();
|
||||
|
||||
@@ -1686,7 +1687,7 @@ mod tests {
|
||||
let expected_compute_budget = ComputeBudget {
|
||||
max_units: 500_000,
|
||||
heap_size: Some(256_usize.saturating_mul(1024)),
|
||||
..ComputeBudget::default()
|
||||
..ComputeBudget::new(false)
|
||||
};
|
||||
assert_eq!(
|
||||
*invoke_context.get_compute_budget(),
|
||||
@@ -1699,7 +1700,7 @@ mod tests {
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
*invoke_context.get_compute_budget(),
|
||||
ComputeBudget::default()
|
||||
ComputeBudget::new(false)
|
||||
);
|
||||
invoke_context.pop();
|
||||
}
|
||||
|
@@ -5,7 +5,7 @@ edition = "2021"
|
||||
license = "Apache-2.0"
|
||||
name = "solana-program-test"
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
|
||||
[dependencies]
|
||||
async-trait = "0.1.51"
|
||||
@@ -14,14 +14,14 @@ bincode = "1.3.3"
|
||||
chrono-humanize = "0.2.1"
|
||||
log = "0.4.14"
|
||||
serde = "1.0.130"
|
||||
solana-banks-client = { path = "../banks-client", version = "=1.9.6" }
|
||||
solana-banks-server = { path = "../banks-server", version = "=1.9.6" }
|
||||
solana-bpf-loader-program = { path = "../programs/bpf_loader", version = "=1.9.6" }
|
||||
solana-logger = { path = "../logger", version = "=1.9.6" }
|
||||
solana-program-runtime = { path = "../program-runtime", version = "=1.9.6" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.9.6" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.6" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.9.6" }
|
||||
solana-banks-client = { path = "../banks-client", version = "=1.9.7" }
|
||||
solana-banks-server = { path = "../banks-server", version = "=1.9.7" }
|
||||
solana-bpf-loader-program = { path = "../programs/bpf_loader", version = "=1.9.7" }
|
||||
solana-logger = { path = "../logger", version = "=1.9.7" }
|
||||
solana-program-runtime = { path = "../program-runtime", version = "=1.9.7" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.9.7" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.7" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.9.7" }
|
||||
thiserror = "1.0"
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
|
||||
|
@@ -25,6 +25,7 @@ use {
|
||||
account_info::AccountInfo,
|
||||
clock::Slot,
|
||||
entrypoint::{ProgramResult, SUCCESS},
|
||||
feature_set::FEATURE_NAMES,
|
||||
fee_calculator::{FeeCalculator, FeeRateGovernor},
|
||||
genesis_config::{ClusterType, GenesisConfig},
|
||||
hash::Hash,
|
||||
@@ -41,7 +42,7 @@ use {
|
||||
solana_vote_program::vote_state::{VoteState, VoteStateVersions},
|
||||
std::{
|
||||
cell::RefCell,
|
||||
collections::HashMap,
|
||||
collections::{HashMap, HashSet},
|
||||
convert::TryFrom,
|
||||
fs::File,
|
||||
io::{self, Read},
|
||||
@@ -58,7 +59,10 @@ use {
|
||||
tokio::task::JoinHandle,
|
||||
};
|
||||
// Export types so test clients can limit their solana crate dependencies
|
||||
pub use {solana_banks_client::BanksClient, solana_program_runtime::invoke_context::InvokeContext};
|
||||
pub use {
|
||||
solana_banks_client::{BanksClient, BanksClientError},
|
||||
solana_program_runtime::invoke_context::InvokeContext,
|
||||
};
|
||||
|
||||
pub mod programs;
|
||||
|
||||
@@ -469,6 +473,7 @@ pub struct ProgramTest {
|
||||
compute_max_units: Option<u64>,
|
||||
prefer_bpf: bool,
|
||||
use_bpf_jit: bool,
|
||||
deactivate_feature_set: HashSet<Pubkey>,
|
||||
}
|
||||
|
||||
impl Default for ProgramTest {
|
||||
@@ -499,6 +504,7 @@ impl Default for ProgramTest {
|
||||
compute_max_units: None,
|
||||
prefer_bpf,
|
||||
use_bpf_jit: false,
|
||||
deactivate_feature_set: HashSet::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -728,6 +734,13 @@ impl ProgramTest {
|
||||
.push(Builtin::new(program_name, program_id, process_instruction));
|
||||
}
|
||||
|
||||
/// Deactivate a runtime feature.
|
||||
///
|
||||
/// Note that all features are activated by default.
|
||||
pub fn deactivate_feature(&mut self, feature_id: Pubkey) {
|
||||
self.deactivate_feature_set.insert(feature_id);
|
||||
}
|
||||
|
||||
fn setup_bank(
|
||||
&self,
|
||||
) -> (
|
||||
@@ -767,6 +780,25 @@ impl ProgramTest {
|
||||
ClusterType::Development,
|
||||
vec![],
|
||||
);
|
||||
|
||||
// Remove features tagged to deactivate
|
||||
for deactivate_feature_pk in &self.deactivate_feature_set {
|
||||
if FEATURE_NAMES.contains_key(deactivate_feature_pk) {
|
||||
match genesis_config.accounts.remove(deactivate_feature_pk) {
|
||||
Some(_) => debug!("Feature for {:?} deactivated", deactivate_feature_pk),
|
||||
None => warn!(
|
||||
"Feature {:?} set for deactivation not found in genesis_config account list, ignored.",
|
||||
deactivate_feature_pk
|
||||
),
|
||||
}
|
||||
} else {
|
||||
warn!(
|
||||
"Feature {:?} set for deactivation is not a known Feature public key",
|
||||
deactivate_feature_pk
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let target_tick_duration = Duration::from_micros(100);
|
||||
genesis_config.poh_config = PohConfig::new_sleep(target_tick_duration);
|
||||
debug!("Payer address: {}", mint_keypair.pubkey());
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "solana-address-lookup-table-program-tests"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
@@ -14,9 +14,9 @@ publish = false
|
||||
[dev-dependencies]
|
||||
assert_matches = "1.5.0"
|
||||
bincode = "1.3.3"
|
||||
solana-address-lookup-table-program = { path = "../address-lookup-table", version = "=1.9.6" }
|
||||
solana-program-test = { path = "../../program-test", version = "=1.9.6" }
|
||||
solana-sdk = { path = "../../sdk", version = "=1.9.6" }
|
||||
solana-address-lookup-table-program = { path = "../address-lookup-table", version = "=1.9.7" }
|
||||
solana-program-test = { path = "../../program-test", version = "=1.9.7" }
|
||||
solana-sdk = { path = "../../sdk", version = "=1.9.7" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-address-lookup-table-program"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
description = "Solana address lookup table program"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -16,10 +16,10 @@ log = "0.4.14"
|
||||
num-derive = "0.3"
|
||||
num-traits = "0.2"
|
||||
serde = { version = "1.0.127", features = ["derive"] }
|
||||
solana-frozen-abi = { path = "../../frozen-abi", version = "=1.9.6" }
|
||||
solana-frozen-abi-macro = { path = "../../frozen-abi/macro", version = "=1.9.6" }
|
||||
solana-program-runtime = { path = "../../program-runtime", version = "=1.9.6" }
|
||||
solana-sdk = { path = "../../sdk", version = "=1.9.6" }
|
||||
solana-frozen-abi = { path = "../../frozen-abi", version = "=1.9.7" }
|
||||
solana-frozen-abi-macro = { path = "../../frozen-abi/macro", version = "=1.9.7" }
|
||||
solana-program-runtime = { path = "../../program-runtime", version = "=1.9.7" }
|
||||
solana-sdk = { path = "../../sdk", version = "=1.9.7" }
|
||||
thiserror = "1.0"
|
||||
|
||||
[build-dependencies]
|
||||
|
317
programs/bpf/Cargo.lock
generated
317
programs/bpf/Cargo.lock
generated
@@ -2364,7 +2364,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-account-decoder"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"Inflector",
|
||||
"base64 0.12.3",
|
||||
@@ -2385,7 +2385,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-address-lookup-table-program"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"bytemuck",
|
||||
@@ -2394,8 +2394,8 @@ dependencies = [
|
||||
"num-traits",
|
||||
"rustc_version",
|
||||
"serde",
|
||||
"solana-frozen-abi 1.9.6",
|
||||
"solana-frozen-abi-macro 1.9.6",
|
||||
"solana-frozen-abi 1.9.7",
|
||||
"solana-frozen-abi-macro 1.9.7",
|
||||
"solana-program-runtime",
|
||||
"solana-sdk",
|
||||
"thiserror",
|
||||
@@ -2403,12 +2403,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-banks-client"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"borsh",
|
||||
"futures",
|
||||
"solana-banks-interface",
|
||||
"solana-program 1.9.6",
|
||||
"solana-program 1.9.7",
|
||||
"solana-sdk",
|
||||
"tarpc",
|
||||
"thiserror",
|
||||
@@ -2418,7 +2418,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-banks-interface"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"solana-sdk",
|
||||
@@ -2427,7 +2427,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-banks-server"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"futures",
|
||||
@@ -2443,7 +2443,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-bloom"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"bv",
|
||||
"fnv",
|
||||
@@ -2453,14 +2453,14 @@ dependencies = [
|
||||
"rustc_version",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"solana-frozen-abi 1.9.6",
|
||||
"solana-frozen-abi-macro 1.9.6",
|
||||
"solana-frozen-abi 1.9.7",
|
||||
"solana-frozen-abi-macro 1.9.7",
|
||||
"solana-sdk",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-loader-program"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"byteorder 1.4.3",
|
||||
@@ -2476,7 +2476,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-programs"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"byteorder 1.4.3",
|
||||
@@ -2491,7 +2491,7 @@ dependencies = [
|
||||
"solana-bpf-rust-realloc",
|
||||
"solana-bpf-rust-realloc-invoke",
|
||||
"solana-cli-output",
|
||||
"solana-logger 1.9.6",
|
||||
"solana-logger 1.9.7",
|
||||
"solana-measure",
|
||||
"solana-program-runtime",
|
||||
"solana-runtime",
|
||||
@@ -2503,170 +2503,170 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-128bit"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"solana-bpf-rust-128bit-dep",
|
||||
"solana-program 1.9.6",
|
||||
"solana-program 1.9.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-128bit-dep"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"solana-program 1.9.6",
|
||||
"solana-program 1.9.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-alloc"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"solana-program 1.9.6",
|
||||
"solana-program 1.9.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-call-depth"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"solana-program 1.9.6",
|
||||
"solana-program 1.9.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-caller-access"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"solana-program 1.9.6",
|
||||
"solana-program 1.9.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-custom-heap"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"solana-program 1.9.6",
|
||||
"solana-program 1.9.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-dep-crate"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"byteorder 1.4.3",
|
||||
"solana-program 1.9.6",
|
||||
"solana-program 1.9.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-deprecated-loader"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"solana-program 1.9.6",
|
||||
"solana-program 1.9.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-dup-accounts"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"solana-program 1.9.6",
|
||||
"solana-program 1.9.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-error-handling"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"num-derive",
|
||||
"num-traits",
|
||||
"solana-program 1.9.6",
|
||||
"solana-program 1.9.7",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-external-spend"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"solana-program 1.9.6",
|
||||
"solana-program 1.9.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-finalize"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"solana-program 1.9.6",
|
||||
"solana-program 1.9.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-instruction-introspection"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"solana-program 1.9.6",
|
||||
"solana-program 1.9.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-invoke"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"solana-bpf-rust-invoked",
|
||||
"solana-program 1.9.6",
|
||||
"solana-program 1.9.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-invoke-and-error"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"solana-program 1.9.6",
|
||||
"solana-program 1.9.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-invoke-and-ok"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"solana-program 1.9.6",
|
||||
"solana-program 1.9.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-invoke-and-return"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"solana-program 1.9.6",
|
||||
"solana-program 1.9.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-invoked"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"solana-program 1.9.6",
|
||||
"solana-program 1.9.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-iter"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"solana-program 1.9.6",
|
||||
"solana-program 1.9.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-log-data"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"solana-program 1.9.6",
|
||||
"solana-program 1.9.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-many-args"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"solana-bpf-rust-many-args-dep",
|
||||
"solana-program 1.9.6",
|
||||
"solana-program 1.9.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-many-args-dep"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"solana-program 1.9.6",
|
||||
"solana-program 1.9.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-mem"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"solana-program 1.9.6",
|
||||
"solana-program 1.9.7",
|
||||
"solana-program-runtime",
|
||||
"solana-program-test",
|
||||
"solana-sdk",
|
||||
@@ -2674,84 +2674,84 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-membuiltins"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"solana-bpf-rust-mem",
|
||||
"solana-program 1.9.6",
|
||||
"solana-program 1.9.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-noop"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"solana-program 1.9.6",
|
||||
"solana-program 1.9.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-panic"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"solana-program 1.9.6",
|
||||
"solana-program 1.9.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-param-passing"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"solana-bpf-rust-param-passing-dep",
|
||||
"solana-program 1.9.6",
|
||||
"solana-program 1.9.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-param-passing-dep"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"solana-program 1.9.6",
|
||||
"solana-program 1.9.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-rand"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"getrandom 0.1.16",
|
||||
"rand 0.7.3",
|
||||
"solana-program 1.9.6",
|
||||
"solana-program 1.9.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-realloc"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"solana-program 1.9.6",
|
||||
"solana-program 1.9.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-realloc-invoke"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"solana-bpf-rust-realloc",
|
||||
"solana-program 1.9.6",
|
||||
"solana-program 1.9.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-ro-account_modify"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"solana-program 1.9.6",
|
||||
"solana-program 1.9.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-ro-modify"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"solana-program 1.9.6",
|
||||
"solana-program 1.9.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-sanity"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"solana-program 1.9.6",
|
||||
"solana-program 1.9.7",
|
||||
"solana-program-runtime",
|
||||
"solana-program-test",
|
||||
"solana-sdk",
|
||||
@@ -2759,52 +2759,52 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-secp256k1-recover"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"solana-program 1.9.6",
|
||||
"solana-program 1.9.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-sha"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"blake3",
|
||||
"solana-program 1.9.6",
|
||||
"solana-program 1.9.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-sibling-instructions"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"solana-program 1.9.6",
|
||||
"solana-program 1.9.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-sibling_inner-instructions"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"solana-program 1.9.6",
|
||||
"solana-program 1.9.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-spoof1"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"solana-program 1.9.6",
|
||||
"solana-program 1.9.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-spoof1-system"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"solana-program 1.9.6",
|
||||
"solana-program 1.9.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-sysvar"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"solana-program 1.9.6",
|
||||
"solana-program 1.9.7",
|
||||
"solana-program-runtime",
|
||||
"solana-program-test",
|
||||
"solana-sdk",
|
||||
@@ -2812,28 +2812,28 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-upgradeable"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"solana-program 1.9.6",
|
||||
"solana-program 1.9.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-upgraded"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"solana-program 1.9.6",
|
||||
"solana-program 1.9.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bucket-map"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"fs_extra",
|
||||
"log",
|
||||
"memmap2",
|
||||
"rand 0.7.3",
|
||||
"rayon",
|
||||
"solana-logger 1.9.6",
|
||||
"solana-logger 1.9.7",
|
||||
"solana-measure",
|
||||
"solana-sdk",
|
||||
"tempfile",
|
||||
@@ -2841,7 +2841,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-clap-utils"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"clap",
|
||||
@@ -2857,7 +2857,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-cli-config"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"dirs-next",
|
||||
"lazy_static",
|
||||
@@ -2869,7 +2869,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-cli-output"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"Inflector",
|
||||
"base64 0.13.0",
|
||||
@@ -2891,7 +2891,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-client"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"base64 0.13.0",
|
||||
"bincode",
|
||||
@@ -2923,7 +2923,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-compute-budget-program"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"solana-program-runtime",
|
||||
"solana-sdk",
|
||||
@@ -2931,7 +2931,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-config-program"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"chrono",
|
||||
@@ -2943,7 +2943,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-faucet"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"byteorder 1.4.3",
|
||||
@@ -2953,7 +2953,7 @@ dependencies = [
|
||||
"serde_derive",
|
||||
"solana-clap-utils",
|
||||
"solana-cli-config",
|
||||
"solana-logger 1.9.6",
|
||||
"solana-logger 1.9.7",
|
||||
"solana-metrics",
|
||||
"solana-sdk",
|
||||
"solana-version",
|
||||
@@ -2984,7 +2984,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-frozen-abi"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"bs58",
|
||||
"bv",
|
||||
@@ -2995,8 +2995,8 @@ dependencies = [
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"sha2",
|
||||
"solana-frozen-abi-macro 1.9.6",
|
||||
"solana-logger 1.9.6",
|
||||
"solana-frozen-abi-macro 1.9.7",
|
||||
"solana-logger 1.9.7",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
@@ -3014,7 +3014,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-frozen-abi-macro"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.36",
|
||||
"quote 1.0.14",
|
||||
@@ -3035,7 +3035,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-logger"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"env_logger",
|
||||
"lazy_static",
|
||||
@@ -3044,7 +3044,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-measure"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"log",
|
||||
"solana-sdk",
|
||||
@@ -3052,7 +3052,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-metrics"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"env_logger",
|
||||
"gethostname",
|
||||
@@ -3064,7 +3064,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-net-utils"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"clap",
|
||||
@@ -3074,7 +3074,7 @@ dependencies = [
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"socket2",
|
||||
"solana-logger 1.9.6",
|
||||
"solana-logger 1.9.7",
|
||||
"solana-sdk",
|
||||
"solana-version",
|
||||
"tokio",
|
||||
@@ -3083,7 +3083,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-perf"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"ahash 0.7.6",
|
||||
"bincode",
|
||||
@@ -3101,7 +3101,7 @@ dependencies = [
|
||||
"rayon",
|
||||
"serde",
|
||||
"solana-bloom",
|
||||
"solana-logger 1.9.6",
|
||||
"solana-logger 1.9.7",
|
||||
"solana-metrics",
|
||||
"solana-rayon-threadlimit",
|
||||
"solana-sdk",
|
||||
@@ -3153,7 +3153,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-program"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"base64 0.13.0",
|
||||
"bincode",
|
||||
@@ -3184,17 +3184,17 @@ dependencies = [
|
||||
"serde_derive",
|
||||
"sha2",
|
||||
"sha3",
|
||||
"solana-frozen-abi 1.9.6",
|
||||
"solana-frozen-abi-macro 1.9.6",
|
||||
"solana-logger 1.9.6",
|
||||
"solana-sdk-macro 1.9.6",
|
||||
"solana-frozen-abi 1.9.7",
|
||||
"solana-frozen-abi-macro 1.9.7",
|
||||
"solana-logger 1.9.7",
|
||||
"solana-sdk-macro 1.9.7",
|
||||
"thiserror",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-program-runtime"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"base64 0.13.0",
|
||||
"bincode",
|
||||
@@ -3206,9 +3206,9 @@ dependencies = [
|
||||
"num-traits",
|
||||
"rustc_version",
|
||||
"serde",
|
||||
"solana-frozen-abi 1.9.6",
|
||||
"solana-frozen-abi-macro 1.9.6",
|
||||
"solana-logger 1.9.6",
|
||||
"solana-frozen-abi 1.9.7",
|
||||
"solana-frozen-abi-macro 1.9.7",
|
||||
"solana-logger 1.9.7",
|
||||
"solana-measure",
|
||||
"solana-sdk",
|
||||
"thiserror",
|
||||
@@ -3216,7 +3216,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-program-test"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"base64 0.12.3",
|
||||
@@ -3227,7 +3227,7 @@ dependencies = [
|
||||
"solana-banks-client",
|
||||
"solana-banks-server",
|
||||
"solana-bpf-loader-program",
|
||||
"solana-logger 1.9.6",
|
||||
"solana-logger 1.9.7",
|
||||
"solana-program-runtime",
|
||||
"solana-runtime",
|
||||
"solana-sdk",
|
||||
@@ -3238,7 +3238,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-rayon-threadlimit"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"num_cpus",
|
||||
@@ -3246,7 +3246,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-remote-wallet"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"base32",
|
||||
"console",
|
||||
@@ -3265,12 +3265,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-runtime"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"arrayref",
|
||||
"bincode",
|
||||
"blake3",
|
||||
"bv",
|
||||
"bytemuck",
|
||||
"byteorder 1.4.3",
|
||||
"bzip2",
|
||||
"crossbeam-channel",
|
||||
@@ -3299,9 +3300,9 @@ dependencies = [
|
||||
"solana-bucket-map",
|
||||
"solana-compute-budget-program",
|
||||
"solana-config-program",
|
||||
"solana-frozen-abi 1.9.6",
|
||||
"solana-frozen-abi-macro 1.9.6",
|
||||
"solana-logger 1.9.6",
|
||||
"solana-frozen-abi 1.9.7",
|
||||
"solana-frozen-abi-macro 1.9.7",
|
||||
"solana-logger 1.9.7",
|
||||
"solana-measure",
|
||||
"solana-metrics",
|
||||
"solana-program-runtime",
|
||||
@@ -3318,7 +3319,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-sdk"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"assert_matches",
|
||||
"base64 0.13.0",
|
||||
@@ -3355,11 +3356,11 @@ dependencies = [
|
||||
"serde_json",
|
||||
"sha2",
|
||||
"sha3",
|
||||
"solana-frozen-abi 1.9.6",
|
||||
"solana-frozen-abi-macro 1.9.6",
|
||||
"solana-logger 1.9.6",
|
||||
"solana-program 1.9.6",
|
||||
"solana-sdk-macro 1.9.6",
|
||||
"solana-frozen-abi 1.9.7",
|
||||
"solana-frozen-abi-macro 1.9.7",
|
||||
"solana-logger 1.9.7",
|
||||
"solana-program 1.9.7",
|
||||
"solana-sdk-macro 1.9.7",
|
||||
"thiserror",
|
||||
"uriparse",
|
||||
"wasm-bindgen",
|
||||
@@ -3380,7 +3381,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-sdk-macro"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"bs58",
|
||||
"proc-macro2 1.0.36",
|
||||
@@ -3391,10 +3392,10 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-send-transaction-service"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"log",
|
||||
"solana-logger 1.9.6",
|
||||
"solana-logger 1.9.7",
|
||||
"solana-metrics",
|
||||
"solana-runtime",
|
||||
"solana-sdk",
|
||||
@@ -3402,7 +3403,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-stake-program"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"log",
|
||||
@@ -3412,8 +3413,8 @@ dependencies = [
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"solana-config-program",
|
||||
"solana-frozen-abi 1.9.6",
|
||||
"solana-frozen-abi-macro 1.9.6",
|
||||
"solana-frozen-abi 1.9.7",
|
||||
"solana-frozen-abi-macro 1.9.7",
|
||||
"solana-metrics",
|
||||
"solana-program-runtime",
|
||||
"solana-sdk",
|
||||
@@ -3423,7 +3424,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-transaction-status"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"Inflector",
|
||||
"base64 0.12.3",
|
||||
@@ -3448,20 +3449,20 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana-version"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"log",
|
||||
"rustc_version",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"solana-frozen-abi 1.9.6",
|
||||
"solana-frozen-abi-macro 1.9.6",
|
||||
"solana-frozen-abi 1.9.7",
|
||||
"solana-frozen-abi-macro 1.9.7",
|
||||
"solana-sdk",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-vote-program"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"log",
|
||||
@@ -3470,9 +3471,9 @@ dependencies = [
|
||||
"rustc_version",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"solana-frozen-abi 1.9.6",
|
||||
"solana-frozen-abi-macro 1.9.6",
|
||||
"solana-logger 1.9.6",
|
||||
"solana-frozen-abi 1.9.7",
|
||||
"solana-frozen-abi-macro 1.9.7",
|
||||
"solana-logger 1.9.7",
|
||||
"solana-metrics",
|
||||
"solana-program-runtime",
|
||||
"solana-sdk",
|
||||
|
@@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "solana-bpf-programs"
|
||||
description = "Blockchain, Rebuilt for Scale"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
documentation = "https://docs.rs/solana"
|
||||
homepage = "https://solana.com/"
|
||||
readme = "README.md"
|
||||
@@ -26,19 +26,19 @@ itertools = "0.10.1"
|
||||
log = "0.4.11"
|
||||
miow = "0.3.6"
|
||||
net2 = "0.2.37"
|
||||
solana-bpf-rust-invoke = { path = "rust/invoke", version = "=1.9.6"}
|
||||
solana-bpf-loader-program = { path = "../bpf_loader", version = "=1.9.6"}
|
||||
solana-bpf-rust-realloc = { path = "rust/realloc", version = "=1.9.6"}
|
||||
solana-bpf-rust-realloc-invoke = { path = "rust/realloc_invoke", version = "=1.9.6"}
|
||||
solana-cli-output = { path = "../../cli-output", version = "=1.9.6" }
|
||||
solana-logger = { path = "../../logger", version = "=1.9.6" }
|
||||
solana-measure = { path = "../../measure", version = "=1.9.6" }
|
||||
solana-bpf-rust-invoke = { path = "rust/invoke", version = "=1.9.7"}
|
||||
solana-bpf-loader-program = { path = "../bpf_loader", version = "=1.9.7"}
|
||||
solana-bpf-rust-realloc = { path = "rust/realloc", version = "=1.9.7"}
|
||||
solana-bpf-rust-realloc-invoke = { path = "rust/realloc_invoke", version = "=1.9.7"}
|
||||
solana-cli-output = { path = "../../cli-output", version = "=1.9.7" }
|
||||
solana-logger = { path = "../../logger", version = "=1.9.7" }
|
||||
solana-measure = { path = "../../measure", version = "=1.9.7" }
|
||||
solana_rbpf = "=0.2.23"
|
||||
solana-runtime = { path = "../../runtime", version = "=1.9.6" }
|
||||
solana-program-runtime = { path = "../../program-runtime", version = "=1.9.6" }
|
||||
solana-sdk = { path = "../../sdk", version = "=1.9.6" }
|
||||
solana-transaction-status = { path = "../../transaction-status", version = "=1.9.6" }
|
||||
solana-account-decoder = { path = "../../account-decoder", version = "=1.9.6" }
|
||||
solana-runtime = { path = "../../runtime", version = "=1.9.7" }
|
||||
solana-program-runtime = { path = "../../program-runtime", version = "=1.9.7" }
|
||||
solana-sdk = { path = "../../sdk", version = "=1.9.7" }
|
||||
solana-transaction-status = { path = "../../transaction-status", version = "=1.9.7" }
|
||||
solana-account-decoder = { path = "../../account-decoder", version = "=1.9.7" }
|
||||
|
||||
[[bench]]
|
||||
name = "bpf_loader"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-bpf-rust-128bit"
|
||||
version = "1.9.6"
|
||||
version = "1.9.7"
|
||||
description = "Solana BPF test program written in Rust"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
@@ -10,8 +10,8 @@ documentation = "https://docs.rs/solana-bpf-rust-128bit"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
solana-program = { path = "../../../../sdk/program", version = "=1.9.6" }
|
||||
solana-bpf-rust-128bit-dep = { path = "../128bit_dep", version = "=1.9.6" }
|
||||
solana-program = { path = "../../../../sdk/program", version = "=1.9.7" }
|
||||
solana-bpf-rust-128bit-dep = { path = "../128bit_dep", version = "=1.9.7" }
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user