Compare commits

...

239 Commits

Author SHA1 Message Date
HaoranYi
83f5f8bfc3 Move test_purge_huge test (#23587)
* ignore test_purge_huge tests it is expensive.

* move test_purge to integration tests
2022-03-10 15:31:43 -06:00
Jack May
ddd9d5a5a5 deny slice indexing (#23565) 2022-03-10 11:48:33 -08:00
Jack May
ead8cc4366 Check for physical region overlap (#23568) 2022-03-10 11:48:09 -08:00
Russell Wong
7b238b3645 fix: renamed the internal wasm_bindgen init function to avoid collision 2022-03-10 11:33:24 -08:00
Tao Zhu
35d1235ed0 - move unprocessed_packet_batches from BankingStage to its own (#23508)
module
- deserialize packets during receving and buffering
2022-03-10 18:47:46 +00:00
Brooks Prumo
3c6840050c Ensure blocks do not exceed the max accounts data size during Replay Stage (#23422) 2022-03-10 10:24:31 -06:00
steviez
58c0db9704 Cleanup several blockstore functions (#23390)
* Rename excludes_from_compaction to should_exclude_from_compaction
* Make subfunction to create all cf descriptors
* Condense logic for when to disable compactions
2022-03-10 02:08:38 -06:00
sethgirvan
37189f20c5 Fix error message typo (#23574) 2022-03-10 05:03:02 +00:00
carllin
588414a776 Report even if slot begins and ends in process_buffered_packets() (#23549) 2022-03-09 23:42:35 -05:00
Brian Anderson
72af687aa6 Fix broken links in solana-client (#23503)
* Fix broken links in solana-client

* Revise docs for RpcClient::new_sender

* Add docs for RpcClient::new_mock etc

* Fix doc warnings on RpcSender

* rustfmt
2022-03-09 21:42:23 -07:00
Tao Zhu
f68c5a274d remove persist_cost_table code 2022-03-09 21:05:47 -07:00
Tao Zhu
9f71958d7d Patch validator from loading persisted program costs 2022-03-09 21:05:47 -07:00
ryleung-solana
17b00ad3a4 Add quic-client module (#23166)
* Add quic-client module to send transactions via quic, abstracted behind the TpuConnection trait (along with a legacy UDP implementation of TpuConnection) and change thin-client to use TpuConnection
2022-03-09 21:33:05 -05:00
Brooks Prumo
1fe0d6eeeb Set ordering flushing_active.swap() to AcqRel (#23567) 2022-03-10 01:22:42 +00:00
Alexander Meißner
e60c9b97c9 Removes KeyedAccount from tests in stake instruction. (Part 1) (#23473)
* Migrates test_stake_delegate().

* Migrates test_stake_initialize().

* Migrates test_initialize_incorrect_account_sizes().

* Migrates test_authorize().

* Migrates test_authorize_lockup().

* Migrates test_authorize_override().

* Migrates test_authorize_with_seed().

* Migrates test_split().

* Migrates test_split_fake_stake_dest().

* Migrates test_deactivate().

* Migrates test_set_lockup().

* Migrates test_optional_lockup_for_stake_program().

* Migrates test_withdraw_stake().

* Migrates test_withdraw_stake_invalid_state().

* Migrates test_withdraw_stake_before_warmup().

* Migrates test_withdraw_lockup().

* Migrates test_withdraw_identical_authorities().

* Migrates test_withdraw_rent_exempt().

* Migrates test_authorize_delegated_stake().

* Migrates test_redelegate_consider_balance_changes().
2022-03-09 23:48:10 +01:00
Brooks Prumo
ea1bcd3d59 Add newlines in templates (#23540) 2022-03-09 16:10:23 -06:00
Brooks Prumo
1eddb6d1e9 Move ArchiveFormat into own module (#23562) 2022-03-09 16:09:34 -06:00
dependabot[bot]
26ef6111bb chore: bump follow-redirects from 1.13.1 to 1.14.8 in /web3.js (#23122)
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.13.1 to 1.14.8.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.13.1...v1.14.8)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-09 14:09:06 -08:00
Brooks Prumo
9bbccbe27c Use AsRef<Path> instead of PathBuf for parameters (#23560) 2022-03-09 16:08:33 -06:00
SolanaMonkeyBusiness
fb974489a5 fix(explorer): metaplexNFTHeader for unverified collection (#23498)
Current behavior: 
When the NFT is in an unverified collection, the metaplex NFT header displays a 0.
Example : https://explorer.solana.com/address/ARA6zvFJZAydh6mdAgc7A6pMpZotCQj6eYugUMpEWKYh

Expected behavior:
The metaplex NFT header should display nothing
2022-03-09 13:44:12 -08:00
HaoranYi
ba54b30101 clippy (#23563) 2022-03-09 15:33:50 -06:00
HaoranYi
a1c45d5acb typo (#23564) 2022-03-09 15:11:21 -06:00
Brian Anderson
176fd23002 Continue making it possible to implement RpcSender (#23561)
* Make nonblocking RpcClient::new_sender pub

As is the blocking RpcClient::new_sender, per #23503.

* Make solana_client::rpc_sender pub

Per #17631 it is supposed to be possible to implement RpcSender in
order to call RpcClient::new_sender. As of now though it is
not possible to name RpcSender in order to implement it.
2022-03-09 14:07:51 -07:00
klykov
3688ac4eae upd Cargo.lock 2022-03-09 17:53:06 +01:00
klykov
cc55684f5f update clap to v3: rbpf-cli 2022-03-09 17:53:06 +01:00
klykov
e2bc326d58 update clap to v3: test-bpf 2022-03-09 17:53:06 +01:00
klykov
8abaa5d350 update clap to v3: bpf-tools 2022-03-09 17:53:06 +01:00
Richard Patel
949006b5a2 explorer: format Instructions title as singular/plural (#23553) 2022-03-09 20:53:29 +08:00
axleiro
afc41c7b11 fix: vercel preview "PR commit URl" on slack (#23519)
* fix: vercel preview "PR commit URl" on slack

added command to get "PR commit URl" on slack along with vercel preview deploy link on PR.

* fix: error trailing whitespace on buildkite
2022-03-09 17:06:36 +05:30
sakridge
7a9884c831 Quic limit connections (#23283)
* quic server limit connections

* bump per_ip

* Review comments

* Make the connections per port
2022-03-09 10:52:31 +01:00
dependabot[bot]
8a4b019ded chore: bump byte-unit from 4.0.13 to 4.0.14 (#23550)
Bumps [byte-unit](https://github.com/magiclen/byte-unit) from 4.0.13 to 4.0.14.
- [Release notes](https://github.com/magiclen/byte-unit/releases)
- [Commits](https://github.com/magiclen/byte-unit/compare/v4.0.13...v4.0.14)

---
updated-dependencies:
- dependency-name: byte-unit
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-09 08:28:42 +00:00
Justin Starry
249d926d1b Refactor: Add transaction binary encoding enum (#23546) 2022-03-09 16:09:08 +08:00
dependabot[bot]
65e2d9b2f2 chore: bump hidapi from 1.3.3 to 1.3.4 (#23544)
Bumps [hidapi](https://github.com/ruabmbua/hidapi-rs) from 1.3.3 to 1.3.4.
- [Release notes](https://github.com/ruabmbua/hidapi-rs/releases)
- [Commits](https://github.com/ruabmbua/hidapi-rs/commits)

---
updated-dependencies:
- dependency-name: hidapi
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-09 05:57:59 +00:00
dependabot[bot]
5c722519cf chore: bump etcd-client from 0.8.3 to 0.8.4
Bumps [etcd-client](https://github.com/etcdv3/etcd-client) from 0.8.3 to 0.8.4.
- [Release notes](https://github.com/etcdv3/etcd-client/releases)
- [Commits](https://github.com/etcdv3/etcd-client/compare/0.8.3...v0.8.4)

---
updated-dependencies:
- dependency-name: etcd-client
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-08 17:33:24 -08:00
Carl Lin
5a0cd05866 Revert "- estimate a program cost as 2 standard deviation above mean"
This reverts commit a25ac1c988.
2022-03-08 17:18:44 -08:00
Carl Lin
9acbfa5eb1 Revert "use EMA in place of Welford"
This reverts commit 6587dbfa47.
2022-03-08 17:18:44 -08:00
Carl Lin
c878c9e2cb Revert "1. Persist to blockstore less frequently;"
This reverts commit 7aa1fb4e24.
2022-03-08 17:18:44 -08:00
Carl Lin
0a17edcc1f Revert "fix tests after merge"
This reverts commit ba2d83f580.
2022-03-08 17:18:44 -08:00
Jeff Washington (jwash)
cc4d75a16f fix typo (#23535) 2022-03-08 18:28:00 -06:00
Michael Vines
b719d6a2ad solana-validator set-identity no longer writes a tower file unnecessarily 2022-03-08 15:34:23 -08:00
Mark Percival
8438366d1b fix: update 'borsh' dependency to v0.7.0 (#22425)
Fixes issue with usage of 'global' when used in the browser.

Currently the web3.js distributable is built with a commonJS rollup, but if you
use the npm package with another packager, it will fail when it hits the call
to 'global' inside the browser. Borsh fixed this in v0.7.0
2022-03-08 15:07:33 -08:00
dependabot[bot]
46ec5d563b chore: bump libc from 0.2.117 to 0.2.119 (#23527)
* chore: bump libc from 0.2.117 to 0.2.119

Bumps [libc](https://github.com/rust-lang/libc) from 0.2.117 to 0.2.119.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.117...0.2.119)

---
updated-dependencies:
- dependency-name: libc
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* [auto-commit] Update all Cargo lock files

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: dependabot-buildkite <dependabot-buildkite@noreply.solana.com>
2022-03-08 14:25:38 -07:00
Brooks Prumo
9b80452c7c Fix getting the golden snapshot hashes during bootstrap with Incremental Snapshots (#23518) 2022-03-08 15:16:53 -06:00
Jack May
c2ec294401 featurize loader sat math (#23516) 2022-03-08 11:48:22 -08:00
Michael Vines
536a99705b Update regex to v1.5.5 2022-03-08 10:45:47 -08:00
dependabot[bot]
00558227be chore: bump pbkdf2 from 0.10.0 to 0.10.1 (#23522)
* chore: bump pbkdf2 from 0.10.0 to 0.10.1

Bumps [pbkdf2](https://github.com/RustCrypto/password-hashes) from 0.10.0 to 0.10.1.
- [Release notes](https://github.com/RustCrypto/password-hashes/releases)
- [Commits](https://github.com/RustCrypto/password-hashes/compare/pbkdf2-v0.10.0...pbkdf2-v0.10.1)

---
updated-dependencies:
- dependency-name: pbkdf2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* [auto-commit] Update all Cargo lock files

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: dependabot-buildkite <dependabot-buildkite@noreply.solana.com>
2022-03-08 10:50:33 -07:00
Michael Vines
5599bd9442 Remove BankFromArchiveTimings from ledger/ 2022-03-08 08:11:50 -08:00
Michael Vines
9cfa21f7d1 Inline load_from_genesis 2022-03-08 08:11:50 -08:00
dependabot[bot]
12337d8daf chore: bump curve25519-dalek from 3.2.0 to 3.2.1 (#23517)
Bumps [curve25519-dalek](https://github.com/dalek-cryptography/curve25519-dalek) from 3.2.0 to 3.2.1.
- [Release notes](https://github.com/dalek-cryptography/curve25519-dalek/releases)
- [Changelog](https://github.com/dalek-cryptography/curve25519-dalek/blob/main/CHANGELOG.md)
- [Commits](https://github.com/dalek-cryptography/curve25519-dalek/compare/3.2.0...3.2.1)

---
updated-dependencies:
- dependency-name: curve25519-dalek
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-08 01:14:37 -07:00
Justin Starry
3114c199bd Add RPC support for versioned transactions (#22530)
* Add RPC support for versioned transactions

* fix doc tests

* Add rpc test for versioned txs

* Switch to preflight bank
2022-03-08 15:20:34 +08:00
Tao Zhu
e790d0fc53 Optional Cli parameter to add additional-fee to solana ping (#23513)
* Optional Cli parameter to add additional-fee to solana ping

Co-authored-by: Tyera Eulberg <teulberg@gmail.com>
Co-authored-by: Trent Nelson <trent.a.b.nelson@gmail.com>

* Update cli/src/cluster_query.rs

correct the help message for arg

Co-authored-by: Tyera Eulberg <teulberg@gmail.com>

Co-authored-by: Tyera Eulberg <teulberg@gmail.com>
Co-authored-by: Trent Nelson <trent.a.b.nelson@gmail.com>
2022-03-08 03:49:36 +00:00
dependabot[bot]
7933c7fc24 chore: bump anyhow from 1.0.55 to 1.0.56 (#23514)
* chore: bump anyhow from 1.0.55 to 1.0.56

Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.55 to 1.0.56.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.55...1.0.56)

---
updated-dependencies:
- dependency-name: anyhow
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* [auto-commit] Update all Cargo lock files

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: dependabot-buildkite <dependabot-buildkite@noreply.solana.com>
2022-03-07 16:26:30 -07:00
Brian Anderson
ddbf5c782f Fix broken doc links in solana-runtime (#23504) 2022-03-07 22:21:40 +00:00
dependabot[bot]
38d8bbb19c chore: bump sysctl from 0.4.3 to 0.4.4 (#23505)
Bumps [sysctl](https://github.com/johalun/sysctl-rs) from 0.4.3 to 0.4.4.
- [Release notes](https://github.com/johalun/sysctl-rs/releases)
- [Changelog](https://github.com/johalun/sysctl-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/johalun/sysctl-rs/commits)

---
updated-dependencies:
- dependency-name: sysctl
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-07 14:24:19 -07:00
HaoranYi
181fffb916 rename status filename to be consistent (#23501) 2022-03-07 17:34:35 +00:00
samkim-crypto
08c9a650db zk-token-sdk: generalize range proof (#23506)
* zk-token-sdk: update range proof in transfers for more flexible setting of params

* zk-token-sdk: clippy
2022-03-07 12:27:56 -05:00
dependabot[bot]
3a0271c113 chore: bump dashmap from 4.0.2 to 5.1.0 (#23372)
* chore: bump dashmap from 4.0.2 to 5.1.0

Bumps [dashmap](https://github.com/xacrimon/dashmap) from 4.0.2 to 5.1.0.
- [Release notes](https://github.com/xacrimon/dashmap/releases)
- [Commits](https://github.com/xacrimon/dashmap/commits/v5.1.0)

---
updated-dependencies:
- dependency-name: dashmap
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

* [auto-commit] Update all Cargo lock files

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: dependabot-buildkite <dependabot-buildkite@noreply.solana.com>
2022-03-07 00:00:26 -05:00
HaoranYi
463cd564cf fix typos (#23495)
* fix typos
2022-03-05 20:46:46 -06:00
Yueh-Hsuan Chiang
b8b7163b66 (Ledger Store) Report RocksDB Column Family Metrics (#22503)
This PR enables blockstore to periodically report RocksDB column family properties.
The reported properties are under blockstore_rocksdb_cfs, and the properties also
support group by operation on cf_name.
2022-03-05 16:13:03 -08:00
Will Roeder
ba771cdc45 feat(explorer): adding verified on-chain collection support (#23490)
* Adding Verified On-chain Collection tag to help consumers check if their NFTs are authentic

* On-chain isn't quite the same as NO-chain

* Grammar fix

* Added Collection Owner verification to guarantee this is actually a Collection Mint
2022-03-04 18:35:35 -08:00
samkim-crypto
d2b23da9ea Zk token sdk clean decryption (#23478)
* zk-token-sdk: add decryption for pod elgamal ciphertexts

* zk-token-sdk: add decryption for pod elgamal ciphertexts

* zk-token-sdk: cargo fmt

* zk-token-sdk: minor update to docs

* zk-token-sdk: minor

* zk-token-sdk: fix bpf build error

* zk-token-sdk: more simplifying discrete log

* zk-token-sdk: fmt

* zk-token-sdk: minor update to doc
2022-03-04 15:57:19 -04:00
Jack May
09b58e1cfb sha-2:0.9.8 yanked, bump to 0.9.9 (#23477) 2022-03-04 08:13:52 -08:00
Alexander Meißner
e23c6ce62b Increases check_number_of_instruction_accounts() in BPF loader. (#23440) 2022-03-04 14:33:27 +01:00
Justin Starry
38db1dead4 Refactor RPC tests (#23483) 2022-03-04 18:20:11 +08:00
Michael Vines
36ad59673c drop mut 2022-03-04 09:52:46 +01:00
Michael Vines
0d33b54d74 Rework do_process_blockstore_from_root to use BankForks 2022-03-04 09:52:46 +01:00
Michael Vines
93c8e04d51 Simplify do_process_blockstore_from_root slightly 2022-03-04 09:52:46 +01:00
Michael Vines
b28acd2d4d Reduce fn visibility 2022-03-04 09:52:46 +01:00
dependabot[bot]
360f6466a3 chore: bump futures from 0.3.19 to 0.3.21 (#23476)
* chore: bump futures from 0.3.19 to 0.3.21

Bumps [futures](https://github.com/rust-lang/futures-rs) from 0.3.19 to 0.3.21.
- [Release notes](https://github.com/rust-lang/futures-rs/releases)
- [Changelog](https://github.com/rust-lang/futures-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/futures-rs/compare/0.3.19...0.3.21)

---
updated-dependencies:
- dependency-name: futures
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* [auto-commit] Update all Cargo lock files

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: dependabot-buildkite <dependabot-buildkite@noreply.solana.com>
2022-03-03 16:44:43 -07:00
HaoranYi
aad73f1f2e fix recycler free stat report (#23159)
* fix recycler free stat report

* update comments for ewma window size

* one atomic update with aggregated local counter

* fix clippy integer arithmetic error

* move free calcs outside of loop

* fix integer arithmetic error
2022-03-03 17:08:59 -06:00
dependabot[bot]
afda8c4020 chore: bump memmap2 from 0.5.2 to 0.5.3 (#23475)
* chore: bump memmap2 from 0.5.2 to 0.5.3

Bumps [memmap2](https://github.com/RazrFalcon/memmap2-rs) from 0.5.2 to 0.5.3.
- [Release notes](https://github.com/RazrFalcon/memmap2-rs/releases)
- [Changelog](https://github.com/RazrFalcon/memmap2-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/RazrFalcon/memmap2-rs/compare/v0.5.2...v0.5.3)

---
updated-dependencies:
- dependency-name: memmap2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* [auto-commit] Update all Cargo lock files

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: dependabot-buildkite <you@example.com>
2022-03-03 14:45:07 -07:00
Yueh-Hsuan Chiang
62d2a4cd88 Make ShredStorageType::RocksLevel public (#23272)
#### Summary of Changes
This PR adds two hidden arguments to the validator that allow users to use RocksDB's FIFO compaction for storing shreds.

        --shred-storage <SHRED_STORAGE>
            EXPERIMENTAL: Controls how RocksDB compacts shreds.  *WARNING*: You will lose your ledger data
            when you switch between options. Possible values are: 'level': stores shreds using RocksDB's default (level)
            compaction. 'fifo': stores shreds under RocksDB's FIFO compaction. This option is more efficient on
            disk-write-bytes of the ledger store. [default: level]  [possible values: level, fifo]

        --shred-storage-size <SHRED_STORAGE_SIZE_BYTES>
            The shred storage size in bytes. The suggested value is 50% of your ledger storage size in bytes. [default:
            268435456000]
2022-03-03 12:43:58 -08:00
samkim-crypto
8d53ea81e9 zk-token-sdk: change variable names to use suffix rather than prefix (#23474)
* zk-token-sdk: change variable names to use suffix rather than prefix for type

* zk-token-sdk: cargo fmt
2022-03-03 15:07:27 -05:00
dependabot[bot]
f2fa49a771 chore: bump lru from 0.7.2 to 0.7.3 (#23462)
Bumps [lru](https://github.com/jeromefroe/lru-rs) from 0.7.2 to 0.7.3.
- [Release notes](https://github.com/jeromefroe/lru-rs/releases)
- [Changelog](https://github.com/jeromefroe/lru-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/jeromefroe/lru-rs/compare/0.7.2...0.7.3)

---
updated-dependencies:
- dependency-name: lru
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-03 12:01:49 -07:00
mooori
7b7160448b Rename AccountsDataMeter::consume (#23037) 2022-03-03 12:23:06 -06:00
Jeff Washington (jwash)
7f608965ef new counter data point for unexpected rent_epoch (#23449) 2022-03-03 09:09:31 -06:00
Jeff Washington (jwash)
ddfd4f86f3 exit early from acct bg svc if no shrink candidates (#23459) 2022-03-03 08:47:39 -06:00
Jeff Washington (jwash)
a99fd09c16 allow index update to change storage slot # (#23311) 2022-03-03 08:40:48 -06:00
axleiro
4b59bfe6d8 testing latest changes on explorer (#23470) 2022-03-03 16:48:18 +05:30
axleiro
5ac3466f26 added PAT token
fixing Error: Resource not accessible by integration
2022-03-03 16:24:09 +05:30
axleiro
2e750722c7 resolving promote to prod issue (#23469) 2022-03-03 15:40:49 +05:30
axleiro
a9fd807f61 adding default working dir to fix promote to prod issue 2022-03-03 15:23:41 +05:30
axleiro
011472a8e8 add comment to trigger the file to check the previous merge (#23468)
* fix the issue of "promote to Production" on vercel

* fix the issue "promote to production" on vercel for production deployment

* add comment to trigger the file to check the previous merge for vercel "promote to prod" issue
2022-03-03 15:05:02 +05:30
axleiro
b4480e6b70 fixing the vercel " promote to production" issue (#23466)
* fix the issue of "promote to Production" on vercel

* fix the issue "promote to production" on vercel for production deployment
2022-03-03 13:20:32 +05:30
dependabot[bot]
61d7bdd66f chore: bump serde_json from 1.0.78 to 1.0.79 (#23461)
* chore: bump serde_json from 1.0.78 to 1.0.79

Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.78 to 1.0.79.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.78...v1.0.79)

---
updated-dependencies:
- dependency-name: serde_json
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* [auto-commit] Update all Cargo lock files

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: dependabot-buildkite <you@example.com>
2022-03-02 23:38:06 -07:00
Josh
43347f3da6 fix(explorer): change title to average ping time (#23463) 2022-03-03 03:28:23 +00:00
Yueh-Hsuan Chiang
634f4eb37d (LedgerStore) Use different path for different blockstore storage type. (#23236)
#### Summary of Changes
To avoid mixing the use of different shred storage types, each shred storage type
will have its blockstore in a different directory.

This PR still keeps the RocksFifo setting hidden.  The default ShredStorageType and
blockstore directory are still RocksLevel and `rocksdb`.

Will follow-up with PRs on making FIFO option public in ledger-tool and validator.

#### Test Plan
* Added a new test to verify the existence of `rocksdb-fifo` directory when FIFO compaction is used.
* Updated existing test to verify the current setting still store ledger under `rocksdb` directory.
* Manually ran ledger_cleanup_test with both level and fifo compaction and verified the resulting ledger.
* Ran a validator with this PR.
2022-03-02 18:30:22 -08:00
dependabot[bot]
39387e8446 chore: bump blake3 from 1.3.0 to 1.3.1 (#23460)
* chore: bump blake3 from 1.3.0 to 1.3.1

Bumps [blake3](https://github.com/BLAKE3-team/BLAKE3) from 1.3.0 to 1.3.1.
- [Release notes](https://github.com/BLAKE3-team/BLAKE3/releases)
- [Commits](https://github.com/BLAKE3-team/BLAKE3/compare/1.3.0...1.3.1)

---
updated-dependencies:
- dependency-name: blake3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* [auto-commit] Update all Cargo lock files

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: dependabot-buildkite <dependabot-buildkite@noreply.solana.com>
2022-03-02 18:20:30 -07:00
Brooks Prumo
79a515e88e Add tests for split() from Uninitialized account where dest=source (#23442) 2022-03-02 18:32:15 -06:00
Brooks Prumo
e87b941a51 Test stake split: destination delegation is at least the minimum (#23456) 2022-03-02 17:29:40 -06:00
dependabot[bot]
fe7604589d chore: bump retain_mut from 0.1.5 to 0.1.7 (#23450)
Bumps [retain_mut](https://github.com/upsuper/retain_mut) from 0.1.5 to 0.1.7.
- [Release notes](https://github.com/upsuper/retain_mut/releases)
- [Commits](https://github.com/upsuper/retain_mut/commits)

---
updated-dependencies:
- dependency-name: retain_mut
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-02 23:15:33 +00:00
Jack May
e9912744ef use saturating arithmetic (#23435) 2022-03-02 14:50:16 -08:00
Jeff Washington (jwash)
8184f755ae 2 more rent collection tests don't skip epochs (#23446) 2022-03-02 15:04:34 -06:00
Jack May
97d40ba3da Resized accounts must be rent exempt 2022-03-02 13:02:02 -08:00
Kirill Fomichev
82cb61dc36 Add Copy/Eq derive traits to SlotStatus in accountsdb-plugin (#23100)
* Add copy/eq derive traits to SlotStatus in accountsdb-plugin

* move Eq to derive

* remove not required clone
2022-03-02 12:49:11 -08:00
Will Hickey
1a99251498 Bump version to 1.10.1 (#23453) 2022-03-02 13:47:01 -06:00
Krešimir Klas
41ab690a61 feat: add getMultipleAccountsInfoAndContext method to Connection
Similar to `getAccountInfoAndContext`.
2022-03-02 20:39:48 +01:00
Brian Long
7dbde2247d Adds comments related to the public RPC endpoints (#22797)
* Adds comments related to the public RPC endpoints

* Update docs/src/cluster/rpc-endpoints.md

Co-authored-by: Michael Vines <mvines@gmail.com>

Co-authored-by: Brian Long <bl@triton.one>
Co-authored-by: Tyera Eulberg <teulberg@gmail.com>
Co-authored-by: Michael Vines <mvines@gmail.com>
2022-03-02 19:15:35 +00:00
dependabot[bot]
da00d29de0 chore: bump bytemuck from 1.7.3 to 1.8.0 (#23437)
* chore: bump bytemuck from 1.7.3 to 1.8.0

Bumps [bytemuck](https://github.com/Lokathor/bytemuck) from 1.7.3 to 1.8.0.
- [Release notes](https://github.com/Lokathor/bytemuck/releases)
- [Changelog](https://github.com/Lokathor/bytemuck/blob/main/changelog.md)
- [Commits](https://github.com/Lokathor/bytemuck/compare/v1.7.3...v1.8.0)

---
updated-dependencies:
- dependency-name: bytemuck
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* [auto-commit] Update all Cargo lock files

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: dependabot-buildkite <dependabot-buildkite@noreply.solana.com>
2022-03-02 19:04:54 +00:00
Jeff Washington (jwash)
e88da2ec0a minor test cleanup (#23447)
* minor test cleanup

* fmt
2022-03-02 12:10:05 -06:00
Jeff Washington (jwash)
26aa18b3f3 fmt (#23448) 2022-03-02 11:54:58 -06:00
Jeff Washington (jwash)
e630eb73d7 rework test to avoid multi-epoch gap (#23393) 2022-03-02 11:12:10 -06:00
Jeff Washington (jwash)
ef8b7d9c62 ledger tool halt at slot verify hash (#23424) 2022-03-02 11:11:18 -06:00
Jeff Washington (jwash)
d909b7c80b log hash and lamport result of calculate_accounts_hash_without_index (#23425) 2022-03-02 11:10:40 -06:00
Jordan Sexton
8eefe60c44 chore: web3.js: fix cjs file reference in package.json (#21940) 2022-03-02 10:00:55 -07:00
Josh
d43786edcf fix(explorer): remove purple from ping (#23445) 2022-03-02 16:57:41 +00:00
Michael Vines
9ec514f6c5 Restore solana-test-validator informational output 2022-03-02 17:27:27 +01:00
Josh
3ddd018452 feat(explorer): reenable solana ping widget (#23443) 2022-03-02 16:11:35 +00:00
HaoranYi
41f78b9925 small optimization. use shift for pow of 2. (#22975) 2022-03-02 09:11:12 -06:00
HaoranYi
4f0070a5c6 unittest for bind two consecutive ports (#23008)
* minor fix of comments in fork-selection tests

* fix doc link

* add unittest for bind_two_consecutive_in_range
2022-03-02 09:10:29 -06:00
HaoranYi
8de88d0a55 Refactor packet_threshold adjustment code into its own struct (#23216)
* refactor packet_threshold adjustment code into own struct and add unittest for it

* fix a typo in error message

* code review feedbacks

* another code review feedback

* Update core/src/ancestor_hashes_service.rs

Co-authored-by: Trent Nelson <trent.a.b.nelson@gmail.com>

* share packet threshold with repair service (credit to carl)

Co-authored-by: Trent Nelson <trent.a.b.nelson@gmail.com>
2022-03-02 09:09:06 -06:00
HaoranYi
86e2f728c3 Fix a batch limits bug in banking (#23327)
* add thread index in thread name for debugging

* fix batch_limit

* use NUM_VOTE_THREAD instead of hardcoded number (credit to carllin)
2022-03-02 09:08:08 -06:00
Jeff Washington (jwash)
7b7fdb42d9 minor test refactoring (#23423) 2022-03-02 08:31:14 -06:00
Jeff Washington (jwash)
c8cb940b4e tweak 2 rent tests to narrow epoch ranges (#23420) 2022-03-02 08:22:33 -06:00
sakridge
a4f4ac5279 add plumbing to allow for arbitrary tpu address in gossip (#22703)
* add plumbing to allow for arbitrary tpu address in gossip

* make clippy happy

* Review comments

Co-authored-by: CherryWorm <nico.gruendel@web.de>
2022-03-02 09:42:14 +01:00
Tyera Eulberg
d3ebe8d8f5 Remove unneeded jsonrpc dependencies/features; update do-audit (#23436)
* Update generic-array note

* Remove unneeded jsonrpc deps

* Remove unneeded jsonrpc features

* Rewrite slot-update test without websocket crate

* Rewrite rpc-subscription test without websocket crate, and remove jsonrpc deps

* Update expected balance to accommodate rent-exempt minimum transfer amount

* Remove obsolete audit ignores
2022-03-02 01:42:01 -07:00
dependabot[bot]
7d1a090cfb chore: bump semver from 1.0.5 to 1.0.6 (#23429)
* chore: bump semver from 1.0.5 to 1.0.6

Bumps [semver](https://github.com/dtolnay/semver) from 1.0.5 to 1.0.6.
- [Release notes](https://github.com/dtolnay/semver/releases)
- [Commits](https://github.com/dtolnay/semver/compare/1.0.5...1.0.6)

---
updated-dependencies:
- dependency-name: semver
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* [auto-commit] Update all Cargo lock files

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: dependabot-buildkite <dependabot-buildkite@noreply.solana.com>
2022-03-01 22:16:44 -07:00
Jeff Biseda
c69e3b73ff bench get_retransmit_peers (#23292) 2022-03-01 19:10:29 -08:00
Tyera Eulberg
2a17a661e6 Remove failure audit ignore (#23431) 2022-03-01 17:02:55 -07:00
dependabot[bot]
a0d68ef60e chore: bump futures-util from 0.3.19 to 0.3.21 (#23418)
* chore: bump futures-util from 0.3.19 to 0.3.21

Bumps [futures-util](https://github.com/rust-lang/futures-rs) from 0.3.19 to 0.3.21.
- [Release notes](https://github.com/rust-lang/futures-rs/releases)
- [Changelog](https://github.com/rust-lang/futures-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/futures-rs/compare/0.3.19...0.3.21)

---
updated-dependencies:
- dependency-name: futures-util
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* [auto-commit] Update all Cargo lock files

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: dependabot-buildkite <dependabot-buildkite@noreply.solana.com>
2022-03-01 16:44:30 -07:00
dependabot[bot]
7d1810bbcc chore: bump hidapi from 1.3.2 to 1.3.3 (#23416)
Bumps [hidapi](https://github.com/ruabmbua/hidapi-rs) from 1.3.2 to 1.3.3.
- [Release notes](https://github.com/ruabmbua/hidapi-rs/releases)
- [Commits](https://github.com/ruabmbua/hidapi-rs/commits/v1.3.3)

---
updated-dependencies:
- dependency-name: hidapi
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-01 16:06:56 -07:00
Alexander Meißner
6c56eb9663 Replaces KeyedAccount by BorrowedAccount in the BPF loader. (#23056) 2022-03-01 22:55:26 +01:00
Josh
d0ba914d2b fix(explorer): rollback ping until api is more stable (#23419) 2022-03-01 19:57:23 +00:00
Josh
7943e8a1c3 fix(explorer): retry should trigger loading state (#23417)
* fix(explorer): retry should trigger loading state

* fix(explorer): Solana ping add refreshing state
2022-03-01 11:41:11 -08:00
dependabot[bot]
3e48cc4e00 chore: bump dialoguer from 0.9.0 to 0.10.0 (#23413)
* chore: bump dialoguer from 0.9.0 to 0.10.0

Bumps [dialoguer](https://github.com/mitsuhiko/dialoguer) from 0.9.0 to 0.10.0.
- [Release notes](https://github.com/mitsuhiko/dialoguer/releases)
- [Changelog](https://github.com/mitsuhiko/dialoguer/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mitsuhiko/dialoguer/compare/v0.9.0...v0.10.0)

---
updated-dependencies:
- dependency-name: dialoguer
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* [auto-commit] Update all Cargo lock files

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: dependabot-buildkite <dependabot-buildkite@noreply.solana.com>
2022-03-01 19:31:03 +00:00
dependabot[bot]
ce4d579499 chore: bump serial_test from 0.5.1 to 0.6.0 (#23414)
Bumps [serial_test](https://github.com/palfrey/serial_test) from 0.5.1 to 0.6.0.
- [Release notes](https://github.com/palfrey/serial_test/releases)
- [Commits](https://github.com/palfrey/serial_test/compare/v0.5.1...v0.6.0)

---
updated-dependencies:
- dependency-name: serial_test
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-01 12:13:40 -07:00
Josh
f6a06826d8 feat(explorer): add Solana Ping to cluster stats page (#23239)
* feat: add Solana Ping to explorer

* fix: remove br tags in label
2022-03-01 10:50:48 -08:00
dependabot[bot]
93c5642f9f chore: bump rcgen from 0.9.1 to 0.9.2 (#23406)
Bumps [rcgen](https://github.com/est31/rcgen) from 0.9.1 to 0.9.2.
- [Release notes](https://github.com/est31/rcgen/releases)
- [Changelog](https://github.com/est31/rcgen/blob/master/CHANGELOG.md)
- [Commits](https://github.com/est31/rcgen/compare/v0.9.1...v0.9.2)

---
updated-dependencies:
- dependency-name: rcgen
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-01 10:09:14 -07:00
behzad nouri
1282277126 bumps up crds-shards-bits (#23220)
The commit adjust CRDS_SHARDS_BITS up to be in-line with mask_bits in
gossip pull request. This will avoid redundant filtering of irrelevant
crds entries when responding to pull requests.
2022-03-01 15:14:11 +00:00
Jeff Washington (jwash)
454e82683e refactor rent test (#23392) 2022-03-01 08:47:09 -06:00
Jeff Washington (jwash)
6b2683f7da refactor test (#23384) 2022-03-01 08:22:10 -06:00
dependabot[bot]
ec798f5aad chore: bump anyhow from 1.0.53 to 1.0.55 (#23402)
* chore: bump anyhow from 1.0.53 to 1.0.55

Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.53 to 1.0.55.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.53...1.0.55)

---
updated-dependencies:
- dependency-name: anyhow
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* [auto-commit] Update all Cargo lock files

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: dependabot-buildkite <dependabot-buildkite@noreply.solana.com>
2022-03-01 00:16:26 -07:00
Tyera Eulberg
3b5b71ce44 Improve UX querying rpc for blocks at or before the snapshot from boot (#23403)
* Bump first-available block to first complete block

* Remove obsolete purges in tests (PrimaryIndex toggling no longer in use

* Check first-available block in Rpc check_slot_cleaned_up
2022-02-28 23:57:41 -07:00
Tyera Eulberg
19448ba078 Allow sub-rent-exempt-minimum transfers to 1nc1nerator (#23382)
* Add failing test

* Allow small burns to incinerator

* Use check_id method
2022-02-28 23:56:34 -07:00
dependabot[bot]
e3fa55f88d chore: bump hmac from 0.12.0 to 0.12.1 (#23396)
* chore: bump hmac from 0.12.0 to 0.12.1

Bumps [hmac](https://github.com/RustCrypto/MACs) from 0.12.0 to 0.12.1.
- [Release notes](https://github.com/RustCrypto/MACs/releases)
- [Commits](https://github.com/RustCrypto/MACs/compare/hmac-v0.12.0...hmac-v0.12.1)

---
updated-dependencies:
- dependency-name: hmac
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* [auto-commit] Update all Cargo lock files

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: dependabot-buildkite <dependabot-buildkite@noreply.solana.com>
2022-03-01 02:07:33 +00:00
Trent Nelson
5877e38baa docs: resolve svgbob binary 2022-02-28 17:33:30 -07:00
Tyera Eulberg
0de7b757d0 Update durable-nonce docs (#23397)
* Use parsable blockhash string

* Remove deprecated cli command from docs
2022-02-28 17:03:26 -07:00
dependabot[bot]
6dfd1b9883 chore: bump quinn from 0.8.0 to 0.8.1 (#23380)
Bumps [quinn](https://github.com/quinn-rs/quinn) from 0.8.0 to 0.8.1.
- [Release notes](https://github.com/quinn-rs/quinn/releases)
- [Commits](https://github.com/quinn-rs/quinn/compare/0.8.0...0.8.1)

---
updated-dependencies:
- dependency-name: quinn
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-28 15:50:58 -07:00
Trent Nelson
6666f23c01 client: expose creating RpcClients with custom RpcSender impls 2022-02-28 22:04:15 +00:00
Jeff Washington (jwash)
f0a235d16f add comment (#23378) 2022-02-28 15:18:42 -06:00
Jeff Washington (jwash)
4eeb9f4648 acct idx comments (#23377) 2022-02-28 15:00:53 -06:00
Trent Nelson
f814c4a082 ci: move all formerly-default-queue jobs to solana queue 2022-02-28 13:50:34 -07:00
dependabot[bot]
911c5a8362 chore: bump cipher from 0.3.0 to 0.4.3 (#23362)
* chore: bump cipher from 0.3.0 to 0.4.3

Bumps [cipher](https://github.com/RustCrypto/traits) from 0.3.0 to 0.4.3.
- [Release notes](https://github.com/RustCrypto/traits/releases)
- [Commits](https://github.com/RustCrypto/traits/compare/cipher-v0.3.0...cipher-v0.4.3)

---
updated-dependencies:
- dependency-name: cipher
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* Update Cargo.lock files

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Tyera Eulberg <tyera@solana.com>
2022-02-28 11:06:18 -07:00
tigarcia
22d2a40133 Updating known validators in the docs for testnet 2022-02-28 09:57:57 -07:00
Jeff Washington (jwash)
611d745241 refactor rent_due for normal case of exempt (#23350) 2022-02-28 09:42:42 -06:00
Alexander Meißner
ee3fc39f1c Refactor: Prepare stake_instruction.rs to remove KeyedAccounts (#23375)
* Adds instruction_account_indices to stake instruction.

* Uses instruction_account_indices in stake instruction.

* Replaces get_sysvar_with_account_check by get_sysvar_with_account_check2 in stake instruction.

* Adds check_number_of_instruction_accounts().
2022-02-28 16:24:40 +01:00
dependabot[bot]
fe18ea35a2 chore: bump cargo_metadata from 0.14.1 to 0.14.2 (#23365)
Bumps [cargo_metadata](https://github.com/oli-obk/cargo_metadata) from 0.14.1 to 0.14.2.
- [Release notes](https://github.com/oli-obk/cargo_metadata/releases)
- [Commits](https://github.com/oli-obk/cargo_metadata/compare/0.14.1...0.14.2)

---
updated-dependencies:
- dependency-name: cargo_metadata
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-28 05:46:47 +00:00
Jeff Washington (jwash)
30dafc7135 list -> slot_list (#23355) 2022-02-27 23:08:58 -06:00
dependabot[bot]
186bb19965 chore:(deps): bump url-parse from 1.5.7 to 1.5.10 in /explorer (#23371)
Bumps [url-parse](https://github.com/unshiftio/url-parse) from 1.5.7 to 1.5.10.
- [Release notes](https://github.com/unshiftio/url-parse/releases)
- [Commits](https://github.com/unshiftio/url-parse/compare/1.5.7...1.5.10)

---
updated-dependencies:
- dependency-name: url-parse
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-28 04:33:23 +00:00
Michael Vines
87b76aeeb0 Align the solana validators output columns for -ud,-ut, and -um 2022-02-27 16:54:13 -08:00
SAITO Kosuke | Coinfra NFT Creator
a57c7ba5df Change comments (#23366)
* change url

* change comment

Co-authored-by: cosuke2000 <saitou@matchingood.co.jp>
2022-02-27 10:36:25 -07:00
dependabot[bot]
2efb909051 chore: bump fd-lock from 3.0.3 to 3.0.4 (#23347)
Bumps [fd-lock](https://github.com/yoshuawuyts/fd-lock) from 3.0.3 to 3.0.4.
- [Release notes](https://github.com/yoshuawuyts/fd-lock/releases)
- [Commits](https://github.com/yoshuawuyts/fd-lock/commits/v3.0.4)

---
updated-dependencies:
- dependency-name: fd-lock
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-27 08:16:43 +00:00
dependabot[bot]
418076ab3e chore: bump ed25519-dalek-bip32 from 0.1.1 to 0.2.0 (#23346)
* chore: bump ed25519-dalek-bip32 from 0.1.1 to 0.2.0

Bumps [ed25519-dalek-bip32](https://github.com/jpopesculian/ed25519-dalek-bip32) from 0.1.1 to 0.2.0.
- [Release notes](https://github.com/jpopesculian/ed25519-dalek-bip32/releases)
- [Commits](https://github.com/jpopesculian/ed25519-dalek-bip32/commits/v0.2.0)

---
updated-dependencies:
- dependency-name: ed25519-dalek-bip32
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* [auto-commit] Update all Cargo lock files

* Bump derivation-path

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: dependabot-buildkite <dependabot-buildkite@noreply.solana.com>
Co-authored-by: Tyera Eulberg <tyera@solana.com>
2022-02-27 00:15:04 +00:00
Tyera Eulberg
36484f4f08 Prevent new RentPaying state created by paying fees (#23358)
* Add failing test

* Check fee-payer rent-state change on load

* Add more test cases

* Review comments
2022-02-26 12:10:01 -07:00
Alexander Meißner
569d531573 Code cleanup: In vote and stake processor (#23353)
* Enable benchmarks of vote processor.

* Inlines from_keyed_account() in stake instruction.
2022-02-25 21:05:05 +01:00
Jeff Washington (jwash)
0ad4757159 plumbing for 'other_slot' in 'update_index' (#23330) 2022-02-25 12:58:08 -06:00
Alexander Meißner
e2fa6a0f7a Replaces KeyedAccount by BorrowedAccount in vote processor (#23348)
* Use instruction_account_indices, get_sysvar_with_account_check2 and instruction_context.get_signers in vote processor.

* Replaces KeyedAccount by BorrowedAccount in vote processor.

* Removes KeyedAccount from benches in vote processor.
2022-02-25 17:22:54 +01:00
Brooks Prumo
533eca3b4c Simplify replay_blockstore_into_bank() (#23282) 2022-02-25 06:57:04 -06:00
axleiro
ff04a5b989 changing permission on "buildkite-pipeline-in-disk" 2022-02-25 15:35:47 +05:30
axleiro
cf18292fd3 adding a new script with in_disk_env var 2022-02-25 15:28:04 +05:30
axleiro
92216c01ff Create buildkite-pipeline-in-disk.sh 2022-02-25 15:26:45 +05:30
axleiro
0e5a58b883 adding a copy of "pipeline-upload.sh"
for the new pipeline
2022-02-25 15:25:37 +05:30
Trent Nelson
d4292774c5 checks 2022-02-25 08:05:28 +00:00
Trent Nelson
97b5a71ceb bump rust to 1.59.0 2022-02-25 08:05:28 +00:00
Alexander Meißner
804fac8ea9 Removes KeyedAccount from tests in vote processor. (#23333) 2022-02-25 08:21:28 +01:00
dependabot[bot]
985af71241 chore: bump sha2 from 0.10.1 to 0.10.2 (#23343)
* chore: bump sha2 from 0.10.1 to 0.10.2

Bumps [sha2](https://github.com/RustCrypto/hashes) from 0.10.1 to 0.10.2.
- [Release notes](https://github.com/RustCrypto/hashes/releases)
- [Commits](https://github.com/RustCrypto/hashes/compare/sha2-v0.10.1...sha2-v0.10.2)

---
updated-dependencies:
- dependency-name: sha2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* [auto-commit] Update all Cargo lock files

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: dependabot-buildkite <dependabot-buildkite@noreply.solana.com>
2022-02-24 23:57:42 -07:00
dependabot[bot]
98f059e89c chore: bump reqwest from 0.11.6 to 0.11.9 (#23337)
* chore: bump reqwest from 0.11.6 to 0.11.9

Bumps [reqwest](https://github.com/seanmonstar/reqwest) from 0.11.6 to 0.11.9.
- [Release notes](https://github.com/seanmonstar/reqwest/releases)
- [Changelog](https://github.com/seanmonstar/reqwest/blob/master/CHANGELOG.md)
- [Commits](https://github.com/seanmonstar/reqwest/compare/v0.11.6...v0.11.9)

---
updated-dependencies:
- dependency-name: reqwest
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* [auto-commit] Update all Cargo lock files

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: dependabot-buildkite <dependabot-buildkite@noreply.solana.com>
2022-02-24 22:40:01 -07:00
Michael Vines
274a6a5ccb Narrow scope of client_targets build 2022-02-24 21:08:43 -08:00
Tyera Eulberg
2d55a8e1c3 Refresh blockhash for fee calculations (#23338) 2022-02-24 21:21:38 -07:00
dependabot[bot]
3f35d7fad9 chore: bump rustls from 0.20.2 to 0.20.4 (#23324)
* chore: bump rustls from 0.20.2 to 0.20.4

Bumps [rustls](https://github.com/rustls/rustls) from 0.20.2 to 0.20.4.
- [Release notes](https://github.com/rustls/rustls/releases)
- [Changelog](https://github.com/rustls/rustls/blob/main/RELEASE_NOTES.md)
- [Commits](https://github.com/rustls/rustls/compare/v/0.20.2...v/0.20.4)

---
updated-dependencies:
- dependency-name: rustls
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* [auto-commit] Update all Cargo lock files

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: dependabot-buildkite <dependabot-buildkite@noreply.solana.com>
2022-02-24 19:57:35 -07:00
Michael Vines
7111918596 solana gossip now includes feature set information 2022-02-24 18:04:38 -08:00
Trent Nelson
5e0086c1ee followup safety checks for #23295 2022-02-24 17:50:58 -07:00
alnoki
d1f141484e Update derivation path integer sign specification (#23336)
Previously, `ACCOUNT` and `CHANGE` were specified as being positive integers, but since both can assume a value of 0 (as in the given example), they should be specified as nonnegative integers
2022-02-24 16:49:58 -07:00
dependabot[bot]
db12d90735 chore: bump ouroboros from 0.13.0 to 0.14.2 (#23328)
* chore: bump ouroboros from 0.13.0 to 0.14.2

Bumps [ouroboros](https://github.com/joshua-maros/ouroboros) from 0.13.0 to 0.14.2.
- [Release notes](https://github.com/joshua-maros/ouroboros/releases)
- [Commits](https://github.com/joshua-maros/ouroboros/commits/0.14.2)

---
updated-dependencies:
- dependency-name: ouroboros
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* [auto-commit] Update all Cargo lock files

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: dependabot-buildkite <dependabot-buildkite@noreply.solana.com>
2022-02-24 15:56:13 -07:00
Jeff Washington (jwash)
2207e49633 all TestValdiators act like validators (#23318) 2022-02-24 12:12:47 -06:00
Jeff Washington (jwash)
39c86c6c44 fmt (#23329) 2022-02-24 12:12:29 -06:00
dependabot[bot]
6c53f7f588 chore: bump tokio from 1.16.1 to 1.17.0 (#23322)
* chore: bump tokio from 1.16.1 to 1.17.0

Bumps [tokio](https://github.com/tokio-rs/tokio) from 1.16.1 to 1.17.0.
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.16.1...tokio-1.17.0)

---
updated-dependencies:
- dependency-name: tokio
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* [auto-commit] Update all Cargo lock files

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: dependabot-buildkite <dependabot-buildkite@noreply.solana.com>
2022-02-24 10:54:50 -07:00
Jeff Washington (jwash)
2b0f16e7c3 slot per account in StorableAccounts (#23313) 2022-02-24 10:34:38 -06:00
Jeff Washington (jwash)
017170c99d DiskIdx: new items are not dirty by default (#23123) 2022-02-24 10:17:35 -06:00
Alexander Meißner
a14c7c37ee Replaces KeyedAccount by BorrowedAccount in the config processor. (#23302) 2022-02-24 09:44:25 +01:00
dependabot[bot]
9d2232306e chore: bump tungstenite from 0.16.0 to 0.17.2 (#23268)
* chore: bump tungstenite from 0.16.0 to 0.17.2

Bumps [tungstenite](https://github.com/snapview/tungstenite-rs) from 0.16.0 to 0.17.2.
- [Release notes](https://github.com/snapview/tungstenite-rs/releases)
- [Changelog](https://github.com/snapview/tungstenite-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/snapview/tungstenite-rs/compare/v0.16.0...v0.17.2)

---
updated-dependencies:
- dependency-name: tungstenite
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* Bump tokio-tungstenite in tandem

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Tyera Eulberg <tyera@solana.com>
2022-02-24 01:39:55 -07:00
steviez
12bddbc4ec Use rocksdb property constant instead of local constant (#23147) 2022-02-23 23:02:11 -06:00
Brooks Prumo
fcaf01e243 Add test to check destination for stake splitting (#23303) 2022-02-23 22:47:57 -06:00
dependabot[bot]
856d29c7b7 chore: bump parking_lot from 0.11.2 to 0.12.0 (#23087)
* chore: bump parking_lot from 0.11.2 to 0.12.0

Bumps [parking_lot](https://github.com/Amanieu/parking_lot) from 0.11.2 to 0.12.0.
- [Release notes](https://github.com/Amanieu/parking_lot/releases)
- [Changelog](https://github.com/Amanieu/parking_lot/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Amanieu/parking_lot/compare/0.11.2...0.12.0)

---
updated-dependencies:
- dependency-name: parking_lot
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* Sync parking_lot

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Tyera Eulberg <tyera@solana.com>
2022-02-23 20:07:07 -07:00
Trent Nelson
6a0d2fcfa7 docs: post merge review for #23286 2022-02-24 01:53:54 +00:00
Jeff Washington (jwash)
4bc440666a add arg --disable_accounts_disk_index (#23308) 2022-02-23 18:07:24 -06:00
Jeff Washington (jwash)
c0d0724be0 clippy (#23310) 2022-02-23 18:07:00 -06:00
Jeff Washington (jwash)
7ee549e5ae fix params for store_accounts_frozen (#23312) 2022-02-23 17:40:51 -06:00
Jeff Washington (jwash)
227df52213 update comment (#23314) 2022-02-23 17:33:06 -06:00
Jeff Washington (jwash)
99a057927c started_from_validator, ignore env var for cli (#23309) 2022-02-23 17:15:43 -06:00
Jeff Washington (jwash)
cafc18c3f9 update_index uses ReadableAccount to reduce params (#23305) 2022-02-23 17:01:23 -06:00
Masaya Funakoshi
0dd36f3201 Grammar corrections PR#23206 Review Fixes (#23291)
* Accounts page grammar edits

* calling-between-programs page grammar edits

* PR #23206 "Grammar Corrections" review fixes

* Update docs/src/developing/clients/jsonrpc-api.md

Co-authored-by: Tyera Eulberg <teulberg@gmail.com>

* Update docs/src/developing/programming-model/accounts.md

Co-authored-by: Tyera Eulberg <teulberg@gmail.com>

Co-authored-by: Tyera Eulberg <teulberg@gmail.com>
2022-02-23 15:34:13 -07:00
Michael Vines
3ea9ca35fa grant public access to ProofError enum 2022-02-23 14:22:42 -08:00
Jeff Washington (jwash)
a245efe83d trait for acct data with slot per item (#23285) 2022-02-23 15:22:29 -06:00
Trent Nelson
c81dd602c4 Hack fix for ICE as seen in CI 2022-02-23 11:17:39 -07:00
Lijun Wang
084fb79ad8 Unhide AccountsDb plugin parameters (#23284)
* Unhide AccountsDb plugin parameters

* addressed feedback from Trent
2022-02-23 10:01:14 -08:00
Bruno
2e3eafaa11 RPC Client: Use Tokio's RwLock instead of std to make using in async easier (#23299) 2022-02-23 09:33:32 -08:00
Jeff Washington (jwash)
2996f1f783 add comments (#23275) 2022-02-23 10:53:11 -06:00
kirill lykov
05f04a22b7 Fix small problems in transaction-dos tool (#23234)
* Fix small problems in transaction-dos tool
2022-02-23 17:17:06 +01:00
Justin Starry
d0e85c293f Fix rustfmt check (#23296) 2022-02-23 16:38:53 +08:00
Michael Vines
6872fc79ba Derive Clone for AeCiphertext (#23293) 2022-02-22 22:47:26 -08:00
Dmitri Makarov
0a3a18744f Update the consumed compute units cost for hashing syscalls
This change prevents zero-cost computation of hash functions on
unbound number of zero-length slices of data.  The cost for each slice
is at least equal to the base cost of a memory operation, but could be
more for longer slices.
2022-02-23 02:32:41 +00:00
Trent Nelson
09d064c090 docs: clarify spl token account creation handling for exchange integrations 2022-02-23 00:22:44 +00:00
Masaya Funakoshi
ff604efc44 Grammar corrections (#23206)
* Accounts page grammar edits

* Runtime page grammar edits

* calling-between-programs page grammar edits

* transactions page grammar edits

* small changes with e.g. following Chicago Manual
2022-02-22 15:23:47 -08:00
Gavin Chan
20d031e2b8 Refactor ExecuteTimings w/ enum-indexed array (#23085) 2022-02-22 14:46:56 -08:00
Trent Nelson
5766567e9f ci: revert cache version hack 2022-02-22 19:01:29 +00:00
Brooks Prumo
88e1192c6b Refactor new() and default() for CostTracker (#23267) 2022-02-22 10:44:23 -06:00
Anton Lazarev
cadc2de77d add github workflow to check solana-client compilation on android/ios targets 2022-02-22 09:05:51 -07:00
Jeff Washington (jwash)
8b32e80ee2 DiskIdx: rename 'remove' to 'evict' (#23188) 2022-02-22 09:40:25 -06:00
Jeff Washington (jwash)
7ebf398ed7 AcctIdx: env var "SOLANA_TEST_ACCOUNTS_INDEX_MEMORY_LIMIT_MB" (#23194)
* AcctIdx: env var "SOLANA_TEST_ACCOUNTS_INDEX_MEMORY_LIMIT_MB"

* ignore env var when starting as validator

* Update runtime/src/bucket_map_holder.rs

Co-authored-by: Trent Nelson <trent.a.b.nelson@gmail.com>

Co-authored-by: Trent Nelson <trent.a.b.nelson@gmail.com>
2022-02-22 09:40:12 -06:00
Brooks Prumo
ac70070e5b Add MINIMUM_STAKE_DELEGATION constant (#23259)
Co-authored-by: Tyera Eulberg <teulberg@gmail.com>
2022-02-22 09:21:23 -06:00
microwavedcola1
f00016b647 add support for time in force order type (#23255)
Signed-off-by: microwavedcola1 <microwavedcola@gmail.com>
2022-02-22 21:12:02 +08:00
Justin Starry
bcda74f42f Fix builtin handling on epoch boundaries (#23256) 2022-02-22 20:54:08 +08:00
Justin Starry
c97f34a0fd Add script for running nightly rustfmt on all workspaces (#23244)
* Add script for running nightly rustfmt on all workspaces

* invalidate ci cache
2022-02-22 11:59:06 +08:00
Michael Vines
72c68695b5 Do not keep oldest full snapshot 2022-02-21 17:10:31 -07:00
Alexander Meißner
d0d256ee9a Bump rbpf to v0.2.24 (#23263) 2022-02-21 23:38:12 +01:00
Tyera Eulberg
7e08ae1d0c Revert "Add simulation detection countermeasure (#22880)" (#23261)
This reverts commit c42b80f099.
2022-02-21 21:15:37 +00:00
Pierre
ebe3d2d59d fix: simulateTransaction accounts items can be null (#23229)
* fix: simulated accounts can be null

* Use Missing rather than token program id

Co-authored-by: Arrowana <8245419+Arrowana@users.noreply.github.com>
2022-02-21 14:20:11 +08:00
HaoranYi
04d23a1597 fix memory ordering in append_vec (#23215) 2022-02-20 20:30:49 -06:00
dependabot[bot]
42bdf1d864 chore:(deps): bump url-parse from 1.5.1 to 1.5.7 in /explorer (#23245)
Bumps [url-parse](https://github.com/unshiftio/url-parse) from 1.5.1 to 1.5.7.
- [Release notes](https://github.com/unshiftio/url-parse/releases)
- [Commits](https://github.com/unshiftio/url-parse/compare/1.5.1...1.5.7)

---
updated-dependencies:
- dependency-name: url-parse
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-19 11:34:37 +00:00
Yueh-Hsuan Chiang
8c872e9ce0 (LedgerStore/FIFO) Refactor FIFO options and sanity check. (#23131) 2022-02-19 00:58:38 -08:00
buffalu
70ebab2c82 Add rustfmt.toml and cargo fmt (#23238)
* fmt

* formatted

Co-authored-by: Lucas B <buffalu@jito.network>
2022-02-19 13:32:29 +08:00
Yueh-Hsuan Chiang
1add82aa9e (Ledger Store Benchmark) Add flags for checking shred storage size. (#22451) 2022-02-18 19:35:28 -08:00
Trent Nelson
e2d0ede630 cli: accept 'system' program id mnemonic for with seed 2022-02-18 19:51:18 -07:00
Trent Nelson
dcd0a39cb6 cli: coerce with seed program id mnemonics to uppercase 2022-02-18 19:51:18 -07:00
Justin Starry
1719d2349f Skip adding builtins if they will be removed (#23233)
* Add failing test for precompile transition

* Skip adding builtins if they will be removed

* cargo clean

* nits

* fix abi check

* remove workaround

Co-authored-by: Jack May <jack@solana.com>
2022-02-18 18:36:59 -08:00
Alexander Meißner
ee7e411d68 Replaces KeyedAccount by BorrowedAccount in system_instruction_processor. (#23217)
* Adds InstructionContext::check_number_of_instruction_accounts() and InstructionContext::get_instruction_account_key().
Bases check_sysvar_account() on instuction account indices.

* Adds instruction_account_indices enums to system_instruction_processor.

* Reorders parameters and adds InstructionContext.

* Replaces KeyedAccount by BorrowedAccount in system_instruction_processor (part 1).

* Replaces KeyedAccount by BorrowedAccount in system_instruction_processor (part 2).

* Replaces KeyedAccount by BorrowedAccount in system_instruction_processor (part 3).

* Replaces KeyedAccount by BorrowedAccount in system_instruction_processor (part 4).

* Replaces KeyedAccount by BorrowedAccount in system_instruction_processor (part 5).

* Code cleanup
2022-02-19 02:06:33 +01:00
Jack May
970f543ef6 Precompiles owned by the native loader (#23237) 2022-02-18 15:41:59 -08:00
Justin Starry
1351c1bbcf Explorer: Add ed25519 sigverify precompile to search results (#23228) 2022-02-18 07:18:01 +00:00
Will Hickey
c696944d36 Add --locked to spl-token-cli install (#23223) 2022-02-17 22:09:29 -06:00
mooori
5726f42a7c feat(stake-program): support splitWithSeed (#23213) 2022-02-17 12:21:07 -07:00
Dmitri Makarov
ae7fedf0b1 Extend buildkite cargo cache name to include host side rust version 2022-02-17 09:53:51 -08:00
samkim-crypto
b4100a9b5d Add additional zkp for fee (#23112)
* zk-token-sdk: add equality proof for fee

* zk-token-sdk: tweak some naming conventions for readability

* zk-token-sdk: add verify withdraw withheld instruction

* zk-token-sdk: add test for withdraw withheld verification

* zk-token-sdk: more renaming of variables for readability

* zk-token-sdk: cargo fmt

* zk-token-sdk: minor

* zk-token-sdk: resolve bpf compilation warnings

* zk-token-sdk: minor update to doc
2022-02-17 12:45:07 -05:00
Alexander Meißner
1a68f81f89 Replaces KeyedAccount by BorrowedAccount in nonce_keyed_account. (#23214)
* Adds get_sysvar_with_account_check2 for ABIv2.

* Replaces get_signers() and get_sysvar_with_account_check() in system_instruction_processor.

* Replaces KeyedAccount by BorrowedAccount in nonce_keyed_account.
2022-02-17 17:36:55 +01:00
Alexander Meißner
da00b39f4f Cleanup: get_program_key() and get_loader_key() in TransactionContext (#23191)
* Moves TransactionContext::get_program_key() to InstructionContext::get_program_key().

* Removes TransactionContext::get_loader_key().

* Test full program and loader executable account chain in BPF loader.
2022-02-17 10:16:28 +01:00
carllin
619335df1a Add execute timings (#23097) 2022-02-17 01:14:32 -05:00
Trent Nelson
fa680a35ea docs: remove wallet ads 2022-02-16 22:19:10 -07:00
sethgirvan
b66a304e7b docs: fix typos (#22320) 2022-02-16 22:57:22 -06:00
Tao Zhu
3c235503de remove block limit for bench tests to avoid skew test result (#23204) 2022-02-17 03:44:34 +00:00
455 changed files with 22611 additions and 17321 deletions

View File

@@ -0,0 +1,19 @@
#!/usr/bin/env bash
#
# This script is used to upload the full buildkite pipeline. The steps defined
# in the buildkite UI should simply be:
#
# steps:
# - command: ".buildkite/pipeline-upload.sh"
#
set -e
cd "$(dirname "$0")"/..
source ci/_
sudo chmod 0777 ci/buildkite-pipeline-in-disk.sh
_ ci/buildkite-pipeline-in-disk.sh pipeline.yml
echo +++ pipeline
cat pipeline.yml
_ buildkite-agent pipeline upload pipeline.yml

View File

@@ -13,7 +13,13 @@ export PS4="++"
#
eval "$(ci/channel-info.sh)"
eval "$(ci/sbf-tools-info.sh)"
export CARGO_TARGET_CACHE=$HOME/cargo-target-cache/"$CHANNEL"-"$BUILDKITE_LABEL"-"$SBF_TOOLS_VERSION"
source "ci/rust-version.sh"
HOST_RUST_VERSION="$rust_stable"
pattern='^[0-9]+\.[0-9]+\.[0-9]+$'
if [[ ${HOST_RUST_VERSION} =~ ${pattern} ]]; then
HOST_RUST_VERSION="${rust_stable%.*}"
fi
export CARGO_TARGET_CACHE=$HOME/cargo-target-cache/"$CHANNEL"-"$BUILDKITE_LABEL"-"$SBF_TOOLS_VERSION"-"$HOST_RUST_VERSION"
(
set -x
MAX_CACHE_SIZE=18 # gigabytes

View File

@@ -4,3 +4,4 @@
#### Proposed Solution

View File

@@ -1,5 +1,9 @@
#### Problem
#### Summary of Changes
Fixes #

66
.github/workflows/client-targets.yml vendored Normal file
View File

@@ -0,0 +1,66 @@
name: client_targets
on:
pull_request:
branches:
- master
paths:
- "client/**"
- "sdk/**"
- ".github/workflows/client-targets.yml"
env:
CARGO_TERM_COLOR: always
jobs:
check_compilation:
name: Client compilation
runs-on: ${{ matrix.os }}
strategy:
matrix:
target: [aarch64-apple-ios, x86_64-apple-ios, aarch64-apple-darwin, x86_64-apple-darwin, aarch64-linux-android, armv7-linux-androideabi, i686-linux-android, x86_64-linux-android]
include:
- target: aarch64-apple-ios
platform: ios
os: macos-latest
- target: x86_64-apple-ios
platform: ios
os: macos-latest
- target: aarch64-apple-darwin
platform: ios
os: macos-latest
- target: x86_64-apple-darwin
platform: ios
os: macos-latest
- target: aarch64-linux-android
platform: android
os: ubuntu-latest
- target: armv7-linux-androideabi
platform: android
os: ubuntu-latest
- target: i686-linux-android
platform: android
os: ubuntu-latest
- target: x86_64-linux-android
platform: android
os: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
target: ${{ matrix.target }}
- name: Install cargo-ndk
if: ${{ matrix.platform == 'android' }}
run: cargo install cargo-ndk
- uses: actions-rs/cargo@v1
if: ${{ matrix.platform == 'android' }}
with:
command: ndk
args: --target ${{ matrix.target }} build -p solana-client
- uses: actions-rs/cargo@v1
if: ${{ matrix.platform == 'ios' }}
with:
command: build
args: -p solana-client --target ${{ matrix.target }}

View File

@@ -17,8 +17,7 @@ jobs:
vercel-token: ${{ secrets.VERCEL_TOKEN }} # Required
github-token: ${{ secrets.GITHUB_TOKEN }} #Optional
vercel-org-id: ${{ secrets.ORG_ID}} #Required
vercel-project-id: ${{ secrets.PROJECT_ID}} #Required
working-directory: ./explorer
vercel-project-id: ${{ secrets.PROJECT_ID}} #Required
scope: ${{ secrets.TEAM_ID }}
- name: vercel url
@@ -36,17 +35,24 @@ jobs:
#filtered_url=$(cat vercelfile2.txt )
#echo "$filtered_url" >> .env.preview1
- name: Run tests
- name: Fetching Vercel Preview Deployment Link
uses: mathiasvr/command-output@v1
id: tests2
id: test1
with:
run: |
echo "$(cat .env.preview1)"
- name: Fetching PR commit URL
uses: mathiasvr/command-output@v1
id: test2
with:
run: |
HEAD_SHA=$(curl -H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/solana-labs/solana/pulls | jq .[0] | jq -r .head.sha)
USER_NAME=$(curl -H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/solana-labs/solana/pulls | jq .[0] | jq -r .head.user.login)
echo "github.com/$USER_NAME/solana/commit/$HEAD_SHA"
- name: Slack Notification1
- name: Slack Notification4
uses: rtCamp/action-slack-notify@master
env:
SLACK_MESSAGE: ${{ steps.tests2.outputs.stdout }}
SLACK_TITLE: Vercel "Explorer" Preview Deployment Link
SLACK_MESSAGE: ' Vercel Link: ${{ steps.test1.outputs.stdout }} PR Commit: ${{steps.test2.outputs.stdout}}'
SLACK_TITLE: Vercel "Explorer" Preview Deployment Link , PR Commit
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}

View File

@@ -30,7 +30,8 @@ jobs:
runs-on: ubuntu-latest
defaults:
run:
working-directory: explorer
working-directory: explorer
steps:
- uses: actions/checkout@v2
with:
@@ -38,9 +39,8 @@ jobs:
- uses: amondnet/vercel-action@v20
with:
vercel-token: ${{ secrets.VERCEL_TOKEN }} # Required
github-token: ${{ secrets.GITHUB_TOKEN }} #Optional
github-token: ${{ secrets.PAT }} #Optional
vercel-args: '--prod' #for production
vercel-org-id: ${{ secrets.ORG_ID}} #Required
vercel-project-id: ${{ secrets.PROJECT_ID}} #Required
working-directory: ./explorer
scope: ${{ secrets.TEAM_ID }}

1738
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-account-decoder"
version = "1.10.0"
version = "1.10.1"
description = "Solana account decoder"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
@@ -18,10 +18,10 @@ Inflector = "0.11.4"
lazy_static = "1.4.0"
serde = "1.0.136"
serde_derive = "1.0.103"
serde_json = "1.0.78"
solana-config-program = { path = "../programs/config", version = "=1.10.0" }
solana-sdk = { path = "../sdk", version = "=1.10.0" }
solana-vote-program = { path = "../programs/vote", version = "=1.10.0" }
serde_json = "1.0.79"
solana-config-program = { path = "../programs/config", version = "=1.10.1" }
solana-sdk = { path = "../sdk", version = "=1.10.1" }
solana-vote-program = { path = "../programs/vote", version = "=1.10.1" }
spl-token = { version = "=3.2.0", features = ["no-entrypoint"] }
thiserror = "1.0"
zstd = "0.10.0"

View File

@@ -33,7 +33,7 @@ pub type StringDecimals = String;
pub const MAX_BASE58_BYTES: usize = 128;
/// A duplicate representation of an Account for pretty JSON serialization
#[derive(Serialize, Deserialize, Clone, Debug)]
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct UiAccount {
pub lamports: u64,

View File

@@ -2,7 +2,7 @@
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
edition = "2021"
name = "solana-accounts-bench"
version = "1.10.0"
version = "1.10.1"
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.10.0" }
solana-runtime = { path = "../runtime", version = "=1.10.0" }
solana-measure = { path = "../measure", version = "=1.10.0" }
solana-sdk = { path = "../sdk", version = "=1.10.0" }
solana-version = { path = "../version", version = "=1.10.0" }
solana-logger = { path = "../logger", version = "=1.10.1" }
solana-runtime = { path = "../runtime", version = "=1.10.1" }
solana-measure = { path = "../measure", version = "=1.10.1" }
solana-sdk = { path = "../sdk", version = "=1.10.1" }
solana-version = { path = "../version", version = "=1.10.1" }
clap = "2.33.1"
[package.metadata.docs.rs]

View File

@@ -2,7 +2,7 @@
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
edition = "2021"
name = "solana-accounts-cluster-bench"
version = "1.10.0"
version = "1.10.1"
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.10.0" }
solana-clap-utils = { path = "../clap-utils", version = "=1.10.0" }
solana-client = { path = "../client", version = "=1.10.0" }
solana-faucet = { path = "../faucet", version = "=1.10.0" }
solana-gossip = { path = "../gossip", version = "=1.10.0" }
solana-logger = { path = "../logger", version = "=1.10.0" }
solana-measure = { path = "../measure", version = "=1.10.0" }
solana-net-utils = { path = "../net-utils", version = "=1.10.0" }
solana-runtime = { path = "../runtime", version = "=1.10.0" }
solana-sdk = { path = "../sdk", version = "=1.10.0" }
solana-streamer = { path = "../streamer", version = "=1.10.0" }
solana-transaction-status = { path = "../transaction-status", version = "=1.10.0" }
solana-version = { path = "../version", version = "=1.10.0" }
solana-account-decoder = { path = "../account-decoder", version = "=1.10.1" }
solana-clap-utils = { path = "../clap-utils", version = "=1.10.1" }
solana-client = { path = "../client", version = "=1.10.1" }
solana-faucet = { path = "../faucet", version = "=1.10.1" }
solana-gossip = { path = "../gossip", version = "=1.10.1" }
solana-logger = { path = "../logger", version = "=1.10.1" }
solana-measure = { path = "../measure", version = "=1.10.1" }
solana-net-utils = { path = "../net-utils", version = "=1.10.1" }
solana-runtime = { path = "../runtime", version = "=1.10.1" }
solana-sdk = { path = "../sdk", version = "=1.10.1" }
solana-streamer = { path = "../streamer", version = "=1.10.1" }
solana-transaction-status = { path = "../transaction-status", version = "=1.10.1" }
solana-version = { path = "../version", version = "=1.10.1" }
spl-token = { version = "=3.2.0", features = ["no-entrypoint"] }
[dev-dependencies]
solana-core = { path = "../core", version = "=1.10.0" }
solana-local-cluster = { path = "../local-cluster", version = "=1.10.0" }
solana-test-validator = { path = "../test-validator", version = "=1.10.0" }
solana-core = { path = "../core", version = "=1.10.1" }
solana-local-cluster = { path = "../local-cluster", version = "=1.10.1" }
solana-test-validator = { path = "../test-validator", version = "=1.10.1" }
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -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.10.0"
version = "1.10.1"
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.10.0" }
solana-transaction-status = { path = "../transaction-status", version = "=1.10.0" }
solana-sdk = { path = "../sdk", version = "=1.10.1" }
solana-transaction-status = { path = "../transaction-status", version = "=1.10.1" }
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -9,9 +9,7 @@ use {
thiserror::Error,
};
impl Eq for ReplicaAccountInfo<'_> {}
#[derive(Clone, PartialEq, Debug)]
#[derive(Debug, Clone, PartialEq, Eq)]
/// Information about an account being updated
pub struct ReplicaAccountInfo<'a> {
/// The Pubkey for the account
@@ -112,7 +110,7 @@ pub enum AccountsDbPluginError {
}
/// The current status of a slot
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SlotStatus {
/// The highest slot of the heaviest fork processed by the node. Ledger state at this slot is
/// not derived from a confirmed or finalized block, but if multiple forks are present, is from

View File

@@ -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.10.0"
version = "1.10.1"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -15,14 +15,14 @@ crossbeam-channel = "0.5"
json5 = "0.4.1"
libloading = "0.7.3"
log = "0.4.11"
serde_json = "1.0.78"
solana-accountsdb-plugin-interface = { path = "../accountsdb-plugin-interface", version = "=1.10.0" }
solana-measure = { path = "../measure", version = "=1.10.0" }
solana-metrics = { path = "../metrics", version = "=1.10.0" }
solana-rpc = { path = "../rpc", version = "=1.10.0" }
solana-runtime = { path = "../runtime", version = "=1.10.0" }
solana-sdk = { path = "../sdk", version = "=1.10.0" }
solana-transaction-status = { path = "../transaction-status", version = "=1.10.0" }
serde_json = "1.0.79"
solana-accountsdb-plugin-interface = { path = "../accountsdb-plugin-interface", version = "=1.10.1" }
solana-measure = { path = "../measure", version = "=1.10.1" }
solana-metrics = { path = "../metrics", version = "=1.10.1" }
solana-rpc = { path = "../rpc", version = "=1.10.1" }
solana-runtime = { path = "../runtime", version = "=1.10.1" }
solana-sdk = { path = "../sdk", version = "=1.10.1" }
solana-transaction-status = { path = "../transaction-status", version = "=1.10.1" }
thiserror = "1.0.30"
[package.metadata.docs.rs]

View File

@@ -52,7 +52,7 @@ impl SlotStatusNotifierImpl {
for plugin in plugin_manager.plugins.iter_mut() {
let mut measure = Measure::start("accountsdb-plugin-update-slot");
match plugin.update_slot_status(slot, parent, slot_status.clone()) {
match plugin.update_slot_status(slot, parent, slot_status) {
Err(err) => {
error!(
"Failed to update slot status at slot {}, error: {} to plugin {}",

View File

@@ -2,7 +2,7 @@
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
edition = "2021"
name = "solana-banking-bench"
version = "1.10.0"
version = "1.10.1"
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.10.0" }
solana-gossip = { path = "../gossip", version = "=1.10.0" }
solana-ledger = { path = "../ledger", version = "=1.10.0" }
solana-logger = { path = "../logger", version = "=1.10.0" }
solana-measure = { path = "../measure", version = "=1.10.0" }
solana-perf = { path = "../perf", version = "=1.10.0" }
solana-poh = { path = "../poh", version = "=1.10.0" }
solana-runtime = { path = "../runtime", version = "=1.10.0" }
solana-streamer = { path = "../streamer", version = "=1.10.0" }
solana-sdk = { path = "../sdk", version = "=1.10.0" }
solana-version = { path = "../version", version = "=1.10.0" }
solana-core = { path = "../core", version = "=1.10.1" }
solana-gossip = { path = "../gossip", version = "=1.10.1" }
solana-ledger = { path = "../ledger", version = "=1.10.1" }
solana-logger = { path = "../logger", version = "=1.10.1" }
solana-measure = { path = "../measure", version = "=1.10.1" }
solana-perf = { path = "../perf", version = "=1.10.1" }
solana-poh = { path = "../poh", version = "=1.10.1" }
solana-runtime = { path = "../runtime", version = "=1.10.1" }
solana-streamer = { path = "../streamer", version = "=1.10.1" }
solana-sdk = { path = "../sdk", version = "=1.10.1" }
solana-version = { path = "../version", version = "=1.10.1" }
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -175,6 +175,11 @@ fn main() {
let mut bank_forks = BankForks::new(bank0);
let mut bank = bank_forks.working_bank();
// set cost tracker limits to MAX so it will not filter out TXs
bank.write_cost_tracker()
.unwrap()
.set_limits(std::u64::MAX, std::u64::MAX, std::u64::MAX);
info!("threads: {} txs: {}", num_threads, total_num_transactions);
let same_payer = matches.is_present("same_payer");
@@ -335,6 +340,13 @@ fn main() {
bank = bank_forks.working_bank();
insert_time.stop();
// set cost tracker limits to MAX so it will not filter out TXs
bank.write_cost_tracker().unwrap().set_limits(
std::u64::MAX,
std::u64::MAX,
std::u64::MAX,
);
poh_recorder.lock().unwrap().set_bank(&bank);
assert!(poh_recorder.lock().unwrap().bank().is_some());
if bank.slot() > 32 {

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-banks-client"
version = "1.10.0"
version = "1.10.1"
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.3"
futures = "0.3"
solana-banks-interface = { path = "../banks-interface", version = "=1.10.0" }
solana-program = { path = "../sdk/program", version = "=1.10.0" }
solana-sdk = { path = "../sdk", version = "=1.10.0" }
solana-banks-interface = { path = "../banks-interface", version = "=1.10.1" }
solana-program = { path = "../sdk/program", version = "=1.10.1" }
solana-sdk = { path = "../sdk", version = "=1.10.1" }
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.10.0" }
solana-banks-server = { path = "../banks-server", version = "=1.10.0" }
solana-runtime = { path = "../runtime", version = "=1.10.1" }
solana-banks-server = { path = "../banks-server", version = "=1.10.1" }
[lib]
crate-type = ["lib"]

View File

@@ -5,8 +5,10 @@
//! but they are undocumented, may change over time, and are generally more
//! cumbersome to use.
pub use crate::error::BanksClientError;
pub use solana_banks_interface::{BanksClient as TarpcClient, TransactionStatus};
pub use {
crate::error::BanksClientError,
solana_banks_interface::{BanksClient as TarpcClient, TransactionStatus},
};
use {
borsh::BorshDeserialize,
futures::{future::join_all, Future, FutureExt, TryFutureExt},

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-banks-interface"
version = "1.10.0"
version = "1.10.1"
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.136", features = ["derive"] }
solana-sdk = { path = "../sdk", version = "=1.10.0" }
solana-sdk = { path = "../sdk", version = "=1.10.1" }
tarpc = { version = "0.27.2", features = ["full"] }
[lib]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-banks-server"
version = "1.10.0"
version = "1.10.1"
description = "Solana banks server"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
@@ -13,10 +13,10 @@ edition = "2021"
bincode = "1.3.3"
crossbeam-channel = "0.5"
futures = "0.3"
solana-banks-interface = { path = "../banks-interface", version = "=1.10.0" }
solana-runtime = { path = "../runtime", version = "=1.10.0" }
solana-sdk = { path = "../sdk", version = "=1.10.0" }
solana-send-transaction-service = { path = "../send-transaction-service", version = "=1.10.0" }
solana-banks-interface = { path = "../banks-interface", version = "=1.10.1" }
solana-runtime = { path = "../runtime", version = "=1.10.1" }
solana-sdk = { path = "../sdk", version = "=1.10.1" }
solana-send-transaction-service = { path = "../send-transaction-service", version = "=1.10.1" }
tarpc = { version = "0.27.2", features = ["full"] }
tokio = { version = "1", features = ["full"] }
tokio-serde = { version = "0.8", features = ["bincode"] }

View File

@@ -2,7 +2,7 @@
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
edition = "2021"
name = "solana-bench-streamer"
version = "1.10.0"
version = "1.10.1"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -11,9 +11,9 @@ publish = false
[dependencies]
crossbeam-channel = "0.5"
clap = "2.33.1"
solana-streamer = { path = "../streamer", version = "=1.10.0" }
solana-net-utils = { path = "../net-utils", version = "=1.10.0" }
solana-version = { path = "../version", version = "=1.10.0" }
solana-streamer = { path = "../streamer", version = "=1.10.1" }
solana-net-utils = { path = "../net-utils", version = "=1.10.1" }
solana-version = { path = "../version", version = "=1.10.1" }
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -2,7 +2,7 @@
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
edition = "2021"
name = "solana-bench-tps"
version = "1.10.0"
version = "1.10.1"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -13,25 +13,25 @@ clap = "2.33.1"
crossbeam-channel = "0.5"
log = "0.4.14"
rayon = "1.5.1"
serde_json = "1.0.78"
serde_json = "1.0.79"
serde_yaml = "0.8.23"
solana-core = { path = "../core", version = "=1.10.0" }
solana-genesis = { path = "../genesis", version = "=1.10.0" }
solana-client = { path = "../client", version = "=1.10.0" }
solana-faucet = { path = "../faucet", version = "=1.10.0" }
solana-gossip = { path = "../gossip", version = "=1.10.0" }
solana-logger = { path = "../logger", version = "=1.10.0" }
solana-metrics = { path = "../metrics", version = "=1.10.0" }
solana-measure = { path = "../measure", version = "=1.10.0" }
solana-net-utils = { path = "../net-utils", version = "=1.10.0" }
solana-runtime = { path = "../runtime", version = "=1.10.0" }
solana-sdk = { path = "../sdk", version = "=1.10.0" }
solana-streamer = { path = "../streamer", version = "=1.10.0" }
solana-version = { path = "../version", version = "=1.10.0" }
solana-core = { path = "../core", version = "=1.10.1" }
solana-genesis = { path = "../genesis", version = "=1.10.1" }
solana-client = { path = "../client", version = "=1.10.1" }
solana-faucet = { path = "../faucet", version = "=1.10.1" }
solana-gossip = { path = "../gossip", version = "=1.10.1" }
solana-logger = { path = "../logger", version = "=1.10.1" }
solana-metrics = { path = "../metrics", version = "=1.10.1" }
solana-measure = { path = "../measure", version = "=1.10.1" }
solana-net-utils = { path = "../net-utils", version = "=1.10.1" }
solana-runtime = { path = "../runtime", version = "=1.10.1" }
solana-sdk = { path = "../sdk", version = "=1.10.1" }
solana-streamer = { path = "../streamer", version = "=1.10.1" }
solana-version = { path = "../version", version = "=1.10.1" }
[dev-dependencies]
serial_test = "0.5.1"
solana-local-cluster = { path = "../local-cluster", version = "=1.10.0" }
serial_test = "0.6.0"
solana-local-cluster = { path = "../local-cluster", version = "=1.10.1" }
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -110,7 +110,7 @@ fn generate_chunked_transfers(
shared_txs: &SharedTransactions,
shared_tx_active_thread_count: Arc<AtomicIsize>,
source_keypair_chunks: Vec<Vec<&Keypair>>,
dest_keypair_chunks: &mut Vec<VecDeque<&Keypair>>,
dest_keypair_chunks: &mut [VecDeque<&Keypair>],
threads: usize,
duration: Duration,
sustained: bool,
@@ -475,6 +475,7 @@ fn do_tx_transfers<T: Client>(
let tx_len = txs0.len();
let transfer_start = Instant::now();
let mut old_transactions = false;
let mut transactions = Vec::<_>::new();
for tx in txs0 {
let now = timestamp();
// Transactions that are too old will be rejected by the cluster Don't bother
@@ -483,10 +484,13 @@ fn do_tx_transfers<T: Client>(
old_transactions = true;
continue;
}
client
.async_send_transaction(tx.0)
.expect("async_send_transaction in do_tx_transfers");
transactions.push(tx.0);
}
if let Err(error) = client.async_send_batch(transactions) {
warn!("send_batch_sync in do_tx_transfers failed: {}", error);
}
if old_transactions {
let mut shared_txs_wl = shared_txs.write().expect("write lock in do_tx_transfers");
shared_txs_wl.clear();

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-bloom"
version = "1.10.0"
version = "1.10.1"
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.136", features = ["rc"] }
rayon = "1.5.1"
serde_derive = "1.0.103"
solana-frozen-abi = { path = "../frozen-abi", version = "=1.10.0" }
solana-frozen-abi-macro = { path = "../frozen-abi/macro", version = "=1.10.0" }
solana-sdk = { path = "../sdk", version = "=1.10.0" }
solana-frozen-abi = { path = "../frozen-abi", version = "=1.10.1" }
solana-frozen-abi-macro = { path = "../frozen-abi/macro", version = "=1.10.1" }
solana-sdk = { path = "../sdk", version = "=1.10.1" }
log = "0.4.14"
[lib]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-bucket-map"
version = "1.10.0"
version = "1.10.1"
description = "solana-bucket-map"
homepage = "https://solana.com/"
documentation = "https://docs.rs/solana-bucket-map"
@@ -11,10 +11,10 @@ license = "Apache-2.0"
edition = "2021"
[dependencies]
solana-sdk = { path = "../sdk", version = "=1.10.0" }
memmap2 = "0.5.2"
solana-sdk = { path = "../sdk", version = "=1.10.1" }
memmap2 = "0.5.3"
log = { version = "0.4.11" }
solana-measure = { path = "../measure", version = "=1.10.0" }
solana-measure = { path = "../measure", version = "=1.10.1" }
rand = "0.7.0"
tempfile = "3.3.0"
modular-bitfield = "0.11.2"
@@ -22,7 +22,7 @@ modular-bitfield = "0.11.2"
[dev-dependencies]
fs_extra = "1.2.0"
rayon = "1.5.0"
solana-logger = { path = "../logger", version = "=1.10.0" }
solana-logger = { path = "../logger", version = "=1.10.1" }
[lib]
crate-type = ["lib"]

View File

@@ -0,0 +1,365 @@
#!/usr/bin/env bash
#
# Builds a buildkite pipeline based on the environment variables
#
set -e
cd "$(dirname "$0")"/..
output_file=${1:-/dev/stderr}
if [[ -n $CI_PULL_REQUEST ]]; then
IFS=':' read -ra affected_files <<< "$(buildkite-agent meta-data get affected_files)"
if [[ ${#affected_files[*]} -eq 0 ]]; then
echo "Unable to determine the files affected by this PR"
exit 1
fi
else
affected_files=()
fi
annotate() {
if [[ -n $BUILDKITE ]]; then
buildkite-agent annotate "$@"
fi
}
# Checks if a CI pull request affects one or more path patterns. Each
# pattern argument is checked in series. If one of them found to be affected,
# return immediately as such.
#
# Bash regular expressions are permitted in the pattern:
# affects .rs$ -- any file or directory ending in .rs
# affects .rs -- also matches foo.rs.bar
# affects ^snap/ -- anything under the snap/ subdirectory
# affects snap/ -- also matches foo/snap/
# Any pattern starting with the ! character will be negated:
# affects !^docs/ -- anything *not* under the docs/ subdirectory
#
affects() {
if [[ -z $CI_PULL_REQUEST ]]; then
# affected_files metadata is not currently available for non-PR builds so assume
# the worse (affected)
return 0
fi
# Assume everyting needs to be tested when any Dockerfile changes
for pattern in ^ci/docker-rust/Dockerfile ^ci/docker-rust-nightly/Dockerfile "$@"; do
if [[ ${pattern:0:1} = "!" ]]; then
for file in "${affected_files[@]}"; do
if [[ ! $file =~ ${pattern:1} ]]; then
return 0 # affected
fi
done
else
for file in "${affected_files[@]}"; do
if [[ $file =~ $pattern ]]; then
return 0 # affected
fi
done
fi
done
return 1 # not affected
}
# Checks if a CI pull request affects anything other than the provided path patterns
#
# Syntax is the same as `affects()` except that the negation prefix is not
# supported
#
affects_other_than() {
if [[ -z $CI_PULL_REQUEST ]]; then
# affected_files metadata is not currently available for non-PR builds so assume
# the worse (affected)
return 0
fi
for file in "${affected_files[@]}"; do
declare matched=false
for pattern in "$@"; do
if [[ $file =~ $pattern ]]; then
matched=true
fi
done
if ! $matched; then
return 0 # affected
fi
done
return 1 # not affected
}
start_pipeline() {
echo "# $*" > "$output_file"
echo "steps:" >> "$output_file"
}
command_step() {
cat >> "$output_file" <<EOF
- name: "$1"
command: "$2"
timeout_in_minutes: $3
artifact_paths: "log-*.txt"
EOF
}
trigger_secondary_step() {
cat >> "$output_file" <<"EOF"
- trigger: "solana-secondary"
branches: "!pull/*"
async: true
build:
message: "${BUILDKITE_MESSAGE}"
commit: "${BUILDKITE_COMMIT}"
branch: "${BUILDKITE_BRANCH}"
env:
TRIGGERED_BUILDKITE_TAG: "${BUILDKITE_TAG}"
EOF
}
wait_step() {
echo " - wait" >> "$output_file"
}
all_test_steps() {
command_step checks ". ci/rust-version.sh; ci/docker-run.sh \$\$rust_nightly_docker_image ci/test-checks.sh" 20
wait_step
# Coverage...
if affects \
.rs$ \
Cargo.lock$ \
Cargo.toml$ \
^ci/rust-version.sh \
^ci/test-coverage.sh \
^scripts/coverage.sh \
; then
command_step coverage ". ci/rust-version.sh; ci/docker-run.sh \$\$rust_nightly_docker_image ci/test-coverage.sh" 40
wait_step
else
annotate --style info --context test-coverage \
"Coverage skipped as no .rs files were modified"
fi
# Coverage in disk...
if affects \
.rs$ \
Cargo.lock$ \
Cargo.toml$ \
^ci/rust-version.sh \
^ci/test-coverage.sh \
^scripts/coverage-in-disk.sh \
; then
command_step coverage-in-disk ". ci/rust-version.sh; ci/docker-run.sh \$\$rust_nightly_docker_image ci/test-coverage.sh" 40
wait_step
else
annotate --style info --context test-coverage \
"Coverage skipped as no .rs files were modified"
fi
# Full test suite
command_step stable ". ci/rust-version.sh; ci/docker-run.sh \$\$rust_stable_docker_image ci/test-stable.sh" 60
wait_step
# BPF test suite
if affects \
.rs$ \
Cargo.lock$ \
Cargo.toml$ \
^ci/rust-version.sh \
^ci/test-stable-bpf.sh \
^ci/test-stable.sh \
^ci/test-local-cluster.sh \
^core/build.rs \
^fetch-perf-libs.sh \
^programs/ \
^sdk/ \
; then
cat >> "$output_file" <<"EOF"
- command: "ci/test-stable-bpf.sh"
name: "stable-bpf"
timeout_in_minutes: 20
artifact_paths: "bpf-dumps.tar.bz2"
agents:
- "queue=default"
EOF
else
annotate --style info \
"Stable-BPF skipped as no relevant files were modified"
fi
# Perf test suite
if affects \
.rs$ \
Cargo.lock$ \
Cargo.toml$ \
^ci/rust-version.sh \
^ci/test-stable-perf.sh \
^ci/test-stable.sh \
^ci/test-local-cluster.sh \
^core/build.rs \
^fetch-perf-libs.sh \
^programs/ \
^sdk/ \
; then
cat >> "$output_file" <<"EOF"
- command: "ci/test-stable-perf.sh"
name: "stable-perf"
timeout_in_minutes: 20
artifact_paths: "log-*.txt"
agents:
- "queue=cuda"
EOF
else
annotate --style info \
"Stable-perf skipped as no relevant files were modified"
fi
# Downstream backwards compatibility
if affects \
.rs$ \
Cargo.lock$ \
Cargo.toml$ \
^ci/rust-version.sh \
^ci/test-stable-perf.sh \
^ci/test-stable.sh \
^ci/test-local-cluster.sh \
^core/build.rs \
^fetch-perf-libs.sh \
^programs/ \
^sdk/ \
^scripts/build-downstream-projects.sh \
; then
cat >> "$output_file" <<"EOF"
- command: "scripts/build-downstream-projects.sh"
name: "downstream-projects"
timeout_in_minutes: 30
EOF
else
annotate --style info \
"downstream-projects skipped as no relevant files were modified"
fi
# Downstream Anchor projects backwards compatibility
if affects \
.rs$ \
Cargo.lock$ \
Cargo.toml$ \
^ci/rust-version.sh \
^ci/test-stable-perf.sh \
^ci/test-stable.sh \
^ci/test-local-cluster.sh \
^core/build.rs \
^fetch-perf-libs.sh \
^programs/ \
^sdk/ \
^scripts/build-downstream-anchor-projects.sh \
; then
cat >> "$output_file" <<"EOF"
- command: "scripts/build-downstream-anchor-projects.sh"
name: "downstream-anchor-projects"
timeout_in_minutes: 10
EOF
else
annotate --style info \
"downstream-anchor-projects skipped as no relevant files were modified"
fi
# Wasm support
if affects \
^ci/test-wasm.sh \
^ci/test-stable.sh \
^sdk/ \
; then
command_step wasm ". ci/rust-version.sh; ci/docker-run.sh \$\$rust_stable_docker_image ci/test-wasm.sh" 20
else
annotate --style info \
"wasm skipped as no relevant files were modified"
fi
# Benches...
if affects \
.rs$ \
Cargo.lock$ \
Cargo.toml$ \
^ci/rust-version.sh \
^ci/test-coverage.sh \
^ci/test-bench.sh \
; then
command_step bench "ci/test-bench.sh" 30
else
annotate --style info --context test-bench \
"Bench skipped as no .rs files were modified"
fi
command_step "local-cluster" \
". ci/rust-version.sh; ci/docker-run.sh \$\$rust_stable_docker_image ci/test-local-cluster.sh" \
40
command_step "local-cluster-flakey" \
". ci/rust-version.sh; ci/docker-run.sh \$\$rust_stable_docker_image ci/test-local-cluster-flakey.sh" \
10
command_step "local-cluster-slow" \
". ci/rust-version.sh; ci/docker-run.sh \$\$rust_stable_docker_image ci/test-local-cluster-slow.sh" \
30
}
pull_or_push_steps() {
command_step sanity "ci/test-sanity.sh" 5
wait_step
# Check for any .sh file changes
if affects .sh$; then
command_step shellcheck "ci/shellcheck.sh" 5
wait_step
fi
# Run the full test suite by default, skipping only if modifications are local
# to some particular areas of the tree
if affects_other_than ^.buildkite ^.mergify .md$ ^docs/ ^web3.js/ ^explorer/ ^.gitbook; then
all_test_steps
fi
# web3.js, explorer and docs changes run on Travis or Github actions...
}
if [[ -n $BUILDKITE_TAG ]]; then
start_pipeline "Tag pipeline for $BUILDKITE_TAG"
annotate --style info --context release-tag \
"https://github.com/solana-labs/solana/releases/$BUILDKITE_TAG"
# Jump directly to the secondary build to publish release artifacts quickly
trigger_secondary_step
exit 0
fi
if [[ $BUILDKITE_BRANCH =~ ^pull ]]; then
echo "+++ Affected files in this PR"
for file in "${affected_files[@]}"; do
echo "- $file"
done
start_pipeline "Pull request pipeline for $BUILDKITE_BRANCH"
# Add helpful link back to the corresponding Github Pull Request
annotate --style info --context pr-backlink \
"Github Pull Request: https://github.com/solana-labs/solana/$BUILDKITE_BRANCH"
if [[ $GITHUB_USER = "dependabot[bot]" ]]; then
command_step dependabot "ci/dependabot-pr.sh" 5
wait_step
fi
pull_or_push_steps
exit 0
fi
start_pipeline "Push pipeline for ${BUILDKITE_BRANCH:-?unknown branch?}"
pull_or_push_steps
wait_step
trigger_secondary_step
exit 0

View File

@@ -102,6 +102,8 @@ command_step() {
command: "$2"
timeout_in_minutes: $3
artifact_paths: "log-*.txt"
agents:
- "queue=solana"
EOF
}
@@ -168,7 +170,7 @@ all_test_steps() {
timeout_in_minutes: 20
artifact_paths: "bpf-dumps.tar.bz2"
agents:
- "queue=default"
- "queue=solana"
EOF
else
annotate --style info \
@@ -221,6 +223,8 @@ EOF
- command: "scripts/build-downstream-projects.sh"
name: "downstream-projects"
timeout_in_minutes: 30
agents:
- "queue=solana"
EOF
else
annotate --style info \
@@ -246,6 +250,8 @@ EOF
- command: "scripts/build-downstream-anchor-projects.sh"
name: "downstream-anchor-projects"
timeout_in_minutes: 10
agents:
- "queue=solana"
EOF
else
annotate --style info \

View File

@@ -8,11 +8,6 @@ src_root="$(readlink -f "${here}/..")"
cd "${src_root}"
cargo_audit_ignores=(
# failure is officially deprecated/unmaintained
#
# Blocked on multiple upstream crates removing their `failure` dependency.
--ignore RUSTSEC-2020-0036
# `net2` crate has been deprecated; use `socket2` instead
#
# Blocked on https://github.com/paritytech/jsonrpc/issues/575
@@ -30,22 +25,10 @@ cargo_audit_ignores=(
# generic-array: arr! macro erases lifetimes
#
# Blocked on libsecp256k1 releasing with upgraded dependencies
# https://github.com/paritytech/libsecp256k1/issues/66
# Blocked on new spl dependencies on solana-program v1.9
# due to curve25519-dalek dependency
--ignore RUSTSEC-2020-0146
# hyper: Lenient `hyper` header parsing of `Content-Length` could allow request smuggling
#
# Blocked on jsonrpc removing dependency on unmaintained `websocket`
# https://github.com/paritytech/jsonrpc/issues/605
--ignore RUSTSEC-2021-0078
# hyper: Integer overflow in `hyper`'s parsing of the `Transfer-Encoding` header leads to data loss
#
# Blocked on jsonrpc removing dependency on unmaintained `websocket`
# https://github.com/paritytech/jsonrpc/issues/605
--ignore RUSTSEC-2021-0079
# chrono: Potential segfault in `localtime_r` invocations
#
# Blocked due to no safe upgrade

View File

@@ -1,4 +1,4 @@
FROM solanalabs/rust:1.58.1
FROM solanalabs/rust:1.59.0
ARG date
RUN set -x \

View File

@@ -1,6 +1,6 @@
# Note: when the rust version is changed also modify
# ci/rust-version.sh to pick up the new image tag
FROM rust:1.58.1
FROM rust:1.59.0
# Add Google Protocol Buffers for Libra's metrics library.
ENV PROTOC_VERSION 3.8.0

View File

@@ -18,13 +18,13 @@
if [[ -n $RUST_STABLE_VERSION ]]; then
stable_version="$RUST_STABLE_VERSION"
else
stable_version=1.58.1
stable_version=1.59.0
fi
if [[ -n $RUST_NIGHTLY_VERSION ]]; then
nightly_version="$RUST_NIGHTLY_VERSION"
else
nightly_version=2022-01-21
nightly_version=2022-02-24
fi

View File

@@ -69,20 +69,14 @@ _ ci/order-crates-for-publishing.py
# run nightly clippy for `sdk/` as there's a moderate amount of nightly-only code there
_ "$cargo" nightly clippy -Zunstable-options --workspace --all-targets -- --deny=warnings --deny=clippy::integer_arithmetic
_ "$cargo" stable fmt --all -- --check
_ "$cargo" nightly fmt --all -- --check
_ ci/do-audit.sh
{
cd programs/bpf
for project in rust/*/ ; do
echo "+++ do_bpf_checks $project"
(
cd "$project"
_ "$cargo" nightly clippy -- --deny=warnings --allow=clippy::missing_safety_doc
_ "$cargo" stable fmt -- --check
)
done
_ "$cargo" nightly clippy --all -- --deny=warnings --allow=clippy::missing_safety_doc
_ "$cargo" nightly fmt --all -- --check
}
echo --- ok

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-clap-utils"
version = "1.10.0"
version = "1.10.1"
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.10.0" }
solana-remote-wallet = { path = "../remote-wallet", version = "=1.10.0", default-features = false}
solana-sdk = { path = "../sdk", version = "=1.10.0" }
solana-perf = { path = "../perf", version = "=1.10.1" }
solana-remote-wallet = { path = "../remote-wallet", version = "=1.10.1", default-features = false}
solana-sdk = { path = "../sdk", version = "=1.10.1" }
thiserror = "1.0.30"
tiny-bip39 = "0.8.2"
uriparse = "0.6.3"

View File

@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.foundation>"]
edition = "2021"
name = "solana-cli-config"
description = "Blockchain, Rebuilt for Scale"
version = "1.10.0"
version = "1.10.1"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -18,7 +18,7 @@ serde_yaml = "0.8.23"
url = "2.2.2"
[dev-dependencies]
anyhow = "1.0.53"
anyhow = "1.0.56"
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.foundation>"]
edition = "2021"
name = "solana-cli-output"
description = "Blockchain, Rebuilt for Scale"
version = "1.10.0"
version = "1.10.1"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -18,13 +18,13 @@ humantime = "2.0.1"
Inflector = "0.11.4"
indicatif = "0.16.2"
serde = "1.0.136"
serde_json = "1.0.78"
solana-account-decoder = { path = "../account-decoder", version = "=1.10.0" }
solana-clap-utils = { path = "../clap-utils", version = "=1.10.0" }
solana-client = { path = "../client", version = "=1.10.0" }
solana-sdk = { path = "../sdk", version = "=1.10.0" }
solana-transaction-status = { path = "../transaction-status", version = "=1.10.0" }
solana-vote-program = { path = "../programs/vote", version = "=1.10.0" }
serde_json = "1.0.79"
solana-account-decoder = { path = "../account-decoder", version = "=1.10.1" }
solana-clap-utils = { path = "../clap-utils", version = "=1.10.1" }
solana-client = { path = "../client", version = "=1.10.1" }
solana-sdk = { path = "../sdk", version = "=1.10.1" }
solana-transaction-status = { path = "../transaction-status", version = "=1.10.1" }
solana-vote-program = { path = "../programs/vote", version = "=1.10.1" }
spl-memo = { version = "=3.0.1", features = ["no-entrypoint"] }
[package.metadata.docs.rs]

View File

@@ -393,19 +393,19 @@ impl fmt::Display for CliValidators {
) -> fmt::Result {
fn non_zero_or_dash(v: u64, max_v: u64) -> String {
if v == 0 {
"- ".into()
" - ".into()
} else if v == max_v {
format!("{:>8} ( 0)", v)
format!("{:>9} ( 0)", v)
} else if v > max_v.saturating_sub(100) {
format!("{:>8} ({:>3})", v, -(max_v.saturating_sub(v) as isize))
format!("{:>9} ({:>3})", v, -(max_v.saturating_sub(v) as isize))
} else {
format!("{:>8} ", v)
format!("{:>9} ", v)
}
}
writeln!(
f,
"{} {:<44} {:<44} {:>3}% {:>14} {:>14} {:>7} {:>8} {:>7} {}",
"{} {:<44} {:<44} {:>3}% {:>14} {:>14} {:>7} {:>8} {:>7} {:>22} ({:.2}%)",
if validator.delinquent {
WARNING.to_string()
} else {
@@ -419,19 +419,19 @@ impl fmt::Display for CliValidators {
if let Some(skip_rate) = validator.skip_rate {
format!("{:.2}%", skip_rate)
} else {
"- ".to_string()
"- ".to_string()
},
validator.epoch_credits,
validator.version,
if validator.activated_stake > 0 {
format!(
"{} ({:.2}%)",
build_balance_message(validator.activated_stake, use_lamports_unit, true),
100. * validator.activated_stake as f64 / total_active_stake as f64,
)
} else {
"-".into()
},
build_balance_message_with_config(
validator.activated_stake,
&BuildBalanceMessageConfig {
use_lamports_unit,
trim_trailing_zeros: false,
..BuildBalanceMessageConfig::default()
}
),
100. * validator.activated_stake as f64 / total_active_stake as f64,
)
}
@@ -441,13 +441,13 @@ impl fmt::Display for CliValidators {
0
};
let header = style(format!(
"{:padding$} {:<44} {:<38} {} {} {} {} {} {} {}",
"{:padding$} {:<44} {:<38} {} {} {} {} {} {} {}",
" ",
"Identity",
"Vote Account",
"Commission",
"Last Vote ",
"Root Slot ",
"Last Vote ",
"Root Slot ",
"Skip Rate",
"Credits",
"Version",
@@ -2451,6 +2451,8 @@ pub struct CliGossipNode {
pub rpc_host: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub feature_set: Option<u32>,
}
impl CliGossipNode {
@@ -2463,6 +2465,7 @@ impl CliGossipNode {
tpu_port: info.tpu.map(|addr| addr.port()),
rpc_host: info.rpc.map(|addr| addr.to_string()),
version: info.version,
feature_set: info.feature_set,
}
}
}
@@ -2488,7 +2491,7 @@ impl fmt::Display for CliGossipNode {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"{:15} | {:44} | {:6} | {:5} | {:21} | {}",
"{:15} | {:44} | {:6} | {:5} | {:21} | {:8}| {}",
unwrap_to_string_or_none(self.ip_address.as_ref()),
self.identity_label
.as_ref()
@@ -2497,6 +2500,7 @@ impl fmt::Display for CliGossipNode {
unwrap_to_string_or_none(self.tpu_port.as_ref()),
unwrap_to_string_or_none(self.rpc_host.as_ref()),
unwrap_to_string_or_default(self.version.as_ref(), "unknown"),
unwrap_to_string_or_default(self.feature_set.as_ref(), "unknown"),
)
}
}
@@ -2511,10 +2515,10 @@ impl fmt::Display for CliGossipNodes {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
writeln!(
f,
"IP Address | Node identifier \
| Gossip | TPU | RPC Address | Version\n\
"IP Address | Identity \
| Gossip | TPU | RPC Address | Version | Feature Set\n\
----------------+----------------------------------------------+\
--------+-------+-----------------------+----------------",
--------+-------+-----------------------+---------+----------------",
)?;
for node in self.0.iter() {
writeln!(f, "{}", node)?;

View File

@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.foundation>"]
edition = "2021"
name = "solana-cli"
description = "Blockchain, Rebuilt for Scale"
version = "1.10.0"
version = "1.10.1"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -22,34 +22,34 @@ log = "0.4.14"
humantime = "2.0.1"
num-traits = "0.2"
pretty-hex = "0.2.1"
reqwest = { version = "0.11.6", default-features = false, features = ["blocking", "rustls-tls", "json"] }
semver = "1.0.5"
reqwest = { version = "0.11.9", default-features = false, features = ["blocking", "rustls-tls", "json"] }
semver = "1.0.6"
serde = "1.0.136"
serde_derive = "1.0.103"
serde_json = "1.0.78"
solana-account-decoder = { path = "../account-decoder", version = "=1.10.0" }
solana-bpf-loader-program = { path = "../programs/bpf_loader", version = "=1.10.0" }
solana-clap-utils = { path = "../clap-utils", version = "=1.10.0" }
solana-cli-config = { path = "../cli-config", version = "=1.10.0" }
solana-cli-output = { path = "../cli-output", version = "=1.10.0" }
solana-client = { path = "../client", version = "=1.10.0" }
solana-config-program = { path = "../programs/config", version = "=1.10.0" }
solana-faucet = { path = "../faucet", version = "=1.10.0" }
solana-logger = { path = "../logger", version = "=1.10.0" }
solana-program-runtime = { path = "../program-runtime", version = "=1.10.0" }
solana_rbpf = "=0.2.23"
solana-remote-wallet = { path = "../remote-wallet", version = "=1.10.0" }
solana-sdk = { path = "../sdk", version = "=1.10.0" }
solana-transaction-status = { path = "../transaction-status", version = "=1.10.0" }
solana-version = { path = "../version", version = "=1.10.0" }
solana-vote-program = { path = "../programs/vote", version = "=1.10.0" }
serde_json = "1.0.79"
solana-account-decoder = { path = "../account-decoder", version = "=1.10.1" }
solana-bpf-loader-program = { path = "../programs/bpf_loader", version = "=1.10.1" }
solana-clap-utils = { path = "../clap-utils", version = "=1.10.1" }
solana-cli-config = { path = "../cli-config", version = "=1.10.1" }
solana-cli-output = { path = "../cli-output", version = "=1.10.1" }
solana-client = { path = "../client", version = "=1.10.1" }
solana-config-program = { path = "../programs/config", version = "=1.10.1" }
solana-faucet = { path = "../faucet", version = "=1.10.1" }
solana-logger = { path = "../logger", version = "=1.10.1" }
solana-program-runtime = { path = "../program-runtime", version = "=1.10.1" }
solana_rbpf = "=0.2.24"
solana-remote-wallet = { path = "../remote-wallet", version = "=1.10.1" }
solana-sdk = { path = "../sdk", version = "=1.10.1" }
solana-transaction-status = { path = "../transaction-status", version = "=1.10.1" }
solana-version = { path = "../version", version = "=1.10.1" }
solana-vote-program = { path = "../programs/vote", version = "=1.10.1" }
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.10.0" }
solana-test-validator = { path = "../test-validator", version = "=1.10.0" }
solana-streamer = { path = "../streamer", version = "=1.10.1" }
solana-test-validator = { path = "../test-validator", version = "=1.10.1" }
tempfile = "3.3.0"
[[bin]]

View File

@@ -88,6 +88,7 @@ pub enum CliCommand {
timeout: Duration,
blockhash: Option<Hash>,
print_timestamp: bool,
additional_fee: Option<u32>,
},
Rent {
data_length: usize,
@@ -977,6 +978,7 @@ pub fn process_command(config: &CliConfig) -> ProcessResult {
timeout,
blockhash,
print_timestamp,
additional_fee,
} => process_ping(
&rpc_client,
config,
@@ -985,6 +987,7 @@ pub fn process_command(config: &CliConfig) -> ProcessResult {
timeout,
blockhash,
*print_timestamp,
additional_fee,
),
CliCommand::Rent {
data_length,

View File

@@ -33,12 +33,14 @@ use {
rpc_request::DELINQUENT_VALIDATOR_SLOT_DISTANCE,
rpc_response::SlotInfo,
},
solana_program_runtime::compute_budget::ComputeBudget,
solana_remote_wallet::remote_wallet::RemoteWalletManager,
solana_sdk::{
account::from_account,
account_utils::StateMut,
clock::{self, Clock, Slot},
commitment_config::CommitmentConfig,
compute_budget::ComputeBudgetInstruction,
epoch_schedule::Epoch,
hash::Hash,
message::Message,
@@ -269,6 +271,13 @@ impl ClusterQuerySubCommands for App<'_, '_> {
.default_value("15")
.help("Wait up to timeout seconds for transaction confirmation"),
)
.arg(
Arg::with_name("additional_fee")
.long("additional-fee")
.value_name("NUMBER")
.takes_value(true)
.help("Request additional-fee for transaction"),
)
.arg(blockhash_arg()),
)
.subcommand(
@@ -513,6 +522,7 @@ pub fn parse_cluster_ping(
let timeout = Duration::from_secs(value_t_or_exit!(matches, "timeout", u64));
let blockhash = value_of(matches, BLOCKHASH_ARG.name);
let print_timestamp = matches.is_present("print_timestamp");
let additional_fee = value_of(matches, "additional_fee");
Ok(CliCommandInfo {
command: CliCommand::Ping {
interval,
@@ -520,6 +530,7 @@ pub fn parse_cluster_ping(
timeout,
blockhash,
print_timestamp,
additional_fee,
},
signers: vec![default_signer.signer_from_path(matches, wallet_manager)?],
})
@@ -1350,6 +1361,7 @@ pub fn process_ping(
timeout: &Duration,
fixed_blockhash: &Option<Hash>,
print_timestamp: bool,
additional_fee: &Option<u32>,
) -> ProcessResult {
let (signal_sender, signal_receiver) = unbounded();
ctrlc::set_handler(move || {
@@ -1374,6 +1386,7 @@ pub fn process_ping(
blockhash_from_cluster = true;
}
}
'mainloop: for seq in 0..count.unwrap_or(std::u64::MAX) {
let now = Instant::now();
if fixed_blockhash.is_none() && now.duration_since(blockhash_acquired).as_secs() > 60 {
@@ -1388,8 +1401,18 @@ pub fn process_ping(
lamports += 1;
let build_message = |lamports| {
let ix = system_instruction::transfer(&config.signers[0].pubkey(), &to, lamports);
Message::new(&[ix], Some(&config.signers[0].pubkey()))
let mut ixs = vec![system_instruction::transfer(
&config.signers[0].pubkey(),
&to,
lamports,
)];
if let Some(additional_fee) = additional_fee {
ixs.push(ComputeBudgetInstruction::request_units(
ComputeBudget::new(false).max_units as u32,
*additional_fee,
));
}
Message::new(&ixs, Some(&config.signers[0].pubkey()))
};
let (message, _) = resolve_spend_tx_and_check_account_balance(
rpc_client,
@@ -2019,6 +2042,7 @@ pub fn process_transaction_history(
RpcTransactionConfig {
encoding: Some(UiTransactionEncoding::Base64),
commitment: Some(CommitmentConfig::confirmed()),
max_supported_transaction_version: None,
},
) {
Ok(confirmed_transaction) => {
@@ -2312,6 +2336,7 @@ mod tests {
Hash::from_str("4CCNp28j6AhGq7PkjPDP4wbQWBS8LLbQin2xV5n8frKX").unwrap()
),
print_timestamp: true,
additional_fee: None,
},
signers: vec![default_keypair.into()],
}

View File

@@ -39,7 +39,9 @@ use {
system_program,
transaction::Transaction,
},
solana_transaction_status::{Encodable, EncodedTransaction, UiTransactionEncoding},
solana_transaction_status::{
Encodable, EncodedTransaction, TransactionBinaryEncoding, UiTransactionEncoding,
},
std::{fmt::Write as FmtWrite, fs::File, io::Write, sync::Arc},
};
@@ -189,7 +191,7 @@ impl WalletSubCommands for App<'_, '_> {
Arg::with_name("encoding")
.index(2)
.value_name("ENCODING")
.possible_values(&["base58", "base64"]) // Subset of `UiTransactionEncoding` enum
.possible_values(&["base58", "base64"]) // Variants of `TransactionBinaryEncoding` enum
.default_value("base58")
.takes_value(true)
.required(true)
@@ -273,11 +275,14 @@ impl WalletSubCommands for App<'_, '_> {
}
fn resolve_derived_address_program_id(matches: &ArgMatches<'_>, arg_name: &str) -> Option<Pubkey> {
matches.value_of(arg_name).and_then(|v| match v {
"NONCE" => Some(system_program::id()),
"STAKE" => Some(stake::program::id()),
"VOTE" => Some(solana_vote_program::id()),
_ => pubkey_of(matches, arg_name),
matches.value_of(arg_name).and_then(|v| {
let upper = v.to_ascii_uppercase();
match upper.as_str() {
"NONCE" | "SYSTEM" => Some(system_program::id()),
"STAKE" => Some(stake::program::id()),
"VOTE" => Some(solana_vote_program::id()),
_ => pubkey_of(matches, arg_name),
}
})
}
@@ -338,13 +343,13 @@ pub fn parse_balance(
pub fn parse_decode_transaction(matches: &ArgMatches<'_>) -> Result<CliCommandInfo, CliError> {
let blob = value_t_or_exit!(matches, "transaction", String);
let encoding = match matches.value_of("encoding").unwrap() {
"base58" => UiTransactionEncoding::Base58,
"base64" => UiTransactionEncoding::Base64,
let binary_encoding = match matches.value_of("encoding").unwrap() {
"base58" => TransactionBinaryEncoding::Base58,
"base64" => TransactionBinaryEncoding::Base64,
_ => unreachable!(),
};
let encoded_transaction = EncodedTransaction::Binary(blob, encoding);
let encoded_transaction = EncodedTransaction::Binary(blob, binary_encoding);
if let Some(transaction) = encoded_transaction.decode() {
Ok(CliCommandInfo {
command: CliCommand::DecodeTransaction(transaction),
@@ -556,6 +561,7 @@ pub fn process_confirm(
RpcTransactionConfig {
encoding: Some(UiTransactionEncoding::Base64),
commitment: Some(CommitmentConfig::confirmed()),
max_supported_transaction_version: None,
},
) {
Ok(confirmed_transaction) => {

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-client-test"
version = "1.10.0"
version = "1.10.1"
description = "Solana RPC Test"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
@@ -10,28 +10,28 @@ documentation = "https://docs.rs/solana-client-test"
edition = "2021"
[dependencies]
futures-util = "0.3.19"
serde_json = "1.0.78"
serial_test = "0.5.1"
solana-client = { path = "../client", version = "=1.10.0" }
solana-ledger = { path = "../ledger", version = "=1.10.0" }
solana-measure = { path = "../measure", version = "=1.10.0" }
solana-merkle-tree = { path = "../merkle-tree", version = "=1.10.0" }
solana-metrics = { path = "../metrics", version = "=1.10.0" }
solana-perf = { path = "../perf", version = "=1.10.0" }
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "=1.10.0" }
solana-rpc = { path = "../rpc", version = "=1.10.0" }
solana-runtime = { path = "../runtime", version = "=1.10.0" }
solana-sdk = { path = "../sdk", version = "=1.10.0" }
solana-streamer = { path = "../streamer", version = "=1.10.0" }
solana-test-validator = { path = "../test-validator", version = "=1.10.0" }
solana-transaction-status = { path = "../transaction-status", version = "=1.10.0" }
solana-version = { path = "../version", version = "=1.10.0" }
futures-util = "0.3.21"
serde_json = "1.0.79"
serial_test = "0.6.0"
solana-client = { path = "../client", version = "=1.10.1" }
solana-ledger = { path = "../ledger", version = "=1.10.1" }
solana-measure = { path = "../measure", version = "=1.10.1" }
solana-merkle-tree = { path = "../merkle-tree", version = "=1.10.1" }
solana-metrics = { path = "../metrics", version = "=1.10.1" }
solana-perf = { path = "../perf", version = "=1.10.1" }
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "=1.10.1" }
solana-rpc = { path = "../rpc", version = "=1.10.1" }
solana-runtime = { path = "../runtime", version = "=1.10.1" }
solana-sdk = { path = "../sdk", version = "=1.10.1" }
solana-streamer = { path = "../streamer", version = "=1.10.1" }
solana-test-validator = { path = "../test-validator", version = "=1.10.1" }
solana-transaction-status = { path = "../transaction-status", version = "=1.10.1" }
solana-version = { path = "../version", version = "=1.10.1" }
systemstat = "0.1.10"
tokio = { version = "1", features = ["full"] }
[dev-dependencies]
solana-logger = { path = "../logger", version = "=1.10.0" }
solana-logger = { path = "../logger", version = "=1.10.1" }
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -15,7 +15,7 @@ use {
solana_ledger::{blockstore::Blockstore, get_tmp_ledger_path},
solana_rpc::{
optimistically_confirmed_bank_tracker::OptimisticallyConfirmedBank,
rpc::create_test_transactions_and_populate_blockstore,
rpc::{create_test_transaction_entries, populate_blockstore_for_tests},
rpc_pubsub_service::{PubSubConfig, PubSubService},
rpc_subscriptions::RpcSubscriptions,
},
@@ -36,7 +36,9 @@ use {
},
solana_streamer::socket::SocketAddrSpace,
solana_test_validator::TestValidator,
solana_transaction_status::{ConfirmedBlock, TransactionDetails, UiTransactionEncoding},
solana_transaction_status::{
BlockEncodingOptions, ConfirmedBlock, TransactionDetails, UiTransactionEncoding,
},
std::{
collections::HashSet,
net::{IpAddr, SocketAddr},
@@ -230,9 +232,12 @@ fn test_block_subscription() {
let max_complete_transaction_status_slot = Arc::new(AtomicU64::new(blockstore.max_root()));
bank.transfer(rent_exempt_amount, &alice, &keypair2.pubkey())
.unwrap();
let _confirmed_block_signatures = create_test_transactions_and_populate_blockstore(
vec![&alice, &keypair1, &keypair2, &keypair3],
0,
populate_blockstore_for_tests(
create_test_transaction_entries(
vec![&alice, &keypair1, &keypair2, &keypair3],
bank.clone(),
)
.0,
bank,
blockstore.clone(),
max_complete_transaction_status_slot,
@@ -270,6 +275,7 @@ fn test_block_subscription() {
encoding: Some(UiTransactionEncoding::Json),
transaction_details: Some(TransactionDetails::Signatures),
show_rewards: None,
max_supported_transaction_version: None,
}),
)
.unwrap();
@@ -281,14 +287,17 @@ fn test_block_subscription() {
match maybe_actual {
Ok(actual) => {
let versioned_block = blockstore.get_complete_block(slot, false).unwrap();
let legacy_block = ConfirmedBlock::from(versioned_block)
.into_legacy_block()
let confirmed_block = ConfirmedBlock::from(versioned_block);
let block = confirmed_block
.encode_with_options(
UiTransactionEncoding::Json,
BlockEncodingOptions {
transaction_details: TransactionDetails::Signatures,
show_rewards: false,
max_supported_transaction_version: None,
},
)
.unwrap();
let block = legacy_block.configure(
UiTransactionEncoding::Json,
TransactionDetails::Signatures,
false,
);
assert_eq!(actual.value.slot, slot);
assert!(block.eq(&actual.value.block.unwrap()));
}

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-client"
version = "1.10.0"
version = "1.10.1"
description = "Solana Client"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
@@ -10,42 +10,48 @@ license = "Apache-2.0"
edition = "2021"
[dependencies]
async-mutex = "1.4.0"
async-trait = "0.1.52"
base64 = "0.13.0"
bincode = "1.3.3"
bs58 = "0.4.0"
bytes = "1.1.0"
clap = "2.33.0"
crossbeam-channel = "0.5"
futures-util = "0.3.19"
futures = "0.3"
futures-util = "0.3.21"
indicatif = "0.16.2"
itertools = "0.10.2"
jsonrpc-core = "18.0.0"
log = "0.4.14"
quinn = "0.8.0"
rayon = "1.5.1"
reqwest = { version = "0.11.6", default-features = false, features = ["blocking", "rustls-tls", "json"] }
semver = "1.0.5"
reqwest = { version = "0.11.9", default-features = false, features = ["blocking", "rustls-tls", "json"] }
rustls = { version = "0.20.2", features = ["dangerous_configuration"] }
semver = "1.0.6"
serde = "1.0.136"
serde_derive = "1.0.103"
serde_json = "1.0.78"
solana-account-decoder = { path = "../account-decoder", version = "=1.10.0" }
solana-clap-utils = { path = "../clap-utils", version = "=1.10.0" }
solana-faucet = { path = "../faucet", version = "=1.10.0" }
solana-net-utils = { path = "../net-utils", version = "=1.10.0" }
solana-measure = { path = "../measure", version = "=1.10.0" }
solana-sdk = { path = "../sdk", version = "=1.10.0" }
solana-transaction-status = { path = "../transaction-status", version = "=1.10.0" }
solana-version = { path = "../version", version = "=1.10.0" }
solana-vote-program = { path = "../programs/vote", version = "=1.10.0" }
serde_json = "1.0.79"
solana-account-decoder = { path = "../account-decoder", version = "=1.10.1" }
solana-clap-utils = { path = "../clap-utils", version = "=1.10.1" }
solana-faucet = { path = "../faucet", version = "=1.10.1" }
solana-net-utils = { path = "../net-utils", version = "=1.10.1" }
solana-measure = { path = "../measure", version = "=1.10.1" }
solana-sdk = { path = "../sdk", version = "=1.10.1" }
solana-transaction-status = { path = "../transaction-status", version = "=1.10.1" }
solana-version = { path = "../version", version = "=1.10.1" }
solana-vote-program = { path = "../programs/vote", version = "=1.10.1" }
thiserror = "1.0"
tokio = { version = "1", features = ["full"] }
tokio-stream = "0.1.8"
tokio-tungstenite = { version = "0.16.0", features = ["rustls-tls-webpki-roots"] }
tungstenite = { version = "0.16.0", features = ["rustls-tls-webpki-roots"] }
tokio-tungstenite = { version = "0.17.1", features = ["rustls-tls-webpki-roots"] }
tungstenite = { version = "0.17.2", features = ["rustls-tls-webpki-roots"] }
url = "2.2.2"
[dev-dependencies]
assert_matches = "1.5.0"
jsonrpc-http-server = "18.0.0"
solana-logger = { path = "../logger", version = "=1.10.0" }
solana-logger = { path = "../logger", version = "=1.10.1" }
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -1,6 +1,7 @@
pub use reqwest;
use {
crate::{rpc_request, rpc_response},
quinn::{ConnectError, WriteError},
solana_faucet::faucet::FaucetError,
solana_sdk::{
signature::SignerError, transaction::TransactionError, transport::TransportError,
@@ -72,6 +73,18 @@ impl From<ClientErrorKind> for TransportError {
}
}
impl From<WriteError> for ClientErrorKind {
fn from(write_error: WriteError) -> Self {
Self::Custom(format!("{:?}", write_error))
}
}
impl From<ConnectError> for ClientErrorKind {
fn from(connect_error: ConnectError) -> Self {
Self::Custom(format!("{:?}", connect_error))
}
}
#[derive(Error, Debug)]
#[error("{kind}")]
pub struct ClientError {

View File

@@ -10,6 +10,7 @@ pub mod nonblocking;
pub mod nonce_utils;
pub mod perf_utils;
pub mod pubsub_client;
pub mod quic_client;
pub mod rpc_cache;
pub mod rpc_client;
pub mod rpc_config;
@@ -18,11 +19,13 @@ pub mod rpc_deprecated_config;
pub mod rpc_filter;
pub mod rpc_request;
pub mod rpc_response;
pub(crate) mod rpc_sender;
pub mod rpc_sender;
pub mod spinner;
pub mod thin_client;
pub mod tpu_client;
pub mod tpu_connection;
pub mod transaction_executor;
pub mod udp_client;
pub mod mock_sender_for_cli {
/// Magic `SIGNATURE` value used by `solana-cli` unit tests.

View File

@@ -28,13 +28,13 @@ use {
pubkey::Pubkey,
signature::Signature,
sysvar::epoch_schedule::EpochSchedule,
transaction::{self, Transaction, TransactionError},
transaction::{self, Transaction, TransactionError, TransactionVersion},
},
solana_transaction_status::{
EncodedConfirmedBlock, EncodedConfirmedTransactionWithStatusMeta, EncodedTransaction,
EncodedTransactionWithStatusMeta, Rewards, TransactionConfirmationStatus,
TransactionStatus, UiCompiledInstruction, UiMessage, UiRawMessage, UiTransaction,
UiTransactionEncoding, UiTransactionStatusMeta,
EncodedTransactionWithStatusMeta, Rewards, TransactionBinaryEncoding,
TransactionConfirmationStatus, TransactionStatus, UiCompiledInstruction, UiMessage,
UiRawMessage, UiTransaction, UiTransactionStatusMeta,
},
solana_version::Version,
std::{collections::HashMap, net::SocketAddr, str::FromStr, sync::RwLock},
@@ -192,6 +192,7 @@ impl RpcSender for MockSender {
"getTransaction" => serde_json::to_value(EncodedConfirmedTransactionWithStatusMeta {
slot: 2,
transaction: EncodedTransactionWithStatusMeta {
version: Some(TransactionVersion::LEGACY),
transaction: EncodedTransaction::Json(
UiTransaction {
signatures: vec!["3AsdoALgZFuq2oUVWrDYhg2pNeaLJKPLf8hU2mQ6U8qJxeJ6hsrPVpMn9ma39DtfYCrDQSvngWRP8NnTpEhezJpE".to_string()],
@@ -213,6 +214,7 @@ impl RpcSender for MockSender {
accounts: vec![0, 1],
data: "3Bxs49DitAvXtoDR".to_string(),
}],
address_table_lookups: None,
})
}),
meta: Some(UiTransactionStatusMeta {
@@ -226,6 +228,7 @@ impl RpcSender for MockSender {
pre_token_balances: None,
post_token_balances: None,
rewards: None,
loaded_addresses: None,
}),
},
block_time: Some(1628633791),
@@ -378,9 +381,10 @@ impl RpcSender for MockSender {
pLHxcaShD81xBNaFDgnA2nkkdHnKtZt4hVSfKAmw3VRZbjrZ7L2fKZBx21CwsG\
hD6onjM2M3qZW5C8J6d1pj41MxKmZgPBSha3MyKkNLkAGFASK"
.to_string(),
UiTransactionEncoding::Base58,
TransactionBinaryEncoding::Base58,
),
meta: None,
version: Some(TransactionVersion::LEGACY),
}],
rewards: Rewards::new(),
block_time: None,

View File

@@ -238,6 +238,7 @@ impl PubsubClient {
},
Message::Pong(_data) => continue,
Message::Close(_frame) => break,
Message::Frame(_frame) => continue,
};

View File

@@ -6,6 +6,7 @@
//!
//! [JSON-RPC]: https://www.jsonrpc.org/specification
pub use crate::mock_sender::Mocks;
#[allow(deprecated)]
use crate::rpc_deprecated_config::{
RpcConfirmedBlockConfig, RpcConfirmedTransactionConfig,
@@ -15,7 +16,7 @@ use {
crate::{
client_error::{ClientError, ClientErrorKind, Result as ClientResult},
http_sender::HttpSender,
mock_sender::{MockSender, Mocks},
mock_sender::MockSender,
rpc_client::{GetConfirmedSignaturesForAddress2Config, RpcClientConfig},
rpc_config::{RpcAccountInfoConfig, *},
rpc_request::{RpcError, RpcRequest, RpcResponseErrorData, TokenAccountsFilter},
@@ -52,10 +53,9 @@ use {
cmp::min,
net::SocketAddr,
str::FromStr,
sync::RwLock,
time::{Duration, Instant},
},
tokio::time::sleep,
tokio::{sync::RwLock, time::sleep},
};
/// A client of a remote Solana node.
@@ -147,9 +147,9 @@ impl RpcClient {
///
/// This is the basic constructor, allowing construction with any type of
/// `RpcSender`. Most applications should use one of the other constructors,
/// such as [`new`] and [`new_mock`], which create an `RpcClient`
/// encapsulating an [`HttpSender`] and [`MockSender`] respectively.
pub(crate) fn new_sender<T: RpcSender + Send + Sync + 'static>(
/// such as [`RpcClient::new`], [`RpcClient::new_with_commitment`] or
/// [`RpcClient::new_with_timeout`].
pub fn new_sender<T: RpcSender + Send + Sync + 'static>(
sender: T,
config: RpcClientConfig,
) -> Self {
@@ -315,8 +315,34 @@ impl RpcClient {
/// Create a mock `RpcClient`.
///
/// See the [`MockSender`] documentation for an explanation of
/// how it treats the `url` argument.
/// A mock `RpcClient` contains an implementation of [`RpcSender`] that does
/// not use the network, and instead returns synthetic responses, for use in
/// tests.
///
/// It is primarily for internal use, with limited customizability, and
/// behaviors determined by internal Solana test cases. New users should
/// consider implementing `RpcSender` themselves and constructing
/// `RpcClient` with [`RpcClient::new_sender`] to get mock behavior.
///
/// Unless directed otherwise, a mock `RpcClient` will generally return a
/// reasonable default response to any request, at least for [`RpcRequest`]
/// values for which responses have been implemented.
///
/// This mock can be customized by changing the `url` argument, which is not
/// actually a URL, but a simple string directive that changes the mock
/// behavior in specific scenarios:
///
/// - It is customary to set the `url` to "succeeds" for mocks that should
/// return sucessfully, though this value is not actually interpreted.
///
/// - If `url` is "fails" then any call to `send` will return `Ok(Value::Null)`.
///
/// - Other possible values of `url` are specific to different `RpcRequest`
/// values. Read the implementation of (non-public) `MockSender` for
/// details.
///
/// The [`RpcClient::new_mock_with_mocks`] function offers further
/// customization options.
///
/// # Examples
///
@@ -342,8 +368,43 @@ impl RpcClient {
/// Create a mock `RpcClient`.
///
/// See the [`MockSender`] documentation for an explanation of how it treats
/// the `url` argument.
/// A mock `RpcClient` contains an implementation of [`RpcSender`] that does
/// not use the network, and instead returns synthetic responses, for use in
/// tests.
///
/// It is primarily for internal use, with limited customizability, and
/// behaviors determined by internal Solana test cases. New users should
/// consider implementing `RpcSender` themselves and constructing
/// `RpcClient` with [`RpcClient::new_sender`] to get mock behavior.
///
/// Unless directed otherwise, a mock `RpcClient` will generally return a
/// reasonable default response to any request, at least for [`RpcRequest`]
/// values for which responses have been implemented.
///
/// This mock can be customized in two ways:
///
/// 1) By changing the `url` argument, which is not actually a URL, but a
/// simple string directive that changes the mock behavior in specific
/// scenarios.
///
/// It is customary to set the `url` to "succeeds" for mocks that should
/// return sucessfully, though this value is not actually interpreted.
///
/// If `url` is "fails" then any call to `send` will return `Ok(Value::Null)`.
///
/// Other possible values of `url` are specific to different `RpcRequest`
/// values. Read the implementation of `MockSender` (which is non-public)
/// for details.
///
/// 2) Custom responses can be configured by providing [`Mocks`]. This type
/// is a [`HashMap`] from [`RpcRequest`] to a JSON [`Value`] response,
/// Any entries in this map override the default behavior for the given
/// request.
///
/// The [`RpcClient::new_mock_with_mocks`] function offers further
/// customization options.
///
/// [`HashMap`]: std::collections::HashMap
///
/// # Examples
///
@@ -442,12 +503,12 @@ impl RpcClient {
}
async fn get_node_version(&self) -> Result<semver::Version, RpcError> {
let r_node_version = self.node_version.read().unwrap();
let r_node_version = self.node_version.read().await;
if let Some(version) = &*r_node_version {
Ok(version.clone())
} else {
drop(r_node_version);
let mut w_node_version = self.node_version.write().unwrap();
let mut w_node_version = self.node_version.write().await;
let node_version = self.get_version().await.map_err(|e| {
RpcError::RpcRequestError(format!("cluster version query failed: {}", e))
})?;
@@ -2412,6 +2473,7 @@ impl RpcClient {
/// transaction_details: Some(TransactionDetails::None),
/// rewards: Some(true),
/// commitment: None,
/// max_supported_transaction_version: Some(0),
/// };
/// let block = rpc_client.get_block_with_config(
/// slot,
@@ -3052,6 +3114,7 @@ impl RpcClient {
/// let config = RpcTransactionConfig {
/// encoding: Some(UiTransactionEncoding::Json),
/// commitment: Some(CommitmentConfig::confirmed()),
/// max_supported_transaction_version: Some(0),
/// };
/// let transaction = rpc_client.get_transaction_with_config(
/// &signature,

208
client/src/quic_client.rs Normal file
View File

@@ -0,0 +1,208 @@
//! Simple client that connects to a given UDP port with the QUIC protocol and provides
//! an interface for sending transactions which is restricted by the server's flow control.
use {
crate::{client_error::ClientErrorKind, tpu_connection::TpuConnection},
async_mutex::Mutex,
futures::future::join_all,
itertools::Itertools,
quinn::{ClientConfig, Endpoint, EndpointConfig, NewConnection, WriteError},
rayon::iter::{IntoParallelIterator, ParallelIterator},
solana_sdk::{
quic::{QUIC_MAX_CONCURRENT_STREAMS, QUIC_PORT_OFFSET},
transaction::Transaction,
transport::Result as TransportResult,
},
std::{
net::{SocketAddr, UdpSocket},
sync::Arc,
},
tokio::runtime::Runtime,
};
struct SkipServerVerification;
impl SkipServerVerification {
pub fn new() -> Arc<Self> {
Arc::new(Self)
}
}
impl rustls::client::ServerCertVerifier for SkipServerVerification {
fn verify_server_cert(
&self,
_end_entity: &rustls::Certificate,
_intermediates: &[rustls::Certificate],
_server_name: &rustls::ServerName,
_scts: &mut dyn Iterator<Item = &[u8]>,
_ocsp_response: &[u8],
_now: std::time::SystemTime,
) -> Result<rustls::client::ServerCertVerified, rustls::Error> {
Ok(rustls::client::ServerCertVerified::assertion())
}
}
struct QuicClient {
runtime: Runtime,
endpoint: Endpoint,
connection: Arc<Mutex<Option<Arc<NewConnection>>>>,
addr: SocketAddr,
}
pub struct QuicTpuConnection {
client: Arc<QuicClient>,
}
impl TpuConnection for QuicTpuConnection {
fn new(client_socket: UdpSocket, tpu_addr: SocketAddr) -> Self {
let tpu_addr = SocketAddr::new(tpu_addr.ip(), tpu_addr.port() + QUIC_PORT_OFFSET);
let client = Arc::new(QuicClient::new(client_socket, tpu_addr));
Self { client }
}
fn tpu_addr(&self) -> &SocketAddr {
&self.client.addr
}
fn send_wire_transaction(&self, data: Vec<u8>) -> TransportResult<()> {
let _guard = self.client.runtime.enter();
let send_buffer = self.client.send_buffer(&data[..]);
self.client.runtime.block_on(send_buffer)?;
Ok(())
}
fn send_batch(&self, transactions: Vec<Transaction>) -> TransportResult<()> {
let buffers = transactions
.into_par_iter()
.map(|tx| bincode::serialize(&tx).expect("serialize Transaction in send_batch"))
.collect::<Vec<_>>();
let _guard = self.client.runtime.enter();
let send_batch = self.client.send_batch(&buffers[..]);
self.client.runtime.block_on(send_batch)?;
Ok(())
}
}
impl QuicClient {
pub fn new(client_socket: UdpSocket, addr: SocketAddr) -> Self {
let runtime = tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()
.unwrap();
let _guard = runtime.enter();
let crypto = rustls::ClientConfig::builder()
.with_safe_defaults()
.with_custom_certificate_verifier(SkipServerVerification::new())
.with_no_client_auth();
let create_endpoint = QuicClient::create_endpoint(EndpointConfig::default(), client_socket);
let mut endpoint = runtime.block_on(create_endpoint);
endpoint.set_default_client_config(ClientConfig::new(Arc::new(crypto)));
Self {
runtime,
endpoint,
connection: Arc::new(Mutex::new(None)),
addr,
}
}
// If this function becomes public, it should be changed to
// not expose details of the specific Quic implementation we're using
async fn create_endpoint(config: EndpointConfig, client_socket: UdpSocket) -> Endpoint {
quinn::Endpoint::new(config, None, client_socket).unwrap().0
}
async fn _send_buffer_using_conn(
data: &[u8],
connection: &NewConnection,
) -> Result<(), WriteError> {
let mut send_stream = connection.connection.open_uni().await?;
send_stream.write_all(data).await?;
send_stream.finish().await?;
Ok(())
}
// Attempts to send data, connecting/reconnecting as necessary
// On success, returns the connection used to successfully send the data
async fn _send_buffer(&self, data: &[u8]) -> Result<Arc<NewConnection>, WriteError> {
let connection = {
let mut conn_guard = self.connection.lock().await;
let maybe_conn = (*conn_guard).clone();
match maybe_conn {
Some(conn) => conn.clone(),
None => {
let connecting = self.endpoint.connect(self.addr, "connect").unwrap();
let connection = Arc::new(connecting.await?);
*conn_guard = Some(connection.clone());
connection
}
}
};
match Self::_send_buffer_using_conn(data, &connection).await {
Ok(()) => Ok(connection),
_ => {
let connection = {
let connecting = self.endpoint.connect(self.addr, "connect").unwrap();
let connection = Arc::new(connecting.await?);
let mut conn_guard = self.connection.lock().await;
*conn_guard = Some(connection.clone());
connection
};
Self::_send_buffer_using_conn(data, &connection).await?;
Ok(connection)
}
}
}
pub async fn send_buffer(&self, data: &[u8]) -> Result<(), ClientErrorKind> {
self._send_buffer(data).await?;
Ok(())
}
pub async fn send_batch(&self, buffers: &[Vec<u8>]) -> Result<(), ClientErrorKind> {
// Start off by "testing" the connection by sending the first transaction
// This will also connect to the server if not already connected
// and reconnect and retry if the first send attempt failed
// (for example due to a timed out connection), returning an error
// or the connection that was used to successfully send the transaction.
// We will use the returned connection to send the rest of the transactions in the batch
// to avoid touching the mutex in self, and not bother reconnecting if we fail along the way
// since testing even in the ideal GCE environment has found no cases
// where reconnecting and retrying in the middle of a batch send
// (i.e. we encounter a connection error in the middle of a batch send, which presumably cannot
// be due to a timed out connection) has succeeded
if buffers.is_empty() {
return Ok(());
}
let connection = self._send_buffer(&buffers[0][..]).await?;
// Used to avoid dereferencing the Arc multiple times below
// by just getting a reference to the NewConnection once
let connection_ref: &NewConnection = &connection;
let chunks = buffers[1..buffers.len()]
.iter()
.chunks(QUIC_MAX_CONCURRENT_STREAMS);
let futures = chunks.into_iter().map(|buffs| {
join_all(
buffs
.into_iter()
.map(|buf| Self::_send_buffer_using_conn(&buf[..], connection_ref)),
)
});
for f in futures {
f.await.into_iter().try_for_each(|res| res)?;
}
Ok(())
}
}

View File

@@ -6,13 +6,14 @@
//!
//! [JSON-RPC]: https://www.jsonrpc.org/specification
pub use crate::mock_sender::Mocks;
#[allow(deprecated)]
use crate::rpc_deprecated_config::{RpcConfirmedBlockConfig, RpcConfirmedTransactionConfig};
use {
crate::{
client_error::Result as ClientResult,
http_sender::HttpSender,
mock_sender::{MockSender, Mocks},
mock_sender::MockSender,
nonblocking::{self, rpc_client::get_rpc_request_str},
rpc_config::{RpcAccountInfoConfig, *},
rpc_request::{RpcRequest, TokenAccountsFilter},
@@ -103,8 +104,8 @@ pub struct GetConfirmedSignaturesForAddress2Config {
/// [`Processed`] commitment level. These exceptions are noted in the method
/// documentation.
///
/// [`Finalized`]: CommitmentLevel::Finalized
/// [`Processed`]: CommitmentLevel::Processed
/// [`Finalized`]: solana_sdk::commitment_config::CommitmentLevel::Finalized
/// [`Processed`]: solana_sdk::commitment_config::CommitmentLevel::Processed
/// [jsonprot]: https://docs.solana.com/developing/clients/jsonrpc-api
/// [JSON-RPC]: https://www.jsonrpc.org/specification
/// [slots]: https://docs.solana.com/terminology#slot
@@ -145,6 +146,10 @@ pub struct GetConfirmedSignaturesForAddress2Config {
/// [`is_timeout`](crate::client_error::reqwest::Error::is_timeout) method
/// returns `true`. The default timeout is 30 seconds, and may be changed by
/// calling an appropriate constructor with a `timeout` parameter.
///
/// [`ClientError`]: crate::client_error::ClientError
/// [`ClientErrorKind`]: crate::client_error::ClientErrorKind
/// [`ClientErrorKind::Reqwest`]: crate::client_error::ClientErrorKind::Reqwest
pub struct RpcClient {
rpc_client: nonblocking::rpc_client::RpcClient,
runtime: Option<tokio::runtime::Runtime>,
@@ -161,9 +166,9 @@ impl RpcClient {
///
/// This is the basic constructor, allowing construction with any type of
/// `RpcSender`. Most applications should use one of the other constructors,
/// such as [`new`] and [`new_mock`], which create an `RpcClient`
/// encapsulating an [`HttpSender`] and [`MockSender`] respectively.
fn new_sender<T: RpcSender + Send + Sync + 'static>(
/// such as [`RpcClient::new`], [`RpcClient::new_with_commitment`] or
/// [`RpcClient::new_with_timeout`].
pub fn new_sender<T: RpcSender + Send + Sync + 'static>(
sender: T,
config: RpcClientConfig,
) -> Self {
@@ -186,9 +191,10 @@ impl RpcClient {
/// "http://localhost:8899".
///
/// The client has a default timeout of 30 seconds, and a default [commitment
/// level][cl] of [`Finalized`](CommitmentLevel::Finalized).
/// level][cl] of [`Finalized`].
///
/// [cl]: https://docs.solana.com/developing/clients/jsonrpc-api#configuring-state-commitment
/// [`Finalized`]: solana_sdk::commitment_config::CommitmentLevel::Finalized
///
/// # Examples
///
@@ -211,6 +217,8 @@ impl RpcClient {
/// The client has a default timeout of 30 seconds, and a user-specified
/// [`CommitmentLevel`] via [`CommitmentConfig`].
///
/// [`CommitmentLevel`]: solana_sdk::commitment_config::CommitmentLevel
///
/// # Examples
///
/// ```
@@ -233,9 +241,10 @@ impl RpcClient {
/// "http://localhost:8899".
///
/// The client has and a default [commitment level][cl] of
/// [`Finalized`](CommitmentLevel::Finalized).
/// [`Finalized`].
///
/// [cl]: https://docs.solana.com/developing/clients/jsonrpc-api#configuring-state-commitment
/// [`Finalized`]: solana_sdk::commitment_config::CommitmentLevel::Finalized
///
/// # Examples
///
@@ -335,8 +344,34 @@ impl RpcClient {
/// Create a mock `RpcClient`.
///
/// See the [`MockSender`] documentation for an explanation of
/// how it treats the `url` argument.
/// A mock `RpcClient` contains an implementation of [`RpcSender`] that does
/// not use the network, and instead returns synthetic responses, for use in
/// tests.
///
/// It is primarily for internal use, with limited customizability, and
/// behaviors determined by internal Solana test cases. New users should
/// consider implementing `RpcSender` themselves and constructing
/// `RpcClient` with [`RpcClient::new_sender`] to get mock behavior.
///
/// Unless directed otherwise, a mock `RpcClient` will generally return a
/// reasonable default response to any request, at least for [`RpcRequest`]
/// values for which responses have been implemented.
///
/// This mock can be customized by changing the `url` argument, which is not
/// actually a URL, but a simple string directive that changes the mock
/// behavior in specific scenarios:
///
/// - It is customary to set the `url` to "succeeds" for mocks that should
/// return sucessfully, though this value is not actually interpreted.
///
/// - If `url` is "fails" then any call to `send` will return `Ok(Value::Null)`.
///
/// - Other possible values of `url` are specific to different `RpcRequest`
/// values. Read the implementation of (non-public) `MockSender` for
/// details.
///
/// The [`RpcClient::new_mock_with_mocks`] function offers further
/// customization options.
///
/// # Examples
///
@@ -362,8 +397,43 @@ impl RpcClient {
/// Create a mock `RpcClient`.
///
/// See the [`MockSender`] documentation for an explanation of how it treats
/// the `url` argument.
/// A mock `RpcClient` contains an implementation of [`RpcSender`] that does
/// not use the network, and instead returns synthetic responses, for use in
/// tests.
///
/// It is primarily for internal use, with limited customizability, and
/// behaviors determined by internal Solana test cases. New users should
/// consider implementing `RpcSender` themselves and constructing
/// `RpcClient` with [`RpcClient::new_sender`] to get mock behavior.
///
/// Unless directed otherwise, a mock `RpcClient` will generally return a
/// reasonable default response to any request, at least for [`RpcRequest`]
/// values for which responses have been implemented.
///
/// This mock can be customized in two ways:
///
/// 1) By changing the `url` argument, which is not actually a URL, but a
/// simple string directive that changes the mock behavior in specific
/// scenarios.
///
/// It is customary to set the `url` to "succeeds" for mocks that should
/// return sucessfully, though this value is not actually interpreted.
///
/// If `url` is "fails" then any call to `send` will return `Ok(Value::Null)`.
///
/// Other possible values of `url` are specific to different `RpcRequest`
/// values. Read the implementation of `MockSender` (which is non-public)
/// for details.
///
/// 2) Custom responses can be configured by providing [`Mocks`]. This type
/// is a [`HashMap`] from [`RpcRequest`] to a JSON [`Value`] response,
/// Any entries in this map override the default behavior for the given
/// request.
///
/// The [`RpcClient::new_mock_with_mocks`] function offers further
/// customization options.
///
/// [`HashMap`]: std::collections::HashMap
///
/// # Examples
///
@@ -397,9 +467,10 @@ impl RpcClient {
/// Create an HTTP `RpcClient` from a [`SocketAddr`].
///
/// The client has a default timeout of 30 seconds, and a default [commitment
/// level][cl] of [`Finalized`](CommitmentLevel::Finalized).
/// level][cl] of [`Finalized`].
///
/// [cl]: https://docs.solana.com/developing/clients/jsonrpc-api#configuring-state-commitment
/// [`Finalized`]: solana_sdk::commitment_config::CommitmentLevel::Finalized
///
/// # Examples
///
@@ -420,6 +491,8 @@ impl RpcClient {
/// The client has a default timeout of 30 seconds, and a user-specified
/// [`CommitmentLevel`] via [`CommitmentConfig`].
///
/// [`CommitmentLevel`]: solana_sdk::commitment_config::CommitmentLevel
///
/// # Examples
///
/// ```
@@ -442,9 +515,10 @@ impl RpcClient {
/// Create an HTTP `RpcClient` from a [`SocketAddr`] with specified timeout.
///
/// The client has a default [commitment level][cl] of [`Finalized`](CommitmentLevel::Finalized).
/// The client has a default [commitment level][cl] of [`Finalized`].
///
/// [cl]: https://docs.solana.com/developing/clients/jsonrpc-api#configuring-state-commitment
/// [`Finalized`]: solana_sdk::commitment_config::CommitmentLevel::Finalized
///
/// # Examples
///
@@ -469,7 +543,9 @@ impl RpcClient {
/// determines how thoroughly committed a transaction must be when waiting
/// for its confirmation or otherwise checking for confirmation. If not
/// specified, the default commitment level is
/// [`Finalized`](CommitmentLevel::Finalized).
/// [`Finalized`].
///
/// [`Finalized`]: solana_sdk::commitment_config::CommitmentLevel::Finalized
///
/// The default commitment level is overridden when calling methods that
/// explicitly provide a [`CommitmentConfig`], like
@@ -503,7 +579,8 @@ impl RpcClient {
/// containing an [`RpcResponseError`] with `code` set to
/// [`JSON_RPC_SERVER_ERROR_NODE_UNHEALTHY`].
///
/// [`RpcResponseError`]: RpcError::RpcResponseError
/// [`RpcError`]: crate::rpc_request::RpcError
/// [`RpcResponseError`]: crate::rpc_request::RpcError::RpcResponseError
/// [`JSON_RPC_SERVER_ERROR_TRANSACTION_SIGNATURE_VERIFICATION_FAILURE`]: crate::rpc_custom_error::JSON_RPC_SERVER_ERROR_TRANSACTION_SIGNATURE_VERIFICATION_FAILURE
/// [`JSON_RPC_SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE`]: crate::rpc_custom_error::JSON_RPC_SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE
/// [`JSON_RPC_SERVER_ERROR_NODE_UNHEALTHY`]: crate::rpc_custom_error::JSON_RPC_SERVER_ERROR_NODE_UNHEALTHY
@@ -616,7 +693,8 @@ impl RpcClient {
/// containing an [`RpcResponseError`] with `code` set to
/// [`JSON_RPC_SERVER_ERROR_NODE_UNHEALTHY`].
///
/// [`RpcResponseError`]: RpcError::RpcResponseError
/// [`RpcError`]: crate::rpc_request::RpcError
/// [`RpcResponseError`]: crate::rpc_request::RpcError::RpcResponseError
/// [`JSON_RPC_SERVER_ERROR_TRANSACTION_SIGNATURE_VERIFICATION_FAILURE`]: crate::rpc_custom_error::JSON_RPC_SERVER_ERROR_TRANSACTION_SIGNATURE_VERIFICATION_FAILURE
/// [`JSON_RPC_SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE`]: crate::rpc_custom_error::JSON_RPC_SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE
/// [`JSON_RPC_SERVER_ERROR_NODE_UNHEALTHY`]: crate::rpc_custom_error::JSON_RPC_SERVER_ERROR_NODE_UNHEALTHY
@@ -690,7 +768,8 @@ impl RpcClient {
/// containing an [`RpcResponseError`] with `code` set to
/// [`JSON_RPC_SERVER_ERROR_NODE_UNHEALTHY`].
///
/// [`RpcResponseError`]: RpcError::RpcResponseError
/// [`RpcError`]: crate::rpc_request::RpcError
/// [`RpcResponseError`]: crate::rpc_request::RpcError::RpcResponseError
/// [`JSON_RPC_SERVER_ERROR_TRANSACTION_SIGNATURE_VERIFICATION_FAILURE`]: crate::rpc_custom_error::JSON_RPC_SERVER_ERROR_TRANSACTION_SIGNATURE_VERIFICATION_FAILURE
/// [`JSON_RPC_SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE`]: crate::rpc_custom_error::JSON_RPC_SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE
/// [`JSON_RPC_SERVER_ERROR_NODE_UNHEALTHY`]: crate::rpc_custom_error::JSON_RPC_SERVER_ERROR_NODE_UNHEALTHY
@@ -2034,6 +2113,7 @@ impl RpcClient {
/// transaction_details: Some(TransactionDetails::None),
/// rewards: Some(true),
/// commitment: None,
/// max_supported_transaction_version: Some(0),
/// };
/// let block = rpc_client.get_block_with_config(
/// slot,
@@ -2101,7 +2181,7 @@ impl RpcClient {
///
/// This method uses the [`Finalized`] [commitment level][cl].
///
/// [`Finalized`]: CommitmentLevel::Finalized
/// [`Finalized`]: solana_sdk::commitment_config::CommitmentLevel::Finalized
/// [`get_blocks_with_limit`]: RpcClient::get_blocks_with_limit.
/// [cl]: https://docs.solana.com/developing/clients/jsonrpc-api#configuring-state-commitment
///
@@ -2160,7 +2240,7 @@ impl RpcClient {
/// This method returns an error if the given commitment level is below
/// [`Confirmed`].
///
/// [`Confirmed`]: CommitmentLevel::Confirmed
/// [`Confirmed`]: solana_sdk::commitment_config::CommitmentLevel::Confirmed
///
/// # RPC Reference
///
@@ -2253,7 +2333,7 @@ impl RpcClient {
/// [`Confirmed`].
///
/// [cl]: https://docs.solana.com/developing/clients/jsonrpc-api#configuring-state-commitment
/// [`Confirmed`]: CommitmentLevel::Confirmed
/// [`Confirmed`]: solana_sdk::commitment_config::CommitmentLevel::Confirmed
///
/// # RPC Reference
///
@@ -2414,7 +2494,7 @@ impl RpcClient {
/// [`Confirmed`].
///
/// [cl]: https://docs.solana.com/developing/clients/jsonrpc-api#configuring-state-commitment
/// [`Confirmed`]: CommitmentLevel::Confirmed
/// [`Confirmed`]: solana_sdk::commitment_config::CommitmentLevel::Confirmed
///
/// # RPC Reference
///
@@ -2504,7 +2584,7 @@ impl RpcClient {
///
/// This method uses the [`Finalized`] [commitment level][cl].
///
/// [`Finalized`]: CommitmentLevel::Finalized
/// [`Finalized`]: solana_sdk::commitment_config::CommitmentLevel::Finalized
/// [cl]: https://docs.solana.com/developing/clients/jsonrpc-api#configuring-state-commitment
///
/// # RPC Reference
@@ -2559,7 +2639,7 @@ impl RpcClient {
/// [`Confirmed`].
///
/// [cl]: https://docs.solana.com/developing/clients/jsonrpc-api#configuring-state-commitment
/// [`Confirmed`]: CommitmentLevel::Confirmed
/// [`Confirmed`]: solana_sdk::commitment_config::CommitmentLevel::Confirmed
///
/// # RPC Reference
///
@@ -2596,6 +2676,7 @@ impl RpcClient {
/// let config = RpcTransactionConfig {
/// encoding: Some(UiTransactionEncoding::Json),
/// commitment: Some(CommitmentConfig::confirmed()),
/// max_supported_transaction_version: Some(0),
/// };
/// let transaction = rpc_client.get_transaction_with_config(
/// &signature,
@@ -2924,7 +3005,7 @@ impl RpcClient {
///
/// This method uses the [`Finalized`] [commitment level][cl].
///
/// [`Finalized`]: CommitmentLevel::Finalized
/// [`Finalized`]: solana_sdk::commitment_config::CommitmentLevel::Finalized
/// [cl]: https://docs.solana.com/developing/clients/jsonrpc-api#configuring-state-commitment
///
/// # RPC Reference
@@ -3082,6 +3163,7 @@ impl RpcClient {
/// [`RpcError::ForUser`]. This is unlike [`get_account_with_commitment`],
/// which returns `Ok(None)` if the account does not exist.
///
/// [`RpcError::ForUser`]: crate::rpc_request::RpcError::ForUser
/// [`get_account_with_commitment`]: RpcClient::get_account_with_commitment
///
/// # RPC Reference

View File

@@ -197,6 +197,7 @@ pub struct RpcBlockSubscribeConfig {
pub encoding: Option<UiTransactionEncoding>,
pub transaction_details: Option<TransactionDetails>,
pub show_rewards: Option<bool>,
pub max_supported_transaction_version: Option<u8>,
}
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
@@ -248,6 +249,7 @@ pub struct RpcBlockConfig {
pub rewards: Option<bool>,
#[serde(flatten)]
pub commitment: Option<CommitmentConfig>,
pub max_supported_transaction_version: Option<u8>,
}
impl EncodingConfig for RpcBlockConfig {
@@ -288,6 +290,7 @@ pub struct RpcTransactionConfig {
pub encoding: Option<UiTransactionEncoding>,
#[serde(flatten)]
pub commitment: Option<CommitmentConfig>,
pub max_supported_transaction_version: Option<u8>,
}
impl EncodingConfig for RpcTransactionConfig {

View File

@@ -3,6 +3,7 @@ use {
crate::rpc_response::RpcSimulateTransactionResult,
jsonrpc_core::{Error, ErrorCode},
solana_sdk::clock::Slot,
solana_transaction_status::EncodeError,
thiserror::Error,
};
@@ -59,7 +60,7 @@ pub enum RpcCustomError {
#[error("BlockStatusNotAvailableYet")]
BlockStatusNotAvailableYet { slot: Slot },
#[error("UnsupportedTransactionVersion")]
UnsupportedTransactionVersion,
UnsupportedTransactionVersion(u8),
}
#[derive(Debug, Serialize, Deserialize)]
@@ -68,6 +69,16 @@ pub struct NodeUnhealthyErrorData {
pub num_slots_behind: Option<Slot>,
}
impl From<EncodeError> for RpcCustomError {
fn from(err: EncodeError) -> Self {
match err {
EncodeError::UnsupportedTransactionVersion(version) => {
Self::UnsupportedTransactionVersion(version)
}
}
}
}
impl From<RpcCustomError> for Error {
fn from(e: RpcCustomError) -> Self {
match e {
@@ -172,9 +183,9 @@ impl From<RpcCustomError> for Error {
message: format!("Block status not yet available for slot {}", slot),
data: None,
},
RpcCustomError::UnsupportedTransactionVersion => Self {
RpcCustomError::UnsupportedTransactionVersion(version) => Self {
code: ErrorCode::ServerError(JSON_RPC_SERVER_ERROR_UNSUPPORTED_TRANSACTION_VERSION),
message: "Versioned transactions are not supported".to_string(),
message: format!("Transaction version ({}) is not supported", version),
data: None,
},
}

View File

@@ -71,6 +71,7 @@ impl From<RpcConfirmedBlockConfig> for RpcBlockConfig {
transaction_details: config.transaction_details,
rewards: config.rewards,
commitment: config.commitment,
max_supported_transaction_version: None,
}
}
}
@@ -98,6 +99,7 @@ impl From<RpcConfirmedTransactionConfig> for RpcTransactionConfig {
Self {
encoding: config.encoding,
commitment: config.commitment,
max_supported_transaction_version: None,
}
}
}

View File

@@ -117,7 +117,7 @@ pub struct RpcInflationRate {
pub epoch: Epoch,
}
#[derive(Serialize, Deserialize, Clone, Debug)]
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct RpcKeyedAccount {
pub pubkey: String,
@@ -246,7 +246,7 @@ pub struct RpcBlockProductionRange {
pub last_slot: Slot,
}
#[derive(Serialize, Deserialize, Clone)]
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct RpcBlockProduction {
/// Map of leader base58 identity pubkeys to a tuple of `(number of leader slots, number of blocks produced)`
@@ -363,7 +363,7 @@ pub struct RpcAccountBalance {
pub lamports: u64,
}
#[derive(Serialize, Deserialize, Clone, Debug)]
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct RpcSupply {
pub total: u64,
@@ -432,8 +432,8 @@ pub enum RpcBlockUpdateError {
#[error("block store error")]
BlockStoreError,
#[error("unsupported transaction version")]
UnsupportedTransactionVersion,
#[error("unsupported transaction version ({0})")]
UnsupportedTransactionVersion(u8),
}
#[derive(Serialize, Deserialize, Debug)]

View File

@@ -23,13 +23,9 @@ pub struct RpcTransportStats {
/// `RpcSender` implements the underlying transport of requests to, and
/// responses from, a Solana node, and is used primarily by [`RpcClient`].
///
/// It is typically implemented by [`HttpSender`] in production, and
/// [`MockSender`] in unit tests.
///
/// [`HttpSender`]: crate::http_sender::HttpSender
/// [`MockSender`]: crate::mock_sender::MockSender
/// [`RpcClient`]: crate::rpc_client::RpcClient
#[async_trait]
pub(crate) trait RpcSender {
pub trait RpcSender {
async fn send(
&self,
request: RpcRequest,

View File

@@ -4,8 +4,10 @@
//! unstable and may change in future releases.
use {
crate::{rpc_client::RpcClient, rpc_config::RpcProgramAccountsConfig, rpc_response::Response},
bincode::{serialize_into, serialized_size},
crate::{
rpc_client::RpcClient, rpc_config::RpcProgramAccountsConfig, rpc_response::Response,
tpu_connection::TpuConnection, udp_client::UdpTpuConnection,
},
log::*,
solana_sdk::{
account::Account,
@@ -17,7 +19,6 @@ use {
hash::Hash,
instruction::Instruction,
message::Message,
packet::PACKET_DATA_SIZE,
pubkey::Pubkey,
signature::{Keypair, Signature, Signer},
signers::Signers,
@@ -117,22 +118,20 @@ impl ClientOptimizer {
}
/// An object for querying and sending transactions to the network.
pub struct ThinClient {
transactions_socket: UdpSocket,
tpu_addrs: Vec<SocketAddr>,
pub struct ThinClient<C: 'static + TpuConnection> {
rpc_clients: Vec<RpcClient>,
tpu_connections: Vec<C>,
optimizer: ClientOptimizer,
}
impl ThinClient {
impl<C: 'static + TpuConnection> ThinClient<C> {
/// Create a new ThinClient that will interface with the Rpc at `rpc_addr` using TCP
/// and the Tpu at `tpu_addr` over `transactions_socket` using UDP.
/// and the Tpu at `tpu_addr` over `transactions_socket` using Quic or UDP
/// (currently hardcoded to UDP)
pub fn new(rpc_addr: SocketAddr, tpu_addr: SocketAddr, transactions_socket: UdpSocket) -> Self {
Self::new_from_client(
tpu_addr,
transactions_socket,
RpcClient::new_socket(rpc_addr),
)
let tpu_connection = C::new(transactions_socket, tpu_addr);
Self::new_from_client(RpcClient::new_socket(rpc_addr), tpu_connection)
}
pub fn new_socket_with_timeout(
@@ -142,18 +141,14 @@ impl ThinClient {
timeout: Duration,
) -> Self {
let rpc_client = RpcClient::new_socket_with_timeout(rpc_addr, timeout);
Self::new_from_client(tpu_addr, transactions_socket, rpc_client)
let tpu_connection = C::new(transactions_socket, tpu_addr);
Self::new_from_client(rpc_client, tpu_connection)
}
fn new_from_client(
tpu_addr: SocketAddr,
transactions_socket: UdpSocket,
rpc_client: RpcClient,
) -> Self {
fn new_from_client(rpc_client: RpcClient, tpu_connection: C) -> Self {
Self {
transactions_socket,
tpu_addrs: vec![tpu_addr],
rpc_clients: vec![rpc_client],
tpu_connections: vec![tpu_connection],
optimizer: ClientOptimizer::new(0),
}
}
@@ -168,16 +163,19 @@ impl ThinClient {
let rpc_clients: Vec<_> = rpc_addrs.into_iter().map(RpcClient::new_socket).collect();
let optimizer = ClientOptimizer::new(rpc_clients.len());
let tpu_connections: Vec<_> = tpu_addrs
.into_iter()
.map(|tpu_addr| C::new(transactions_socket.try_clone().unwrap(), tpu_addr))
.collect();
Self {
transactions_socket,
tpu_addrs,
rpc_clients,
tpu_connections,
optimizer,
}
}
fn tpu_addr(&self) -> &SocketAddr {
&self.tpu_addrs[self.optimizer.best()]
fn tpu_connection(&self) -> &C {
&self.tpu_connections[self.optimizer.best()]
}
fn rpc_client(&self) -> &RpcClient {
@@ -205,7 +203,6 @@ impl ThinClient {
self.send_and_confirm_transaction(&[keypair], transaction, tries, 0)
}
/// Retry sending a signed Transaction to the server for processing
pub fn send_and_confirm_transaction<T: Signers>(
&self,
keypairs: &T,
@@ -215,18 +212,13 @@ impl ThinClient {
) -> TransportResult<Signature> {
for x in 0..tries {
let now = Instant::now();
let mut buf = vec![0; serialized_size(&transaction).unwrap() as usize];
let mut wr = std::io::Cursor::new(&mut buf[..]);
let mut num_confirmed = 0;
let mut wait_time = MAX_PROCESSING_AGE;
serialize_into(&mut wr, &transaction)
.expect("serialize Transaction in pub fn transfer_signed");
// resend the same transaction until the transaction has no chance of succeeding
while now.elapsed().as_secs() < wait_time as u64 {
if num_confirmed == 0 {
// Send the transaction if there has been no confirmation (e.g. the first time)
self.transactions_socket
.send_to(&buf[..], &self.tpu_addr())?;
self.tpu_connection().send_transaction(transaction)?;
}
if let Ok(confirmed_blocks) = self.poll_for_signature_confirmation(
@@ -321,13 +313,13 @@ impl ThinClient {
}
}
impl Client for ThinClient {
impl<C: 'static + TpuConnection> Client for ThinClient<C> {
fn tpu_addr(&self) -> String {
self.tpu_addr().to_string()
self.tpu_connection().tpu_addr().to_string()
}
}
impl SyncClient for ThinClient {
impl<C: 'static + TpuConnection> SyncClient for ThinClient<C> {
fn send_and_confirm_message<T: Signers>(
&self,
keypairs: &T,
@@ -607,17 +599,16 @@ impl SyncClient for ThinClient {
}
}
impl AsyncClient for ThinClient {
impl<C: 'static + TpuConnection> AsyncClient for ThinClient<C> {
fn async_send_transaction(&self, transaction: Transaction) -> TransportResult<Signature> {
let mut buf = vec![0; serialized_size(&transaction).unwrap() as usize];
let mut wr = std::io::Cursor::new(&mut buf[..]);
serialize_into(&mut wr, &transaction)
.expect("serialize Transaction in pub fn transfer_signed");
assert!(buf.len() < PACKET_DATA_SIZE);
self.transactions_socket
.send_to(&buf[..], &self.tpu_addr())?;
self.tpu_connection().send_transaction(&transaction)?;
Ok(transaction.signatures[0])
}
fn async_send_batch(&self, transactions: Vec<Transaction>) -> TransportResult<()> {
self.tpu_connection().send_batch(transactions)
}
fn async_send_message<T: Signers>(
&self,
keypairs: &T,
@@ -649,20 +640,23 @@ impl AsyncClient for ThinClient {
}
}
pub fn create_client((rpc, tpu): (SocketAddr, SocketAddr), range: (u16, u16)) -> ThinClient {
pub fn create_client(
(rpc, tpu): (SocketAddr, SocketAddr),
range: (u16, u16),
) -> ThinClient<UdpTpuConnection> {
let (_, transactions_socket) =
solana_net_utils::bind_in_range(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), range).unwrap();
ThinClient::new(rpc, tpu, transactions_socket)
ThinClient::<UdpTpuConnection>::new(rpc, tpu, transactions_socket)
}
pub fn create_client_with_timeout(
(rpc, tpu): (SocketAddr, SocketAddr),
range: (u16, u16),
timeout: Duration,
) -> ThinClient {
) -> ThinClient<UdpTpuConnection> {
let (_, transactions_socket) =
solana_net_utils::bind_in_range(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), range).unwrap();
ThinClient::new_socket_with_timeout(rpc, tpu, transactions_socket, timeout)
ThinClient::<UdpTpuConnection>::new_socket_with_timeout(rpc, tpu, transactions_socket, timeout)
}
#[cfg(test)]

View File

@@ -0,0 +1,19 @@
use {
solana_sdk::{transaction::Transaction, transport::Result as TransportResult},
std::net::{SocketAddr, UdpSocket},
};
pub trait TpuConnection {
fn new(client_socket: UdpSocket, tpu_addr: SocketAddr) -> Self;
fn tpu_addr(&self) -> &SocketAddr;
fn send_transaction(&self, tx: &Transaction) -> TransportResult<()> {
let data = bincode::serialize(tx).expect("serialize Transaction in send_transaction");
self.send_wire_transaction(data)
}
fn send_wire_transaction(&self, data: Vec<u8>) -> TransportResult<()>;
fn send_batch(&self, transactions: Vec<Transaction>) -> TransportResult<()>;
}

42
client/src/udp_client.rs Normal file
View File

@@ -0,0 +1,42 @@
//! Simple TPU client that communicates with the given UDP port with UDP and provides
//! an interface for sending transactions
use {
crate::tpu_connection::TpuConnection,
solana_sdk::{transaction::Transaction, transport::Result as TransportResult},
std::net::{SocketAddr, UdpSocket},
};
pub struct UdpTpuConnection {
socket: UdpSocket,
addr: SocketAddr,
}
impl TpuConnection for UdpTpuConnection {
fn new(client_socket: UdpSocket, tpu_addr: SocketAddr) -> Self {
Self {
socket: client_socket,
addr: tpu_addr,
}
}
fn tpu_addr(&self) -> &SocketAddr {
&self.addr
}
fn send_wire_transaction(&self, data: Vec<u8>) -> TransportResult<()> {
self.socket.send_to(&data[..], self.addr)?;
Ok(())
}
fn send_batch(&self, transactions: Vec<Transaction>) -> TransportResult<()> {
transactions
.into_iter()
.map(|tx| bincode::serialize(&tx).expect("serialize Transaction in send_batch"))
.try_for_each(|buff| -> TransportResult<()> {
self.socket.send_to(&buff[..], self.addr)?;
Ok(())
})?;
Ok(())
}
}

View File

@@ -1,7 +1,7 @@
[package]
name = "solana-core"
description = "Blockchain, Rebuilt for Scale"
version = "1.10.0"
version = "1.10.1"
homepage = "https://solana.com/"
documentation = "https://docs.rs/solana-core"
readme = "../README.md"
@@ -20,68 +20,64 @@ bincode = "1.3.3"
bs58 = "0.4.0"
chrono = { version = "0.4.11", features = ["serde"] }
crossbeam-channel = "0.5"
dashmap = { version = "4.0.2", features = ["rayon", "raw-api"] }
etcd-client = { version = "0.8.3", features = ["tls"]}
dashmap = { version = "5.1.0", features = ["rayon", "raw-api"] }
etcd-client = { version = "0.8.4", features = ["tls"]}
fs_extra = "1.2.0"
histogram = "0.6.9"
itertools = "0.10.3"
log = "0.4.14"
lru = "0.7.2"
lru = "0.7.3"
rand = "0.7.0"
rand_chacha = "0.2.2"
rayon = "1.5.1"
retain_mut = "0.1.5"
retain_mut = "0.1.7"
serde = "1.0.136"
serde_derive = "1.0.103"
solana-address-lookup-table-program = { path = "../programs/address-lookup-table", version = "=1.10.0" }
solana-bloom = { path = "../bloom", version = "=1.10.0" }
solana-accountsdb-plugin-manager = { path = "../accountsdb-plugin-manager", version = "=1.10.0" }
solana-client = { path = "../client", version = "=1.10.0" }
solana-entry = { path = "../entry", version = "=1.10.0" }
solana-gossip = { path = "../gossip", version = "=1.10.0" }
solana-ledger = { path = "../ledger", version = "=1.10.0" }
solana-measure = { path = "../measure", version = "=1.10.0" }
solana-metrics = { path = "../metrics", version = "=1.10.0" }
solana-net-utils = { path = "../net-utils", version = "=1.10.0" }
solana-perf = { path = "../perf", version = "=1.10.0" }
solana-poh = { path = "../poh", version = "=1.10.0" }
solana-program-runtime = { path = "../program-runtime", version = "=1.10.0" }
solana-rpc = { path = "../rpc", version = "=1.10.0" }
solana-replica-lib = { path = "../replica-lib", version = "=1.10.0" }
solana-runtime = { path = "../runtime", version = "=1.10.0" }
solana-sdk = { path = "../sdk", version = "=1.10.0" }
solana-frozen-abi = { path = "../frozen-abi", version = "=1.10.0" }
solana-frozen-abi-macro = { path = "../frozen-abi/macro", version = "=1.10.0" }
solana-send-transaction-service = { path = "../send-transaction-service", version = "=1.10.0" }
solana-streamer = { path = "../streamer", version = "=1.10.0" }
solana-transaction-status = { path = "../transaction-status", version = "=1.10.0" }
solana-vote-program = { path = "../programs/vote", version = "=1.10.0" }
solana-address-lookup-table-program = { path = "../programs/address-lookup-table", version = "=1.10.1" }
solana-bloom = { path = "../bloom", version = "=1.10.1" }
solana-accountsdb-plugin-manager = { path = "../accountsdb-plugin-manager", version = "=1.10.1" }
solana-client = { path = "../client", version = "=1.10.1" }
solana-entry = { path = "../entry", version = "=1.10.1" }
solana-gossip = { path = "../gossip", version = "=1.10.1" }
solana-ledger = { path = "../ledger", version = "=1.10.1" }
solana-measure = { path = "../measure", version = "=1.10.1" }
solana-metrics = { path = "../metrics", version = "=1.10.1" }
solana-net-utils = { path = "../net-utils", version = "=1.10.1" }
solana-perf = { path = "../perf", version = "=1.10.1" }
solana-poh = { path = "../poh", version = "=1.10.1" }
solana-program-runtime = { path = "../program-runtime", version = "=1.10.1" }
solana-rpc = { path = "../rpc", version = "=1.10.1" }
solana-replica-lib = { path = "../replica-lib", version = "=1.10.1" }
solana-runtime = { path = "../runtime", version = "=1.10.1" }
solana-sdk = { path = "../sdk", version = "=1.10.1" }
solana-frozen-abi = { path = "../frozen-abi", version = "=1.10.1" }
solana-frozen-abi-macro = { path = "../frozen-abi/macro", version = "=1.10.1" }
solana-send-transaction-service = { path = "../send-transaction-service", version = "=1.10.1" }
solana-streamer = { path = "../streamer", version = "=1.10.1" }
solana-transaction-status = { path = "../transaction-status", version = "=1.10.1" }
solana-vote-program = { path = "../programs/vote", version = "=1.10.1" }
tempfile = "3.3.0"
thiserror = "1.0"
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "=1.10.0" }
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "=1.10.1" }
sys-info = "0.9.1"
tokio = { version = "1", features = ["full"] }
trees = "0.4.2"
[dev-dependencies]
jsonrpc-core = "18.0.0"
jsonrpc-core-client = { version = "18.0.0", features = ["ipc", "ws"] }
jsonrpc-derive = "18.0.0"
jsonrpc-pubsub = "18.0.0"
matches = "0.1.9"
raptorq = "1.6.5"
reqwest = { version = "0.11.6", default-features = false, features = ["blocking", "rustls-tls", "json"] }
serde_json = "1.0.78"
serial_test = "0.5.1"
solana-logger = { path = "../logger", version = "=1.10.0" }
solana-program-runtime = { path = "../program-runtime", version = "=1.10.0" }
solana-stake-program = { path = "../programs/stake", version = "=1.10.0" }
solana-version = { path = "../version", version = "=1.10.0" }
reqwest = { version = "0.11.9", default-features = false, features = ["blocking", "rustls-tls", "json"] }
serde_json = "1.0.79"
serial_test = "0.6.0"
solana-logger = { path = "../logger", version = "=1.10.1" }
solana-program-runtime = { path = "../program-runtime", version = "=1.10.1" }
solana-stake-program = { path = "../programs/stake", version = "=1.10.1" }
solana-version = { path = "../version", version = "=1.10.1" }
static_assertions = "1.1.0"
systemstat = "0.1.10"
[target."cfg(unix)".dependencies]
sysctl = "0.4.3"
sysctl = "0.4.4"
[build-dependencies]
rustc_version = "0.4"

View File

@@ -12,6 +12,7 @@ use {
banking_stage::{BankingStage, BankingStageStats},
leader_slot_banking_stage_metrics::LeaderSlotMetricsTracker,
qos_service::QosService,
unprocessed_packet_batches::*,
},
solana_entry::entry::{next_hash, Entry},
solana_gossip::cluster_info::{ClusterInfo, Node},
@@ -82,7 +83,11 @@ fn bench_consume_buffered(bencher: &mut Bencher) {
let mut packet_batches = VecDeque::new();
for batch in batches {
let batch_len = batch.packets.len();
packet_batches.push_back((batch, vec![0usize; batch_len], false));
packet_batches.push_back(DeserializedPacketBatch::new(
batch,
vec![0usize; batch_len],
false,
));
}
let (s, _r) = unbounded();
// This tests the performance of buffering packets.

View File

@@ -0,0 +1,112 @@
#![feature(test)]
extern crate test;
use {
rand::{seq::SliceRandom, Rng},
solana_core::{
cluster_nodes::{make_test_cluster, new_cluster_nodes, ClusterNodes},
retransmit_stage::RetransmitStage,
},
solana_gossip::contact_info::ContactInfo,
solana_sdk::{clock::Slot, hash::hashv, pubkey::Pubkey, signature::Signature},
test::Bencher,
};
const NUM_SIMULATED_SHREDS: usize = 4;
fn make_cluster_nodes<R: Rng>(
rng: &mut R,
unstaked_ratio: Option<(u32, u32)>,
) -> (Vec<ContactInfo>, ClusterNodes<RetransmitStage>) {
let (nodes, stakes, cluster_info) = make_test_cluster(rng, 5_000, unstaked_ratio);
let cluster_nodes = new_cluster_nodes::<RetransmitStage>(&cluster_info, &stakes);
(nodes, cluster_nodes)
}
fn get_retransmit_peers_deterministic(
cluster_nodes: &ClusterNodes<RetransmitStage>,
slot: &Slot,
slot_leader: &Pubkey,
num_simulated_shreds: usize,
) {
for i in 0..num_simulated_shreds {
// see Shred::seed
let shred_seed = hashv(&[
&slot.to_le_bytes(),
&(i as u32).to_le_bytes(),
&slot_leader.to_bytes(),
])
.to_bytes();
let (_neighbors, _children) = cluster_nodes.get_retransmit_peers_deterministic(
shred_seed,
solana_gossip::cluster_info::DATA_PLANE_FANOUT,
*slot_leader,
);
}
}
fn get_retransmit_peers_compat(
cluster_nodes: &ClusterNodes<RetransmitStage>,
slot_leader: &Pubkey,
signatures: &[Signature],
) {
for signature in signatures.iter() {
// see Shred::seed
let signature = signature.as_ref();
let offset = signature.len().checked_sub(32).unwrap();
let shred_seed = signature[offset..].try_into().unwrap();
let (_neighbors, _children) = cluster_nodes.get_retransmit_peers_compat(
shred_seed,
solana_gossip::cluster_info::DATA_PLANE_FANOUT,
*slot_leader,
);
}
}
fn get_retransmit_peers_deterministic_wrapper(b: &mut Bencher, unstaked_ratio: Option<(u32, u32)>) {
let mut rng = rand::thread_rng();
let (nodes, cluster_nodes) = make_cluster_nodes(&mut rng, unstaked_ratio);
let slot_leader = nodes[1..].choose(&mut rng).unwrap().id;
let slot = rand::random::<u64>();
b.iter(|| {
get_retransmit_peers_deterministic(
&cluster_nodes,
&slot,
&slot_leader,
NUM_SIMULATED_SHREDS,
)
});
}
fn get_retransmit_peers_compat_wrapper(b: &mut Bencher, unstaked_ratio: Option<(u32, u32)>) {
let mut rng = rand::thread_rng();
let (nodes, cluster_nodes) = make_cluster_nodes(&mut rng, unstaked_ratio);
let slot_leader = nodes[1..].choose(&mut rng).unwrap().id;
let signatures: Vec<_> = std::iter::repeat_with(Signature::new_unique)
.take(NUM_SIMULATED_SHREDS)
.collect();
b.iter(|| get_retransmit_peers_compat(&cluster_nodes, &slot_leader, &signatures));
}
#[bench]
fn bench_get_retransmit_peers_deterministic_unstaked_ratio_1_2(b: &mut Bencher) {
get_retransmit_peers_deterministic_wrapper(b, Some((1, 2)));
}
#[bench]
fn bench_get_retransmit_peers_compat_unstaked_ratio_1_2(b: &mut Bencher) {
get_retransmit_peers_compat_wrapper(b, Some((1, 2)));
}
#[bench]
fn bench_get_retransmit_peers_deterministic_unstaked_ratio_1_32(b: &mut Bencher) {
get_retransmit_peers_deterministic_wrapper(b, Some((1, 32)));
}
#[bench]
fn bench_get_retransmit_peers_compat_unstaked_ratio_1_32(b: &mut Bencher) {
get_retransmit_peers_compat_wrapper(b, Some((1, 32)));
}

View File

@@ -9,7 +9,10 @@ use {
log::*,
rand::{thread_rng, Rng},
solana_core::{sigverify::TransactionSigVerifier, sigverify_stage::SigVerifyStage},
solana_perf::{packet::to_packet_batches, packet::PacketBatch, test_tx::test_tx},
solana_perf::{
packet::{to_packet_batches, PacketBatch},
test_tx::test_tx,
},
solana_sdk::{
hash::Hash,
signature::{Keypair, Signer},

View File

@@ -3,6 +3,7 @@ use {
cluster_slots::ClusterSlots,
duplicate_repair_status::{DeadSlotAncestorRequestStatus, DuplicateAncestorDecision},
outstanding_requests::OutstandingRequests,
packet_threshold::DynamicPacketToProcessThreshold,
repair_response::{self},
repair_service::{DuplicateSlotsResetSender, RepairInfo, RepairStatsGroup},
replay_stage::DUPLICATE_THRESHOLD,
@@ -12,7 +13,6 @@ use {
crossbeam_channel::{unbounded, Receiver, Sender},
dashmap::{mapref::entry::Entry::Occupied, DashMap},
solana_ledger::{blockstore::Blockstore, shred::SIZE_OF_NONCE},
solana_measure::measure::Measure,
solana_perf::{
packet::{limited_deserialize, Packet, PacketBatch},
recycler::Recycler,
@@ -208,7 +208,7 @@ impl AncestorHashesService {
.spawn(move || {
let mut last_stats_report = Instant::now();
let mut stats = AncestorHashesResponsesStats::default();
let mut max_packets = 1024;
let mut packet_threshold = DynamicPacketToProcessThreshold::default();
loop {
let result = Self::process_new_packets_from_channel(
&ancestor_hashes_request_statuses,
@@ -216,13 +216,13 @@ impl AncestorHashesService {
&blockstore,
&outstanding_requests,
&mut stats,
&mut max_packets,
&mut packet_threshold,
&duplicate_slots_reset_sender,
&retryable_slots_sender,
);
match result {
Err(Error::RecvTimeout(_)) | Ok(_) => {}
Err(err) => info!("ancestors hashes reponses listener error: {:?}", err),
Err(err) => info!("ancestors hashes responses listener error: {:?}", err),
};
if exit.load(Ordering::Relaxed) {
return;
@@ -243,7 +243,7 @@ impl AncestorHashesService {
blockstore: &Blockstore,
outstanding_requests: &RwLock<OutstandingAncestorHashesRepairs>,
stats: &mut AncestorHashesResponsesStats,
max_packets: &mut usize,
packet_threshold: &mut DynamicPacketToProcessThreshold,
duplicate_slots_reset_sender: &DuplicateSlotsResetSender,
retryable_slots_sender: &RetryableSlotsSender,
) -> Result<()> {
@@ -254,18 +254,17 @@ impl AncestorHashesService {
let mut dropped_packets = 0;
while let Ok(batch) = response_receiver.try_recv() {
total_packets += batch.packets.len();
if total_packets < *max_packets {
// Drop the rest in the channel in case of DOS
packet_batches.push(batch);
} else {
if packet_threshold.should_drop(total_packets) {
dropped_packets += batch.packets.len();
} else {
packet_batches.push(batch);
}
}
stats.dropped_packets += dropped_packets;
stats.total_packets += total_packets;
let mut time = Measure::start("ancestor_hashes::handle_packets");
let timer = Instant::now();
for packet_batch in packet_batches {
Self::process_packet_batch(
ancestor_hashes_request_statuses,
@@ -277,14 +276,7 @@ impl AncestorHashesService {
retryable_slots_sender,
);
}
time.stop();
if total_packets >= *max_packets {
if time.as_ms() > 1000 {
*max_packets = (*max_packets * 9) / 10;
} else {
*max_packets = (*max_packets * 10) / 9;
}
}
packet_threshold.update(total_packets, timer.elapsed());
Ok(())
}

File diff suppressed because it is too large Load Diff

View File

@@ -2,12 +2,14 @@ use {
crate::{broadcast_stage::BroadcastStage, retransmit_stage::RetransmitStage},
itertools::Itertools,
lru::LruCache,
rand::SeedableRng,
rand::{seq::SliceRandom, Rng, SeedableRng},
rand_chacha::ChaChaRng,
solana_gossip::{
cluster_info::{compute_retransmit_peers, ClusterInfo},
contact_info::ContactInfo,
crds::GossipRoute,
crds_gossip_pull::CRDS_GOSSIP_PULL_CRDS_TIMEOUT_MS,
crds_value::{CrdsData, CrdsValue},
weighted_shuffle::{weighted_best, weighted_shuffle, WeightedShuffle},
},
solana_ledger::shred::Shred,
@@ -16,6 +18,7 @@ use {
clock::{Epoch, Slot},
feature_set,
pubkey::Pubkey,
signature::Keypair,
timing::timestamp,
},
solana_streamer::socket::SocketAddrSpace,
@@ -23,6 +26,7 @@ use {
any::TypeId,
cmp::Reverse,
collections::HashMap,
iter::repeat_with,
marker::PhantomData,
net::SocketAddr,
ops::Deref,
@@ -39,7 +43,7 @@ enum NodeId {
Pubkey(Pubkey),
}
struct Node {
pub struct Node {
node: NodeId,
stake: u64,
}
@@ -233,6 +237,18 @@ impl ClusterNodes<RetransmitStage> {
if !enable_turbine_peers_shuffle_patch(shred.slot(), root_bank) {
return self.get_retransmit_peers_compat(shred_seed, fanout, slot_leader);
}
self.get_retransmit_peers_deterministic(shred_seed, fanout, slot_leader)
}
pub fn get_retransmit_peers_deterministic(
&self,
shred_seed: [u8; 32],
fanout: usize,
slot_leader: Pubkey,
) -> (
Vec<&Node>, // neighbors
Vec<&Node>, // children
) {
let mut weighted_shuffle = self.weighted_shuffle.clone();
// Exclude slot leader from list of nodes.
if slot_leader == self.pubkey {
@@ -256,7 +272,7 @@ impl ClusterNodes<RetransmitStage> {
(neighbors, children)
}
fn get_retransmit_peers_compat(
pub fn get_retransmit_peers_compat(
&self,
shred_seed: [u8; 32],
fanout: usize,
@@ -297,7 +313,7 @@ impl ClusterNodes<RetransmitStage> {
}
}
fn new_cluster_nodes<T: 'static>(
pub fn new_cluster_nodes<T: 'static>(
cluster_info: &ClusterInfo,
stakes: &HashMap<Pubkey, u64>,
) -> ClusterNodes<T> {
@@ -462,22 +478,61 @@ impl From<Pubkey> for NodeId {
}
}
pub fn make_test_cluster<R: Rng>(
rng: &mut R,
num_nodes: usize,
unstaked_ratio: Option<(u32, u32)>,
) -> (
Vec<ContactInfo>,
HashMap<Pubkey, u64>, // stakes
ClusterInfo,
) {
let (unstaked_numerator, unstaked_denominator) = unstaked_ratio.unwrap_or((1, 7));
let mut nodes: Vec<_> = repeat_with(|| ContactInfo::new_rand(rng, None))
.take(num_nodes)
.collect();
nodes.shuffle(rng);
let this_node = nodes[0].clone();
let mut stakes: HashMap<Pubkey, u64> = nodes
.iter()
.filter_map(|node| {
if rng.gen_ratio(unstaked_numerator, unstaked_denominator) {
None // No stake for some of the nodes.
} else {
Some((node.id, rng.gen_range(0, 20)))
}
})
.collect();
// Add some staked nodes with no contact-info.
stakes.extend(repeat_with(|| (Pubkey::new_unique(), rng.gen_range(0, 20))).take(100));
let cluster_info = ClusterInfo::new(
this_node,
Arc::new(Keypair::new()),
SocketAddrSpace::Unspecified,
);
{
let now = timestamp();
let mut gossip_crds = cluster_info.gossip.crds.write().unwrap();
// First node is pushed to crds table by ClusterInfo constructor.
for node in nodes.iter().skip(1) {
let node = CrdsData::ContactInfo(node.clone());
let node = CrdsValue::new_unsigned(node);
assert_eq!(
gossip_crds.insert(node, now, GossipRoute::LocalMessage),
Ok(())
);
}
}
(nodes, stakes, cluster_info)
}
#[cfg(test)]
mod tests {
use {
super::*,
rand::{seq::SliceRandom, Rng},
solana_gossip::{
crds::GossipRoute,
crds_value::{CrdsData, CrdsValue},
deprecated::{
shuffle_peers_and_index, sorted_retransmit_peers_and_stakes,
sorted_stakes_with_index,
},
solana_gossip::deprecated::{
shuffle_peers_and_index, sorted_retransmit_peers_and_stakes, sorted_stakes_with_index,
},
solana_sdk::{signature::Keypair, timing::timestamp},
solana_streamer::socket::SocketAddrSpace,
std::{iter::repeat_with, sync::Arc},
};
// Legacy methods copied for testing backward compatibility.
@@ -499,55 +554,10 @@ mod tests {
sorted_stakes_with_index(peers, stakes)
}
fn make_cluster<R: Rng>(
rng: &mut R,
) -> (
Vec<ContactInfo>,
HashMap<Pubkey, u64>, // stakes
ClusterInfo,
) {
let mut nodes: Vec<_> = repeat_with(|| ContactInfo::new_rand(rng, None))
.take(1000)
.collect();
nodes.shuffle(rng);
let this_node = nodes[0].clone();
let mut stakes: HashMap<Pubkey, u64> = nodes
.iter()
.filter_map(|node| {
if rng.gen_ratio(1, 7) {
None // No stake for some of the nodes.
} else {
Some((node.id, rng.gen_range(0, 20)))
}
})
.collect();
// Add some staked nodes with no contact-info.
stakes.extend(repeat_with(|| (Pubkey::new_unique(), rng.gen_range(0, 20))).take(100));
let cluster_info = ClusterInfo::new(
this_node,
Arc::new(Keypair::new()),
SocketAddrSpace::Unspecified,
);
{
let now = timestamp();
let mut gossip_crds = cluster_info.gossip.crds.write().unwrap();
// First node is pushed to crds table by ClusterInfo constructor.
for node in nodes.iter().skip(1) {
let node = CrdsData::ContactInfo(node.clone());
let node = CrdsValue::new_unsigned(node);
assert_eq!(
gossip_crds.insert(node, now, GossipRoute::LocalMessage),
Ok(())
);
}
}
(nodes, stakes, cluster_info)
}
#[test]
fn test_cluster_nodes_retransmit() {
let mut rng = rand::thread_rng();
let (nodes, stakes, cluster_info) = make_cluster(&mut rng);
let (nodes, stakes, cluster_info) = make_test_cluster(&mut rng, 1_000, None);
let this_node = cluster_info.my_contact_info();
// ClusterInfo::tvu_peers excludes the node itself.
assert_eq!(cluster_info.tvu_peers().len(), nodes.len() - 1);
@@ -628,7 +638,7 @@ mod tests {
#[test]
fn test_cluster_nodes_broadcast() {
let mut rng = rand::thread_rng();
let (nodes, stakes, cluster_info) = make_cluster(&mut rng);
let (nodes, stakes, cluster_info) = make_test_cluster(&mut rng, 1_000, None);
// ClusterInfo::tvu_peers excludes the node itself.
assert_eq!(cluster_info.tvu_peers().len(), nodes.len() - 1);
let cluster_nodes = ClusterNodes::<BroadcastStage>::new(&cluster_info, &stakes);

View File

@@ -1,9 +1,9 @@
use crate::tower1_7_14::Tower1_7_14;
use {
crate::{
heaviest_subtree_fork_choice::HeaviestSubtreeForkChoice,
latest_validator_votes_for_frozen_banks::LatestValidatorVotesForFrozenBanks,
progress_map::{LockoutIntervals, ProgressMap},
tower1_7_14::Tower1_7_14,
tower_storage::{SavedTower, SavedTowerVersions, TowerStorage},
},
chrono::prelude::*,

View File

@@ -11,44 +11,33 @@ use {
solana_runtime::{bank::Bank, cost_model::CostModel},
solana_sdk::timing::timestamp,
std::{
sync::{Arc, RwLock},
sync::{
atomic::{AtomicBool, Ordering},
Arc, RwLock,
},
thread::{self, Builder, JoinHandle},
time::Duration,
},
};
// Update blockstore persistence storage when accumulated cost_table updates count exceeds the threshold
const PERSIST_THRESHOLD: u64 = 1_000;
#[derive(Default)]
pub struct CostUpdateServiceTiming {
last_print: u64,
update_cost_model_count: u64,
update_cost_model_elapsed: u64,
persist_cost_table_elapsed: u64,
}
impl CostUpdateServiceTiming {
fn update(
&mut self,
update_cost_model_count: Option<u64>,
update_cost_model_elapsed: Option<u64>,
persist_cost_table_elapsed: Option<u64>,
) {
if let Some(update_cost_model_count) = update_cost_model_count {
self.update_cost_model_count += update_cost_model_count;
}
if let Some(update_cost_model_elapsed) = update_cost_model_elapsed {
self.update_cost_model_elapsed += update_cost_model_elapsed;
}
if let Some(persist_cost_table_elapsed) = persist_cost_table_elapsed {
self.persist_cost_table_elapsed += persist_cost_table_elapsed;
}
fn update(&mut self, update_cost_model_count: u64, update_cost_model_elapsed: u64) {
self.update_cost_model_count += update_cost_model_count;
self.update_cost_model_elapsed += update_cost_model_elapsed;
let now = timestamp();
let elapsed_ms = now - self.last_print;
if elapsed_ms > 1000 {
datapoint_info!(
"cost-update-service-stats",
("total_elapsed_us", elapsed_ms * 1000, i64),
(
"update_cost_model_count",
self.update_cost_model_count as i64,
@@ -59,11 +48,6 @@ impl CostUpdateServiceTiming {
self.update_cost_model_elapsed as i64,
i64
),
(
"persist_cost_table_elapsed",
self.persist_cost_table_elapsed as i64,
i64
),
);
*self = CostUpdateServiceTiming::default();
@@ -90,6 +74,7 @@ pub struct CostUpdateService {
impl CostUpdateService {
#[allow(clippy::new_ret_no_self)]
pub fn new(
exit: Arc<AtomicBool>,
blockstore: Arc<Blockstore>,
cost_model: Arc<RwLock<CostModel>>,
cost_update_receiver: CostUpdateReceiver,
@@ -97,7 +82,7 @@ impl CostUpdateService {
let thread_hdl = Builder::new()
.name("solana-cost-update-service".to_string())
.spawn(move || {
Self::service_loop(blockstore, cost_model, cost_update_receiver);
Self::service_loop(exit, blockstore, cost_model, cost_update_receiver);
})
.unwrap();
@@ -109,99 +94,85 @@ impl CostUpdateService {
}
fn service_loop(
blockstore: Arc<Blockstore>,
exit: Arc<AtomicBool>,
_blockstore: Arc<Blockstore>,
cost_model: Arc<RwLock<CostModel>>,
cost_update_receiver: CostUpdateReceiver,
) {
let mut cost_update_service_timing = CostUpdateServiceTiming::default();
let mut update_count = 0_u64;
let mut update_count: u64;
let wait_timer = Duration::from_millis(100);
for cost_update in cost_update_receiver.iter() {
match cost_update {
CostUpdate::FrozenBank { bank } => {
bank.read_cost_tracker().unwrap().report_stats(bank.slot());
loop {
if exit.load(Ordering::Relaxed) {
break;
}
update_count = 0_u64;
let mut update_cost_model_time = Measure::start("update_cost_model_time");
for cost_update in cost_update_receiver.try_iter() {
match cost_update {
CostUpdate::FrozenBank { bank } => {
bank.read_cost_tracker().unwrap().report_stats(bank.slot());
}
CostUpdate::ExecuteTiming {
mut execute_timings,
} => {
Self::update_cost_model(&cost_model, &mut execute_timings);
update_count += 1;
}
}
CostUpdate::ExecuteTiming {
mut execute_timings,
} => {
let mut update_cost_model_time = Measure::start("update_cost_model_time");
update_count += Self::update_cost_model(&cost_model, &mut execute_timings);
update_cost_model_time.stop();
cost_update_service_timing.update(
Some(update_count),
Some(update_cost_model_time.as_us()),
None,
);
}
update_cost_model_time.stop();
if update_count > PERSIST_THRESHOLD {
let mut persist_cost_table_time = Measure::start("persist_cost_table_time");
Self::persist_cost_table(&blockstore, &cost_model);
update_count = 0_u64;
persist_cost_table_time.stop();
cost_update_service_timing.update(
None,
None,
Some(persist_cost_table_time.as_us()),
cost_update_service_timing.update(update_count, update_cost_model_time.as_us());
thread::sleep(wait_timer);
}
}
fn update_cost_model(
cost_model: &RwLock<CostModel>,
execute_timings: &mut ExecuteTimings,
) -> bool {
let mut dirty = false;
{
for (program_id, program_timings) in &mut execute_timings.details.per_program_timings {
let current_estimated_program_cost =
cost_model.read().unwrap().find_instruction_cost(program_id);
program_timings.coalesce_error_timings(current_estimated_program_cost);
if program_timings.count < 1 {
continue;
}
let units = program_timings.accumulated_units / program_timings.count as u64;
match cost_model
.write()
.unwrap()
.upsert_instruction_cost(program_id, units)
{
Ok(c) => {
debug!(
"after replayed into bank, instruction {:?} has averaged cost {}",
program_id, c
);
dirty = true;
}
Err(err) => {
debug!(
"after replayed into bank, instruction {:?} failed to update cost, err: {}",
program_id, err
);
}
}
}
}
}
// Normalize `program_timings` with current estimated cost, update instruction_cost table
// Returns number of updates applied
fn update_cost_model(
cost_model: &RwLock<CostModel>,
execute_timings: &mut ExecuteTimings,
) -> u64 {
let mut update_count = 0_u64;
for (program_id, program_timings) in &mut execute_timings.details.per_program_timings {
let current_estimated_program_cost =
cost_model.read().unwrap().find_instruction_cost(program_id);
program_timings.coalesce_error_timings(current_estimated_program_cost);
if program_timings.count < 1 {
continue;
}
let units = program_timings.accumulated_units / program_timings.count as u64;
cost_model
.write()
.unwrap()
.upsert_instruction_cost(program_id, units);
update_count += 1;
debug!(
"After replayed into bank, updated cost for instruction {:?}, update_value {}, pre_aggregated_value {}",
program_id, units, current_estimated_program_cost
);
}
update_count
}
// 1. Remove obsolete program entries from persisted table to limit its size
// 2. Update persisted program cost. This involves EMA cost calculation at
// execute_cost_table.get_cost()
fn persist_cost_table(blockstore: &Blockstore, cost_model: &RwLock<CostModel>) {
let db_records = blockstore.read_program_costs().expect("read programs");
let cost_model = cost_model.read().unwrap();
let active_program_keys = cost_model.get_program_keys();
// delete records from blockstore if they are no longer in cost_table
db_records.iter().for_each(|(pubkey, _)| {
if !active_program_keys.contains(&pubkey) {
blockstore
.delete_program_cost(pubkey)
.expect("delete old program");
}
});
active_program_keys.iter().for_each(|program_id| {
let cost = cost_model.find_instruction_cost(program_id);
blockstore
.write_program_cost(program_id, &cost)
.expect("persist program costs to blockstore");
});
debug!(
"after replayed into bank, updated cost model instruction cost table, current values: {:?}",
cost_model.read().unwrap().get_instruction_cost_table()
);
dirty
}
}
@@ -213,9 +184,15 @@ mod tests {
fn test_update_cost_model_with_empty_execute_timings() {
let cost_model = Arc::new(RwLock::new(CostModel::default()));
let mut empty_execute_timings = ExecuteTimings::default();
CostUpdateService::update_cost_model(&cost_model, &mut empty_execute_timings);
assert_eq!(
CostUpdateService::update_cost_model(&cost_model, &mut empty_execute_timings),
0
0,
cost_model
.read()
.unwrap()
.get_instruction_cost_table()
.len()
);
}
@@ -233,7 +210,7 @@ mod tests {
let accumulated_units: u64 = 100;
let total_errored_units = 0;
let count: u32 = 10;
expected_cost = accumulated_units / count as u64; // = 10
expected_cost = accumulated_units / count as u64;
execute_timings.details.per_program_timings.insert(
program_key_1,
@@ -245,15 +222,22 @@ mod tests {
total_errored_units,
},
);
let update_count =
CostUpdateService::update_cost_model(&cost_model, &mut execute_timings);
assert_eq!(1, update_count);
CostUpdateService::update_cost_model(&cost_model, &mut execute_timings);
assert_eq!(
expected_cost,
1,
cost_model
.read()
.unwrap()
.find_instruction_cost(&program_key_1)
.get_instruction_cost_table()
.len()
);
assert_eq!(
Some(&expected_cost),
cost_model
.read()
.unwrap()
.get_instruction_cost_table()
.get(&program_key_1)
);
}
@@ -262,8 +246,8 @@ mod tests {
let accumulated_us: u64 = 2000;
let accumulated_units: u64 = 200;
let count: u32 = 10;
// to expect new cost = (mean + 2 * std) of [10, 20]
expected_cost = 13;
// to expect new cost is Average(new_value, existing_value)
expected_cost = ((accumulated_units / count as u64) + expected_cost) / 2;
execute_timings.details.per_program_timings.insert(
program_key_1,
@@ -275,15 +259,22 @@ mod tests {
total_errored_units: 0,
},
);
let update_count =
CostUpdateService::update_cost_model(&cost_model, &mut execute_timings);
assert_eq!(1, update_count);
CostUpdateService::update_cost_model(&cost_model, &mut execute_timings);
assert_eq!(
expected_cost,
1,
cost_model
.read()
.unwrap()
.find_instruction_cost(&program_key_1)
.get_instruction_cost_table()
.len()
);
assert_eq!(
Some(&expected_cost),
cost_model
.read()
.unwrap()
.get_instruction_cost_table()
.get(&program_key_1)
);
}
}
@@ -307,49 +298,20 @@ mod tests {
total_errored_units: 0,
},
);
CostUpdateService::update_cost_model(&cost_model, &mut execute_timings);
// If both the `errored_txs_compute_consumed` is empty and `count == 0`, then
// nothing should be inserted into the cost model
assert_eq!(
CostUpdateService::update_cost_model(&cost_model, &mut execute_timings),
0
);
}
// set up current instruction cost to 100
let current_program_cost = 100;
{
execute_timings.details.per_program_timings.insert(
program_key_1,
ProgramTiming {
accumulated_us: 1000,
accumulated_units: current_program_cost,
count: 1,
errored_txs_compute_consumed: vec![],
total_errored_units: 0,
},
);
let update_count =
CostUpdateService::update_cost_model(&cost_model, &mut execute_timings);
assert_eq!(1, update_count);
assert_eq!(
current_program_cost,
cost_model
.read()
.unwrap()
.find_instruction_cost(&program_key_1)
);
assert!(cost_model
.read()
.unwrap()
.get_instruction_cost_table()
.is_empty());
}
// Test updating cost model with only erroring compute costs where the `cost_per_error` is
// greater than the current instruction cost for the program. Should update with the
// new erroring compute costs
let cost_per_error = 1000;
// expected_cost = (mean + 2*std) of data points:
// [
// 100, // original program_cost
// 1000, // cost_per_error
// ]
let expected_cost = 289u64;
{
let errored_txs_compute_consumed = vec![cost_per_error; 3];
let total_errored_units = errored_txs_compute_consumed.iter().sum();
@@ -363,23 +325,29 @@ mod tests {
total_errored_units,
},
);
let update_count =
CostUpdateService::update_cost_model(&cost_model, &mut execute_timings);
assert_eq!(1, update_count);
CostUpdateService::update_cost_model(&cost_model, &mut execute_timings);
assert_eq!(
expected_cost,
1,
cost_model
.read()
.unwrap()
.find_instruction_cost(&program_key_1)
.get_instruction_cost_table()
.len()
);
assert_eq!(
Some(&cost_per_error),
cost_model
.read()
.unwrap()
.get_instruction_cost_table()
.get(&program_key_1)
);
}
// Test updating cost model with only erroring compute costs where the error cost is
// `smaller_cost_per_error`, less than the current instruction cost for the program.
// The cost should not decrease for these new lesser errors
let smaller_cost_per_error = expected_cost - 10;
let smaller_cost_per_error = cost_per_error - 10;
{
let errored_txs_compute_consumed = vec![smaller_cost_per_error; 3];
let total_errored_units = errored_txs_compute_consumed.iter().sum();
@@ -393,23 +361,22 @@ mod tests {
total_errored_units,
},
);
let update_count =
CostUpdateService::update_cost_model(&cost_model, &mut execute_timings);
// expected_cost = (mean = 2*std) of data points:
// [
// 100, // original program cost,
// 1000, // cost_per_error from above test
// 289, // the smaller_cost_per_error will be coalesced to prev cost
// ]
let expected_cost = 293u64;
assert_eq!(1, update_count);
CostUpdateService::update_cost_model(&cost_model, &mut execute_timings);
assert_eq!(
expected_cost,
1,
cost_model
.read()
.unwrap()
.find_instruction_cost(&program_key_1)
.get_instruction_cost_table()
.len()
);
assert_eq!(
Some(&cost_per_error),
cost_model
.read()
.unwrap()
.get_instruction_cost_table()
.get(&program_key_1)
);
}
}

View File

@@ -2715,7 +2715,8 @@ mod test {
stake
);
}
for slot in &[17] {
{
let slot = &17;
assert_eq!(
tree1
.stake_voted_subtree(&(*slot, Hash::default()))

View File

@@ -1,4 +1,5 @@
use {
crate::leader_slot_banking_stage_timing_metrics::*,
solana_poh::poh_recorder::BankStart,
solana_sdk::{clock::Slot, saturating_add_assign},
std::time::Instant,
@@ -38,41 +39,12 @@ pub(crate) struct ProcessTransactionsSummary {
// 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,
// Total amount of time spent running the cost model
pub cost_model_us: u64,
// 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),
);
}
// Breakdown of time spent executing and comitting transactions
pub execute_and_commit_timings: LeaderExecuteAndCommitTimings,
}
// Metrics describing packets ingested/processed in various parts of BankingStage during this
@@ -362,6 +334,8 @@ impl LeaderSlotMetricsTracker {
failed_commit_count,
ref retryable_transaction_indexes,
cost_model_throttled_transactions_count,
cost_model_us,
ref execute_and_commit_timings,
..
} = process_transactions_summary;
@@ -415,9 +389,23 @@ impl LeaderSlotMetricsTracker {
.cost_model_throttled_transactions_count,
*cost_model_throttled_transactions_count as u64
);
saturating_add_assign!(
leader_slot_metrics
.timing_metrics
.process_packets_timings
.cost_model_us,
*cost_model_us as u64
);
leader_slot_metrics
.timing_metrics
.execute_and_commit_timings
.accumulate(execute_and_commit_timings);
}
}
// Packet inflow/outflow/processing metrics
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!(
@@ -527,6 +515,166 @@ impl LeaderSlotMetricsTracker {
);
}
}
// Outermost banking thread's loop timing metrics
pub(crate) fn increment_process_buffered_packets_us(&mut self, us: u64) {
if let Some(leader_slot_metrics) = &mut self.leader_slot_metrics {
saturating_add_assign!(
leader_slot_metrics
.timing_metrics
.outer_loop_timings
.process_buffered_packets_us,
us
);
}
}
pub(crate) fn increment_slot_metrics_check_slot_boundary_us(&mut self, us: u64) {
if let Some(leader_slot_metrics) = &mut self.leader_slot_metrics {
saturating_add_assign!(
leader_slot_metrics
.timing_metrics
.outer_loop_timings
.slot_metrics_check_slot_boundary_us,
us
);
}
}
pub(crate) fn increment_receive_and_buffer_packets_us(&mut self, us: u64) {
if let Some(leader_slot_metrics) = &mut self.leader_slot_metrics {
saturating_add_assign!(
leader_slot_metrics
.timing_metrics
.outer_loop_timings
.receive_and_buffer_packets_us,
us
);
}
}
// Processing buffer timing metrics
pub(crate) fn increment_make_decision_us(&mut self, us: u64) {
if let Some(leader_slot_metrics) = &mut self.leader_slot_metrics {
saturating_add_assign!(
leader_slot_metrics
.timing_metrics
.process_buffered_packets_timings
.make_decision_us,
us
);
}
}
pub(crate) fn increment_consume_buffered_packets_us(&mut self, us: u64) {
if let Some(leader_slot_metrics) = &mut self.leader_slot_metrics {
saturating_add_assign!(
leader_slot_metrics
.timing_metrics
.process_buffered_packets_timings
.consume_buffered_packets_us,
us
);
}
}
pub(crate) fn increment_forward_us(&mut self, us: u64) {
if let Some(leader_slot_metrics) = &mut self.leader_slot_metrics {
saturating_add_assign!(
leader_slot_metrics
.timing_metrics
.process_buffered_packets_timings
.forward_us,
us
);
}
}
pub(crate) fn increment_forward_and_hold_us(&mut self, us: u64) {
if let Some(leader_slot_metrics) = &mut self.leader_slot_metrics {
saturating_add_assign!(
leader_slot_metrics
.timing_metrics
.process_buffered_packets_timings
.forward_and_hold_us,
us
);
}
}
// Consuming buffered packets timing metrics
pub(crate) fn increment_end_of_slot_filtering_us(&mut self, us: u64) {
if let Some(leader_slot_metrics) = &mut self.leader_slot_metrics {
saturating_add_assign!(
leader_slot_metrics
.timing_metrics
.consume_buffered_packets_timings
.end_of_slot_filtering_us,
us
);
}
}
pub(crate) fn increment_consume_buffered_packets_poh_recorder_lock_us(&mut self, us: u64) {
if let Some(leader_slot_metrics) = &mut self.leader_slot_metrics {
saturating_add_assign!(
leader_slot_metrics
.timing_metrics
.consume_buffered_packets_timings
.poh_recorder_lock_us,
us
);
}
}
pub(crate) fn increment_process_packets_transactions_us(&mut self, us: u64) {
if let Some(leader_slot_metrics) = &mut self.leader_slot_metrics {
saturating_add_assign!(
leader_slot_metrics
.timing_metrics
.consume_buffered_packets_timings
.process_packets_transactions_us,
us
);
}
}
// Processing packets timing metrics
pub(crate) fn increment_transactions_from_packets_us(&mut self, us: u64) {
if let Some(leader_slot_metrics) = &mut self.leader_slot_metrics {
saturating_add_assign!(
leader_slot_metrics
.timing_metrics
.process_packets_timings
.transactions_from_packets_us,
us
);
}
}
pub(crate) fn increment_process_transactions_us(&mut self, us: u64) {
if let Some(leader_slot_metrics) = &mut self.leader_slot_metrics {
saturating_add_assign!(
leader_slot_metrics
.timing_metrics
.process_packets_timings
.process_transactions_us,
us
);
}
}
pub(crate) fn increment_filter_retryable_packets_us(&mut self, us: u64) {
if let Some(leader_slot_metrics) = &mut self.leader_slot_metrics {
saturating_add_assign!(
leader_slot_metrics
.timing_metrics
.process_packets_timings
.filter_retryable_packets_us,
us
);
}
}
}
#[cfg(test)]

View File

@@ -0,0 +1,286 @@
use {
solana_program_runtime::timings::ExecuteTimings,
solana_sdk::{clock::Slot, saturating_add_assign},
std::time::Instant,
};
#[derive(Default, Debug)]
pub struct LeaderExecuteAndCommitTimings {
pub collect_balances_us: u64,
pub load_execute_us: u64,
pub freeze_lock_us: u64,
pub record_us: u64,
pub commit_us: u64,
pub find_and_send_votes_us: u64,
pub record_transactions_timings: RecordTransactionsTimings,
pub execute_timings: ExecuteTimings,
}
impl LeaderExecuteAndCommitTimings {
pub fn accumulate(&mut self, other: &LeaderExecuteAndCommitTimings) {
saturating_add_assign!(self.collect_balances_us, other.collect_balances_us);
saturating_add_assign!(self.load_execute_us, other.load_execute_us);
saturating_add_assign!(self.freeze_lock_us, other.freeze_lock_us);
saturating_add_assign!(self.record_us, other.record_us);
saturating_add_assign!(self.commit_us, other.commit_us);
saturating_add_assign!(self.find_and_send_votes_us, other.find_and_send_votes_us);
saturating_add_assign!(self.commit_us, other.commit_us);
self.record_transactions_timings
.accumulate(&other.record_transactions_timings);
self.execute_timings.accumulate(&other.execute_timings);
}
pub fn report(&self, id: u32, slot: Slot) {
datapoint_info!(
"banking_stage-leader_slot_execute_and_commit_timings",
("id", id as i64, i64),
("slot", slot as i64, i64),
("collect_balances_us", self.collect_balances_us as i64, i64),
("load_execute_us", self.load_execute_us as i64, i64),
("freeze_lock_us", self.freeze_lock_us as i64, i64),
("record_us", self.record_us as i64, i64),
("commit_us", self.commit_us as i64, i64),
(
"find_and_send_votes_us",
self.find_and_send_votes_us as i64,
i64
),
);
datapoint_info!(
"banking_stage-leader_slot_record_timings",
("id", id as i64, i64),
("slot", slot as i64, i64),
(
"execution_results_to_transactions_us",
self.record_transactions_timings
.execution_results_to_transactions_us as i64,
i64
),
(
"hash_us",
self.record_transactions_timings.hash_us as i64,
i64
),
(
"poh_record_us",
self.record_transactions_timings.poh_record_us as i64,
i64
),
);
}
}
#[derive(Default, Debug)]
pub struct RecordTransactionsTimings {
pub execution_results_to_transactions_us: u64,
pub hash_us: u64,
pub poh_record_us: u64,
}
impl RecordTransactionsTimings {
pub fn accumulate(&mut self, other: &RecordTransactionsTimings) {
saturating_add_assign!(
self.execution_results_to_transactions_us,
other.execution_results_to_transactions_us
);
saturating_add_assign!(self.hash_us, other.hash_us);
saturating_add_assign!(self.poh_record_us, other.poh_record_us);
}
}
// Metrics capturing wallclock time spent in various parts of BankingStage during this
// validator's leader slot
#[derive(Debug)]
pub(crate) struct LeaderSlotTimingMetrics {
pub outer_loop_timings: OuterLoopTimings,
pub process_buffered_packets_timings: ProcessBufferedPacketsTimings,
pub consume_buffered_packets_timings: ConsumeBufferedPacketsTimings,
pub process_packets_timings: ProcessPacketsTimings,
pub execute_and_commit_timings: LeaderExecuteAndCommitTimings,
}
impl LeaderSlotTimingMetrics {
pub(crate) fn new(bank_creation_time: &Instant) -> Self {
Self {
outer_loop_timings: OuterLoopTimings::new(bank_creation_time),
process_buffered_packets_timings: ProcessBufferedPacketsTimings::default(),
consume_buffered_packets_timings: ConsumeBufferedPacketsTimings::default(),
process_packets_timings: ProcessPacketsTimings::default(),
execute_and_commit_timings: LeaderExecuteAndCommitTimings::default(),
}
}
pub(crate) fn report(&self, id: u32, slot: Slot) {
self.outer_loop_timings.report(id, slot);
self.process_buffered_packets_timings.report(id, slot);
self.consume_buffered_packets_timings.report(id, slot);
self.process_packets_timings.report(id, slot);
self.execute_and_commit_timings.report(id, slot);
}
}
#[derive(Debug)]
pub(crate) struct OuterLoopTimings {
pub bank_detected_time: Instant,
// Delay from when the bank was created to when this thread detected it
pub bank_detected_delay_us: u64,
// Time spent processing buffered packets
pub process_buffered_packets_us: u64,
// Time spent checking for slot boundary and reporting leader slot metrics
pub slot_metrics_check_slot_boundary_us: u64,
// Time spent processing new incoming packets to the banking thread
pub receive_and_buffer_packets_us: u64,
}
impl OuterLoopTimings {
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,
process_buffered_packets_us: 0,
slot_metrics_check_slot_boundary_us: 0,
receive_and_buffer_packets_us: 0,
}
}
fn report(&self, id: u32, slot: Slot) {
let bank_detected_to_now_us = 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_slot_end_detected_us",
bank_detected_to_now_us,
i64
),
(
"bank_creation_to_slot_end_detected_us",
bank_detected_to_now_us + self.bank_detected_delay_us,
i64
),
("bank_detected_delay_us", self.bank_detected_delay_us, i64),
(
"process_buffered_packets_us",
self.process_buffered_packets_us,
i64
),
(
"slot_metrics_check_slot_boundary_us",
self.slot_metrics_check_slot_boundary_us,
i64
),
(
"receive_and_buffer_packets_us",
self.receive_and_buffer_packets_us,
i64
),
);
}
}
#[derive(Debug, Default)]
pub(crate) struct ProcessBufferedPacketsTimings {
pub make_decision_us: u64,
pub consume_buffered_packets_us: u64,
pub forward_us: u64,
pub forward_and_hold_us: u64,
}
impl ProcessBufferedPacketsTimings {
fn report(&self, id: u32, slot: Slot) {
datapoint_info!(
"banking_stage-leader_slot_process_buffered_packets_timings",
("id", id as i64, i64),
("slot", slot as i64, i64),
("make_decision_us", self.make_decision_us as i64, i64),
(
"consume_buffered_packets_us",
self.consume_buffered_packets_us as i64,
i64
),
("forward_us", self.forward_us as i64, i64),
("forward_and_hold_us", self.forward_and_hold_us as i64, i64),
);
}
}
#[derive(Debug, Default)]
pub(crate) struct ConsumeBufferedPacketsTimings {
// Time spent grabbing poh recorder lock
pub poh_recorder_lock_us: u64,
// Time spent filtering invalid packets after leader slot has ended
pub end_of_slot_filtering_us: u64,
// Time spent processing transactions
pub process_packets_transactions_us: u64,
}
impl ConsumeBufferedPacketsTimings {
fn report(&self, id: u32, slot: Slot) {
datapoint_info!(
"banking_stage-leader_slot_consume_buffered_packets_timings",
("id", id as i64, i64),
("slot", slot as i64, i64),
(
"poh_recorder_lock_us",
self.poh_recorder_lock_us as i64,
i64
),
(
"end_of_slot_filtering_us",
self.end_of_slot_filtering_us as i64,
i64
),
(
"process_packets_transactions_us",
self.process_packets_transactions_us as i64,
i64
),
);
}
}
#[derive(Debug, Default)]
pub(crate) struct ProcessPacketsTimings {
// Time spent converting packets to transactions
pub transactions_from_packets_us: u64,
// Time spent processing transactions
pub process_transactions_us: u64,
// Time spent filtering retryable packets that were returned after transaction
// processing
pub filter_retryable_packets_us: u64,
// Time spent running the cost model in processing transactions before executing
// transactions
pub cost_model_us: u64,
}
impl ProcessPacketsTimings {
fn report(&self, id: u32, slot: Slot) {
datapoint_info!(
"banking_stage-leader_slot_process_packets_timings",
("id", id as i64, i64),
("slot", slot as i64, i64),
(
"transactions_from_packets_us",
self.transactions_from_packets_us,
i64
),
("process_transactions_us", self.process_transactions_us, i64),
(
"filter_retryable_packets_us",
self.filter_retryable_packets_us,
i64
),
("cost_model_us", self.cost_model_us, i64),
);
}
}

View File

@@ -0,0 +1,44 @@
//! The `ledger_metric_report_service` periodically reports ledger store metrics.
use {
solana_ledger::blockstore::Blockstore,
std::{
string::ToString,
sync::{
atomic::{AtomicBool, Ordering},
Arc,
},
thread::{self, Builder, JoinHandle},
time::Duration,
},
};
// Determines how often we report blockstore metrics.
const BLOCKSTORE_METRICS_REPORT_PERIOD_MILLIS: u64 = 10000;
pub struct LedgerMetricReportService {
t_cf_metric: JoinHandle<()>,
}
impl LedgerMetricReportService {
pub fn new(blockstore: Arc<Blockstore>, exit: &Arc<AtomicBool>) -> Self {
let exit_signal = exit.clone();
let t_cf_metric = Builder::new()
.name("metric_report_rocksdb_cf_metrics".to_string())
.spawn(move || loop {
if exit_signal.load(Ordering::Relaxed) {
break;
}
thread::sleep(Duration::from_millis(
BLOCKSTORE_METRICS_REPORT_PERIOD_MILLIS,
));
blockstore.submit_rocksdb_cf_metrics_for_all_cfs();
})
.unwrap();
Self { t_cf_metric }
}
pub fn join(self) -> thread::Result<()> {
self.t_cf_metric.join()
}
}

View File

@@ -29,10 +29,13 @@ 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 leader_slot_banking_stage_timing_metrics;
pub mod ledger_cleanup_service;
pub mod ledger_metric_report_service;
pub mod optimistic_confirmation_verifier;
pub mod outstanding_requests;
pub mod packet_hasher;
pub mod packet_threshold;
pub mod progress_map;
pub mod qos_service;
pub mod repair_generic_traversal;
@@ -61,6 +64,7 @@ pub mod tpu;
pub mod tree_diff;
pub mod tvu;
pub mod unfrozen_gossip_verified_vote_hashes;
pub mod unprocessed_packet_batches;
pub mod validator;
pub mod verified_vote_packets;
pub mod vote_simulator;

View File

@@ -0,0 +1,84 @@
use std::time::Duration;
enum PacketThresholdUpdate {
Increase,
Decrease,
}
impl PacketThresholdUpdate {
const PERCENTAGE: usize = 90;
fn calculate(&self, current: usize) -> usize {
match *self {
PacketThresholdUpdate::Increase => {
current.saturating_mul(100).saturating_div(Self::PERCENTAGE)
}
PacketThresholdUpdate::Decrease => {
current.saturating_mul(Self::PERCENTAGE).saturating_div(100)
}
}
}
}
#[derive(Debug)]
pub struct DynamicPacketToProcessThreshold {
max_packets: usize,
}
impl Default for DynamicPacketToProcessThreshold {
fn default() -> Self {
Self {
max_packets: Self::DEFAULT_MAX_PACKETS,
}
}
}
impl DynamicPacketToProcessThreshold {
const DEFAULT_MAX_PACKETS: usize = 1024;
const TIME_THRESHOLD: Duration = Duration::from_secs(1);
pub fn update(&mut self, total_packets: usize, compute_time: Duration) {
if total_packets >= self.max_packets {
let threshold_update = if compute_time > Self::TIME_THRESHOLD {
PacketThresholdUpdate::Decrease
} else {
PacketThresholdUpdate::Increase
};
self.max_packets = threshold_update.calculate(self.max_packets);
}
}
pub fn should_drop(&self, total: usize) -> bool {
total >= self.max_packets
}
}
#[cfg(test)]
mod test {
use {super::DynamicPacketToProcessThreshold, std::time::Duration};
#[test]
fn test_dynamic_packet_threshold() {
let mut threshold = DynamicPacketToProcessThreshold::default();
assert_eq!(
threshold.max_packets,
DynamicPacketToProcessThreshold::DEFAULT_MAX_PACKETS
);
assert!(!threshold.should_drop(10));
assert!(threshold.should_drop(2000));
let old = threshold.max_packets;
// Increase
let total = 2000;
let compute_time = Duration::from_millis(500);
threshold.update(total, compute_time);
assert!(threshold.max_packets > old);
// Decrease
let compute_time = Duration::from_millis(2000);
threshold.update(total, compute_time);
assert_eq!(threshold.max_packets, old - 1); // due to rounding error, there is a difference of 1
}
}

View File

@@ -6,10 +6,12 @@ use {
replay_stage::SUPERMINORITY_THRESHOLD,
},
solana_ledger::blockstore_processor::{ConfirmationProgress, ConfirmationTiming},
solana_program_runtime::timings::ExecuteTimingType,
solana_runtime::{bank::Bank, bank_forks::BankForks, vote_account::VoteAccount},
solana_sdk::{clock::Slot, hash::Hash, pubkey::Pubkey},
std::{
collections::{BTreeMap, HashMap, HashSet},
ops::Index,
sync::{Arc, RwLock},
time::Instant,
},
@@ -62,23 +64,60 @@ impl ReplaySlotStats {
),
("total_entries", num_entries as i64, i64),
("total_shreds", num_shreds as i64, i64),
("check_us", self.execute_timings.check_us, i64),
("load_us", self.execute_timings.load_us, i64),
("execute_us", self.execute_timings.execute_us, i64),
("store_us", self.execute_timings.store_us, i64),
(
"check_us",
*self
.execute_timings
.metrics
.index(ExecuteTimingType::CheckUs),
i64
),
(
"load_us",
*self
.execute_timings
.metrics
.index(ExecuteTimingType::LoadUs),
i64
),
(
"execute_us",
*self
.execute_timings
.metrics
.index(ExecuteTimingType::ExecuteUs),
i64
),
(
"store_us",
*self
.execute_timings
.metrics
.index(ExecuteTimingType::StoreUs),
i64
),
(
"update_stakes_cache_us",
self.execute_timings.update_stakes_cache_us,
*self
.execute_timings
.metrics
.index(ExecuteTimingType::UpdateStakesCacheUs),
i64
),
(
"total_batches_len",
self.execute_timings.total_batches_len,
*self
.execute_timings
.metrics
.index(ExecuteTimingType::TotalBatchesLen),
i64
),
(
"num_execute_batches",
self.execute_timings.num_execute_batches,
*self
.execute_timings
.metrics
.index(ExecuteTimingType::NumExecuteBatches),
i64
),
(
@@ -300,7 +339,7 @@ pub struct RetransmitInfo {
impl RetransmitInfo {
pub fn reached_retransmit_threshold(&self) -> bool {
let backoff = std::cmp::min(self.retry_iteration, RETRANSMIT_BACKOFF_CAP);
let backoff_duration_ms = 2_u64.pow(backoff) * RETRANSMIT_BASE_DELAY_MS;
let backoff_duration_ms = (1_u64 << backoff) * RETRANSMIT_BASE_DELAY_MS;
self.retry_time
.map(|time| time.elapsed().as_millis() > backoff_duration_ms.into())
.unwrap_or(true)

View File

@@ -642,7 +642,7 @@ impl RepairWeight {
}
// Heavier, smaller slots come first
fn sort_by_stake_weight_slot(slot_stake_voted: &mut Vec<(Slot, u64)>) {
fn sort_by_stake_weight_slot(slot_stake_voted: &mut [(Slot, u64)]) {
slot_stake_voted.sort_by(|(slot, stake_voted), (slot_, stake_voted_)| {
if stake_voted == stake_voted_ {
slot.cmp(slot_)

View File

@@ -735,11 +735,16 @@ impl ReplayStage {
restored_tower.adjust_lockouts_after_replay(root_bank.slot(), &slot_history)
}).
unwrap_or_else(|err| {
// It's a fatal error if the tower is not present. This is
// necessary to prevent the validator from violating
// lockouts for its new identity
error!("Failed to load tower for {}: {}", my_pubkey, err);
std::process::exit(1);
if err.is_file_missing() {
Tower::new_from_bankforks(
&bank_forks.read().unwrap(),
&my_pubkey,
&vote_account,
)
} else {
error!("Failed to load tower for {}: {}", my_pubkey, err);
std::process::exit(1);
}
});
// Ensure the validator can land votes with the new identity before
@@ -1593,10 +1598,7 @@ impl ReplayStage {
root_slot,
my_pubkey,
rpc_subscriptions,
NewBankOptions {
vote_only_bank,
simulation_bank: false,
},
NewBankOptions { vote_only_bank },
);
let tpu_bank = bank_forks.write().unwrap().insert(tpu_bank);
@@ -1616,7 +1618,10 @@ impl ReplayStage {
verify_recyclers: &VerifyRecyclers,
) -> result::Result<usize, BlockstoreProcessorError> {
let tx_count_before = bank_progress.replay_progress.num_txs;
let confirm_result = blockstore_processor::confirm_slot(
// All errors must lead to marking the slot as dead, otherwise,
// the `check_slot_agrees_with_cluster()` called by `replay_active_banks()`
// will break!
blockstore_processor::confirm_slot(
blockstore,
bank,
&mut bank_progress.replay_stats,
@@ -1628,16 +1633,9 @@ impl ReplayStage {
None,
verify_recyclers,
false,
);
)?;
let tx_count_after = bank_progress.replay_progress.num_txs;
let tx_count = tx_count_after - tx_count_before;
confirm_result.map_err(|err| {
// All errors must lead to marking the slot as dead, otherwise,
// the `check_slot_agrees_with_cluster()` called by `replay_active_banks()`
// will break!
err
})?;
Ok(tx_count)
}
@@ -3136,7 +3134,7 @@ pub mod tests {
},
solana_rpc::{
optimistically_confirmed_bank_tracker::OptimisticallyConfirmedBank,
rpc::create_test_transactions_and_populate_blockstore,
rpc::{create_test_transaction_entries, populate_blockstore_for_tests},
},
solana_runtime::{
accounts_background_service::AbsRequestSender,
@@ -4005,15 +4003,18 @@ pub mod tests {
let bank1 = Arc::new(Bank::new_from_parent(&bank0, &Pubkey::default(), 1));
let slot = bank1.slot();
let mut test_signatures_iter = create_test_transactions_and_populate_blockstore(
let (entries, test_signatures) = create_test_transaction_entries(
vec![&mint_keypair, &keypair1, &keypair2, &keypair3],
bank0.slot(),
bank1.clone(),
);
populate_blockstore_for_tests(
entries,
bank1,
blockstore.clone(),
Arc::new(AtomicU64::default()),
)
.into_iter();
);
let mut test_signatures_iter = test_signatures.into_iter();
let confirmed_block = blockstore.get_rooted_block(slot, false).unwrap();
let actual_tx_results: Vec<_> = confirmed_block
.transactions

View File

@@ -416,7 +416,7 @@ pub fn retransmitter(
.unwrap()
}
pub(crate) struct RetransmitStage {
pub struct RetransmitStage {
retransmit_thread_handle: JoinHandle<()>,
window_service: WindowService,
cluster_slots_service: ClusterSlotsService,

View File

@@ -2,6 +2,7 @@ use {
crate::{
cluster_slots::ClusterSlots,
duplicate_repair_status::ANCESTOR_HASH_REPAIR_SAMPLE_SIZE,
packet_threshold::DynamicPacketToProcessThreshold,
repair_response,
repair_service::{OutstandingShredRepairs, RepairStats},
request_response::RequestResponse,
@@ -23,7 +24,6 @@ use {
blockstore::Blockstore,
shred::{Nonce, Shred, SIZE_OF_NONCE},
},
solana_measure::measure::Measure,
solana_metrics::inc_new_counter_debug,
solana_perf::packet::{limited_deserialize, PacketBatch, PacketBatchRecycler},
solana_sdk::{
@@ -322,7 +322,7 @@ impl ServeRepair {
requests_receiver: &PacketBatchReceiver,
response_sender: &PacketBatchSender,
stats: &mut ServeRepairStats,
max_packets: &mut usize,
packet_threshold: &mut DynamicPacketToProcessThreshold,
) -> Result<()> {
//TODO cache connections
let timeout = Duration::new(1, 0);
@@ -332,29 +332,21 @@ impl ServeRepair {
let mut dropped_packets = 0;
while let Ok(more) = requests_receiver.try_recv() {
total_packets += more.packets.len();
if total_packets < *max_packets {
// Drop the rest in the channel in case of dos
reqs_v.push(more);
} else {
if packet_threshold.should_drop(total_packets) {
dropped_packets += more.packets.len();
} else {
reqs_v.push(more);
}
}
stats.dropped_packets += dropped_packets;
stats.total_packets += total_packets;
let mut time = Measure::start("repair::handle_packets");
let timer = Instant::now();
for reqs in reqs_v {
Self::handle_packets(obj, recycler, blockstore, reqs, response_sender, stats);
}
time.stop();
if total_packets >= *max_packets {
if time.as_ms() > 1000 {
*max_packets = (*max_packets * 9) / 10;
} else {
*max_packets = (*max_packets * 10) / 9;
}
}
packet_threshold.update(total_packets, timer.elapsed());
Ok(())
}
@@ -403,7 +395,7 @@ impl ServeRepair {
.spawn(move || {
let mut last_print = Instant::now();
let mut stats = ServeRepairStats::default();
let mut max_packets = 1024;
let mut packet_threshold = DynamicPacketToProcessThreshold::default();
loop {
let result = Self::run_listen(
&me,
@@ -412,7 +404,7 @@ impl ServeRepair {
&requests_receiver,
&response_sender,
&mut stats,
&mut max_packets,
&mut packet_threshold,
);
match result {
Err(Error::RecvTimeout(_)) | Ok(_) => {}

View File

@@ -11,8 +11,10 @@ use {
crossbeam_channel::{Receiver, RecvTimeoutError, SendError, Sender},
itertools::Itertools,
solana_measure::measure::Measure,
solana_perf::packet::PacketBatch,
solana_perf::sigverify::{count_valid_packets, shrink_batches, Deduper},
solana_perf::{
packet::PacketBatch,
sigverify::{count_valid_packets, shrink_batches, Deduper},
},
solana_sdk::timing,
solana_streamer::streamer::{self, PacketBatchReceiver, StreamerError},
std::{
@@ -370,12 +372,15 @@ 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 {super::*, solana_perf::packet::Packet};
use {
super::*,
crate::{sigverify::TransactionSigVerifier, sigverify_stage::timing::duration_as_ms},
crossbeam_channel::unbounded,
solana_perf::{
packet::{to_packet_batches, Packet},
test_tx::test_tx,
},
};
fn count_non_discard(packet_batches: &[PacketBatch]) -> usize {
packet_batches

View File

@@ -219,7 +219,7 @@ mod tests {
snapshot_archive_info::SnapshotArchiveInfo,
snapshot_package::{SnapshotPackage, SnapshotType},
snapshot_utils::{
self, ArchiveFormat, SnapshotVersion, SNAPSHOT_STATUS_CACHE_FILE_NAME,
self, ArchiveFormat, SnapshotVersion, SNAPSHOT_STATUS_CACHE_FILENAME,
},
},
solana_sdk::hash::Hash,
@@ -335,7 +335,7 @@ mod tests {
// the source dir for snapshots
let dummy_slot_deltas: Vec<BankSlotDelta> = vec![];
snapshot_utils::serialize_snapshot_data_file(
&snapshots_dir.join(SNAPSHOT_STATUS_CACHE_FILE_NAME),
&snapshots_dir.join(SNAPSHOT_STATUS_CACHE_FILENAME),
|stream| {
serialize_into(stream, &dummy_slot_deltas)?;
Ok(())

View File

@@ -1,11 +1,13 @@
use crate::consensus::{SwitchForkDecision, TowerError};
use solana_sdk::{
clock::Slot,
hash::Hash,
pubkey::Pubkey,
signature::{Signature, Signer},
use {
crate::consensus::{SwitchForkDecision, TowerError},
solana_sdk::{
clock::Slot,
hash::Hash,
pubkey::Pubkey,
signature::{Signature, Signer},
},
solana_vote_program::vote_state::{BlockTimestamp, Vote, VoteState},
};
use solana_vote_program::vote_state::{BlockTimestamp, Vote, VoteState};
#[frozen_abi(digest = "7phMrqmBo2D3rXPdhBj8CpjRvvmx9qgpcU4cDGkL3W9q")]
#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, AbiExample)]

View File

@@ -1,6 +1,8 @@
use {
crate::consensus::{Result, Tower, TowerError, TowerVersions},
crate::tower1_7_14::SavedTower1_7_14,
crate::{
consensus::{Result, Tower, TowerError, TowerVersions},
tower1_7_14::SavedTower1_7_14,
},
solana_sdk::{
pubkey::Pubkey,
signature::{Signature, Signer},

View File

@@ -36,6 +36,9 @@ use {
pub const DEFAULT_TPU_COALESCE_MS: u64 = 5;
// allow multiple connections for NAT and any open/close overlap
pub const MAX_QUIC_CONNECTIONS_PER_IP: usize = 8;
pub struct TpuSockets {
pub transactions: Vec<UdpSocket>,
pub transaction_forwards: Vec<UdpSocket>,
@@ -108,6 +111,7 @@ impl Tpu {
cluster_info.my_contact_info().tpu.ip(),
packet_sender,
exit.clone(),
MAX_QUIC_CONNECTIONS_PER_IP,
)
.unwrap();

View File

@@ -16,6 +16,7 @@ use {
cost_update_service::CostUpdateService,
drop_bank_service::DropBankService,
ledger_cleanup_service::LedgerCleanupService,
ledger_metric_report_service::LedgerMetricReportService,
replay_stage::{ReplayStage, ReplayStageConfig},
retransmit_stage::RetransmitStage,
rewards_recorder_service::RewardsRecorderSender,
@@ -70,6 +71,7 @@ pub struct Tvu {
retransmit_stage: RetransmitStage,
replay_stage: ReplayStage,
ledger_cleanup_service: Option<LedgerCleanupService>,
ledger_metric_report_service: LedgerMetricReportService,
accounts_background_service: AccountsBackgroundService,
accounts_hash_verifier: AccountsHashVerifier,
cost_update_service: CostUpdateService,
@@ -307,8 +309,12 @@ impl Tvu {
);
let (cost_update_sender, cost_update_receiver) = unbounded();
let cost_update_service =
CostUpdateService::new(blockstore.clone(), cost_model.clone(), cost_update_receiver);
let cost_update_service = CostUpdateService::new(
exit.clone(),
blockstore.clone(),
cost_model.clone(),
cost_update_receiver,
);
let (drop_bank_sender, drop_bank_receiver) = unbounded();
@@ -357,6 +363,8 @@ impl Tvu {
)
});
let ledger_metric_report_service = LedgerMetricReportService::new(blockstore, exit);
let accounts_background_service = AccountsBackgroundService::new(
bank_forks.clone(),
exit,
@@ -373,6 +381,7 @@ impl Tvu {
retransmit_stage,
replay_stage,
ledger_cleanup_service,
ledger_metric_report_service,
accounts_background_service,
accounts_hash_verifier,
cost_update_service,
@@ -389,6 +398,7 @@ impl Tvu {
if self.ledger_cleanup_service.is_some() {
self.ledger_cleanup_service.unwrap().join()?;
}
self.ledger_metric_report_service.join()?;
self.accounts_background_service.join()?;
self.replay_stage.join()?;
self.accounts_hash_verifier.join()?;
@@ -417,8 +427,7 @@ pub mod tests {
solana_runtime::bank::Bank,
solana_sdk::signature::{Keypair, Signer},
solana_streamer::socket::SocketAddrSpace,
std::sync::atomic::AtomicU64,
std::sync::atomic::Ordering,
std::sync::atomic::{AtomicU64, Ordering},
};
#[ignore]

View File

@@ -0,0 +1,131 @@
use {
solana_perf::packet::{limited_deserialize, Packet, PacketBatch},
solana_sdk::{
hash::Hash, message::Message, short_vec::decode_shortu16_len, signature::Signature,
transaction::VersionedTransaction,
},
std::{
collections::{HashMap, VecDeque},
mem::size_of,
},
};
pub type UnprocessedPacketBatches = VecDeque<DeserializedPacketBatch>;
/// hold deserialized messages, as well as computed message_hash and other things needed to create
/// SanitizedTransaction
#[derive(Debug, Default)]
pub struct DeserializedPacket {
#[allow(dead_code)]
versioned_transaction: VersionedTransaction,
#[allow(dead_code)]
message_hash: Hash,
#[allow(dead_code)]
is_simple_vote: bool,
}
#[derive(Debug, Default)]
pub struct DeserializedPacketBatch {
pub packet_batch: PacketBatch,
pub forwarded: bool,
// indexes of valid packets in batch, and their corrersponding deserialized_packet
pub unprocessed_packets: HashMap<usize, DeserializedPacket>,
}
impl DeserializedPacketBatch {
pub fn new(packet_batch: PacketBatch, packet_indexes: Vec<usize>, forwarded: bool) -> Self {
let unprocessed_packets = Self::deserialize_packets(&packet_batch, &packet_indexes);
Self {
packet_batch,
unprocessed_packets,
forwarded,
}
}
fn deserialize_packets(
packet_batch: &PacketBatch,
packet_indexes: &[usize],
) -> HashMap<usize, DeserializedPacket> {
packet_indexes
.iter()
.filter_map(|packet_index| {
let deserialized_packet =
Self::deserialize_packet(&packet_batch.packets[*packet_index])?;
Some((*packet_index, deserialized_packet))
})
.collect()
}
fn deserialize_packet(packet: &Packet) -> Option<DeserializedPacket> {
let versioned_transaction: VersionedTransaction =
match limited_deserialize(&packet.data[0..packet.meta.size]) {
Ok(tx) => tx,
Err(_) => return None,
};
if let Some(message_bytes) = Self::packet_message(packet) {
let message_hash = Message::hash_raw_message(message_bytes);
let is_simple_vote = packet.meta.is_simple_vote_tx();
Some(DeserializedPacket {
versioned_transaction,
message_hash,
is_simple_vote,
})
} else {
None
}
}
/// Read the transaction message from packet data
pub fn packet_message(packet: &Packet) -> Option<&[u8]> {
let (sig_len, sig_size) = decode_shortu16_len(&packet.data).ok()?;
let msg_start = sig_len
.checked_mul(size_of::<Signature>())
.and_then(|v| v.checked_add(sig_size))?;
let msg_end = packet.meta.size;
Some(&packet.data[msg_start..msg_end])
}
// Returns whether the given `PacketBatch` has any more remaining unprocessed
// transactions
pub fn update_buffered_packets_with_new_unprocessed(
&mut self,
_original_unprocessed_indexes: &[usize],
new_unprocessed_indexes: &[usize],
) -> bool {
let has_more_unprocessed_transactions = !new_unprocessed_indexes.is_empty();
if has_more_unprocessed_transactions {
self.unprocessed_packets
.retain(|index, _| new_unprocessed_indexes.contains(index));
} else {
self.unprocessed_packets.clear();
}
has_more_unprocessed_transactions
}
}
#[cfg(test)]
mod tests {
use {
super::*,
solana_sdk::{signature::Keypair, system_transaction},
};
#[test]
fn test_packet_message() {
let keypair = Keypair::new();
let pubkey = solana_sdk::pubkey::new_rand();
let blockhash = Hash::new_unique();
let transaction = system_transaction::transfer(&keypair, &pubkey, 1, blockhash);
let packet = Packet::from_data(None, &transaction).unwrap();
assert_eq!(
DeserializedPacketBatch::packet_message(&packet)
.unwrap()
.to_vec(),
transaction.message_data()
);
}
}

View File

@@ -36,7 +36,7 @@ use {
solana_ledger::{
bank_forks_utils,
blockstore::{Blockstore, BlockstoreSignals, CompletedSlotsReceiver, PurgeType},
blockstore_db::{BlockstoreOptions, BlockstoreRecoveryMode},
blockstore_db::{BlockstoreOptions, BlockstoreRecoveryMode, ShredStorageType},
blockstore_processor::{self, TransactionStatusSender},
leader_schedule::FixedSchedule,
leader_schedule_cache::LeaderScheduleCache,
@@ -165,6 +165,7 @@ pub struct ValidatorConfig {
pub no_wait_for_vote_to_start_leader: bool,
pub accounts_shrink_ratio: AccountShrinkThreshold,
pub wait_to_vote_slot: Option<Slot>,
pub shred_storage_type: ShredStorageType,
}
impl Default for ValidatorConfig {
@@ -225,6 +226,7 @@ impl Default for ValidatorConfig {
accounts_shrink_ratio: AccountShrinkThreshold::default(),
accounts_db_config: None,
wait_to_vote_slot: None,
shred_storage_type: ShredStorageType::RocksLevel,
}
}
}
@@ -809,7 +811,8 @@ impl Validator {
let vote_tracker = Arc::<VoteTracker>::default();
let mut cost_model = CostModel::default();
cost_model.initialize_cost_table(&blockstore.read_program_costs().unwrap());
// initialize cost model with built-in instruction costs only
cost_model.initialize_cost_table(&[]);
let cost_model = Arc::new(RwLock::new(cost_model));
let (retransmit_slots_sender, retransmit_slots_receiver) = unbounded();
@@ -1256,6 +1259,7 @@ fn new_banks_from_ledger(
BlockstoreOptions {
recovery_mode: config.wal_recovery_mode.clone(),
enforce_ulimit_nofile,
shred_storage_type: config.shred_storage_type.clone(),
..BlockstoreOptions::default()
},
)

View File

@@ -1,13 +1,13 @@
//! Fork Selection Simulation
//!
//! Description of the algorithm can be found in [docs/src/fork-selection.md](docs/src/fork-selection.md).
//! Description of the algorithm can be found in [docs/src/cluster/managing-forks.md](docs/src/cluster/managing-forks.md).
//!
//! A test library function exists for configuring networks.
//! ```
//! /// * num_partitions - 1 to 100 partitions
//! /// * fail_rate - 0 to 1.0 rate of packet receive failure
//! /// * delay_count - number of forks to observe before voting
//! /// * parasite_rate - number of parasite nodes that vote opposite the greedy choice
//! /// * parasite_rate - percentage of parasite nodes that vote opposite the greedy choice
//! fn test_with_partitions(num_partitions: usize, fail_rate: f64, delay_count: usize, parasite_rate: f64);
//! ```
//! Modify the test function
@@ -497,7 +497,7 @@ fn test_no_partitions() {
/// * num_partitions - 1 to 100 partitions
/// * fail_rate - 0 to 1.0 rate of packet receive failure
/// * delay_count - number of forks to observe before voting
/// * parasite_rate - number of parasite nodes that vote opposite the greedy choice
/// * parasite_rate - percentage of parasite nodes that vote opposite the greedy choice
fn test_with_partitions(
num_partitions: usize,
fail_rate: f64,

View File

@@ -9,7 +9,7 @@ mod tests {
solana_core::ledger_cleanup_service::LedgerCleanupService,
solana_ledger::{
blockstore::{make_many_slot_shreds, Blockstore},
blockstore_db::{BlockstoreOptions, ShredStorageType},
blockstore_db::{BlockstoreOptions, BlockstoreRocksFifoOptions, ShredStorageType},
get_tmp_ledger_path,
},
solana_measure::measure::Measure,
@@ -32,6 +32,7 @@ mod tests {
const DEFAULT_SHREDS_PER_SLOT: u64 = 25;
const DEFAULT_STOP_SIZE_BYTES: u64 = 0;
const DEFAULT_STOP_SIZE_ITERATIONS: u64 = 0;
const DEFAULT_STOP_SIZE_CF_DATA_BYTES: u64 = 0;
const DEFAULT_SHRED_DATA_CF_SIZE_BYTES: u64 = 125 * 1024 * 1024 * 1024;
const ROCKSDB_FLUSH_GRACE_PERIOD_SECS: u64 = 20;
@@ -44,6 +45,7 @@ mod tests {
shreds_per_slot: u64,
stop_size_bytes: u64,
stop_size_iterations: u64,
stop_size_cf_data_bytes: u64,
pre_generate_data: bool,
cleanup_blockstore: bool,
assert_compaction: bool,
@@ -172,11 +174,14 @@ mod tests {
/// Advanced benchmark settings:
/// - `STOP_SIZE_BYTES`: if specified, the benchmark will count how
/// many times the ledger store size exceeds the specified threshold.
/// - `STOP_SIZE_ITERATIONS`: when `STOP_SIZE_BYTES` is specified, the
/// benchmark will stop immediately when the number of times where the
/// ledger store size exceeds the configured `STOP_SIZE_BYTES`. These
/// configs are used to make sure the benchmark runs successfully under
/// the storage limitation.
/// - `STOP_SIZE_CF_DATA_BYTES`: if specified, the benchmark will count how
/// many times the storage size of `cf::ShredData` which stores data shred
/// exceeds the specified threshold.
/// - `STOP_SIZE_ITERATIONS`: when any of the stop size is specified, the
/// benchmark will stop immediately when the number of consecutive times
/// where the ledger store size exceeds the configured `STOP_SIZE_BYTES`.
/// These configs are used to make sure the benchmark runs successfully
/// under the storage limitation.
/// - `CLEANUP_BLOCKSTORE`: if true, the ledger store created in the current
/// benchmark run will be deleted. Default: true.
/// - `NO_COMPACTION`: whether to stop rocksdb's background compaction
@@ -208,6 +213,8 @@ mod tests {
let shreds_per_slot = read_env("SHREDS_PER_SLOT", DEFAULT_SHREDS_PER_SLOT);
let stop_size_bytes = read_env("STOP_SIZE_BYTES", DEFAULT_STOP_SIZE_BYTES);
let stop_size_iterations = read_env("STOP_SIZE_ITERATIONS", DEFAULT_STOP_SIZE_ITERATIONS);
let stop_size_cf_data_bytes =
read_env("STOP_SIZE_CF_DATA_BYTES", DEFAULT_STOP_SIZE_CF_DATA_BYTES);
let pre_generate_data = read_env("PRE_GENERATE_DATA", false);
let cleanup_blockstore = read_env("CLEANUP_BLOCKSTORE", true);
// set default to `true` once compaction is merged
@@ -233,6 +240,7 @@ mod tests {
shreds_per_slot,
stop_size_bytes,
stop_size_iterations,
stop_size_cf_data_bytes,
pre_generate_data,
cleanup_blockstore,
assert_compaction,
@@ -286,7 +294,38 @@ mod tests {
*time_previous = time_now;
*storage_previous = storage_now;
*data_shred_storage_previous = data_shred_storage_now;
*data_shred_storage_previous = data_shred_storage_now.try_into().unwrap();
}
/// Helper function of the benchmark `test_ledger_cleanup_compaction` which
/// returns true if the benchmark fails the size limitation check.
fn is_exceeded_stop_size_iterations(
storage_size: u64,
stop_size: u64,
exceeded_iterations: &mut u64,
iteration_limit: u64,
storage_desc: &str,
) -> bool {
if stop_size > 0 {
if storage_size >= stop_size {
*exceeded_iterations += 1;
warn!(
"{} size {} exceeds the stop size {} for {} times!",
storage_desc, storage_size, stop_size, exceeded_iterations
);
} else {
*exceeded_iterations = 0;
}
if *exceeded_iterations >= iteration_limit {
error!(
"{} size exceeds the configured limit {} for {} times",
storage_desc, stop_size, exceeded_iterations,
);
return true;
}
}
false
}
/// The ledger cleanup compaction test which can also be used as a benchmark
@@ -309,8 +348,10 @@ mod tests {
&ledger_path,
if config.fifo_compaction {
BlockstoreOptions {
shred_storage_type: ShredStorageType::RocksFifo,
shred_data_cf_size: config.shred_data_cf_size,
shred_storage_type: ShredStorageType::RocksFifo(BlockstoreRocksFifoOptions {
shred_data_cf_size: config.shred_data_cf_size,
..BlockstoreRocksFifoOptions::default()
}),
..BlockstoreOptions::default()
}
} else {
@@ -332,6 +373,7 @@ mod tests {
let shreds_per_slot = config.shreds_per_slot;
let stop_size_bytes = config.stop_size_bytes;
let stop_size_iterations = config.stop_size_iterations;
let stop_size_cf_data_bytes = config.stop_size_cf_data_bytes;
let pre_generate_data = config.pre_generate_data;
let compaction_interval = config.compaction_interval;
let num_writers = config.num_writers;
@@ -388,6 +430,7 @@ mod tests {
let mut storage_previous = 0;
let mut data_shred_storage_previous = 0;
let mut stop_size_bytes_exceeded_iterations = 0;
let mut stop_size_cf_data_exceeded_iterations = 0;
emit_header();
emit_stats(
@@ -535,16 +578,24 @@ mod tests {
&sys.get_stats(),
);
if stop_size_bytes > 0 {
if storage_previous >= stop_size_bytes {
stop_size_bytes_exceeded_iterations += 1;
} else {
stop_size_bytes_exceeded_iterations = 0;
}
if is_exceeded_stop_size_iterations(
storage_previous,
stop_size_bytes,
&mut stop_size_bytes_exceeded_iterations,
stop_size_iterations,
"Storage",
) {
break;
}
if stop_size_bytes_exceeded_iterations > stop_size_iterations {
break;
}
if is_exceeded_stop_size_iterations(
data_shred_storage_previous,
stop_size_cf_data_bytes,
&mut stop_size_cf_data_exceeded_iterations,
stop_size_iterations,
"cf::ShredData",
) {
break;
}
if finished_batch >= num_batches {

View File

@@ -175,7 +175,7 @@ mod tests {
let check_hash_calculation = false;
let full_snapshot_archive_path = snapshot_utils::build_full_snapshot_archive_path(
snapshot_archives_dir.to_path_buf(),
snapshot_archives_dir,
old_last_bank.slot(),
&old_last_bank.get_accounts_hash(),
ArchiveFormat::TarBzip2,
@@ -432,7 +432,7 @@ mod tests {
// Only save off the files returned by `get_snapshot_storages`. This is because
// some of the storage entries in the accounts directory may be filtered out by
// `get_snapshot_storages()` and will not be included in the snapshot. Ultimately,
// this means copying naitvely everything in `accounts_dir` to the `saved_accounts_dir`
// this means copying natively everything in `accounts_dir` to the `saved_accounts_dir`
// will lead to test failure by mismatch when `saved_accounts_dir` is compared to
// the unpacked snapshot later in this test's call to `verify_snapshot_archive()`.
for file in snapshot_storage_files {
@@ -461,7 +461,7 @@ mod tests {
fs_extra::dir::copy(&last_snapshot_path, &saved_snapshots_dir, &options).unwrap();
saved_archive_path = Some(snapshot_utils::build_full_snapshot_archive_path(
snapshot_archives_dir.to_path_buf(),
snapshot_archives_dir,
slot,
&accounts_hash,
ArchiveFormat::TarBzip2,
@@ -544,7 +544,7 @@ mod tests {
snapshot_utils::serialize_snapshot_data_file(
&saved_snapshots_dir
.path()
.join(snapshot_utils::SNAPSHOT_STATUS_CACHE_FILE_NAME),
.join(snapshot_utils::SNAPSHOT_STATUS_CACHE_FILENAME),
|stream| {
serialize_into(stream, &[] as &[BankSlotDelta])?;
Ok(())

View File

@@ -8,11 +8,17 @@ set -e
cd "$(dirname "$0")"
output_dir=static/img
svgbob_cli="$(command -v svgbob_cli || true)"
if [[ -z "$svgbob_cli" ]]; then
svgbob_cli="$(command -v svgbob || true)"
[[ -n "$svgbob_cli" ]] || ( echo "svgbob_cli binary not found" && exit 1 )
fi
mkdir -p "$output_dir"
while read -r bob_file; do
out_file=$(basename "${bob_file%.*}".svg)
svgbob "$bob_file" --output "$output_dir/$out_file"
"$svgbob_cli" "$bob_file" --output "$output_dir/$out_file"
done < <(find art/*.bob)
while read -r msc_file; do

View File

@@ -3,17 +3,6 @@ module.exports = {
About: ["introduction", "terminology", "history"],
Wallets: [
"wallet-guide",
"wallet-guide/apps",
{
type: "category",
label: "Web Wallets",
items: ["wallet-guide/web-wallets", "wallet-guide/solflare"],
},
{
type: "category",
label: "Hardware Wallets",
items: ["wallet-guide/ledger-live"],
},
{
type: "category",
label: "Command-line Wallets",

View File

@@ -36,7 +36,7 @@ public RPC endpoints currently available and recommended for each public cluster
## Mainnet Beta
#### Endpoints
#### Endpoints*
- `https://api.mainnet-beta.solana.com` - Solana-hosted api node cluster, backed by a load balancer; rate-limited
- `https://solana-api.projectserum.com` - Project Serum-hosted api node
@@ -48,3 +48,17 @@ public RPC endpoints currently available and recommended for each public cluster
- Maximum concurrent connections per IP: 40
- Maximum connection rate per 10 seconds per IP: 40
- Maximum amount of data per 30 second: 100 MB
*The public RPC endpoints are not intended for production applications. Please
use dedicated/private RPC servers when you launch your application, drop NFTs,
etc. The public services are subject to abuse and rate limits may change
without prior notice. Likewise, high-traffic websites may be blocked without
prior notice.
## Common HTTP Error Codes
- 403 -- Your IP address or website has been blocked. It is time to run your own RPC server(s) or find a private service.
- 429 -- Your IP address is exceeding the rate limits. Slow down! Use the
[Retry-After](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After)
HTTP response header to determine how long to wait before making another
request.

View File

@@ -97,8 +97,9 @@ $ solana-validator \
--identity validator-keypair.json \
--vote-account vote-account-keypair.json \
--known-validator 5D1fNXzvv5NjV1ysLjirC4WY92RNsVH18vjmcszZd8on \
--known-validator 7XSY3MrYnK8vq693Rju17bbPkCN3Z7KvvfvJx4kdrsSY \
--known-validator dDzy5SR3AXdYWVqbDEkVFdvSPCtS9ihF5kJkHCtXoFs \
--known-validator Ft5fbkqNa76vnsjYNwjDZUXoTWpP7VYm3mtsaQckQADN \
--known-validator eoKpUABi59aT4rR9HGS3LcMecfut9x7zJyodWWP43YQ \
--known-validator 9QxCLckBiJc783jnMvXZubK4wH86Eqqvashtrwvcsgkv \
--only-known-rpc \
--ledger ledger \
@@ -116,7 +117,9 @@ The identities of the
[`--known-validator`s](running-validator/validator-start.md#known-validators) are:
- `5D1fNXzvv5NjV1ysLjirC4WY92RNsVH18vjmcszZd8on` - Solana Labs (testnet.solana.com)
- `dDzy5SR3AXdYWVqbDEkVFdvSPCtS9ihF5kJkHCtXoFs` - MonkeDAO
- `Ft5fbkqNa76vnsjYNwjDZUXoTWpP7VYm3mtsaQckQADN` - Certus One
- `eoKpUABi59aT4rR9HGS3LcMecfut9x7zJyodWWP43YQ` - SerGo
- `9QxCLckBiJc783jnMvXZubK4wH86Eqqvashtrwvcsgkv` - Algo|Stake
## Mainnet Beta
@@ -126,9 +129,8 @@ A permissionless, persistent cluster for early token holders and launch partners
- Tokens that are issued on Mainnet Beta are **real** SOL
- If you have paid money to purchase/be issued tokens, such as through our
CoinList auction, these tokens will be transferred on Mainnet Beta.
- Note: If you are using a non-command-line wallet such as
[Solflare](wallet-guide/solflare.md),
the wallet will always be connecting to Mainnet Beta.
- Note: If you are using a non-command-line wallet, the wallet will always be
connecting to Mainnet Beta.
- Gossip entrypoint for Mainnet Beta: `entrypoint.mainnet-beta.solana.com:8001`
- Metrics environment variable for Mainnet Beta:

File diff suppressed because it is too large Load Diff

View File

@@ -95,7 +95,7 @@ parameters into C types:
- [BPF Loader deprecated
deserialization](https://github.com/solana-labs/solana/blob/8415c22b593f164020adc7afe782e8041d756ddf/sdk/bpf/c/inc/deserialize_deprecated.h#L25)
Some programs may want to perform deserialzaiton themselves and they can by
Some programs may want to perform deserialization themselves, and they can by
providing their own implementation of the [raw entrypoint](#program-entrypoint).
Take note that the provided deserialization functions retain references back to
the serialized byte array for variables that the program is allowed to modify

View File

@@ -23,11 +23,11 @@ uses an _address_ to look up an account. The address is a 256-bit public key.
## Signers
Transactions may include digital [signatures](terminology.md#signature)
corresponding to the accounts' public keys referenced by the transaction. Such
signatures signify that the holder of the
account's private key signed and thus "authorized" the transaction. In this case,
the account is referred to as a _signer_. Whether an account is a signer or not
Transactions include one or more digital [signatures](terminology.md#signature)
each corresponding to an account address referenced by the transaction. Each of these
addresses must be the public key of an ed25519 keypair, and the signature signifies
that the holder of the matching private key signed, and thus, "authorized" the transaction.
In this case, the account is referred to as a _signer_. Whether an account is a signer or not
is communicated to the program as part of the account's metadata. Programs can
then use that information to make authority decisions.
@@ -71,7 +71,7 @@ previously created, the program will be passed an account with no data and zero
that is owned by the system program.
Such newly created accounts reflect
whether they sign the transaction and therefore can be used as an
whether they sign the transaction, and therefore, can be used as an
authority. Authorities in this context convey to the program that the holder of
the private key associated with the account's public key signed the transaction.
The account's public key may be known to the program or recorded in another
@@ -85,14 +85,14 @@ System program and is called a _system account_ aptly. An account includes
"owner" metadata. The owner is a program id. The runtime grants the program
write access to the account if its id matches the owner. For the case of the
System program, the runtime allows clients to transfer lamports and importantly
_assign_ account ownership, meaning changing owner to different program id. If
_assign_ account ownership, meaning changing the owner to a different program id. If
an account is not owned by a program, the program is only permitted to read its
data and credit the account.
## Verifying validity of unmodified, reference-only accounts
For security purposes, it is recommended that programs check the validity of any
account it reads but does not modify.
account it reads, but does not modify.
This is because a malicious user
could create accounts with arbitrary data and then pass these accounts to the
@@ -101,17 +101,17 @@ a way that leads to unexpected or harmful program behavior.
The security model enforces that an account's data can only be modified by the
account's `Owner` program. This allows the program to trust that the data
passed to them via accounts they own. The
is passed to them via accounts they own. The
runtime enforces this by rejecting any transaction containing a program that
attempts to write to an account it does not own.
If a program were to not check account validity, it might read an account
it thinks it owns but doesn't. Anyone can
it thinks it owns, but doesn't. Anyone can
issue instructions to a program, and the runtime does not know that those
accounts are expected to be owned by the program.
To check an account's validity, the program should either check the account's
address against a known value or check that the account is indeed owned
address against a known value, or check that the account is indeed owned
correctly (usually owned by the program itself).
One example is when programs use a sysvar account. Unless the program checks the
@@ -120,7 +120,7 @@ valid sysvar account merely by successful deserialization of the account's data.
Accordingly, the Solana SDK [checks the sysvar account's validity during
deserialization](https://github.com/solana-labs/solana/blob/a95675a7ce1651f7b59443eb146b356bc4b3f374/sdk/program/src/sysvar/mod.rs#L65).
A alternative and safer way to read a sysvar is via the sysvar's [`get()`
An alternative and safer way to read a sysvar is via the sysvar's [`get()`
function](https://github.com/solana-labs/solana/blob/64bfc14a75671e4ec3fe969ded01a599645080eb/sdk/program/src/sysvar/mod.rs#L73)
which doesn't require these checks.

View File

@@ -30,8 +30,8 @@ let message = Message::new(vec![
client.send_and_confirm_message(&[&alice_keypair, &bob_keypair], &message);
```
Given two on-chain programs `token` and `acme`, each implementing instructions
`pay()` and `launch_missiles()` respectively, acme can be implemented with a
Given two on-chain programs, `token` and `acme`, each implementing instructions
`pay()` and `launch_missiles()` respectively, `acme` can be implemented with a
call to a function defined in the `token` module by issuing a cross-program
invocation:
@@ -66,12 +66,12 @@ state of the accounts at the beginning of the `acme`'s instruction. After
`pay()` completes, the runtime must again ensure that `token` didn't modify any
accounts owned by `acme` by again applying the runtime's policy, but this time
with the `token` program ID. Lastly, after `pay_and_launch_missiles()`
completes, the runtime must apply the runtime policy one more time, where it
completes, the runtime must apply the runtime policy one more time where it
normally would, but using all updated `pre_*` variables. If executing
`pay_and_launch_missiles()` up to `pay()` made no invalid account changes,
`pay()` made no invalid changes, and executing from `pay()` until
`pay_and_launch_missiles()` returns made no invalid changes, then the runtime
can transitively assume `pay_and_launch_missiles()` as whole made no invalid
can transitively assume `pay_and_launch_missiles()` as a whole made no invalid
account changes, and therefore commit all these account modifications.
### Instructions that require privileges
@@ -111,12 +111,12 @@ To sign an account with program derived addresses, a program may
### Call Depth
Cross-program invocations allow programs to invoke other programs directly but
Cross-program invocations allow programs to invoke other programs directly, but
the depth is constrained currently to 4.
### Reentrancy
Reentrancy is currently limited to direct self recursion capped at a fixed
Reentrancy is currently limited to direct self recursion, capped at a fixed
depth. This restriction prevents situations where a program might invoke another
from an intermediary state without the knowledge that it might later be called
back into. Direct recursion gives the program full control of its state at the
@@ -159,22 +159,22 @@ Program derived address:
present in instructions invoked via [Cross-Program Invocations](#cross-program-invocations).
Given the two conditions, users can securely transfer or assign the authority of
on-chain assets to program addresses and the program can then assign that
on-chain assets to program addresses, and the program can then assign that
authority elsewhere at its discretion.
### Private keys for program addresses
A Program address does not lie on the ed25519 curve and therefore has no valid
A program address does not lie on the ed25519 curve and therefore has no valid
private key associated with it, and thus generating a signature for it is
impossible. While it has no private key of its own, it can be used by a program
to issue an instruction that includes the Program address as a signer.
to issue an instruction that includes the program address as a signer.
### Hash-based generated program addresses
Program addresses are deterministically derived from a collection of seeds and a
program id using a 256-bit pre-image resistant hash function. Program address
must not lie on the ed25519 curve to ensure there is no associated private key.
During generation an error will be returned if the address is found to lie on
During generation, an error will be returned if the address is found to lie on
the curve. There is about a 50/50 chance of this happening for a given
collection of seeds and program id. If this occurs a different set of seeds or
a seed bump (additional 8 bit seed) can be used to find a valid program address
@@ -184,7 +184,7 @@ Deterministic program addresses for programs follow a similar derivation path as
Accounts created with `SystemInstruction::CreateAccountWithSeed` which is
implemented with `Pubkey::create_with_seed`.
For reference that implementation is as follows:
For reference, that implementation is as follows:
```rust,ignore
pub fn create_with_seed(

View File

@@ -12,18 +12,18 @@ signed the transaction using the keypair's _private key_, it knows the client
authorized the token transfer.
In other words, the entire set of accounts owned by a given program can be
regarded as a key-value store where a key is the account address and value is
regarded as a key-value store, where a key is the account address and value is
program-specific arbitrary binary data. A program author can decide how to
manage the program's whole state as possibly many accounts.
manage the program's whole state, possibly as many accounts.
After the runtime executes each of the transaction's instructions, it uses the
account metadata to verify that the access policy was not violated. If a program
violates the policy, the runtime discards all account changes made by all
instructions in the transaction and marks the transaction as failed.
instructions in the transaction, and marks the transaction as failed.
### Policy
After a program has processed an instruction the runtime verifies that the
After a program has processed an instruction, the runtime verifies that the
program only performed operations it was permitted to, and that the results
adhere to the runtime policy.
@@ -31,7 +31,7 @@ The policy is as follows:
- Only the owner of the account may change owner.
- And only if the account is writable.
- And only if the account is not executable
- And only if the account is not executable.
- And only if the data is zero-initialized or empty.
- An account not assigned to the program cannot have its balance decrease.
- The balance of read-only and executable accounts may not change.
@@ -45,15 +45,15 @@ The policy is as follows:
## Compute Budget
To prevent a program from abusing computation resources each instruction in a
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).
a per-transaction model. For more information see [Transaction-wide Compute
Budget](#transaction-wide-compute-budget).
The following operations incur a compute cost:
@@ -65,8 +65,8 @@ The following operations incur a compute cost:
- ...
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 is halted.
parent. If an invoked program consumes the budget or exceeds a bound, the entire
invocation chain and the parent are halted.
The current [compute
budget](https://github.com/solana-labs/solana/blob/0224a8b127ace4c6453dd6492a38c66cb999abd2/sdk/src/compute_budget.rs#L102)
@@ -89,10 +89,10 @@ log_pubkey_units: 100,
Then the program
- Could execute 200,000 BPF instructions if it does nothing else
- Could log 2,000 log messages
- Can not exceed 4k of stack usage
- Can not exceed a BPF call depth of 64
- Could execute 200,000 BPF instructions, if it does nothing else.
- Could log 2,000 log messages.
- Cannot exceed 4k of stack usage.
- Cannot 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
@@ -106,7 +106,7 @@ for more information.
## 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
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.
@@ -114,16 +114,16 @@ 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
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
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
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
@@ -140,7 +140,7 @@ let instruction = ComputeBudgetInstruction::request_units(300_000);
As Solana evolves, new features or patches may be introduced that changes the
behavior of the cluster and how programs run. Changes in behavior must be
coordinated between the various nodes of the cluster, if nodes do not coordinate
coordinated between the various nodes of the cluster. If nodes do not coordinate,
then these changes can result in a break-down of consensus. Solana supports a
mechanism called runtime features to facilitate the smooth adoption of changes.
@@ -157,6 +157,6 @@ tools](cli/install-solana-cli-tools.md):
solana feature status
```
If you encounter problems first ensure that the Solana tools version you are
If you encounter problems, first ensure that the Solana tools version you are
using match the version returned by `solana cluster-version`. If they do not
match [install the correct tool suite](cli/install-solana-cli-tools.md).
match, [install the correct tool suite](cli/install-solana-cli-tools.md).

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