Compare commits

..

168 Commits

Author SHA1 Message Date
mergify[bot]
18b55bbfe1 Remove loop (#8495) 2020-02-27 02:42:42 -08:00
mergify[bot]
85637e8f63 Rename snapshot.tar.bz2 to snapshot-<slot>-<hash>.tar.bz2 (bp #8482) (#8500)
automerge
2020-02-27 00:04:14 -08:00
mergify[bot]
eb3b5d7382 Update voting simulation (#8460) (#8488)
automerge
2020-02-26 21:00:38 -08:00
Tyera Eulberg
1a4de4d3c4 v0.23: backport cli refactoring and remote-wallet signing integration (#8487)
* CLI: dynamic signing reboot (#8384)

* Add keypair_util_from_path helper

* Cli: impl config.keypair as a trait object

* SDK: Add Debug and PartialEq for dyn Signer

* ClapUtils: Arg parsing from pubkey+signers to Presigner

* Impl Signers for &dyn Signer collections

* CLI: Add helper for getting signers from args

* CLI: Replace SigningAuthority with Signer trait-objs

* CLI: Drop disused signers command field

* CLI: Drop redundant tests

* Add clap validator that handles all current signer types

* clap_utils: Factor Presigner resolution to helper

* SDK: `From` for boxing Signer implementors to trait objects

* SDK: Derive `Clone` for `Presigner`

* Remove panic

* Cli: dedup signers in transfer for remote-wallet ergonomics

* Update docs vis-a-vis ASK changes

* Cli: update transaction types to use new dynamic-signer methods

* CLI: Fix tests No. 1

what to do about write_keypair outstanding

* Work around `CliConfig`'s signer not necessarily being a `Keypair`

* CLI: Fix tests No. 2

* Remove unused arg

* Remove unused methods

* Move offline arg constants upstream

* Make cli signing fallible

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

* Reinstate `create-stale-account` w/ seed test (#8401)

automerge

* CLI: collect and deduplicate signers (#8398)

* Rename (keypair util is not a thing)

* Add method to generate_unique_signers

* Cli: refactor signer handling and remote-wallet init

* Fixup unit tests

* Fixup intergation tests

* Update keypair path print statement

* Remove &None

* Use deterministic key in test

* Retain storage-account as index

* Make signer index-handling less brittle

* Cache pubkey on RemoteKeypair::new

* Make signer_of consistent + return pubkey

* Remove &matches double references

* Nonce authorities need special handling

* Make solana root key accessible on Ledger (#8421)

* Use 44/501 key as ledger id

* Add error codes

* Ledger key path rework (#8453)

automerge

* Ledger hardware wallet docs (#8472)

* Update protocol documentation

* Correct app-version command const

* Rough initial Ledger docs

* Add more docs

* Cleanup

* Add remote-wallet to docs TOC

Co-authored-by: Greg Fitzgerald <greg@solana.com>

* Add flag to confirm key on device

Co-authored-by: Trent Nelson <trent.a.b.nelson@gmail.com>
Co-authored-by: Greg Fitzgerald <greg@solana.com>
2020-02-26 17:59:41 -07:00
mergify[bot]
100a11f061 Limit leader schedule search space (#8468) (#8485)
automerge
2020-02-26 15:49:31 -08:00
mergify[bot]
6d431b8210 Refactor select_fork() to avoid clones and for clarity (#8081) (#8483)
automerge
2020-02-26 15:45:15 -08:00
mergify[bot]
242afa7e6b Validate the genesis config downloaded over RPC before accepting it (bp #8474) (#8480)
automerge
2020-02-26 14:54:01 -08:00
mergify[bot]
536e01121f Tower tests (bp #7974) (#8463)
automerge
2020-02-26 13:25:08 -08:00
mergify[bot]
93bcb65d8b Promote dangerous cond. from just warning to panic (#8439) (#8448)
automerge
2020-02-25 19:12:07 -08:00
mergify[bot]
0743334486 Allow withdrawer to change the authorized stake key (#8456) (#8461)
automerge
2020-02-25 19:11:20 -08:00
mergify[bot]
93027fa067 Add --no-check-vote-account argument (#8430) (#8434)
automerge
2020-02-25 00:13:18 -08:00
mergify[bot]
8548c83e48 validator: snapshot fetching cleanup (bp #8413) (#8415)
automerge
2020-02-24 14:37:24 -08:00
mergify[bot]
80dd5db628 Add support for large transactions with Ledger Wallet (#8394) (#8395)
automerge
2020-02-22 09:39:48 -08:00
mergify[bot]
2d0ee7e3dc Add --trusted-validator support for snapshot hash validation (#8390) (#8393)
automerge
2020-02-21 19:46:43 -08:00
Michael Vines
df2b4d31b7 Bump version to 0.23.7 2020-02-21 20:01:54 -07:00
Michael Vines
45612bc988 \ 2020-02-21 18:10:11 -07:00
Michael Vines
51ce98badd Add --enable-warmup-epochs flag
(cherry picked from commit ea5b00364f)
2020-02-21 17:03:35 -07:00
Pankaj Garg
075e784bef Promote some datapoints to info to fix dashboard (#8381)
automerge

(cherry picked from commit aa80f69171)
2020-02-21 17:00:42 -07:00
Michael Vines
c1b587c6e4 4x DEFAULT_MAX_LEDGER_SLOTS to give nodes 3 hours of slots to repair from (#8388)
automerge

(cherry picked from commit fb98df76b7)
2020-02-21 17:00:35 -07:00
mergify[bot]
94e2d0b5c2 Update unlocks (bp #8363) (#8382)
automerge
2020-02-21 11:40:27 -08:00
mergify[bot]
c2be9fdf0e Add handling for fallible signers (#8367) (#8374)
automerge
2020-02-21 01:45:13 -08:00
mergify[bot]
c2b17c7d3f Correct missing entry handling to avoid bad warns (bp #8339) (#8378)
automerge
2020-02-20 23:35:21 -08:00
mergify[bot]
31544f2a82 If the node was loaded from a snapshot, advertise it in gossip (#8364) (#8373)
automerge
2020-02-20 19:57:43 -08:00
Michael Vines
3a88190e4e Enable BPF in TdS epoch 17 (#8370)
automerge
2020-02-20 18:11:58 -08:00
Ryo Onodera
3f30354d1a Add non-bz2 snapshot for faster creation for dev. (#8350)
* Add non-bz2 snapshot for faster creation for dev.

* Fix tests..

* Revert and always just use snapshot.tar.bz2

(cherry picked from commit 5ef06a9d36)
2020-02-20 18:51:16 -07:00
Michael Vines
11f15c0708 Flip Stable and Preview enum values
(cherry picked from commit 2d665da3e1)
2020-02-20 18:29:04 -07:00
mergify[bot]
a83bf85bb3 Search for the validator with the highest snapshot (#8368)
automerge
2020-02-20 17:24:23 -08:00
mergify[bot]
02877814fa Rename KeypairUtil to Signer (#8360) (#8366)
automerge
2020-02-20 16:30:43 -08:00
mergify[bot]
29cdfd6bc9 Book: Add instructions for verifying a paper wallet keypair (#8357) (#8365)
automerge
2020-02-20 14:33:18 -08:00
mergify[bot]
9dffc3abe4 Support transaction signing by heterogenous lists of keypairs (bp #8342) (#8362)
automerge
2020-02-20 14:02:14 -08:00
mergify[bot]
b4eb81546e Snapshot hash gossip changes (#8358) (#8359)
automerge
2020-02-20 12:52:04 -08:00
mergify[bot]
489fd3058f Do not compress small incomplete slot list (#8355) (#8356)
automerge
2020-02-20 10:48:47 -08:00
Pankaj Garg
e5872ef1c1 Bitwise compress incomplete epoch slots (#8341) 2020-02-20 05:49:17 -08:00
Pankaj Garg
cb9d18316a Update epoch slots to include all missing slots (#8276)
* Update epoch slots to include all missing slots

* new test for compress/decompress

* address review comments

* limit cache based on size, instead of comparing roots
2020-02-20 05:49:17 -08:00
mergify[bot]
c3ac85828b Process Gossip in parallel and add an upper limit (#8328) (#8345)
automerge
2020-02-19 21:54:52 -08:00
mergify[bot]
5fbddd5894 Add Preview operating mode, rename SoftLaunch operating mode to Stable (#8331) (#8340)
automerge
2020-02-19 18:13:41 -08:00
Michael Vines
90af35737d Use correct static IP address 2020-02-19 18:15:54 -07:00
mergify[bot]
58cb21402b Remove validators from genesis (#8330) (#8333)
automerge
2020-02-19 15:42:25 -08:00
Michael Vines
824b894977 More testnet->devnet 2020-02-19 16:15:58 -07:00
Michael Vines
2295a5e512 Update README.md 2020-02-19 15:53:17 -07:00
Michael Vines
83a322a211 rename testnet.solana.com to devnet.solana.com
(cherry picked from commit e3cebcf82d)

# Conflicts:
#	README.md
2020-02-19 15:53:17 -07:00
mergify[bot]
a008748d9d grooming: use cleanup, remove some dead code (bp #8324) (#8326)
automerge
2020-02-18 21:06:56 -08:00
mergify[bot]
72cb0b7c9e Add --fee-burn-percentage (#8323)
automerge
2020-02-18 19:03:41 -08:00
mergify[bot]
ede3781f91 Just define BnakSlotDelta type alias (bp #8186) (#8320)
automerge
2020-02-18 16:31:38 -08:00
mergify[bot]
e3ac6fac1e Factor out creating genesis with vote accounts into a utility function (bp #8315) (#8317)
automerge
2020-02-18 13:12:53 -08:00
mergify[bot]
e30561f8a0 CLI: Add optional airdrop recipient (#8291) (#8310)
automerge
2020-02-16 11:32:06 -08:00
mergify[bot]
8d59bef561 Cli: Remove units from various subcommands (#8301) (#8306)
automerge
2020-02-15 12:45:02 -08:00
Michael Vines
897e1fc5d6 Bump version to 0.23.6 2020-02-14 22:38:14 -07:00
mergify[bot]
cb84099b2e Add storage rewards pools in development mode only (#8300)
automerge
2020-02-14 21:15:11 -08:00
Michael Vines
c89b35545c install: support vX.Y.Z in addition to X.Y.Z (#8297)
automerge

(cherry picked from commit 335675c51c)
2020-02-14 21:30:18 -07:00
Michael Vines
370716edd3 ledger-tool: Add print-accounts command
(cherry picked from commit 1bf2285fa2)
2020-02-14 21:29:24 -07:00
mergify[bot]
1dbcd5c298 Presigner KeypairUtil implementer (#8269) (#8271)
automerge
2020-02-14 12:50:00 -08:00
mergify[bot]
ca770d5e74 Datapoints overwhelm the metrics queue and blow up ram usage. (#8272) (#8283)
automerge
2020-02-14 12:42:45 -08:00
mergify[bot]
51a8d0356f Make generate_remote_keypair more generic for potential other remote-wallets (#8274) (#8275)
automerge
2020-02-14 09:37:39 -08:00
mergify[bot]
79e340c499 Enable remote-wallet signing in solana-keygen (#8267) (#8268)
automerge
2020-02-13 13:57:11 -08:00
mergify[bot]
00f92f520f get_confirmed_block: expect() less (#8266)
automerge
2020-02-13 10:43:55 -08:00
mergify[bot]
b90049aafb Retain signature subscriptions that haven't been notified (#8261) (#8265)
automerge
2020-02-13 09:58:16 -08:00
mergify[bot]
c1d66b46fa Retry to curl to codecov.io unfortunately (#8263) (#8264)
automerge
2020-02-13 09:15:55 -08:00
mergify[bot]
c377d1cbbd CLI: Offline-ify remaining stake ops (#8257) (#8259)
automerge
2020-02-12 23:00:16 -08:00
mergify[bot]
bbdb4129cf Add CliCommand::StakeSetLockup (#8248) (#8254)
automerge
2020-02-12 17:23:53 -08:00
Michael Vines
0ecf823986 Cargo.lock 2020-02-12 17:53:27 -07:00
mergify[bot]
43ac961637 Simplify remote wallet (#8249) (#8251)
automerge
2020-02-12 16:19:14 -08:00
Michael Vines
57e6213528 Plumb --enable-rpc-get-confirmed-block flag 2020-02-12 17:09:03 -07:00
mergify[bot]
acafb89ff2 Wrap ed25519_dalek::Keypair (#8247) (#8250)
automerge
2020-02-12 16:01:30 -08:00
Michael Vines
ec319a6043 Bump version to 0.23.5 2020-02-12 13:58:37 -07:00
Michael Vines
f389d434f8 Bump version to 0.23.4 2020-02-12 13:56:59 -07:00
Michael Vines
1b600a7f37 Update cluster_info.rs 2020-02-12 12:50:45 -07:00
Michael Vines
798b457b27 Avoid assigning the serve repair port to the storage port
(cherry picked from commit d0a4686990)

# Conflicts:
#	core/src/cluster_info.rs
2020-02-12 12:50:45 -07:00
mergify[bot]
132d012842 Quash 'repair listener error: Err(RecvTimeoutError(Timeout))' log spam (#8238)
automerge
2020-02-12 10:29:26 -08:00
mergify[bot]
e16f9ad961 Fix accounts_db store counts in purging accounts logic (#8218) (#8236)
automerge
2020-02-12 09:45:06 -08:00
Trent Nelson
66f006108c CLI: Don't hide errors when fees are disabled (#8204)
automerge

(cherry picked from commit ed87229cec)
2020-02-11 23:33:49 -07:00
mergify[bot]
47f887bda0 The getConfirmedBlock RPC API is now disabled by default (#8230)
automerge
2020-02-11 22:18:22 -08:00
Michael Vines
bb64c73aa2 set_read_timeout() can fail, don't expect() it not to
(cherry picked from commit 36c0cb052b)
2020-02-11 21:08:07 -07:00
Michael Vines
1f30d1e77a solana-install init edge when "edge" is not currently installed now works
(cherry picked from commit ed58bcda4c)
2020-02-11 21:08:07 -07:00
mergify[bot]
04dab9b274 Fix RPC pub sub unsubscribe (#8208) (#8228)
automerge
2020-02-11 18:40:21 -08:00
mergify[bot]
fb4e102670 Report validator rewards in getConfirmedBlock JSON RPC (#8226)
automerge
2020-02-11 18:20:16 -08:00
mergify[bot]
67e0ba0356 Add method to sign raw data, enabling easier device app testing (#8221) (#8225)
automerge
2020-02-11 17:59:08 -08:00
mergify[bot]
22bb4e6462 Factor repair from gossip (#8044) (#8220)
automerge
2020-02-11 14:18:45 -08:00
mergify[bot]
79035bdbed Upgrade to rust 1.41.0 (bp #8202) (#8219)
automerge
2020-02-11 13:56:58 -08:00
mergify[bot]
70089a5258 Fixup sign_transaction; pass derivation_path by reference (#8194) (#8217)
automerge
2020-02-11 12:38:31 -08:00
mergify[bot]
34238d5f1e Reliably track proc macro & build.rs code coverage (#8210) (#8213)
automerge
2020-02-11 09:13:21 -08:00
mergify[bot]
cab6917cbd Fix nightly clippy warnings (#8199) (#8212)
automerge
2020-02-11 08:43:12 -08:00
mergify[bot]
2951ee5b1d Channel installs no longer re-download the same release. (#8211)
automerge
2020-02-11 08:24:17 -08:00
mergify[bot]
fb16a15900 CLI: Add fee-payer parame to stake-split subcommand (#8201) (#8205)
automerge
2020-02-11 01:32:07 -08:00
mergify[bot]
76b52f4c5d CLI: transfer fix checks pubkeys (#8198) (#8203)
automerge
2020-02-11 00:26:56 -08:00
mergify[bot]
21a2e643c2 CLI: Harden offline signing and tests (#8052) (#8197)
automerge
2020-02-10 19:23:22 -08:00
mergify[bot]
733d9cb026 Remove repairman as its spamming cluster with unwanted repairs (#8193) (#8195)
automerge
2020-02-10 17:56:45 -08:00
mergify[bot]
2f54f57b7a Fix larger than necessary allocations in streamer (#8187) (#8192)
automerge
2020-02-10 13:06:28 -08:00
mergify[bot]
7bd95019ef Minor logging improvements (bp #8140) (#8190)
automerge
2020-02-10 11:22:26 -08:00
Michael Vines
33557c3271 Check for AVX512 at runtime to avoid invalid opcode trap (#8166)
automerge

(cherry picked from commit ef5fb6fa46)
2020-02-07 17:07:10 -07:00
mergify[bot]
c65b9cd88d Filter old CrdsValues received via Pull Responses in Gossip (#8150) (#8171)
automerge
2020-02-07 14:11:48 -08:00
mergify[bot]
038db8167f CLI: Implement transfer command (#8108) (#8170)
automerge
2020-02-07 13:18:35 -08:00
mergify[bot]
030498ced5 Ledger hardware wallet integration (#8068) (#8169)
automerge
2020-02-07 12:14:41 -08:00
Michael Vines
28eb8b662a Remove unwanted println 2020-02-07 12:59:44 -07:00
Michael Vines
de752eaf80 Lock snapshot version to 0.23.2 (#8167)
automerge
2020-02-07 11:35:54 -08:00
mergify[bot]
9c5ef19d80 Surface shred version more in tools (#8163) (#8165)
automerge
2020-02-07 10:10:00 -08:00
mergify[bot]
235bd0a46b CLI: Support offline fee payers (#8009) (#8164)
automerge
2020-02-07 09:41:35 -08:00
mergify[bot]
465d71a3a3 De-replicode Tower constructors (#8153) (#8154)
automerge
2020-02-06 19:38:47 -08:00
mergify[bot]
14e6029fae Add libudev-dev to docker image to build remote-wallet (#8149) (#8152)
automerge
2020-02-06 16:51:44 -08:00
mergify[bot]
75434158ee Ignore flaky test_exchange_local_cluster (#8146) (#8147)
automerge
2020-02-06 12:24:42 -08:00
mergify[bot]
1cae9fd893 Better surface bank hash verification failures (#8134)
automerge
2020-02-05 12:04:34 -08:00
mergify[bot]
bea34a812c CLI cosmetic: make config get and verbose prints consistent (#8119) (#8133)
automerge
2020-02-05 11:31:29 -08:00
Michael Vines
41a28d7322 Bump version to 0.23.3 2020-02-03 21:10:30 -07:00
mergify[bot]
235158d2bc CLI: Expose sign-only reply parsing helper (#8107) (#8110)
automerge
2020-02-03 19:55:45 -08:00
Michael Vines
521238f7d7 Delete uptime command, report total credits in solana validators instead
(cherry picked from commit 4c0420b884)
2020-02-03 17:15:09 -07:00
sakridge
384f52a607 Fix consensus threshold when new root is created (#8093)
When a new root is created, the oldest slot is popped off
but when the logic checks for identical slots, it assumes
that any difference means a slot was popped off the front.
2020-02-03 16:54:48 -07:00
mergify[bot]
49f2d912ab Add split-stake command (#8092)
automerge
2020-02-03 11:04:21 -08:00
Michael Vines
8652fe30ce Update book release version 2020-02-03 11:36:19 -07:00
Michael Vines
899a14ba51 Disable windows update as windows build artifacts are turned off 2020-02-01 22:25:47 -07:00
Michael Vines
466c7dafb3 Bump version to v0.23.2 2020-02-01 21:46:34 -07:00
mergify[bot]
293bb63ed8 Reduce rpc client pre-flight requests by setting max-age header (#8082) (#8083)
automerge
2020-02-01 08:48:40 -08:00
Trent Nelson
8f8fb720af CLI: Fix stake-account auth withdrawer output (#8071)
automerge

(cherry picked from commit 9739be9ecf)
2020-02-01 08:58:13 -07:00
mergify[bot]
19f414d843 Use solana-cli config keypair in solana-keygen (bp #8074) (#8080)
* Use solana-cli config keypair in solana-keygen (#8074)

* Use solana-cli config keypair in solana-keygen

* s/infile/keypair for consistency across modules and more generality across access methods

* Move config into separate crate

(cherry picked from commit fab8ef379f)

# Conflicts:
#	Cargo.lock
#	cli/Cargo.toml
#	keygen/Cargo.toml

* Fixup version numbers for backport

Co-authored-by: Tyera Eulberg <teulberg@gmail.com>
2020-01-31 23:08:08 -07:00
mergify[bot]
eaca1c3170 Add new colo test cases using reduced node count (#8078) (#8079)
automerge
2020-01-31 19:06:36 -08:00
mergify[bot]
9fc75925f9 CLI: De-replicode SigningAuthority instatiation (#8076) (#8077)
automerge
2020-01-31 17:42:15 -08:00
mergify[bot]
b5098ac87c Filter repairman peers based on shred_version (#8069) (#8073)
automerge
2020-01-31 15:29:30 -08:00
mergify[bot]
e23aec9728 Update key (#8062) (#8066)
automerge
2020-01-31 12:55:49 -08:00
mergify[bot]
57d490c84f Minor cli fixes (bp #8061) (#8065)
automerge
2020-01-31 12:36:35 -08:00
mergify[bot]
aa8c9f6a98 Remove asteroids and pacman from QA/dev testnet availability (#8050) (#8063)
automerge
2020-01-31 11:28:33 -08:00
Michael Vines
57772dc73d s/mint/faucet 2020-01-31 12:15:20 -07:00
Justin Starry
21706108e8 Don't exit early if add. validators not found during gce.sh config
(cherry picked from commit 9adf0d4ee0)
2020-01-31 08:36:03 -07:00
mergify[bot]
50d0caf00f Remove support for 0.22.3 snapshots (#8058)
automerge
2020-01-31 00:15:44 -08:00
mergify[bot]
2739332306 Fix stale gossip entrypoint (#8053) (#8057)
automerge
2020-01-30 23:13:26 -08:00
mergify[bot]
c85c4699aa validator: add --private-rpc flag (bp #8037) (#8054)
automerge
2020-01-30 20:44:53 -08:00
Michael Vines
81add4d6bf Make tds slots-per-epoch configurable 2020-01-30 21:38:39 -07:00
Michael Vines
8e31eeb696 Dial testnet down to a single node 2020-01-30 21:17:38 -07:00
mergify[bot]
e1ce8b37ff Minor --expected-shred fix, clean up shred-related gossip log messages (#8041) (#8045)
automerge
2020-01-30 14:41:21 -08:00
Michael Vines
3f831c05f5 Add different shred test to test_tvu_peers_and_stakes
(cherry picked from commit 0c55b37976)
2020-01-30 11:28:45 -07:00
Trent Nelson
f0d7ce6bb6 CLI: Disallow blockhash/fee-calc lookups when offline (#7981)
* CLI: Add BlockhashSpec to tighten control over --blockhash

* Use BlockhashSpec

* Add a matches-free constructor

* More descriptive naming

(cherry picked from commit 966d077431)
2020-01-30 09:39:04 -07:00
Justin Starry
6ba95b2545 Ignore slow archiver tests (#8032)
automerge

(cherry picked from commit 400412d76c)
2020-01-30 09:38:49 -07:00
Sagar Dhawan
6818e68542 Add shred version filters to Crds Accessors (#8027)
* Add shred version filters to Crds Accessors

* Adopt entrypoint shred_version if one isn't provided

(cherry picked from commit 64c42e28dc)
2020-01-30 08:58:36 -07:00
mergify[bot]
43659d7deb Remove support for stake redelegation (#7995) (#8024)
automerge
2020-01-29 23:46:42 -08:00
Rob Walker
f24d8e7d2d Add set_lockup to stake (#7997)
(cherry picked from commit 0d6c233747)
2020-01-29 23:22:04 -07:00
Jack May
e10fe5e125 Update and fix transaction error documentation (#7998)
(cherry picked from commit fed3817ed3)
2020-01-29 23:20:32 -07:00
mergify[bot]
0f8c9ab1c4 Various fixes/improvements resulting from SLP 1.1 restart debug (bp #8019) (#8026)
automerge
2020-01-29 20:11:23 -08:00
Justin Starry
8a9a9cb991 Log solana-validator args on startup to aid debugging
(cherry picked from commit effe6e3ff3)
2020-01-29 09:40:33 -07:00
Jon-Eric Cook
44208ffa67 refactored 2020-01-28 20:29:56 -07:00
Jon-Eric Cook
5df0478fa3 refactored the thread loop
a thread will break if the atomic bool is true
2020-01-28 20:29:56 -07:00
Jon-Eric Cook
d52567933e refactored grind_parse_args and grind_print_info 2020-01-28 20:29:56 -07:00
Jon-Eric Cook
a32cdb9f4d updated to slice 2020-01-28 20:29:56 -07:00
Jon-Eric Cook
eacd8d986c put some logic into functions 2020-01-28 20:29:56 -07:00
Jon-Eric Cook
1d32603b49 taking care of errors from ./test-check.sh 2020-01-28 20:29:56 -07:00
Jon-Eric Cook
8c6f7ee5a4 ran cargo fmt 2020-01-28 20:29:56 -07:00
Jon-Eric Cook
be482eed3f removed whitespace 2020-01-28 20:29:56 -07:00
Jon-Eric Cook
6e1c53cb0f simplified messaging and if blocks 2020-01-28 20:29:56 -07:00
Jon-Eric Cook
af92f205cf simplified messaging 2020-01-28 20:29:56 -07:00
Jon-Eric Cook
87047b08c8 removed found and changed count to AtomicU64 2020-01-28 20:29:56 -07:00
Jon-Eric Cook
e282161872 updated bs58 decode check 2020-01-28 20:29:56 -07:00
Jon-Eric Cook
01b1e287ed fixed prefix typo 2020-01-28 20:29:56 -07:00
Jon-Eric Cook
d7fd1fa467 added informative print statements 2020-01-28 20:29:56 -07:00
Jon-Eric Cook
bfa34cd494 it works
need to add print out to inform user
2020-01-28 20:29:56 -07:00
Jon-Eric Cook
915835e224 this command works but wont exit right when the 6th key is found
cargo run grind --starts-with hj:2 --ends-with jk:2 --starts-and-ends-with nⓂ️2
2020-01-28 20:29:56 -07:00
Jon-Eric Cook
659332e7ac progress on storing parameters 2020-01-28 20:29:56 -07:00
Jon-Eric Cook
272986c6ac validator methods work 2020-01-28 20:29:56 -07:00
Jon-Eric Cook
4d8ab45c56 removed includes
added ends-with and starts-and-ends-with
updated help messages
added expected number of values
updated .value_name for each option
2020-01-28 20:29:56 -07:00
mergify[bot]
932ae86d47 CLI: Fix tests. sign_only requires a blockhash (#8005) (#8007)
automerge
2020-01-28 19:07:47 -08:00
mergify[bot]
756e6334b0 Add lock to make sure slot-based locktree calls are safe (#7993) (#7999)
automerge
2020-01-28 14:57:37 -08:00
Dan Albert
4e6eca9748 Update cargo files to 0.23.1 (#7994)
automerge
2020-01-27 20:44:44 -08:00
Michael Vines
d9e37eb30c Fix compute_shred_version() (#7989)
automerge

(cherry picked from commit fd7d5cbe0d)
2020-01-27 19:06:20 -07:00
mergify[bot]
04d1b35926 Consensus fix, don't consider threshold check if.. (#7948) (#7991)
automerge
2020-01-27 17:52:48 -08:00
mergify[bot]
d13d609050 Reduce epoch duration from 2 weeks to 2 days (#7987)
automerge
2020-01-27 10:24:20 -08:00
mergify[bot]
20426cf251 Specify where VM images are coming from across GCE projects (#7985) (#7986)
automerge
2020-01-27 09:02:05 -08:00
Michael Vines
4a220d7c8e Remove show- prefix 2020-01-26 21:01:18 -07:00
Michael Vines
436eab41ca Remove stray key 2020-01-26 14:35:50 -07:00
mergify[bot]
c8472d0a96 CLI: --sign-only and --signer require --blockhash (#7982) (#7983)
automerge
2020-01-26 10:19:04 -08:00
mergify[bot]
1a7db9c17e CLI: Consolidate offline arg declarations (#7979) (#7980)
automerge
2020-01-26 01:24:01 -08:00
mergify[bot]
b468d9f17c CLI: Deterministic dummy keypair generation for SigningAuthority::Offline (#7971) (#7978)
automerge
2020-01-26 00:13:06 -08:00
Michael Vines
41cf1d7d23 s/dervied/derived/ 2020-01-25 23:22:55 -07:00
539 changed files with 8759 additions and 16530 deletions

View File

@@ -1,4 +1,4 @@
root: ./docs/src root: ./book/src
structure: structure:
readme: introduction.md readme: introduction.md

6
.gitignore vendored
View File

@@ -1,6 +1,6 @@
/docs/html/ /book/html/
/docs/src/tests.ok /book/src/tests.ok
/docs/src/.gitbook/assets/*.svg /book/src/.gitbook/assets/*.svg
/farf/ /farf/
/solana-release/ /solana-release/
/solana-release.tar.bz2 /solana-release.tar.bz2

View File

@@ -19,6 +19,14 @@ pull_request_rules:
label: label:
add: add:
- automerge - automerge
- name: v0.22 backport
conditions:
- base=master
- label=v0.22
actions:
backport:
branches:
- v0.22
- name: v0.23 backport - name: v0.23 backport
conditions: conditions:
- base=master - base=master
@@ -27,27 +35,11 @@ pull_request_rules:
backport: backport:
branches: branches:
- v0.23 - v0.23
- name: v1.0 backport - name: v0.24 backport
conditions: conditions:
- base=master - base=master
- label=v1.0 - label=v0.24
actions: actions:
backport: backport:
branches: branches:
- v1.0 - v0.24
- name: v1.1 backport
conditions:
- base=master
- label=v1.1
actions:
backport:
branches:
- v1.1
- name: v1.2 backport
conditions:
- base=master
- label=v1.2
actions:
backport:
branches:
- v1.2

View File

@@ -45,7 +45,7 @@ $ git pull --rebase upstream master
If there are no functional changes, PRs can be very large and that's no If there are no functional changes, PRs can be very large and that's no
problem. If, however, your changes are making meaningful changes or additions, problem. If, however, your changes are making meaningful changes or additions,
then about 1000 lines of changes is about the most you should ask a Solana then about 1,000 lines of changes is about the most you should ask a Solana
maintainer to review. maintainer to review.
### Should I send small PRs as I develop large, new components? ### Should I send small PRs as I develop large, new components?
@@ -224,20 +224,21 @@ Inventing new terms is allowed, but should only be done when the term is widely
used and understood. Avoid introducing new 3-letter terms, which can be used and understood. Avoid introducing new 3-letter terms, which can be
confused with 3-letter acronyms. confused with 3-letter acronyms.
[Terms currently in use](docs/src/terminology.md) [Terms currently in use](book/src/terminology.md)
## Design Proposals ## Design Proposals
Solana's architecture is described by docs generated from markdown files in Solana's architecture is described by a book generated from markdown files in
the `docs/src/` directory, maintained by an *editor* (currently @garious). To the `book/src/` directory, maintained by an *editor* (currently @garious). To
add a design proposal, you'll need to include it in the add a design proposal, you'll need to at least propose a change the content
[Accepted Design Proposals](https://docs.solana.com/proposals) under the [Accepted Design
section of the Solana docs. Here's the full process: Proposals](https://docs.solana.com/book/v/master/proposals) chapter. Here's
the full process:
1. Propose a design by creating a PR that adds a markdown document to the 1. Propose a design by creating a PR that adds a markdown document to the
`docs/src/proposals` directory and references it from the [table of directory `book/src/` and references it from the [table of
contents](docs/src/SUMMARY.md). Add any relevant *maintainers* to the PR contents](book/src/SUMMARY.md). Add any relevant *maintainers* to the PR
review. review.
2. The PR being merged indicates your proposed change was accepted and that the 2. The PR being merged indicates your proposed change was accepted and that the
maintainers support your plan of attack. maintainers support your plan of attack.

1449
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -9,12 +9,26 @@ Blockchain Rebuilt for Scale
Solana&trade; is a new blockchain architecture built from the ground up for scale. The architecture supports Solana&trade; is a new blockchain architecture built from the ground up for scale. The architecture supports
up to 710 thousand transactions per second on a gigabit network. up to 710 thousand transactions per second on a gigabit network.
Documentation Disclaimer
=== ===
Before you jump into the code, review the documentation [Solana: Blockchain Rebuilt for Scale](https://docs.solana.com). All claims, content, designs, algorithms, estimates, roadmaps, specifications, and performance measurements described in this project are done with the author's best effort. It is up to the reader to check and validate their accuracy and truthfulness. Furthermore nothing in this project constitutes a solicitation for investment.
(The _latest_ development version of the docs is [available here](https://docs.solana.com/v/master).) Introduction
===
It's possible for a centralized database to process 710,000 transactions per second on a standard gigabit network if the transactions are, on average, no more than 176 bytes. A centralized database can also replicate itself and maintain high availability without significantly compromising that transaction rate using the distributed system technique known as Optimistic Concurrency Control [\[H.T.Kung, J.T.Robinson (1981)\]](http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.65.4735). At Solana, we're demonstrating that these same theoretical limits apply just as well to blockchain on an adversarial network. The key ingredient? Finding a way to share time when nodes can't trust one-another. Once nodes can trust time, suddenly ~40 years of distributed systems research becomes applicable to blockchain!
> Perhaps the most striking difference between algorithms obtained by our method and ones based upon timeout is that using timeout produces a traditional distributed algorithm in which the processes operate asynchronously, while our method produces a globally synchronous one in which every process does the same thing at (approximately) the same time. Our method seems to contradict the whole purpose of distributed processing, which is to permit different processes to operate independently and perform different functions. However, if a distributed system is really a single system, then the processes must be synchronized in some way. Conceptually, the easiest way to synchronize processes is to get them all to do the same thing at the same time. Therefore, our method is used to implement a kernel that performs the necessary synchronization--for example, making sure that two different processes do not try to modify a file at the same time. Processes might spend only a small fraction of their time executing the synchronizing kernel; the rest of the time, they can operate independently--e.g., accessing different files. This is an approach we have advocated even when fault-tolerance is not required. The method's basic simplicity makes it easier to understand the precise properties of a system, which is crucial if one is to know just how fault-tolerant the system is. [\[L.Lamport (1984)\]](http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.71.1078)
Furthermore, and much to our surprise, it can be implemented using a mechanism that has existed in Bitcoin since day one. The Bitcoin feature is called nLocktime and it can be used to postdate transactions using block height instead of a timestamp. As a Bitcoin client, you'd use block height instead of a timestamp if you don't trust the network. Block height turns out to be an instance of what's being called a Verifiable Delay Function in cryptography circles. It's a cryptographically secure way to say time has passed. In Solana, we use a far more granular verifiable delay function, a SHA 256 hash chain, to checkpoint the ledger and coordinate consensus. With it, we implement Optimistic Concurrency Control and are now well en route towards that theoretical limit of 710,000 transactions per second.
Architecture
===
Before you jump into the code, review the online book [Solana: Blockchain Rebuilt for Scale](https://docs.solana.com/book/).
(The _latest_ development version of the online book is also [available here](https://docs.solana.com/book/v/master/).)
Release Binaries Release Binaries
=== ===
@@ -73,8 +87,7 @@ $ rustup update
On Linux systems you may need to install libssl-dev, pkg-config, zlib1g-dev, etc. On Ubuntu: On Linux systems you may need to install libssl-dev, pkg-config, zlib1g-dev, etc. On Ubuntu:
```bash ```bash
$ sudo apt-get update $ sudo apt-get install libssl-dev pkg-config zlib1g-dev llvm clang
$ sudo apt-get install libssl-dev libudev-dev pkg-config zlib1g-dev llvm clang
``` ```
Download the source code: Download the source code:
@@ -107,14 +120,14 @@ $ cargo test
Local Testnet Local Testnet
--- ---
Start your own testnet locally, instructions are in the online docs [Solana: Blockchain Rebuild for Scale: Getting Started](https://docs.solana.com/building-from-source). Start your own testnet locally, instructions are in the book [Solana: Blockchain Rebuild for Scale: Getting Started](https://docs.solana.com/book/getting-started).
Remote Testnets Remote Testnets
--- ---
We maintain several testnets:
* `testnet` - public stable testnet accessible via devnet.solana.com. Runs 24/7 * `testnet` - public stable testnet accessible via devnet.solana.com. Runs 24/7
## Deploy process ## Deploy process
They are deployed with the `ci/testnet-manager.sh` script through a list of [scheduled They are deployed with the `ci/testnet-manager.sh` script through a list of [scheduled
@@ -224,8 +237,3 @@ problem is solved by this code?" On the other hand, if a test does fail and you
better way to solve the same problem, a Pull Request with your solution would most certainly be better way to solve the same problem, a Pull Request with your solution would most certainly be
welcome! Likewise, if rewriting a test can better communicate what code it's protecting, please welcome! Likewise, if rewriting a test can better communicate what code it's protecting, please
send us that patch! send us that patch!
Disclaimer
===
All claims, content, designs, algorithms, estimates, roadmaps, specifications, and performance measurements described in this project are done with the author's best effort. It is up to the reader to check and validate their accuracy and truthfulness. Furthermore nothing in this project constitutes a solicitation for investment.

View File

@@ -138,7 +138,7 @@ There are three release channels that map to branches as follows:
### Update documentation ### Update documentation
TODO: Documentation update procedure is WIP as we move to gitbook TODO: Documentation update procedure is WIP as we move to gitbook
Document the new recommended version by updating `docs/src/running-archiver.md` and `docs/src/validator-testnet.md` on the release (beta) branch to point at the `solana-install` for the upcoming release version. Document the new recommended version by updating `book/src/running-archiver.md` and `book/src/validator-testnet.md` on the release (beta) branch to point at the `solana-install` for the upcoming release version.
### Update software on devnet.solana.com ### Update software on devnet.solana.com

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "solana-archiver-lib" name = "solana-archiver-lib"
version = "1.0.8" version = "0.23.7"
description = "Solana Archiver Library" description = "Solana Archiver Library"
authors = ["Solana Maintainers <maintainers@solana.com>"] authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana" repository = "https://github.com/solana-labs/solana"
@@ -15,22 +15,22 @@ ed25519-dalek = "=1.0.0-pre.1"
log = "0.4.8" log = "0.4.8"
rand = "0.6.5" rand = "0.6.5"
rand_chacha = "0.1.1" rand_chacha = "0.1.1"
solana-client = { path = "../client", version = "1.0.8" } solana-client = { path = "../client", version = "0.23.7" }
solana-storage-program = { path = "../programs/storage", version = "1.0.8" } solana-storage-program = { path = "../programs/storage", version = "0.23.7" }
thiserror = "1.0" thiserror = "1.0"
serde = "1.0.104" serde = "1.0.104"
serde_json = "1.0.46" serde_json = "1.0.44"
serde_derive = "1.0.103" serde_derive = "1.0.103"
solana-net-utils = { path = "../net-utils", version = "1.0.8" } solana-net-utils = { path = "../net-utils", version = "0.23.7" }
solana-chacha = { path = "../chacha", version = "1.0.8" } solana-chacha = { path = "../chacha", version = "0.23.7" }
solana-chacha-sys = { path = "../chacha-sys", version = "1.0.8" } solana-chacha-sys = { path = "../chacha-sys", version = "0.23.7" }
solana-ledger = { path = "../ledger", version = "1.0.8" } solana-ledger = { path = "../ledger", version = "0.23.7" }
solana-logger = { path = "../logger", version = "1.0.8" } solana-logger = { path = "../logger", version = "0.23.7" }
solana-perf = { path = "../perf", version = "1.0.8" } solana-perf = { path = "../perf", version = "0.23.7" }
solana-sdk = { path = "../sdk", version = "1.0.8" } solana-sdk = { path = "../sdk", version = "0.23.7" }
solana-core = { path = "../core", version = "1.0.8" } solana-core = { path = "../core", version = "0.23.7" }
solana-archiver-utils = { path = "../archiver-utils", version = "1.0.8" } solana-archiver-utils = { path = "../archiver-utils", version = "0.23.7" }
solana-metrics = { path = "../metrics", version = "1.0.8" } solana-metrics = { path = "../metrics", version = "0.23.7" }
[dev-dependencies] [dev-dependencies]
hex = "0.4.0" hex = "0.4.0"

View File

@@ -47,7 +47,7 @@ use solana_storage_program::{
}; };
use std::{ use std::{
io::{self, ErrorKind}, io::{self, ErrorKind},
net::{IpAddr, Ipv4Addr, SocketAddr, UdpSocket}, net::{SocketAddr, UdpSocket},
path::{Path, PathBuf}, path::{Path, PathBuf},
result, result,
sync::atomic::{AtomicBool, Ordering}, sync::atomic::{AtomicBool, Ordering},
@@ -211,9 +211,12 @@ impl Archiver {
let client = solana_core::gossip_service::get_client(&nodes); let client = solana_core::gossip_service::get_client(&nodes);
info!("Setting up mining account..."); info!("Setting up mining account...");
if let Err(e) = if let Err(e) = Self::setup_mining_account(
Self::setup_mining_account(&client, &keypair, &storage_keypair, client_commitment) &client,
{ &keypair,
&storage_keypair,
client_commitment.clone(),
) {
//shutdown services before exiting //shutdown services before exiting
exit.store(true, Ordering::Relaxed); exit.store(true, Ordering::Relaxed);
gossip_service.join()?; gossip_service.join()?;
@@ -355,7 +358,7 @@ impl Archiver {
&cluster_info, &cluster_info,
archiver_keypair, archiver_keypair,
storage_keypair, storage_keypair,
meta.client_commitment, meta.client_commitment.clone(),
); );
} }
exit.store(true, Ordering::Relaxed); exit.store(true, Ordering::Relaxed);
@@ -371,7 +374,7 @@ impl Archiver {
let client = solana_core::gossip_service::get_client(&nodes); let client = solana_core::gossip_service::get_client(&nodes);
if let Ok(Some(account)) = if let Ok(Some(account)) =
client.get_account_with_commitment(&storage_keypair.pubkey(), client_commitment) client.get_account_with_commitment(&storage_keypair.pubkey(), client_commitment.clone())
{ {
if let Ok(StorageContract::ArchiverStorage { validations, .. }) = account.state() { if let Ok(StorageContract::ArchiverStorage { validations, .. }) = account.state() {
if !validations.is_empty() { if !validations.is_empty() {
@@ -379,7 +382,8 @@ impl Archiver {
&archiver_keypair.pubkey(), &archiver_keypair.pubkey(),
&storage_keypair.pubkey(), &storage_keypair.pubkey(),
); );
let message = Message::new_with_payer(&[ix], Some(&archiver_keypair.pubkey())); let message =
Message::new_with_payer(vec![ix], Some(&archiver_keypair.pubkey()));
if let Err(e) = client.send_message(&[archiver_keypair.as_ref()], message) { if let Err(e) = client.send_message(&[archiver_keypair.as_ref()], message) {
error!("unable to redeem reward, tx failed: {:?}", e); error!("unable to redeem reward, tx failed: {:?}", e);
} else { } else {
@@ -411,7 +415,7 @@ impl Archiver {
slot_sender: Sender<u64>, slot_sender: Sender<u64>,
) -> Result<WindowService> { ) -> Result<WindowService> {
let slots_per_segment = let slots_per_segment =
match Self::get_segment_config(&cluster_info, meta.client_commitment) { match Self::get_segment_config(&cluster_info, meta.client_commitment.clone()) {
Ok(slots_per_segment) => slots_per_segment, Ok(slots_per_segment) => slots_per_segment,
Err(e) => { Err(e) => {
error!("unable to get segment size configuration, exiting..."); error!("unable to get segment size configuration, exiting...");
@@ -577,7 +581,7 @@ impl Archiver {
&keypair.pubkey(), &keypair.pubkey(),
&Duration::from_millis(100), &Duration::from_millis(100),
&Duration::from_secs(5), &Duration::from_secs(5),
client_commitment, client_commitment.clone(),
)? == 0 )? == 0
{ {
return Err(ArchiverError::EmptyStorageAccountBalance); return Err(ArchiverError::EmptyStorageAccountBalance);
@@ -585,15 +589,16 @@ impl Archiver {
info!("checking storage account keypair..."); info!("checking storage account keypair...");
// check if the storage account exists // check if the storage account exists
let balance = let balance = client
client.poll_get_balance_with_commitment(&storage_keypair.pubkey(), client_commitment); .poll_get_balance_with_commitment(&storage_keypair.pubkey(), client_commitment.clone());
if balance.is_err() || balance.unwrap() == 0 { if balance.is_err() || balance.unwrap() == 0 {
let blockhash = match client.get_recent_blockhash_with_commitment(client_commitment) { let blockhash =
Ok((blockhash, _)) => blockhash, match client.get_recent_blockhash_with_commitment(client_commitment.clone()) {
Err(e) => { Ok((blockhash, _)) => blockhash,
return Err(ArchiverError::TransportError(e)); Err(e) => {
} return Err(ArchiverError::TransportError(e));
}; }
};
let ix = storage_instruction::create_storage_account( let ix = storage_instruction::create_storage_account(
&keypair.pubkey(), &keypair.pubkey(),
@@ -612,7 +617,6 @@ impl Archiver {
ErrorKind::Other, ErrorKind::Other,
"setup_mining_account: signature not found", "setup_mining_account: signature not found",
), ),
TransportError::Custom(e) => io::Error::new(ErrorKind::Other, e),
})?; })?;
} }
Ok(()) Ok(())
@@ -627,27 +631,32 @@ impl Archiver {
// No point if we've got no storage account... // No point if we've got no storage account...
let nodes = cluster_info.read().unwrap().tvu_peers(); let nodes = cluster_info.read().unwrap().tvu_peers();
let client = solana_core::gossip_service::get_client(&nodes); let client = solana_core::gossip_service::get_client(&nodes);
let storage_balance = client let storage_balance = client.poll_get_balance_with_commitment(
.poll_get_balance_with_commitment(&storage_keypair.pubkey(), meta.client_commitment); &storage_keypair.pubkey(),
meta.client_commitment.clone(),
);
if storage_balance.is_err() || storage_balance.unwrap() == 0 { if storage_balance.is_err() || storage_balance.unwrap() == 0 {
error!("Unable to submit mining proof, no storage account"); error!("Unable to submit mining proof, no storage account");
return; return;
} }
// ...or no lamports for fees // ...or no lamports for fees
let balance = client let balance = client.poll_get_balance_with_commitment(
.poll_get_balance_with_commitment(&archiver_keypair.pubkey(), meta.client_commitment); &archiver_keypair.pubkey(),
meta.client_commitment.clone(),
);
if balance.is_err() || balance.unwrap() == 0 { if balance.is_err() || balance.unwrap() == 0 {
error!("Unable to submit mining proof, insufficient Archiver Account balance"); error!("Unable to submit mining proof, insufficient Archiver Account balance");
return; return;
} }
let blockhash = match client.get_recent_blockhash_with_commitment(meta.client_commitment) { let blockhash =
Ok((blockhash, _)) => blockhash, match client.get_recent_blockhash_with_commitment(meta.client_commitment.clone()) {
Err(_) => { Ok((blockhash, _)) => blockhash,
error!("unable to get recent blockhash, can't submit proof"); Err(_) => {
return; error!("unable to get recent blockhash, can't submit proof");
} return;
}; }
};
let instruction = storage_instruction::mining_proof( let instruction = storage_instruction::mining_proof(
&storage_keypair.pubkey(), &storage_keypair.pubkey(),
meta.sha_state, meta.sha_state,
@@ -655,7 +664,7 @@ impl Archiver {
Signature::new(&meta.signature.as_ref()), Signature::new(&meta.signature.as_ref()),
meta.blockhash, meta.blockhash,
); );
let message = Message::new_with_payer(&[instruction], Some(&archiver_keypair.pubkey())); let message = Message::new_with_payer(vec![instruction], Some(&archiver_keypair.pubkey()));
let mut transaction = Transaction::new( let mut transaction = Transaction::new(
&[archiver_keypair.as_ref(), storage_keypair.as_ref()], &[archiver_keypair.as_ref(), storage_keypair.as_ref()],
message, message,
@@ -804,15 +813,14 @@ impl Archiver {
blockstore: &Arc<Blockstore>, blockstore: &Arc<Blockstore>,
slots_per_segment: u64, slots_per_segment: u64,
) -> Result<u64> { ) -> Result<u64> {
let ip_addr = IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0));
// Create a client which downloads from the archiver and see that it // Create a client which downloads from the archiver and see that it
// can respond with shreds. // can respond with shreds.
let start_slot = Self::get_archiver_segment_slot(ip_addr, archiver_info.storage_addr); let start_slot = Self::get_archiver_segment_slot(archiver_info.storage_addr);
info!("Archiver download: start at {}", start_slot); info!("Archiver download: start at {}", start_slot);
let exit = Arc::new(AtomicBool::new(false)); let exit = Arc::new(AtomicBool::new(false));
let (s_reader, r_reader) = channel(); let (s_reader, r_reader) = channel();
let repair_socket = Arc::new(bind_in_range(ip_addr, VALIDATOR_PORT_RANGE).unwrap().1); let repair_socket = Arc::new(bind_in_range(VALIDATOR_PORT_RANGE).unwrap().1);
let t_receiver = receiver( let t_receiver = receiver(
repair_socket.clone(), repair_socket.clone(),
&exit, &exit,
@@ -909,8 +917,8 @@ impl Archiver {
true true
} }
fn get_archiver_segment_slot(bind_ip_addr: IpAddr, to: SocketAddr) -> u64 { fn get_archiver_segment_slot(to: SocketAddr) -> u64 {
let (_port, socket) = bind_in_range(bind_ip_addr, VALIDATOR_PORT_RANGE).unwrap(); let (_port, socket) = bind_in_range(VALIDATOR_PORT_RANGE).unwrap();
socket socket
.set_read_timeout(Some(Duration::from_secs(5))) .set_read_timeout(Some(Duration::from_secs(5)))
.unwrap(); .unwrap();

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "solana-archiver-utils" name = "solana-archiver-utils"
version = "1.0.8" version = "0.23.7"
description = "Solana Archiver Utils" description = "Solana Archiver Utils"
authors = ["Solana Maintainers <maintainers@solana.com>"] authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana" repository = "https://github.com/solana-labs/solana"
@@ -11,12 +11,13 @@ edition = "2018"
[dependencies] [dependencies]
log = "0.4.8" log = "0.4.8"
rand = "0.6.5" rand = "0.6.5"
solana-chacha = { path = "../chacha", version = "1.0.8" } rand_chacha = "0.1.1"
solana-chacha-sys = { path = "../chacha-sys", version = "1.0.8" } solana-chacha = { path = "../chacha", version = "0.23.7" }
solana-ledger = { path = "../ledger", version = "1.0.8" } solana-chacha-sys = { path = "../chacha-sys", version = "0.23.7" }
solana-logger = { path = "../logger", version = "1.0.8" } solana-ledger = { path = "../ledger", version = "0.23.7" }
solana-perf = { path = "../perf", version = "1.0.8" } solana-logger = { path = "../logger", version = "0.23.7" }
solana-sdk = { path = "../sdk", version = "1.0.8" } solana-perf = { path = "../perf", version = "0.23.7" }
solana-sdk = { path = "../sdk", version = "0.23.7" }
[dev-dependencies] [dev-dependencies]
hex = "0.4.0" hex = "0.4.0"

View File

@@ -2,19 +2,19 @@
authors = ["Solana Maintainers <maintainers@solana.com>"] authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018" edition = "2018"
name = "solana-archiver" name = "solana-archiver"
version = "1.0.8" version = "0.23.7"
repository = "https://github.com/solana-labs/solana" repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0" license = "Apache-2.0"
homepage = "https://solana.com/" homepage = "https://solana.com/"
[dependencies] [dependencies]
clap = "2.33.0" clap = "2.33.0"
console = "0.9.2" console = "0.9.1"
solana-clap-utils = { path = "../clap-utils", version = "1.0.8" } solana-clap-utils = { path = "../clap-utils", version = "0.23.7" }
solana-core = { path = "../core", version = "1.0.8" } solana-core = { path = "../core", version = "0.23.7" }
solana-logger = { path = "../logger", version = "1.0.8" } solana-logger = { path = "../logger", version = "0.23.7" }
solana-metrics = { path = "../metrics", version = "1.0.8" } solana-metrics = { path = "../metrics", version = "0.23.7" }
solana-archiver-lib = { path = "../archiver-lib", version = "1.0.8" } solana-archiver-lib = { path = "../archiver-lib", version = "0.23.7" }
solana-net-utils = { path = "../net-utils", version = "1.0.8" } solana-net-utils = { path = "../net-utils", version = "0.23.7" }
solana-sdk = { path = "../sdk", version = "1.0.8" } solana-sdk = { path = "../sdk", version = "0.23.7" }

View File

@@ -2,22 +2,18 @@ use clap::{crate_description, crate_name, App, Arg};
use console::style; use console::style;
use solana_archiver_lib::archiver::Archiver; use solana_archiver_lib::archiver::Archiver;
use solana_clap_utils::{ use solana_clap_utils::{
input_parsers::keypair_of, input_validators::is_keypair_or_ask_keyword, input_validators::is_keypair,
keypair::SKIP_SEED_PHRASE_VALIDATION_ARG, keypair::{
self, keypair_input, KeypairWithSource, ASK_SEED_PHRASE_ARG,
SKIP_SEED_PHRASE_VALIDATION_ARG,
},
}; };
use solana_core::{ use solana_core::{
cluster_info::{Node, VALIDATOR_PORT_RANGE}, cluster_info::{Node, VALIDATOR_PORT_RANGE},
contact_info::ContactInfo, contact_info::ContactInfo,
}; };
use solana_sdk::{ use solana_sdk::{commitment_config::CommitmentConfig, signature::Signer};
commitment_config::CommitmentConfig, use std::{net::SocketAddr, path::PathBuf, process::exit, sync::Arc};
signature::{Keypair, Signer},
};
use std::{
net::{IpAddr, Ipv4Addr, SocketAddr},
path::PathBuf,
sync::Arc,
};
fn main() { fn main() {
solana_logger::setup(); solana_logger::setup();
@@ -28,10 +24,10 @@ fn main() {
.arg( .arg(
Arg::with_name("identity_keypair") Arg::with_name("identity_keypair")
.short("i") .short("i")
.long("identity") .long("identity-keypair")
.value_name("PATH") .value_name("PATH")
.takes_value(true) .takes_value(true)
.validator(is_keypair_or_ask_keyword) .validator(is_keypair)
.help("File containing an identity (keypair)"), .help("File containing an identity (keypair)"),
) )
.arg( .arg(
@@ -59,27 +55,48 @@ fn main() {
.long("storage-keypair") .long("storage-keypair")
.value_name("PATH") .value_name("PATH")
.takes_value(true) .takes_value(true)
.validator(is_keypair_or_ask_keyword) .validator(is_keypair)
.help("File containing the storage account keypair"), .help("File containing the storage account keypair"),
) )
.arg(
Arg::with_name(ASK_SEED_PHRASE_ARG.name)
.long(ASK_SEED_PHRASE_ARG.long)
.value_name("KEYPAIR NAME")
.multiple(true)
.takes_value(true)
.possible_values(&["identity-keypair", "storage-keypair"])
.help(ASK_SEED_PHRASE_ARG.help),
)
.arg( .arg(
Arg::with_name(SKIP_SEED_PHRASE_VALIDATION_ARG.name) Arg::with_name(SKIP_SEED_PHRASE_VALIDATION_ARG.name)
.long(SKIP_SEED_PHRASE_VALIDATION_ARG.long) .long(SKIP_SEED_PHRASE_VALIDATION_ARG.long)
.requires(ASK_SEED_PHRASE_ARG.name)
.help(SKIP_SEED_PHRASE_VALIDATION_ARG.help), .help(SKIP_SEED_PHRASE_VALIDATION_ARG.help),
) )
.get_matches(); .get_matches();
let ledger_path = PathBuf::from(matches.value_of("ledger").unwrap()); let ledger_path = PathBuf::from(matches.value_of("ledger").unwrap());
let identity_keypair = keypair_of(&matches, "identity_keypair").unwrap_or_else(Keypair::new); let identity_keypair = keypair_input(&matches, "identity_keypair")
.unwrap_or_else(|err| {
let storage_keypair = keypair_of(&matches, "storage_keypair").unwrap_or_else(|| { eprintln!("Identity keypair input failed: {}", err);
exit(1);
})
.keypair;
let KeypairWithSource {
keypair: storage_keypair,
source: storage_keypair_source,
} = keypair_input(&matches, "storage_keypair").unwrap_or_else(|err| {
eprintln!("Storage keypair input failed: {}", err);
exit(1);
});
if storage_keypair_source == keypair::Source::Generated {
clap::Error::with_description( clap::Error::with_description(
"The `storage-keypair` argument was not found", "The `storage-keypair` argument was not found",
clap::ErrorKind::ArgumentNotFound, clap::ErrorKind::ArgumentNotFound,
) )
.exit(); .exit();
}); }
let entrypoint_addr = matches let entrypoint_addr = matches
.value_of("entrypoint") .value_of("entrypoint")
@@ -99,7 +116,6 @@ fn main() {
&identity_keypair.pubkey(), &identity_keypair.pubkey(),
&gossip_addr, &gossip_addr,
VALIDATOR_PORT_RANGE, VALIDATOR_PORT_RANGE,
IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)),
); );
println!( println!(

View File

@@ -2,7 +2,7 @@
authors = ["Solana Maintainers <maintainers@solana.com>"] authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018" edition = "2018"
name = "solana-banking-bench" name = "solana-banking-bench"
version = "1.0.8" version = "0.23.7"
repository = "https://github.com/solana-labs/solana" repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0" license = "Apache-2.0"
homepage = "https://solana.com/" homepage = "https://solana.com/"
@@ -10,11 +10,11 @@ homepage = "https://solana.com/"
[dependencies] [dependencies]
log = "0.4.6" log = "0.4.6"
rayon = "1.2.0" rayon = "1.2.0"
solana-core = { path = "../core", version = "1.0.8" } solana-core = { path = "../core", version = "0.23.7" }
solana-ledger = { path = "../ledger", version = "1.0.8" } solana-ledger = { path = "../ledger", version = "0.23.7" }
solana-logger = { path = "../logger", version = "1.0.8" } solana-logger = { path = "../logger", version = "0.23.7" }
solana-runtime = { path = "../runtime", version = "1.0.8" } solana-runtime = { path = "../runtime", version = "0.23.7" }
solana-measure = { path = "../measure", version = "1.0.8" } solana-measure = { path = "../measure", version = "0.23.7" }
solana-sdk = { path = "../sdk", version = "1.0.8" } solana-sdk = { path = "../sdk", version = "0.23.7" }
rand = "0.6.5" rand = "0.6.5"
crossbeam-channel = "0.3" crossbeam-channel = "0.3"

View File

@@ -2,33 +2,40 @@
authors = ["Solana Maintainers <maintainers@solana.com>"] authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018" edition = "2018"
name = "solana-bench-exchange" name = "solana-bench-exchange"
version = "1.0.8" version = "0.23.7"
repository = "https://github.com/solana-labs/solana" repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0" license = "Apache-2.0"
homepage = "https://solana.com/" homepage = "https://solana.com/"
publish = false publish = false
[dependencies] [dependencies]
bincode = "1.2.1"
bs58 = "0.3.0"
clap = "2.32.0" clap = "2.32.0"
env_logger = "0.7.1"
itertools = "0.8.2" itertools = "0.8.2"
log = "0.4.8" log = "0.4.8"
num-derive = "0.3" num-derive = "0.3"
num-traits = "0.2" num-traits = "0.2"
rand = "0.6.5" rand = "0.6.5"
rayon = "1.2.0" rayon = "1.2.0"
serde_json = "1.0.46" serde = "1.0.104"
serde_derive = "1.0.103"
serde_json = "1.0.44"
serde_yaml = "0.8.11" serde_yaml = "0.8.11"
solana-clap-utils = { path = "../clap-utils", version = "1.0.8" } solana-clap-utils = { path = "../clap-utils", version = "0.23.7" }
solana-core = { path = "../core", version = "1.0.8" } solana-core = { path = "../core", version = "0.23.7" }
solana-genesis = { path = "../genesis", version = "1.0.8" } solana-genesis = { path = "../genesis", version = "0.23.7" }
solana-client = { path = "../client", version = "1.0.8" } solana-client = { path = "../client", version = "0.23.7" }
solana-faucet = { path = "../faucet", version = "1.0.8" } solana-faucet = { path = "../faucet", version = "0.23.7" }
solana-exchange-program = { path = "../programs/exchange", version = "1.0.8" } solana-exchange-program = { path = "../programs/exchange", version = "0.23.7" }
solana-logger = { path = "../logger", version = "1.0.8" } solana-logger = { path = "../logger", version = "0.23.7" }
solana-metrics = { path = "../metrics", version = "1.0.8" } solana-metrics = { path = "../metrics", version = "0.23.7" }
solana-net-utils = { path = "../net-utils", version = "1.0.8" } solana-net-utils = { path = "../net-utils", version = "0.23.7" }
solana-runtime = { path = "../runtime", version = "1.0.8" } solana-runtime = { path = "../runtime", version = "0.23.7" }
solana-sdk = { path = "../sdk", version = "1.0.8" } solana-sdk = { path = "../sdk", version = "0.23.7" }
untrusted = "0.7.0"
ws = "0.9.1"
[dev-dependencies] [dev-dependencies]
solana-local-cluster = { path = "../local-cluster", version = "1.0.8" } solana-local-cluster = { path = "../local-cluster", version = "0.23.7" }

View File

@@ -2,14 +2,14 @@
authors = ["Solana Maintainers <maintainers@solana.com>"] authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018" edition = "2018"
name = "solana-bench-streamer" name = "solana-bench-streamer"
version = "1.0.8" version = "0.23.7"
repository = "https://github.com/solana-labs/solana" repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0" license = "Apache-2.0"
homepage = "https://solana.com/" homepage = "https://solana.com/"
[dependencies] [dependencies]
clap = "2.33.0" clap = "2.33.0"
solana-clap-utils = { path = "../clap-utils", version = "1.0.8" } solana-clap-utils = { path = "../clap-utils", version = "0.23.7" }
solana-core = { path = "../core", version = "1.0.8" } solana-core = { path = "../core", version = "0.23.7" }
solana-logger = { path = "../logger", version = "1.0.8" } solana-logger = { path = "../logger", version = "0.23.7" }
solana-net-utils = { path = "../net-utils", version = "1.0.8" } solana-net-utils = { path = "../net-utils", version = "0.23.7" }

View File

@@ -67,8 +67,7 @@ fn main() -> Result<()> {
} }
let mut port = 0; let mut port = 0;
let ip_addr = IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)); let mut addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 0);
let mut addr = SocketAddr::new(ip_addr, 0);
let exit = Arc::new(AtomicBool::new(false)); let exit = Arc::new(AtomicBool::new(false));
@@ -76,7 +75,7 @@ fn main() -> Result<()> {
let mut read_threads = Vec::new(); let mut read_threads = Vec::new();
let recycler = PacketsRecycler::default(); let recycler = PacketsRecycler::default();
for _ in 0..num_sockets { for _ in 0..num_sockets {
let read = solana_net_utils::bind_to(ip_addr, port, false).unwrap(); let read = solana_net_utils::bind_to(port, false).unwrap();
read.set_read_timeout(Some(Duration::new(1, 0))).unwrap(); read.set_read_timeout(Some(Duration::new(1, 0))).unwrap();
addr = read.local_addr().unwrap(); addr = read.local_addr().unwrap();

View File

@@ -2,7 +2,7 @@
authors = ["Solana Maintainers <maintainers@solana.com>"] authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018" edition = "2018"
name = "solana-bench-tps" name = "solana-bench-tps"
version = "1.0.8" version = "0.23.7"
repository = "https://github.com/solana-labs/solana" repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0" license = "Apache-2.0"
homepage = "https://solana.com/" homepage = "https://solana.com/"
@@ -12,26 +12,28 @@ bincode = "1.2.1"
clap = "2.33.0" clap = "2.33.0"
log = "0.4.8" log = "0.4.8"
rayon = "1.2.0" rayon = "1.2.0"
serde_json = "1.0.46" serde = "1.0.104"
serde_derive = "1.0.103"
serde_json = "1.0.44"
serde_yaml = "0.8.11" serde_yaml = "0.8.11"
solana-clap-utils = { path = "../clap-utils", version = "1.0.8" } solana-clap-utils = { path = "../clap-utils", version = "0.23.7" }
solana-core = { path = "../core", version = "1.0.8" } solana-core = { path = "../core", version = "0.23.7" }
solana-genesis = { path = "../genesis", version = "1.0.8" } solana-genesis = { path = "../genesis", version = "0.23.7" }
solana-client = { path = "../client", version = "1.0.8" } solana-client = { path = "../client", version = "0.23.7" }
solana-faucet = { path = "../faucet", version = "1.0.8" } solana-faucet = { path = "../faucet", version = "0.23.7" }
solana-librapay = { path = "../programs/librapay", version = "1.0.8", optional = true } solana-librapay = { path = "../programs/librapay", version = "0.23.7", optional = true }
solana-logger = { path = "../logger", version = "1.0.8" } solana-logger = { path = "../logger", version = "0.23.7" }
solana-metrics = { path = "../metrics", version = "1.0.8" } solana-metrics = { path = "../metrics", version = "0.23.7" }
solana-measure = { path = "../measure", version = "1.0.8" } solana-measure = { path = "../measure", version = "0.23.7" }
solana-net-utils = { path = "../net-utils", version = "1.0.8" } solana-net-utils = { path = "../net-utils", version = "0.23.7" }
solana-runtime = { path = "../runtime", version = "1.0.8" } solana-runtime = { path = "../runtime", version = "0.23.7" }
solana-sdk = { path = "../sdk", version = "1.0.8" } solana-sdk = { path = "../sdk", version = "0.23.7" }
solana-move-loader-program = { path = "../programs/move_loader", version = "1.0.8", optional = true } solana-move-loader-program = { path = "../programs/move_loader", version = "0.23.7", optional = true }
[dev-dependencies] [dev-dependencies]
serial_test = "0.3.2" serial_test = "0.3.2"
serial_test_derive = "0.4.0" serial_test_derive = "0.3.1"
solana-local-cluster = { path = "../local-cluster", version = "1.0.8" } solana-local-cluster = { path = "../local-cluster", version = "0.23.7" }
[features] [features]
move = ["solana-librapay", "solana-move-loader-program"] move = ["solana-librapay", "solana-move-loader-program"]

View File

@@ -1059,8 +1059,8 @@ pub fn generate_and_fund_keypairs<T: 'static + Client + Send + Sync>(
// pay for the transaction fees in a new run. // pay for the transaction fees in a new run.
let enough_lamports = 8 * lamports_per_account / 10; let enough_lamports = 8 * lamports_per_account / 10;
if first_keypair_balance < enough_lamports || last_keypair_balance < enough_lamports { if first_keypair_balance < enough_lamports || last_keypair_balance < enough_lamports {
let fee_rate_governor = client.get_fee_rate_governor().unwrap(); let (_blockhash, fee_calculator) = get_recent_blockhash(client.as_ref());
let max_fee = fee_rate_governor.max_lamports_per_signature; let max_fee = fee_calculator.max_lamports_per_signature;
let extra_fees = extra * max_fee; let extra_fees = extra * max_fee;
let total_keypairs = keypairs.len() as u64 + 1; // Add one for funding keypair let total_keypairs = keypairs.len() as u64 + 1; // Add one for funding keypair
let mut total = lamports_per_account * total_keypairs + extra_fees; let mut total = lamports_per_account * total_keypairs + extra_fees;
@@ -1134,7 +1134,7 @@ mod tests {
use solana_runtime::bank::Bank; use solana_runtime::bank::Bank;
use solana_runtime::bank_client::BankClient; use solana_runtime::bank_client::BankClient;
use solana_sdk::client::SyncClient; use solana_sdk::client::SyncClient;
use solana_sdk::fee_calculator::FeeRateGovernor; use solana_sdk::fee_calculator::FeeCalculator;
use solana_sdk::genesis_config::create_genesis_config; use solana_sdk::genesis_config::create_genesis_config;
#[test] #[test]
@@ -1181,8 +1181,8 @@ mod tests {
#[test] #[test]
fn test_bench_tps_fund_keys_with_fees() { fn test_bench_tps_fund_keys_with_fees() {
let (mut genesis_config, id) = create_genesis_config(10_000); let (mut genesis_config, id) = create_genesis_config(10_000);
let fee_rate_governor = FeeRateGovernor::new(11, 0); let fee_calculator = FeeCalculator::new(11, 0);
genesis_config.fee_rate_governor = fee_rate_governor; genesis_config.fee_calculator = fee_calculator;
let bank = Bank::new(&genesis_config); let bank = Bank::new(&genesis_config);
let client = Arc::new(BankClient::new(bank)); let client = Arc::new(BankClient::new(bank));
let keypair_count = 20; let keypair_count = 20;

View File

@@ -1,6 +1,6 @@
use clap::{crate_description, crate_name, App, Arg, ArgMatches}; use clap::{crate_description, crate_name, App, Arg, ArgMatches};
use solana_faucet::faucet::FAUCET_PORT; use solana_faucet::faucet::FAUCET_PORT;
use solana_sdk::fee_calculator::FeeRateGovernor; use solana_sdk::fee_calculator::FeeCalculator;
use solana_sdk::signature::{read_keypair_file, Keypair}; use solana_sdk::signature::{read_keypair_file, Keypair};
use std::{net::SocketAddr, process::exit, time::Duration}; use std::{net::SocketAddr, process::exit, time::Duration};
@@ -43,7 +43,7 @@ impl Default for Config {
client_ids_and_stake_file: String::new(), client_ids_and_stake_file: String::new(),
write_to_client_file: false, write_to_client_file: false,
read_from_client_file: false, read_from_client_file: false,
target_lamports_per_signature: FeeRateGovernor::default().target_lamports_per_signature, target_lamports_per_signature: FeeCalculator::default().target_lamports_per_signature,
multi_client: true, multi_client: true,
use_move: false, use_move: false,
num_lamports_per_account: NUM_LAMPORTS_PER_ACCOUNT_DEFAULT, num_lamports_per_account: NUM_LAMPORTS_PER_ACCOUNT_DEFAULT,

View File

@@ -3,7 +3,7 @@ use solana_bench_tps::bench::{do_bench_tps, generate_and_fund_keypairs, generate
use solana_bench_tps::cli; use solana_bench_tps::cli;
use solana_core::gossip_service::{discover_cluster, get_client, get_multi_client}; use solana_core::gossip_service::{discover_cluster, get_client, get_multi_client};
use solana_genesis::Base64Account; use solana_genesis::Base64Account;
use solana_sdk::fee_calculator::FeeRateGovernor; use solana_sdk::fee_calculator::FeeCalculator;
use solana_sdk::signature::{Keypair, Signer}; use solana_sdk::signature::{Keypair, Signer};
use solana_sdk::system_program; use solana_sdk::system_program;
use std::{collections::HashMap, fs::File, io::prelude::*, path::Path, process::exit, sync::Arc}; use std::{collections::HashMap, fs::File, io::prelude::*, path::Path, process::exit, sync::Arc};
@@ -41,7 +41,7 @@ fn main() {
let (keypairs, _) = generate_keypairs(&id, keypair_count as u64); let (keypairs, _) = generate_keypairs(&id, keypair_count as u64);
let num_accounts = keypairs.len() as u64; let num_accounts = keypairs.len() as u64;
let max_fee = let max_fee =
FeeRateGovernor::new(*target_lamports_per_signature, 0).max_lamports_per_signature; FeeCalculator::new(*target_lamports_per_signature, 0).max_lamports_per_signature;
let num_lamports_per_account = (num_accounts - 1 + NUM_SIGNATURES_FOR_TXS * max_fee) let num_lamports_per_account = (num_accounts - 1 + NUM_SIGNATURES_FOR_TXS * max_fee)
/ num_accounts / num_accounts
+ num_lamports_per_account; + num_lamports_per_account;

View File

@@ -1,7 +1,7 @@
Building the Solana book Building the Solana book
--- ---
Install dependencies, build, and test the docs: Install the book's dependnecies, build, and test the book:
```bash ```bash
$ ./build.sh $ ./build.sh
@@ -19,7 +19,7 @@ Render markdown as HTML:
$ make build $ make build
``` ```
Render and view the docs: Render and view the book:
```bash ```bash
$ make open $ make open

View File

@@ -8,7 +8,6 @@ TARGET=html/index.html
TEST_STAMP=src/tests.ok TEST_STAMP=src/tests.ok
all: $(TARGET) all: $(TARGET)
./set-solana-release-tag.sh
svg: $(SVG_IMGS) svg: $(SVG_IMGS)

View File

Before

Width:  |  Height:  |  Size: 542 KiB

After

Width:  |  Height:  |  Size: 542 KiB

View File

Before

Width:  |  Height:  |  Size: 256 KiB

After

Width:  |  Height:  |  Size: 256 KiB

View File

Before

Width:  |  Height:  |  Size: 269 KiB

After

Width:  |  Height:  |  Size: 269 KiB

View File

@@ -1,54 +1,33 @@
# Table of contents # Table of contents
* [Introduction](introduction.md) * [Introduction](introduction.md)
* [Install the Solana Tool Suite](install-solana.md) * [Using Solana from the Command-line](cli/README.md)
* [Command-line Guide](cli/README.md) * [Command-line Usage](cli/usage.md)
* [Choose a Wallet](cli/choose-a-wallet.md) * [Remote Wallet](remote-wallet/README.md)
* [Hardware Wallets](remote-wallet/README.md)
* [Ledger Hardware Wallet](remote-wallet/ledger.md) * [Ledger Hardware Wallet](remote-wallet/ledger.md)
* [Paper Wallet](paper-wallet/README.md) * [Paper Wallet](paper-wallet/README.md)
* [Installation](paper-wallet/installation.md)
* [Paper Wallet Usage](paper-wallet/usage.md) * [Paper Wallet Usage](paper-wallet/usage.md)
* [Generate Keys](cli/generate-keys.md)
* [Send and Receive Tokens](cli/transfer-tokens.md)
* [Offline Signing](offline-signing/README.md) * [Offline Signing](offline-signing/README.md)
* [Durable Transaction Nonces](offline-signing/durable-nonce.md) * [Durable Transaction Nonces](offline-signing/durable-nonce.md)
* [Command-line Reference](cli/usage.md) * [Developing Applications](apps/README.md)
* [Develop Applications](apps/README.md)
* [Example: Web Wallet](apps/webwallet.md) * [Example: Web Wallet](apps/webwallet.md)
* [Example: Tic-Tac-Toe](apps/tictactoe.md) * [Example: Tic-Tac-Toe](apps/tictactoe.md)
* [Drones](apps/drones.md) * [Drones](apps/drones.md)
* [Anatomy of a Transaction](transaction.md) * [Anatomy of a Transaction](transaction.md)
* [JSON RPC API](apps/jsonrpc-api.md) * [JSON RPC API](apps/jsonrpc-api.md)
* [JavaScript API](apps/javascript-api.md) * [JavaScript API](apps/javascript-api.md)
* [Participate in Tour de SOL](tour-de-sol/README.md) * [Running a Validator](running-validator/README.md)
* [Useful Links & Discussion](tour-de-sol/useful-links.md)
* [Registration](tour-de-sol/registration/README.md)
* [How To Register](tour-de-sol/registration/how-to-register.md)
* [Terms of Participation](tour-de-sol/registration/terms-of-participation.md)
* [Rewards](tour-de-sol/registration/rewards.md)
* [Confidentiality](tour-de-sol/registration/confidentiality.md)
* [Registration FAQ](tour-de-sol/registration/validator-registration-and-rewards-faq.md)
* [Participation](tour-de-sol/participation/README.md)
* [Requirements to run a validator](tour-de-sol/participation/validator-technical-requirements.md)
* [Steps to create a validator](tour-de-sol/participation/steps-to-create-a-validator/README.md)
* [Install the Solana software](tour-de-sol/participation/steps-to-create-a-validator/install-the-solana-software.md)
* [Create a validator public key](tour-de-sol/participation/steps-to-create-a-validator/validator-public-key-registration.md)
* [Create and configure a Solana validator](tour-de-sol/participation/steps-to-create-a-validator/connecting-your-validator.md)
* [Confirm the Solana network is running](tour-de-sol/participation/steps-to-create-a-validator/confirm-the-solana-network-is-running.md)
* [Connect to the Solana network](tour-de-sol/participation/steps-to-create-a-validator/connect-to-the-solana-network.md)
* [Validator catch-up](tour-de-sol/participation/steps-to-create-a-validator/monitoring-your-validator.md)
* [Staking](tour-de-sol/participation/steps-to-create-a-validator/delegating-stake.md)
* [Publish information about your validator](tour-de-sol/participation/steps-to-create-a-validator/publishing-information-about-your-validator.md)
* [Dry Run 6](tour-de-sol/participation/dry-run-6.md)
* [Submit Bug Reports](tour-de-sol/submitting-bugs.md)
* [Run a Validator](running-validator/README.md)
* [Validator Requirements](running-validator/validator-reqs.md) * [Validator Requirements](running-validator/validator-reqs.md)
* [Start a Validator](running-validator/validator-start.md) * [Choosing a Testnet](running-validator/validator-testnet.md)
* [Stake](running-validator/validator-stake.md) * [Installing the Validator Software](running-validator/validator-software.md)
* [Monitor a Validator](running-validator/validator-monitor.md) * [Starting a Validator](running-validator/validator-start.md)
* [Publish Validator Info](running-validator/validator-info.md) * [Staking](running-validator/validator-stake.md)
* [Troubleshoot](running-validator/validator-troubleshoot.md) * [Monitoring a Validator](running-validator/validator-monitor.md)
* [Solana's Architecture](cluster/README.md) * [Publishing Validator Info](running-validator/validator-info.md)
* [Troubleshooting](running-validator/validator-troubleshoot.md)
* [Running an Archiver](running-archiver.md)
* [Understanding Solana's Architecture](cluster/README.md)
* [Synchronization](cluster/synchronization.md) * [Synchronization](cluster/synchronization.md)
* [Leader Rotation](cluster/leader-rotation.md) * [Leader Rotation](cluster/leader-rotation.md)
* [Fork Generation](cluster/fork-generation.md) * [Fork Generation](cluster/fork-generation.md)
@@ -64,9 +43,8 @@
* [Blockstore](validator/blockstore.md) * [Blockstore](validator/blockstore.md)
* [Gossip Service](validator/gossip.md) * [Gossip Service](validator/gossip.md)
* [The Runtime](validator/runtime.md) * [The Runtime](validator/runtime.md)
* [Build from Source](building-from-source.md) * [Building from Source](building-from-source.md)
* [Terminology](terminology.md) * [Terminology](terminology.md)
* [History](history.md)
* [Implemented Design Proposals](implemented-proposals/README.md) * [Implemented Design Proposals](implemented-proposals/README.md)
* [Cluster Software Installation and Updates](implemented-proposals/installer.md) * [Cluster Software Installation and Updates](implemented-proposals/installer.md)
* [Cluster Economics](implemented-proposals/ed_overview/README.md) * [Cluster Economics](implemented-proposals/ed_overview/README.md)

View File

@@ -1,6 +1,6 @@
# Drones # Drones
This section defines an off-chain service called a _drone_, which acts as custodian of a user's private key. In its simplest form, it can be used to create _airdrop_ transactions, a token transfer from the drone's account to a client's account. This chapter defines an off-chain service called a _drone_, which acts as custodian of a user's private key. In its simplest form, it can be used to create _airdrop_ transactions, a token transfer from the drone's account to a client's account.
## Signing Service ## Signing Service

View File

@@ -24,10 +24,7 @@ To interact with a Solana node inside a JavaScript application, use the [solana-
* [getConfirmedBlocks](jsonrpc-api.md#getconfirmedblocks) * [getConfirmedBlocks](jsonrpc-api.md#getconfirmedblocks)
* [getEpochInfo](jsonrpc-api.md#getepochinfo) * [getEpochInfo](jsonrpc-api.md#getepochinfo)
* [getEpochSchedule](jsonrpc-api.md#getepochschedule) * [getEpochSchedule](jsonrpc-api.md#getepochschedule)
* [getFeeCalculatorForBlockhash](jsonrpc-api.md#getfeecalculatorforblockhash)
* [getFeeRateGovernor](jsonrpc-api.md#getfeerategovernor)
* [getGenesisHash](jsonrpc-api.md#getgenesishash) * [getGenesisHash](jsonrpc-api.md#getgenesishash)
* [getIdentity](jsonrpc-api.md#getidentity)
* [getInflation](jsonrpc-api.md#getinflation) * [getInflation](jsonrpc-api.md#getinflation)
* [getLeaderSchedule](jsonrpc-api.md#getleaderschedule) * [getLeaderSchedule](jsonrpc-api.md#getleaderschedule)
* [getMinimumBalanceForRentExemption](jsonrpc-api.md#getminimumbalanceforrentexemption) * [getMinimumBalanceForRentExemption](jsonrpc-api.md#getminimumbalanceforrentexemption)
@@ -317,13 +314,13 @@ The result field will be an object with the following fields:
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0","id":1,"method":"getConfirmedBlock","params":[430, "json"]}' localhost:8899 curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0","id":1,"method":"getConfirmedBlock","params":[430, "json"]}' localhost:8899
// Result // Result
{"jsonrpc":"2.0","result":{"blockhash":"Gp3t5bfDsJv1ovP8cB1SuRhXVuoTqDv7p3tymyubYg5","parentSlot":429,"previousBlockhash":"EFejToxii1L5aUF2NrK9dsbAEmZSNyN5nsipmZHQR1eA","transactions":[{"transaction":{"message":{"accountKeys":["6H94zdiaYfRfPfKjYLjyr2VFBg6JHXygy84r3qhc3NsC","39UAy8hsoYPywGPGdmun747omSr79zLSjqvPJN3zetoH","SysvarS1otHashes111111111111111111111111111","SysvarC1ock11111111111111111111111111111111","Vote111111111111111111111111111111111111111"],"header":{"numReadonlySignedAccounts":0,"numReadonlyUnsignedAccounts":3,"numRequiredSignatures":2},"instructions":[{"accounts":[1,2,3],"data":"29z5mr1JoRmJYQ6ynmk3pf31cGFRziAF1M3mT3L6sFXf5cKLdkEaMXMT8AqLpD4CpcupHmuMEmtZHpomrwfdZetSomNy3d","programIdIndex":4}],"recentBlockhash":"EFejToxii1L5aUF2NrK9dsbAEmZSNyN5nsipmZHQR1eA"},"signatures":["35YGay1Lwjwgxe9zaH6APSHbt9gYQUCtBWTNL3aVwVGn9xTFw2fgds7qK5AL29mP63A9j3rh8KpN1TgSR62XCaby","4vANMjSKiwEchGSXwVrQkwHnmsbKQmy9vdrsYxWdCup1bLsFzX8gKrFTSVDCZCae2dbxJB9mPNhqB2sD1vvr4sAD"]},"meta":{"fee":1000,"postBalances":[499999972500,15298080,1,1,1],"preBalances":[499999990500,15298080,1,1,1],"status":{"Ok":null}}}]},"id":1} {"jsonrpc":"2.0","result":{"blockhash":"Gp3t5bfDsJv1ovP8cB1SuRhXVuoTqDv7p3tymyubYg5","parentSlot":429,"previousBlockhash":"EFejToxii1L5aUF2NrK9dsbAEmZSNyN5nsipmZHQR1eA","transactions":[{"transaction":{"message":{"accountKeys":["6H94zdiaYfRfPfKjYLjyr2VFBg6JHXygy84r3qhc3NsC","39UAy8hsoYPywGPGdmun747omSr79zLSjqvPJN3zetoH","SysvarS1otHashes111111111111111111111111111","SysvarC1ock11111111111111111111111111111111","Vote111111111111111111111111111111111111111"],"header":{"numReadonlySignedAccounts":0,"numReadonlyUnsignedAccounts":3,"numRequiredSignatures":2},"instructions":[{"accounts":[1,2,3],"data":"29z5mr1JoRmJYQ6ynmk3pf31cGFRziAF1M3mT3L6sFXf5cKLdkEaMXMT8AqLpD4CpcupHmuMEmtZHpomrwfdZetSomNy3d","programIdIndex":4}],"recentBlockhash":"EFejToxii1L5aUF2NrK9dsbAEmZSNyN5nsipmZHQR1eA"},"signatures":["35YGay1Lwjwgxe9zaH6APSHbt9gYQUCtBWTNL3aVwVGn9xTFw2fgds7qK5AL29mP63A9j3rh8KpN1TgSR62XCaby","4vANMjSKiwEchGSXwVrQkwHnmsbKQmy9vdrsYxWdCup1bLsFzX8gKrFTSVDCZCae2dbxJB9mPNhqB2sD1vvr4sAD"]},"meta":{"fee":18000,"postBalances":[499999972500,15298080,1,1,1],"preBalances":[499999990500,15298080,1,1,1],"status":{"Ok":null}}}]},"id":1}
// Request // Request
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0","id":1,"method":"getConfirmedBlock","params":[430, "binary"]}' localhost:8899 curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0","id":1,"method":"getConfirmedBlock","params":[430, "binary"]}' localhost:8899
// Result // Result
{"jsonrpc":"2.0","result":{"blockhash":"Gp3t5bfDsJv1ovP8cB1SuRhXVuoTqDv7p3tymyubYg5","parentSlot":429,"previousBlockhash":"EFejToxii1L5aUF2NrK9dsbAEmZSNyN5nsipmZHQR1eA","transactions":[{"transaction":"81UZJt4dh4Do66jDhrgkQudS8J2N6iG3jaVav7gJrqJSFY4Ug53iA9JFJZh2gxKWcaFdLJwhHx9mRdg9JwDAWB4ywiu5154CRwXV4FMdnPLg7bhxRLwhhYaLsVgMF5AyNRcTzjCVoBvqFgDU7P8VEKDEiMvD3qxzm1pLZVxDG1LTQpT3Dz4Uviv4KQbFQNuC22KupBoyHFB7Zh6KFdMqux4M9PvhoqcoJsJKwXjWpKu7xmEKnnrSbfLadkgjBmmjhW3fdTrFvnhQdTkhtdJxUL1xS9GMuJQer8YgSKNtUXB1eXZQwXU8bU2BjYkZE6Q5Xww8hu9Z4E4Mo4QsooVtHoP6BM3NKw8zjVbWfoCQqxTrwuSzrNCWCWt58C24LHecH67CTt2uXbYSviixvrYkK7A3t68BxTJcF1dXJitEPTFe2ceTkauLJqrJgnER4iUrsjr26T8YgWvpY9wkkWFSviQW6wV5RASTCUasVEcrDiaKj8EQMkgyDoe9HyKitSVg67vMWJFpUXpQobseWJUs5FTWWzmfHmFp8FZ","meta":{"fee":1000,"postBalances":[499999972500,15298080,1,1,1],"preBalances":[499999990500,15298080,1,1,1],"status":{"Ok":null}}}]},"id":1} {"jsonrpc":"2.0","result":{"blockhash":"Gp3t5bfDsJv1ovP8cB1SuRhXVuoTqDv7p3tymyubYg5","parentSlot":429,"previousBlockhash":"EFejToxii1L5aUF2NrK9dsbAEmZSNyN5nsipmZHQR1eA","transactions":[{"transaction":"81UZJt4dh4Do66jDhrgkQudS8J2N6iG3jaVav7gJrqJSFY4Ug53iA9JFJZh2gxKWcaFdLJwhHx9mRdg9JwDAWB4ywiu5154CRwXV4FMdnPLg7bhxRLwhhYaLsVgMF5AyNRcTzjCVoBvqFgDU7P8VEKDEiMvD3qxzm1pLZVxDG1LTQpT3Dz4Uviv4KQbFQNuC22KupBoyHFB7Zh6KFdMqux4M9PvhoqcoJsJKwXjWpKu7xmEKnnrSbfLadkgjBmmjhW3fdTrFvnhQdTkhtdJxUL1xS9GMuJQer8YgSKNtUXB1eXZQwXU8bU2BjYkZE6Q5Xww8hu9Z4E4Mo4QsooVtHoP6BM3NKw8zjVbWfoCQqxTrwuSzrNCWCWt58C24LHecH67CTt2uXbYSviixvrYkK7A3t68BxTJcF1dXJitEPTFe2ceTkauLJqrJgnER4iUrsjr26T8YgWvpY9wkkWFSviQW6wV5RASTCUasVEcrDiaKj8EQMkgyDoe9HyKitSVg67vMWJFpUXpQobseWJUs5FTWWzmfHmFp8FZ","meta":{"fee":18000,"postBalances":[499999972500,15298080,1,1,1],"preBalances":[499999990500,15298080,1,1,1],"status":{"Ok":null}}}]},"id":1}
``` ```
### getConfirmedBlocks ### getConfirmedBlocks
@@ -406,58 +403,6 @@ curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1, "m
{"jsonrpc":"2.0","result":{"firstNormalEpoch":8,"firstNormalSlot":8160,"leaderScheduleSlotOffset":8192,"slotsPerEpoch":8192,"warmup":true},"id":1} {"jsonrpc":"2.0","result":{"firstNormalEpoch":8,"firstNormalSlot":8160,"leaderScheduleSlotOffset":8192,"slotsPerEpoch":8192,"warmup":true},"id":1}
``` ```
### getFeeCalculatorForBlockhash
Returns the fee calculator associated with the query blockhash, or `null` if the blockhash has expired
#### Parameters:
* `blockhash: <string>`, query blockhash as a Base58 encoded string
#### Results:
The `result` field will be `null` if the query blockhash has expired, otherwise an `object` with the following fields:
* `feeCalculator: <object>`, `FeeCalculator` object describing the cluster fee rate at the queried blockhash
#### Example:
```bash
// Request
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1, "method":"getFeeCalculatorForBlockhash", "params":["GJxqhuxcgfn5Tcj6y3f8X4FeCDd2RQ6SnEMo1AAxrPRZ"]}' http://localhost:8899
// Result
{"jsonrpc":"2.0","result":{"context":{"slot":221},"value":{"feeCalculator":{"lamportsPerSignature":5000}}},"id":1}
```
### getFeeRateGovernor
Returns the fee rate governor information from the root bank
#### Parameters:
None
#### Results:
The `result` field will be an `object` with the following fields:
* `burnPercent: <u8>`, Percentage of fees collected to be destroyed
* `maxLamportsPerSignature: <u64>`, Largest value `lamportsPerSignature` can attain for the next slot
* `minLamportsPerSignature: <u64>`, Smallest value `lamportsPerSignature` can attain for the next slot
* `targetLamportsPerSignature: <u64>`, Desired fee rate for the cluster
* `targetSignaturesPerSlot: <u64>`, Desired signature rate for the cluster
#### Example:
```bash
// Request
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1, "method":"getFeeRateGovernor"}' http://localhost:8899
// Result
{"jsonrpc":"2.0","result":{"context":{"slot":54},"value":{"feeRateGovernor":{"burnPercent":50,"maxLamportsPerSignature":100000,"minLamportsPerSignature":5000,"targetLamportsPerSignature":10000,"targetSignaturesPerSlot":20000}}},"id":1}
```
### getGenesisHash ### getGenesisHash
Returns the genesis hash Returns the genesis hash
@@ -480,29 +425,6 @@ curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1, "m
{"jsonrpc":"2.0","result":"GH7ome3EiwEr7tu9JuTh2dpYWBJK3z69Xm1ZE3MEE6JC","id":1} {"jsonrpc":"2.0","result":"GH7ome3EiwEr7tu9JuTh2dpYWBJK3z69Xm1ZE3MEE6JC","id":1}
``` ```
### getIdentity
Returns the identity pubkey for the current node
#### Parameters:
None
#### Results:
The result field will be a JSON object with the following fields:
* `identity`, the identity pubkey of the current node \(as a base-58 encoded string\)
#### Example:
```bash
// Request
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1, "method":"getIdentity"}' http://localhost:8899
// Result
{"jsonrpc":"2.0","result":{"identity": "2r1F4iWqVcb8M1DbAjQuFpebkQHY9hcVU4WuW2DJBppN"},"id":1}
```
### getInflation ### getInflation
Returns the inflation configuration of the cluster Returns the inflation configuration of the cluster
@@ -657,7 +579,7 @@ An RpcResponse containing a JSON object consisting of a string blockhash and Fee
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1, "method":"getRecentBlockhash"}' http://localhost:8899 curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1, "method":"getRecentBlockhash"}' http://localhost:8899
// Result // Result
{"jsonrpc":"2.0","result":{"context":{"slot":1},"value":{"blockhash":"CSymwgTNX1j3E4qhKfJAUE41nBWEwXufoYryPbkde5RR","feeCalculator":{"burnPercent":50,"lamportsPerSignature":5000,"maxLamportsPerSignature":10000,"minLamportsPerSignature":5000,"targetLamportsPerSignature":1000,"targetSignaturesPerSlot":20000}}},"id":1} {"jsonrpc":"2.0","result":{"context":{"slot":1},"value":{"blockhash":"CSymwgTNX1j3E4qhKfJAUE41nBWEwXufoYryPbkde5RR","feeCalculator":{"burnPercent":50,"lamportsPerSignature":5000,"maxLamportsPerSignature":100000,"minLamportsPerSignature":5000,"targetLamportsPerSignature":10000,"targetSignaturesPerSlot":20000}}},"id":1}
``` ```
### getSignatureConfirmation ### getSignatureConfirmation
@@ -908,7 +830,7 @@ The result field will be a JSON object with the following fields:
// Request // Request
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1, "method":"getVersion"}' http://localhost:8899 curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1, "method":"getVersion"}' http://localhost:8899
// Result // Result
{"jsonrpc":"2.0","result":{"solana-core": "1.0.8"},"id":1} {"jsonrpc":"2.0","result":{"solana-core": "0.23.7"},"id":1}
``` ```
### getVoteAccounts ### getVoteAccounts
@@ -994,7 +916,7 @@ Creates new transaction
#### Parameters: #### Parameters:
* `<string>` - fully-signed Transaction, as base-58 encoded string * `<array>` - array of octets containing a fully-signed Transaction
#### Results: #### Results:

View File

@@ -123,7 +123,7 @@ This will dump all the threads stack traces into gdb.txt
### Blockstreamer ### Blockstreamer
Solana supports a node type called a _blockstreamer_. This validator variation is intended for applications that need to observe the data plane without participating in transaction validation or ledger replication. Solana supports a node type called an _blockstreamer_. This validator variation is intended for applications that need to observe the data plane without participating in transaction validation or ledger replication.
A blockstreamer runs without a vote signer, and can optionally stream ledger entries out to a Unix domain socket as they are processed. The JSON-RPC service still functions as on any other node. A blockstreamer runs without a vote signer, and can optionally stream ledger entries out to a Unix domain socket as they are processed. The JSON-RPC service still functions as on any other node.

View File

@@ -1,5 +1,5 @@
# Command-line Guide # Using Solana from the Command-line
This section describes the command-line tools for interacting with Solana. One This chapter describes the command-line tools for interacting with Solana. One
could use these tools to send payments, stake validators, and check account could use these tools to send payments, stake validators, and check account
balances. balances.

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
# A Solana Cluster # A Solana Cluster
A Solana cluster is a set of validators working together to serve client transactions and maintain the integrity of the ledger. Many clusters may coexist. When two clusters share a common genesis block, they attempt to converge. Otherwise, they simply ignore the existence of the other. Transactions sent to the wrong one are quietly rejected. In this section, we'll discuss how a cluster is created, how nodes join the cluster, how they share the ledger, how they ensure the ledger is replicated, and how they cope with buggy and malicious nodes. A Solana cluster is a set of validators working together to serve client transactions and maintain the integrity of the ledger. Many clusters may coexist. When two clusters share a common genesis block, they attempt to converge. Otherwise, they simply ignore the existence of the other. Transactions sent to the wrong one are quietly rejected. In this chapter, we'll discuss how a cluster is created, how nodes join the cluster, how they share the ledger, how they ensure the ledger is replicated, and how they cope with buggy and malicious nodes.
## Creating a Cluster ## Creating a Cluster

View File

@@ -1,6 +1,6 @@
# Fork Generation # Fork Generation
This section describes how forks naturally occur as a consequence of [leader rotation](leader-rotation.md). The chapter describes how forks naturally occur as a consequence of [leader rotation](leader-rotation.md).
## Overview ## Overview

View File

@@ -1,6 +1,6 @@
# Stake Delegation and Rewards # Stake Delegation and Rewards
Stakers are rewarded for helping to validate the ledger. They do this by delegating their stake to validator nodes. Those validators do the legwork of replaying the ledger and send votes to a per-node vote account to which stakers can delegate their stakes. The rest of the cluster uses those stake-weighted votes to select a block when forks arise. Both the validator and staker need some economic incentive to play their part. The validator needs to be compensated for its hardware and the staker needs to be compensated for the risk of getting its stake slashed. The economics are covered in [staking rewards](../implemented-proposals/staking-rewards.md). This section, on the other hand, describes the underlying mechanics of its implementation. Stakers are rewarded for helping to validate the ledger. They do this by delegating their stake to validator nodes. Those validators do the legwork of replaying the ledger and send votes to a per-node vote account to which stakers can delegate their stakes. The rest of the cluster uses those stake-weighted votes to select a block when forks arise. Both the validator and staker need some economic incentive to play their part. The validator needs to be compensated for its hardware and the staker needs to be compensated for the risk of getting its stake slashed. The economics are covered in [staking rewards](../implemented-proposals/staking-rewards.md). This chapter, on the other hand, describes the underlying mechanics of its implementation.
## Basic Design ## Basic Design
@@ -29,7 +29,11 @@ VoteState is the current state of all the votes the validator has submitted to t
* Account::lamports - The accumulated lamports from the commission. These do not count as stakes. * Account::lamports - The accumulated lamports from the commission. These do not count as stakes.
* `authorized_voter` - Only this identity is authorized to submit votes. This field can only modified by this identity. * `authorized_voter` - Only this identity is authorized to submit votes. This field can only modified by this identity.
* `node_pubkey` - The Solana node that votes in this account. * `node_pubkey` - The Solana node that votes in this account.
* `authorized_withdrawer` - the identity of the entity in charge of the lamports of this account, separate from the account's address and the authorized vote signer * `authorized_withdrawer` - the identity of the entity in charge of the lamports of this account, separate from the account's
```text
address and the authorized vote signer
```
### VoteInstruction::Initialize\(VoteInit\) ### VoteInstruction::Initialize\(VoteInit\)
@@ -44,11 +48,13 @@ VoteState is the current state of all the votes the validator has submitted to t
Updates the account with a new authorized voter or withdrawer, according to the VoteAuthorize parameter \(`Voter` or `Withdrawer`\). The transaction must be by signed by the Vote account's current `authorized_voter` or `authorized_withdrawer`. Updates the account with a new authorized voter or withdrawer, according to the VoteAuthorize parameter \(`Voter` or `Withdrawer`\). The transaction must be by signed by the Vote account's current `authorized_voter` or `authorized_withdrawer`.
* `account[0]` - RW - The VoteState * `account[0]` - RW - The VoteState
`VoteState::authorized_voter` or `authorized_withdrawer` is set to to `Pubkey`. `VoteState::authorized_voter` or `authorized_withdrawer` is set to to `Pubkey`.
### VoteInstruction::Vote\(Vote\) ### VoteInstruction::Vote\(Vote\)
* `account[0]` - RW - The VoteState * `account[0]` - RW - The VoteState
`VoteState::lockouts` and `VoteState::credits` are updated according to voting lockout rules see [Tower BFT](../implemented-proposals/tower-bft.md) `VoteState::lockouts` and `VoteState::credits` are updated according to voting lockout rules see [Tower BFT](../implemented-proposals/tower-bft.md)
* `account[1]` - RO - `sysvar::slot_hashes` A list of some N most recent slots and their hashes for the vote to be verified against. * `account[1]` - RO - `sysvar::slot_hashes` A list of some N most recent slots and their hashes for the vote to be verified against.
@@ -67,10 +73,18 @@ StakeState::Stake is the current delegation preference of the **staker** and con
* `voter_pubkey` - The pubkey of the VoteState instance the lamports are delegated to. * `voter_pubkey` - The pubkey of the VoteState instance the lamports are delegated to.
* `credits_observed` - The total credits claimed over the lifetime of the program. * `credits_observed` - The total credits claimed over the lifetime of the program.
* `activated` - the epoch at which this stake was activated/delegated. The full stake will be counted after warm up. * `activated` - the epoch at which this stake was activated/delegated. The full stake will be counted after warm up.
* `deactivated` - the epoch at which this stake was de-activated, some cool down epochs are required before the account is fully deactivated, and the stake available for withdrawal * `deactivated` - the epoch at which this stake was de-activated, some cool down epochs are required before the account
```text
is fully deactivated, and the stake available for withdrawal
```
* `authorized_staker` - the pubkey of the entity that must sign delegation, activation, and deactivation transactions * `authorized_staker` - the pubkey of the entity that must sign delegation, activation, and deactivation transactions
* `authorized_withdrawer` - the identity of the entity in charge of the lamports of this account, separate from the account's address, and the authorized staker * `authorized_withdrawer` - the identity of the entity in charge of the lamports of this account, separate from the account's
```text
address, and the authorized staker
```
### StakeState::RewardsPool ### StakeState::RewardsPool
@@ -154,7 +168,7 @@ Stakers who have delegated to that validator earn points in proportion to their
Stakes, once delegated, do not become effective immediately. They must first pass through a warm up period. During this period some portion of the stake is considered "effective", the rest is considered "activating". Changes occur on epoch boundaries. Stakes, once delegated, do not become effective immediately. They must first pass through a warm up period. During this period some portion of the stake is considered "effective", the rest is considered "activating". Changes occur on epoch boundaries.
The stake program limits the rate of change to total network stake, reflected in the stake program's `config::warmup_rate` \(set to 25% per epoch in the current implementation\). The stake program limits the rate of change to total network stake, reflected in the stake program's `config::warmup_rate` \(typically 25% per epoch\).
The amount of stake that can be warmed up each epoch is a function of the previous epoch's total effective stake, total activating stake, and the stake program's configured warmup rate. The amount of stake that can be warmed up each epoch is a function of the previous epoch's total effective stake, total activating stake, and the stake program's configured warmup rate.
@@ -166,14 +180,14 @@ Rewards are paid against the "effective" portion of the stake for that epoch.
#### Warmup example #### Warmup example
Consider the situation of a single stake of 1000 activated at epoch N, with network warmup rate of 20%, and a quiescent total network stake at epoch N of 2,000. Consider the situation of a single stake of 1,000 activated at epoch N, with network warmup rate of 20%, and a quiescent total network stake at epoch N of 2,000.
At epoch N+1, the amount available to be activated for the network is 400 \(20% of 200\), and at epoch N, this example stake is the only stake activating, and so is entitled to all of the warmup room available. At epoch N+1, the amount available to be activated for the network is 400 \(20% of 200\), and at epoch N, this example stake is the only stake activating, and so is entitled to all of the warmup room available.
| epoch | effective | activating | total effective | total activating | | epoch | effective | activating | total effective | total activating |
| :--- | ---: | ---: | ---: | ---: | | :--- | ---: | ---: | ---: | ---: |
| N-1 | | | 2,000 | 0 | | N-1 | | | 2,000 | 0 |
| N | 0 | 1000 | 2,000 | 1000 | | N | 0 | 1,000 | 2,000 | 1,000 |
| N+1 | 400 | 600 | 2,400 | 600 | | N+1 | 400 | 600 | 2,400 | 600 |
| N+2 | 880 | 120 | 2,880 | 120 | | N+2 | 880 | 120 | 2,880 | 120 |
| N+3 | 1000 | 0 | 3,000 | 0 | | N+3 | 1000 | 0 | 3,000 | 0 |
@@ -183,7 +197,7 @@ Were 2 stakes \(X and Y\) to activate at epoch N, they would be awarded a portio
| epoch | X eff | X act | Y eff | Y act | total effective | total activating | | epoch | X eff | X act | Y eff | Y act | total effective | total activating |
| :--- | ---: | ---: | ---: | ---: | ---: | ---: | | :--- | ---: | ---: | ---: | ---: | ---: | ---: |
| N-1 | | | | | 2,000 | 0 | | N-1 | | | | | 2,000 | 0 |
| N | 0 | 1000 | 0 | 200 | 2,000 | 1,200 | | N | 0 | 1,000 | 0 | 200 | 2,000 | 1,200 |
| N+1 | 333 | 667 | 67 | 133 | 2,400 | 800 | | N+1 | 333 | 667 | 67 | 133 | 2,400 | 800 |
| N+2 | 733 | 267 | 146 | 54 | 2,880 | 321 | | N+2 | 733 | 267 | 146 | 54 | 2,880 | 321 |
| N+3 | 1000 | 0 | 200 | 0 | 3,200 | 0 | | N+3 | 1000 | 0 | 200 | 0 | 3,200 | 0 |

View File

@@ -8,7 +8,7 @@ During its slot, the leader node distributes shreds between the validator nodes
In order for data plane fanout to work, the entire cluster must agree on how the cluster is divided into neighborhoods. To achieve this, all the recognized validator nodes \(the TVU peers\) are sorted by stake and stored in a list. This list is then indexed in different ways to figure out neighborhood boundaries and retransmit peers. For example, the leader will simply select the first nodes to make up layer 0. These will automatically be the highest stake holders, allowing the heaviest votes to come back to the leader first. Layer-0 and lower-layer nodes use the same logic to find their neighbors and next layer peers. In order for data plane fanout to work, the entire cluster must agree on how the cluster is divided into neighborhoods. To achieve this, all the recognized validator nodes \(the TVU peers\) are sorted by stake and stored in a list. This list is then indexed in different ways to figure out neighborhood boundaries and retransmit peers. For example, the leader will simply select the first nodes to make up layer 0. These will automatically be the highest stake holders, allowing the heaviest votes to come back to the leader first. Layer-0 and lower-layer nodes use the same logic to find their neighbors and next layer peers.
To reduce the possibility of attack vectors, each shred is transmitted over a random tree of neighborhoods. Each node uses the same set of nodes representing the cluster. A random tree is generated from the set for each shred using a seed derived from the leader id, slot and shred index. To reduce the possibility of attack vectors, each shred is transmitted over a random tree of neighborhoods. Each node uses the same set of nodes representing the cluster. A random tree is generated from the set for each shred using randomness derived from the shred itself. Since the random seed is not known in advance, attacks that try to eclipse neighborhoods from certain leaders or blocks become very difficult, and should require almost complete control of the stake in the cluster.
## Layer and Neighborhood Structure ## Layer and Neighborhood Structure

View File

@@ -10,8 +10,6 @@ These protocol-based rewards, to be distributed to participating validation and
Transaction fees are market-based participant-to-participant transfers, attached to network interactions as a necessary motivation and compensation for the inclusion and execution of a proposed transaction \(be it a state execution or proof-of-replication verification\). A mechanism for long-term economic stability and forking protection through partial burning of each transaction fee is also discussed below. Transaction fees are market-based participant-to-participant transfers, attached to network interactions as a necessary motivation and compensation for the inclusion and execution of a proposed transaction \(be it a state execution or proof-of-replication verification\). A mechanism for long-term economic stability and forking protection through partial burning of each transaction fee is also discussed below.
A high-level schematic of Solanas crypto-economic design is shown below in **Figure 1**. The specifics of validation-client economics are described in sections: [Validation-client Economics](ed_validation_client_economics/), [State-validation Protocol-based Rewards](ed_validation_client_economics/ed_vce_state_validation_protocol_based_rewards.md), [State-validation Transaction Fees](ed_validation_client_economics/ed_vce_state_validation_transaction_fees.md) and [Replication-validation Transaction Fees](ed_validation_client_economics/ed_vce_replication_validation_transaction_fees.md). Also, the section titled [Validation Stake Delegation](ed_validation_client_economics/ed_vce_validation_stake_delegation.md) closes with a discussion of validator delegation opportunities and marketplace. Additionally, in [Storage Rent Economics](ed_storage_rent_economics.md), we describe an implementation of storage rent to account for the externality costs of maintaining the active state of the ledger. [Replication-client Economics](ed_replication_client_economics/) will review the Solana network design for global ledger storage/redundancy and archiver-client economics \([Storage-replication rewards](ed_replication_client_economics/ed_rce_storage_replication_rewards.md)\) along with an archiver-to-validator delegation mechanism designed to aide participant on-boarding into the Solana economy discussed in [Replication-client Reward Auto-delegation](ed_replication_client_economics/ed_rce_replication_client_reward_auto_delegation.md). An outline of features for an MVP economic design is discussed in the [Economic Design MVP](ed_mvp.md) section. Finally, in [Attack Vectors](ed_attack_vectors.md), various attack vectors will be described and potential vulnerabilities explored and parameterized. A high-level schematic of Solanas crypto-economic design is shown below in **Figure 1**. The specifics of validation-client economics are described in sections: [Validation-client Economics](ed_validation_client_economics/), [State-validation Protocol-based Rewards](ed_validation_client_economics/ed_vce_state_validation_protocol_based_rewards.md), [State-validation Transaction Fees](ed_validation_client_economics/ed_vce_state_validation_transaction_fees.md) and [Replication-validation Transaction Fees](ed_validation_client_economics/ed_vce_replication_validation_transaction_fees.md). Also, the chapter titled [Validation Stake Delegation](ed_validation_client_economics/ed_vce_validation_stake_delegation.md) closes with a discussion of validator delegation opportunties and marketplace. Additionally, in [Storage Rent Economics](ed_storage_rent_economics.md), we describe an implementation of storage rent to account for the externality costs of maintaining the active state of the ledger. The [Replication-client Economics](ed_replication_client_economics/) chapter will review the Solana network design for global ledger storage/redundancy and archiver-client economics \([Storage-replication rewards](ed_replication_client_economics/ed_rce_storage_replication_rewards.md)\) along with an archiver-to-validator delegation mechanism designed to aide participant on-boarding into the Solana economy discussed in [Replication-client Reward Auto-delegation](ed_replication_client_economics/ed_rce_replication_client_reward_auto_delegation.md). An outline of features for an MVP economic design is discussed in the [Economic Design MVP](ed_mvp.md) section. Finally, in chapter [Attack Vectors](ed_attack_vectors.md), various attack vectors will be described and potential vulnerabilities explored and parameterized.
![](../../.gitbook/assets/economic_design_infl_230719.png)
**Figure 1**: Schematic overview of Solana economic incentive design. **Figure 1**: Schematic overview of Solana economic incentive design.

View File

@@ -2,15 +2,13 @@
**Subject to change.** **Subject to change.**
Long term economic sustainability is one of the guiding principles of Solanas economic design. While it is impossible to predict how decentralized economies will develop over time, especially economies with flexible decentralized governances, we can arrange economic components such that, under certain conditions, a sustainable economy may take shape in the long term. In the case of Solanas network, these components take the form of token issuance \(via inflation\) and token burning. Long term economic sustainability is one of the guiding principles of Solanas economic design. While it is impossible to predict how decentralized economies will develop over time, especially economies with flexible decentralized governances, we can arrange economic components such that, under certain conditions, a sustainable economy may take shape in the long term. In the case of Solanas network, these components take the form of token issuance \(via inflation\) and token burning.
The dominant remittances from the Solana mining pool are validator and archiver rewards. The disinflationary mechanism is a flat, protocol-specified and adjusted, % of each transaction fee. The dominant remittances from the Solana mining pool are validator and archiver rewards. The disinflationary mechanism is a flat, protocol-specified and adjusted, % of each transaction fee.
The Archiver rewards are to be delivered to archivers as a portion of the network inflation after successful PoRep validation. The per-PoRep reward amount is determined as a function of the total network storage redundancy at the time of the PoRep validation and the network goal redundancy. This function is likely to take the form of a discount from a base reward to be delivered when the network has achieved and maintained its goal redundancy. An example of such a reward function is shown in **Figure 1** The Archiver rewards are to be delivered to archivers as a portion of the network inflation after successful PoRep validation. The per-PoRep reward amount is determined as a function of the total network storage redundancy at the time of the PoRep validation and the network goal redundancy. This function is likely to take the form of a discount from a base reward to be delivered when the network has achieved and maintained its goal redundancy. An example of such a reward function is shown in **Figure 3**
![](../../.gitbook/assets/porep_reward.png) **Figure 3**: Example PoRep reward design as a function of global network storage redundancy.
**Figure 1**: Example PoRep reward design as a function of global network storage redundancy. In the example shown in Figure 1, multiple per PoRep base rewards are explored \(as a % of Tx Fee\) to be delivered when the global ledger replication redundancy meets 10X. When the global ledger replication redundancy is less than 10X, the base reward is discounted as a function of the square of the ratio of the actual ledger replication redundancy to the goal redundancy \(i.e. 10X\).
In the example shown in **Figure 1**, multiple per PoRep base rewards are explored \(as a % of Tx Fee\) to be delivered when the global ledger replication redundancy meets 10X. When the global ledger replication redundancy is less than 10X, the base reward is discounted as a function of the square of the ratio of the actual ledger replication redundancy to the goal redundancy \(i.e. 10X\).

View File

@@ -2,7 +2,7 @@
**Subject to change.** **Subject to change.**
The preceding sections, outlined in the [Economic Design Overview](./), describe a long-term vision of a sustainable Solana economy. Of course, we don't expect the final implementation to perfectly match what has been described above. We intend to fully engage with network stakeholders throughout the implementation phases \(i.e. pre-testnet, testnet, mainnet\) to ensure the system supports, and is representative of, the various network participants' interests. The first step toward this goal, however, is outlining a some desired MVP economic features to be available for early pre-testnet and testnet participants. Below is a rough sketch outlining basic economic functionality from which a more complete and functional system can be developed. The preceeding sections, outlined in the [Economic Design Overview](./), describe a long-term vision of a sustainable Solana economy. Of course, we don't expect the final implementation to perfectly match what has been described above. We intend to fully engage with network stakeholders throughout the implementation phases \(i.e. pre-testnet, testnet, mainnet\) to ensure the system supports, and is representative of, the various network participants' interests. The first step toward this goal, however, is outlining a some desired MVP economic features to be available for early pre-testnet and testnet participants. Below is a rough sketch outlining basic economic functionality from which a more complete and functional system can be developed.
## MVP Economic Features ## MVP Economic Features

View File

@@ -2,5 +2,5 @@
**Subject to change.** **Subject to change.**
Replication-clients should be rewarded for providing the network with storage space. Incentivization of the set of archivers provides data security through redundancy of the historical ledger. Replication nodes are rewarded in proportion to the amount of ledger data storage provided, as proved by successfully submitting Proofs-of-Replication to the cluster.. These rewards are captured by generating and entering Proofs of Replication \(PoReps\) into the PoH stream which can be validated by Validation nodes as described in [Replication-validation Transaction Fees](../ed_validation_client_economics/ed_vce_replication_validation_transaction_fees.md). Replication-clients should be rewarded for providing the network with storage space. Incentivization of the set of archivers provides data security through redundancy of the historical ledger. Replication nodes are rewarded in proportion to the amount of ledger data storage provided, as proved by successfully submitting Proofs-of-Replication to the cluster.. These rewards are captured by generating and entering Proofs of Replication \(PoReps\) into the PoH stream which can be validated by Validation nodes as described above in the [Replication-validation Transaction Fees](../ed_validation_client_economics/ed_vce_replication_validation_transaction_fees.md) chapter.

View File

@@ -1,12 +1,12 @@
## Storage Rent Economics ## Storage Rent Economics
Each transaction that is submitted to the Solana ledger imposes costs. Transaction fees paid by the submitter, and collected by a validator, in theory, account for the acute, transactional, costs of validating and adding that data to the ledger. At the same time, our compensation design for archivers (see [Replication-client Economics](ed_replication_client_economics.md)), in theory, accounts for the long term storage of the historical ledger. Unaccounted in this process is the mid-term storage of active ledger state, necessarily maintained by the rotating validator set. This type of storage imposes costs not only to validators but also to the broader network as active state grows so does data transmission and validation overhead. To account for these costs, we describe here our preliminary design and implementation of storage rent. Each transaction that is submitted to the Solana ledger imposes costs. Transaction fees paid by the submitter, and collected by a validator, in theory, account for the acute, transacitonal, costs of validating and adding that data to the ledger. At the same time, our compensation design for archivers (see [Replication-client Economics](ed_replication_client_economics.md)), in theory, accounts for the long term storage of the historical ledger. Unaccounted in this process is the mid-term storage of active ledger state, necessarily maintined by the rotating validator set. This type of storage imposes costs not only to validators but also to the broader network as active state grows so does data transmission and validation overhead. To account for these costs, we describe here our preliminary design and implementation of storage rent.
Storage rent can be paid via one of two methods: Storage rent can be paid via one of two methods:
Method 1: Set it and forget it Method 1: Set it and forget it
With this approach, accounts with two-years worth of rent deposits secured are exempt from network rent charges. By maintaining this minimum-balance, the broader network benefits from reduced liquidity and the account holder can trust that their `Account::data` will be retained for continual access/usage. With this approach, accounts with two-years worth of rent deposits secured are exempt from network rent charges. By maintaining this minimum-balance, the broader network benefits from reduced liquitity and the account holder can trust that their `Account::data` will be retained for continual access/usage.
Method 2: Pay per byte Method 2: Pay per byte

View File

@@ -0,0 +1,11 @@
# Replication-validation Transaction Fees
**Subject to change.**
As previously mentioned, validator-clients will also be responsible for validating PoReps submitted into the PoH stream by archiver-clients. In this case, validators are providing compute \(CPU/GPU\) and light storage resources to confirm that these replication proofs could only be generated by a client that is storing the referenced PoH leger block.
While replication-clients are incentivized and rewarded through protocol-based rewards schedule \(see [Replication-client Economics](../ed_replication_client_economics/)\), validator-clients will be incentivized to include and validate PoReps in PoH through collection of transaction fees associated with the submitted PoReps and distribution of protocol rewards proportional to the validated PoReps. As will be described in detail in the Section 3.1, replication-client rewards are protocol-based and designed to reward based on a global data redundancy factor. I.e. the protocol will incentivize replication-client participation through rewards based on a target ledger redundancy \(e.g. 10x data redundancy\).
The validation of PoReps by validation-clients is computationally more expensive than state-validation \(detail in the [Economic Sustainability](../ed_economic_sustainability.md) chapter\), thus the transaction fees are expected to be proportionally higher.
There are various attack vectors available for colluding validation and replication clients, also described in detail below in [Economic Sustainability](../ed_economic_sustainability/README.md). To protect against various collusion attack vectors, for a given epoch, validator rewards are distributed across participating validation-clients in proportion to the number of validated PoReps in the epoch less the number of PoReps that mismatch the archivers challenge. The PoRep challenge game is described in [Ledger Replication](https://github.com/solana-labs/solana/blob/master/book/src/ledger-replication.md#the-porep-game). This design rewards validators proportional to the number of PoReps they process and validate, while providing negative pressure for validation-clients to submit lazy or malicious invalid votes on submitted PoReps \(note that it is computationally prohibitive to determine whether a validator-client has marked a valid PoRep as invalid\).

View File

@@ -15,20 +15,16 @@ The effective protocol-based annual interest rate \(%\) per epoch received by va
* the fraction of staked SOLs out of the current total circulating supply, * the fraction of staked SOLs out of the current total circulating supply,
* the up-time/participation \[% of available slots that validator had opportunity to vote on\] of a given validator over the previous epoch. * the up-time/participation \[% of available slots that validator had opportunity to vote on\] of a given validator over the previous epoch.
The first factor is a function of protocol parameters only \(i.e. independent of validator behavior in a given epoch\) and results in a global validation reward schedule designed to incentivize early participation, provide clear monetary stability and provide optimal security in the network. The first factor is a function of protocol parameters only \(i.e. independent of validator behavior in a given epoch\) and results in a global validation reward schedule designed to incentivize early participation, provide clear montetary stability and provide optimal security in the network.
At any given point in time, a specific validator's interest rate can be determined based on the proportion of circulating supply that is staked by the network and the validator's uptime/activity in the previous epoch. For example, consider a hypothetical instance of the network with an initial circulating token supply of 250MM tokens with an additional 250MM vesting over 3 years. Additionally an inflation rate is specified at network launch of 7.5%, and a disinflationary schedule of 20% decrease in inflation rate per year \(the actual rates to be implemented are to be worked out during the testnet experimentation phase of mainnet launch\). With these broad assumptions, the 10-year inflation rate \(adjusted daily for this example\) is shown in **Figure 1**, while the total circulating token supply is illustrated in **Figure 2**. Neglected in this toy-model is the inflation suppression due to the portion of each transaction fee that is to be destroyed. At any given point in time, a specific validator's interest rate can be determined based on the porportion of circulating supply that is staked by the network and the validator's uptime/activity in the previous epoch. For example, consider a hypothetical instance of the network with an initial circulating token supply of 250MM tokens with an additional 250MM vesting over 3 years. Additionally an inflation rate is specified at network launch of 7.5%, and a disinflationary schedule of 20% decrease in inflation rate per year \(the actual rates to be implemented are to be worked out during the testnet experimentation phase of mainnet launch\). With these broad assumptions, the 10-year inflation rate \(adjusted daily for this example\) is shown in **Figure 2**, while the total circulating token supply is illustrated in **Figure 3**. Neglected in this toy-model is the inflation supression due to the portion of each transaction fee that is to be destroyed.
![](../../../.gitbook/assets/p_ex_schedule.png) ![drawing](../../../.gitbook/assets/p_ex_schedule.png) \*\*Figure 2:\*\* In this example schedule, the annual inflation rate \[%\] reduces at around 20% per year, until it reaches the long-term, fixed, 1.5% rate.
**Figure 1:** In this example schedule, the annual inflation rate \[%\] reduces at around 20% per year, until it reaches the long-term, fixed, 1.5% rate. ![drawing](../../../.gitbook/assets/p_ex_supply.png) \*\*Figure 3:\*\* The total token supply over a 10-year period, based on an initial 250MM tokens with the disinflationary inflation schedule as shown in \*\*Figure 2\*\* Over time, the interest rate, at a fixed network staked percentage, will reduce concordant with network inflation. Validation-client interest rates are designed to be higher in the early days of the network to incentivize participation and jumpstart the network economy. As previously mentioned, the inflation rate is expected to stabalize near 1-2% which also results in a fixed, long-term, interest rate to be provided to validator-clients. This value does not represent the total interest available to validator-clients as transaction fees for state-validation and ledger storage replication \(PoReps\) are not accounted for here. Given these example parameters, annualized validator-specific interest rates can be determined based on the global fraction of tokens bonded as stake, as well as their uptime/activity in the previous epoch. For the purpose of this example, we assume 100% uptime for all validators and a split in interest-based rewards between validators and archiver nodes of 80%/20%. Additionally, the fraction of staked circulating supply is assummed to be constant. Based on these assumptions, an annualized validation-client interest rate schedule as a function of % circulating token supply that is staked is shown in\*\* Figure 4\*\*.
![](../../../.gitbook/assets/p_ex_supply.png) ![drawing](../../../.gitbook/assets/p_ex_interest.png)
**Figure 2:** The total token supply over a 10-year period, based on an initial 250MM tokens with the disinflationary inflation schedule as shown in **Figure 1**. Over time, the interest rate, at a fixed network staked percentage, will reduce concordant with network inflation. Validation-client interest rates are designed to be higher in the early days of the network to incentivize participation and jumpstart the network economy. As previously mentioned, the inflation rate is expected to stabilize near 1-2% which also results in a fixed, long-term, interest rate to be provided to validator-clients. This value does not represent the total interest available to validator-clients as transaction fees for state-validation and ledger storage replication \(PoReps\) are not accounted for here. Given these example parameters, annualized validator-specific interest rates can be determined based on the global fraction of tokens bonded as stake, as well as their uptime/activity in the previous epoch. For the purpose of this example, we assume 100% uptime for all validators and a split in interest-based rewards between validators and archiver nodes of 80%/20%. Additionally, the fraction of staked circulating supply is assumed to be constant. Based on these assumptions, an annualized validation-client interest rate schedule as a function of % circulating token supply that is staked is shown in **Figure 3**. **Figure 4:** Shown here are example validator interest rates over time, neglecting transaction fees, segmented by fraction of total circulating supply bonded as stake.
![](../../../.gitbook/assets/p_ex_interest.png)
**Figure 3:** Shown here are example validator interest rates over time, neglecting transaction fees, segmented by fraction of total circulating supply bonded as stake.
This epoch-specific protocol-defined interest rate sets an upper limit of _protocol-generated_ annual interest rate \(not absolute total interest rate\) possible to be delivered to any validator-client per epoch. The distributed interest rate per epoch is then discounted from this value based on the participation of the validator-client during the previous epoch. This epoch-specific protocol-defined interest rate sets an upper limit of _protocol-generated_ annual interest rate \(not absolute total interest rate\) possible to be delivered to any validator-client per epoch. The distributed interest rate per epoch is then discounted from this value based on the participation of the validator-client during the previous epoch.

View File

@@ -11,8 +11,8 @@ Each transaction sent through the network, to be processed by the current leader
Many current blockchain economies \(e.g. Bitcoin, Ethereum\), rely on protocol-based rewards to support the economy in the short term, with the assumption that the revenue generated through transaction fees will support the economy in the long term, when the protocol derived rewards expire. In an attempt to create a sustainable economy through protocol-based rewards and transaction fees, a fixed portion of each transaction fee is destroyed, with the remaining fee going to the current leader processing the transaction. A scheduled global inflation rate provides a source for rewards distributed to validation-clients, through the process described above, and replication-clients, as discussed below. Many current blockchain economies \(e.g. Bitcoin, Ethereum\), rely on protocol-based rewards to support the economy in the short term, with the assumption that the revenue generated through transaction fees will support the economy in the long term, when the protocol derived rewards expire. In an attempt to create a sustainable economy through protocol-based rewards and transaction fees, a fixed portion of each transaction fee is destroyed, with the remaining fee going to the current leader processing the transaction. A scheduled global inflation rate provides a source for rewards distributed to validation-clients, through the process described above, and replication-clients, as discussed below.
Transaction fees are set by the network cluster based on recent historical throughput, see [Congestion Driven Fees](../../transaction-fees.md#congestion-driven-fees). This minimum portion of each transaction fee can be dynamically adjusted depending on historical gas usage. In this way, the protocol can use the minimum fee to target a desired hardware utilization. By monitoring a protocol specified gas usage with respect to a desired, target usage amount, the minimum fee can be raised/lowered which should, in turn, lower/raise the actual gas usage per block until it reaches the target amount. This adjustment process can be thought of as similar to the difficulty adjustment algorithm in the Bitcoin protocol, however in this case it is adjusting the minimum transaction fee to guide the transaction processing hardware usage to a desired level. Transaction fees are set by the network cluster based on recent historical throughput, see [Congestion Driven Fees](../../transaction-fees.md#congestion-driven-fees). This minimum portion of each transaction fee can be dynamically adjusted depending on historical gas usage. In this way, the protocol can use the minimum fee to target a desired hardware utilisation. By monitoring a protocol specified gas usage with respect to a desired, target usage amount, the minimum fee can be raised/lowered which should, in turn, lower/raise the actual gas usage per block until it reaches the target amount. This adjustment process can be thought of as similar to the difficulty adjustment algorithm in the Bitcoin protocol, however in this case it is adjusting the minimum transaction fee to guide the transaction processing hardware usage to a desired level.
As mentioned, a fixed-proportion of each transaction fee is to be destroyed. The intent of this design is to retain leader incentive to include as many transactions as possible within the leader-slot time, while providing an inflation limiting mechanism that protects against "tax evasion" attacks \(i.e. side-channel fee payments\)[1](../ed_references.md). As mentioned, a fixed-proportion of each transaction fee is to be destroyed. The intent of this design is to retain leader incentive to include as many transactions as possible within the leader-slot time, while providing an inflation limiting mechansim that protects against "tax evasion" attacks \(i.e. side-channel fee payments\)[1](../ed_references.md).
Additionally, the burnt fees can be a consideration in fork selection. In the case of a PoH fork with a malicious, censoring leader, we would expect the total fees destroyed to be less than a comparable honest fork, due to the fees lost from censoring. If the censoring leader is to compensate for these lost protocol fees, they would have to replace the burnt fees on their fork themselves, thus potentially reducing the incentive to censor in the first place. Additionally, the burnt fees can be a consideration in fork selection. In the case of a PoH fork with a malicious, censoring leader, we would expect the total fees destroyed to be less than a comparable honest fork, due to the fees lost from censoring. If the censoring leader is to compensate for these lost protocol fees, they would have to replace the burnt fees on their fork themselves, thus potentially reducing the incentive to censor in the first place.

View File

@@ -11,7 +11,7 @@ This document proposes an easy to use software install and updater that can be u
The easiest install method for supported platforms: The easiest install method for supported platforms:
```bash ```bash
$ curl -sSf https://raw.githubusercontent.com/solana-labs/solana/v1.0.0/install/solana-install-init.sh | sh $ curl -sSf https://raw.githubusercontent.com/solana-labs/solana/v0.18.0/install/solana-install-init.sh | sh
``` ```
This script will check github for the latest tagged release and download and run the `solana-install-init` binary from there. This script will check github for the latest tagged release and download and run the `solana-install-init` binary from there.
@@ -20,7 +20,7 @@ If additional arguments need to be specified during the installation, the follow
```bash ```bash
$ init_args=.... # arguments for `solana-install-init ...` $ init_args=.... # arguments for `solana-install-init ...`
$ curl -sSf https://raw.githubusercontent.com/solana-labs/solana/v1.0.0/install/solana-install-init.sh | sh -s - ${init_args} $ curl -sSf https://raw.githubusercontent.com/solana-labs/solana/v0.18.0/install/solana-install-init.sh | sh -s - ${init_args}
``` ```
### Fetch and run a pre-built installer from a Github release ### Fetch and run a pre-built installer from a Github release
@@ -28,7 +28,7 @@ $ curl -sSf https://raw.githubusercontent.com/solana-labs/solana/v1.0.0/install/
With a well-known release URL, a pre-built binary can be obtained for supported platforms: With a well-known release URL, a pre-built binary can be obtained for supported platforms:
```bash ```bash
$ curl -o solana-install-init https://github.com/solana-labs/solana/releases/download/v1.0.0/solana-install-init-x86_64-apple-darwin $ curl -o solana-install-init https://github.com/solana-labs/solana/releases/download/v0.18.0/solana-install-init-x86_64-apple-darwin
$ chmod +x ./solana-install-init $ chmod +x ./solana-install-init
$ ./solana-install-init --help $ ./solana-install-init --help
``` ```
@@ -77,7 +77,7 @@ pub struct UpdateManifest {
pub download_sha256: String, // SHA256 digest of the release tar.bz2 file pub download_sha256: String, // SHA256 digest of the release tar.bz2 file
} }
/// Data of an Update Manifest program Account. /// Userdata of an Update Manifest program Account.
#[derive(Serialize, Deserialize, Default, Debug, PartialEq)] #[derive(Serialize, Deserialize, Default, Debug, PartialEq)]
pub struct SignedUpdateManifest { pub struct SignedUpdateManifest {
pub manifest: UpdateManifest, pub manifest: UpdateManifest,
@@ -154,7 +154,7 @@ FLAGS:
OPTIONS: OPTIONS:
-d, --data_dir <PATH> Directory to store install data [default: .../Library/Application Support/solana] -d, --data_dir <PATH> Directory to store install data [default: .../Library/Application Support/solana]
-u, --url <URL> JSON RPC URL for the solana cluster [default: http://devnet.solana.com] -u, --url <URL> JSON RPC URL for the solana cluster [default: http://devnet.solana.com:8899]
-p, --pubkey <PUBKEY> Public key of the update manifest [default: 9XX329sPuskWhH4DQh6k16c87dHKhXLBZTL3Gxmve8Gp] -p, --pubkey <PUBKEY> Public key of the update manifest [default: 9XX329sPuskWhH4DQh6k16c87dHKhXLBZTL3Gxmve8Gp]
``` ```

View File

@@ -0,0 +1,49 @@
# Repair Service
## Repair Service
The RepairService is in charge of retrieving missing shreds that failed to be delivered by primary communication protocols like Avalanche. It is in charge of managing the protocols described below in the `Repair Protocols` section below.
## Challenges:
1\) Validators can fail to receive particular shreds due to network failures
2\) Consider a scenario where blockstore contains the set of slots {1, 3, 5}. Then Blockstore receives shreds for some slot 7, where for each of the shreds b, b.parent == 6, so then the parent-child relation 6 -&gt; 7 is stored in blockstore. However, there is no way to chain these slots to any of the existing banks in Blockstore, and thus the `Shred Repair` protocol will not repair these slots. If these slots happen to be part of the main chain, this will halt replay progress on this node.
3\) Validators that find themselves behind the cluster by an entire epoch struggle/fail to catch up because they do not have a leader schedule for future epochs. If nodes were to blindly accept repair shreds in these future epochs, this exposes nodes to spam.
## Repair Protocols
The repair protocol makes best attempts to progress the forking structure of Blockstore.
The different protocol strategies to address the above challenges:
1. Shred Repair \(Addresses Challenge \#1\): This is the most basic repair protocol, with the purpose of detecting and filling "holes" in the ledger. Blockstore tracks the latest root slot. RepairService will then periodically iterate every fork in blockstore starting from the root slot, sending repair requests to validators for any missing shreds. It will send at most some `N` repair reqeusts per iteration.
Note: Validators will only accept shreds within the current verifiable epoch \(epoch the validator has a leader schedule for\).
2. Preemptive Slot Repair \(Addresses Challenge \#2\): The goal of this protocol is to discover the chaining relationship of "orphan" slots that do not currently chain to any known fork.
* Blockstore will track the set of "orphan" slots in a separate column family.
* RepairService will periodically make `RequestOrphan` requests for each of the orphans in blockstore.
`RequestOrphan(orphan)` request - `orphan` is the orphan slot that the requestor wants to know the parents of `RequestOrphan(orphan)` response - The highest shreds for each of the first `N` parents of the requested `orphan`
On receiving the responses `p`, where `p` is some shred in a parent slot, validators will:
* Insert an empty `SlotMeta` in blockstore for `p.slot` if it doesn't already exist.
* If `p.slot` does exist, update the parent of `p` based on `parents`
Note: that once these empty slots are added to blockstore, the `Shred Repair` protocol should attempt to fill those slots.
Note: Validators will only accept responses containing shreds within the current verifiable epoch \(epoch the validator has a leader schedule for\).
3. Repairmen \(Addresses Challenge \#3\): This part of the repair protocol is the primary mechanism by which new nodes joining the cluster catch up after loading a snapshot. This protocol works in a "forward" fashion, so validators can verify every shred that they receive against a known leader schedule.
Each validator advertises in gossip:
* Current root
* The set of all completed slots in the confirmed epochs \(an epoch that was calculated based on a bank &lt;= current root\) past the current root
Observers of this gossip message with higher epochs \(repairmen\) send shreds to catch the lagging node up with the rest of the cluster. The repairmen are responsible for sending the slots within the epochs that are confrimed by the advertised `root` in gossip. The repairmen divide the responsibility of sending each of the missing slots in these epochs based on a random seed \(simple shred.index iteration by N, seeded with the repairman's node\_pubkey\). Ideally, each repairman in an N node cluster \(N nodes whose epochs are higher than that of the repairee\) sends 1/N of the missing shreds. Both data and coding shreds for missing slots are sent. Repairmen do not send shreds again to the same validator until they see the message in gossip updated, at which point they perform another iteration of this protocol.
Gossip messages are updated every time a validator receives a complete slot within the epoch. Completed slots are detected by blockstore and sent over a channel to RepairService. It is important to note that we know that by the time a slot X is complete, the epoch schedule must exist for the epoch that contains slot X because WindowService will reject shreds for unconfirmed epochs. When a newly completed slot is detected, we also update the current root if it has changed since the last update. The root is made available to RepairService through Blockstore, which holds the latest root.

37
book/src/introduction.md Normal file
View File

@@ -0,0 +1,37 @@
# Introduction
## What is Solana?
Solana is an open source project implementing a new, high-performance, permissionless blockchain. Solana is also the name of a company headquartered in San Francisco that maintains the open source project.
## About this Book
This book describes the Solana open source project, a blockchain built from the ground up for scale. The book covers why Solana is useful, how to use it, how it works, and why it will continue to work long after the company Solana closes its doors. The goal of the Solana architecture is to demonstrate there exists a set of software algorithms that when used in combination to implement a blockchain, removes software as a performance bottleneck, allowing transaction throughput to scale proportionally with network bandwidth. The architecture goes on to satisfy all three desirable properties of a proper blockchain: it is scalable, secure and decentralized.
The architecture describes a theoretical upper bound of 710 thousand transactions per second \(tps\) on a standard gigabit network and 28.4 million tps on 40 gigabit. Furthermore, the architecture supports safe, concurrent execution of programs authored in general purpose programming languages such as C or Rust.
## Disclaimer
All claims, content, designs, algorithms, estimates, roadmaps, specifications, and performance measurements described in this project are done with the author's best effort. It is up to the reader to check and validate their accuracy and truthfulness. Furthermore, nothing in this project constitutes a solicitation for investment.
## History of the Solana Codebase
In November of 2017, Anatoly Yakovenko published a whitepaper describing Proof of History, a technique for keeping time between computers that do not trust one another. From Anatoly's previous experience designing distributed systems at Qualcomm, Mesosphere and Dropbox, he knew that a reliable clock makes network synchronization very simple. When synchronization is simple the resulting network can be blazing fast, bound only by network bandwidth.
Anatoly watched as blockchain systems without clocks, such as Bitcoin and Ethereum, struggled to scale beyond 15 transactions per second worldwide when centralized payment systems such as Visa required peaks of 65,000 tps. Without a clock, it was clear they'd never graduate to being the global payment system or global supercomputer most had dreamed them to be. When Anatoly solved the problem of getting computers that dont trust each other to agree on time, he knew he had the key to bring 40 years of distributed systems research to the world of blockchain. The resulting cluster wouldn't be just 10 times faster, or a 100 times, or a 1,000 times, but 10,000 times faster, right out of the gate!
Anatoly's implementation began in a private codebase and was implemented in the C programming language. Greg Fitzgerald, who had previously worked with Anatoly at semiconductor giant Qualcomm Incorporated, encouraged him to reimplement the project in the Rust programming language. Greg had worked on the LLVM compiler infrastructure, which underlies both the Clang C/C++ compiler as well as the Rust compiler. Greg claimed that the language's safety guarantees would improve software productivity and that its lack of a garbage collector would allow programs to perform as well as those written in C. Anatoly gave it a shot and just two weeks later, had migrated his entire codebase to Rust. Sold. With plans to weave all the world's transactions together on a single, scalable blockchain, Anatoly called the project Loom.
On February 13th of 2018, Greg began prototyping the first open source implementation of Anatoly's whitepaper. The project was published to GitHub under the name Silk in the loomprotocol organization. On February 28th, Greg made his first release, demonstrating 10 thousand signed transactions could be verified and processed in just over half a second. Shortly after, another former Qualcomm cohort, Stephen Akridge, demonstrated throughput could be massively improved by offloading signature verification to graphics processors. Anatoly recruited Greg, Stephen and three others to co-found a company, then called Loom.
Around the same time, Ethereum-based project Loom Network sprung up and many people were confused about whether they were the same project. The Loom team decided it would rebrand. They chose the name Solana, a nod to a small beach town North of San Diego called Solana Beach, where Anatoly, Greg and Stephen lived and surfed for three years when they worked for Qualcomm. On March 28th, the team created the Solana Labs GitHub organization and renamed Greg's prototype Silk to Solana.
In June of 2018, the team scaled up the technology to run on cloud-based networks and on July 19th, published a 50-node, permissioned, public testnet consistently supporting bursts of 250,000 transactions per second. In a later release in December, called v0.10 Pillbox, the team published a permissioned testnet running 150 nodes on a gigabit network and demonstrated soak tests processing an _average_ of 200 thousand transactions per second with bursts over 500 thousand. The project was also extended to support on-chain programs written in the C programming language and run concurrently in a safe execution environment called BPF.
## What is a Solana Cluster?
A cluster is a set of computers that work together and can be viewed from the outside as a single system. A Solana cluster is a set of independently owned computers working together \(and sometimes against each other\) to verify the output of untrusted, user-submitted programs. A Solana cluster can be utilized any time a user wants to preserve an immutable record of events in time or programmatic interpretations of those events. One use is to track which of the computers did meaningful work to keep the cluster running. Another use might be to track the possession of real-world assets. In each case, the cluster produces a record of events called the ledger. It will be preserved for the lifetime of the cluster. As long as someone somewhere in the world maintains a copy of the ledger, the output of its programs \(which may contain a record of who possesses what\) will forever be reproducible, independent of the organization that launched it.
## What are SOLs?
A SOL is the name of Solana's native token, which can be passed to nodes in a Solana cluster in exchange for running an on-chain program or validating its output. The system may perform micropayments of fractional SOLs, which are called _lamports_. They are named in honor of Solana's biggest technical influence, [Leslie Lamport](https://en.wikipedia.org/wiki/Leslie_Lamport). A lamport has a value of 0.000000001 SOL.

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