Compare commits

..

43 Commits

Author SHA1 Message Date
mergify[bot]
08569c81e9 getVoteAccounts RPC API no longer returns "idle" vote accounts (#7339) (#7341)
automerge
2019-12-06 18:13:46 -08:00
mergify[bot]
3ba89f8363 Add more pool tokens (#7338) (#7340)
automerge

(cherry picked from commit 8a908a6864)
2019-12-06 18:04:26 -07:00
mergify[bot]
9161dbc08e Fix typo (#7336) (#7337)
(cherry picked from commit 2d6ed7142f)
2019-12-06 16:50:33 -07:00
mergify[bot]
a1b2fa295a cli: Confirm recovered pubkeys (#7316) (#7321)
automerge
2019-12-06 13:34:32 -08:00
mergify[bot]
4f33eaa9dd Increase signature confirmation timeout to fix wallet sanity (#7283) (#7332)
automerge
2019-12-06 13:29:33 -08:00
Michael Vines
3718bab078 Add spare validator accounts (#7330)
automerge
2019-12-06 11:55:24 -08:00
Rob Walker
dfc48705a4 more genesis (#7291) 2019-12-06 10:50:26 -07:00
Rob Walker
f59115b503 bs58 (#7252) 2019-12-06 10:49:14 -07:00
Michael Vines
cac467118e Update name 2019-12-06 10:15:51 -07:00
Greg Fitzgerald
d0718075a7 Add pools (#7324) 2019-12-06 09:27:00 -07:00
Justin Starry
ad55cc79b3 Add verify of keypair (#7301) (#7322)
automerge
2019-12-06 08:26:33 -08:00
Michael Vines
5111cc10ca Add ChainFlow ValidatorInfo 2019-12-06 09:23:20 -07:00
mergify[bot]
a1736606dc Fail fast if account paths cannot be canonicalized (#7300) (#7315)
automerge
2019-12-05 19:45:39 -08:00
Justin Starry
bae659b9c7 Add docs for using a paper wallet with solana cli (#7311) (#7317)
automerge
2019-12-05 19:38:18 -08:00
mergify[bot]
c480c2225d Add RockX ValidatorInfo (#7310) (#7312)
automerge
2019-12-05 18:55:29 -08:00
mergify[bot]
52771c472e Add ChorusOne ValidatorInfo (#7306) (#7308)
automerge
2019-12-05 15:31:12 -08:00
mergify[bot]
5ce21827c8 Only serialize rooted append vecs (#7281) (#7307)
automerge
2019-12-05 15:02:55 -08:00
mergify[bot]
a2c4a70fbf Canonicalize paths before symlink-ing when generating snapshots (#7294) (#7299)
automerge
2019-12-05 12:34:42 -08:00
mergify[bot]
d6e5f78834 custodian signs withdraw (#7286) (#7290)
automerge
2019-12-04 21:57:47 -08:00
mergify[bot]
74eb408460 vote update node_id (#7253) (#7285)
automerge
2019-12-04 18:24:00 -08:00
mergify[bot]
a4c6576ba4 Import validators (#7282) (#7284)
automerge
2019-12-04 18:02:00 -08:00
mergify[bot]
1fcc391a8d Fix typo, grammar, and formatting in Paper Wallet documentation (#7268) (#7271)
automerge
2019-12-04 13:19:16 -08:00
mergify[bot]
2970f960a4 Sanitize whitespace in seed phrase input (#7260) (#7267)
automerge
2019-12-04 12:32:28 -08:00
Rob Walker
d06bea7fb2 genesis validators (#7235) (#7256)
* genesis validators (#7235)

* genesis validators

* slp1 nodes get 500SOL

* no commission

* clippy
2019-12-04 11:34:21 -08:00
mergify[bot]
45a57e8513 Use wrappable code snippet for paper wallet installation (#7261) (#7262)
automerge
2019-12-04 09:33:49 -08:00
mergify[bot]
3622e513aa make tx fee's burn percent in proper range (#7226) (#7228)
automerge
2019-12-04 03:11:25 -08:00
mergify[bot]
c4e1faa853 genesis config hashmaps (#7107) (#7255)
automerge
2019-12-03 23:44:24 -08:00
mergify[bot]
905428bee6 Allow generation of longer seed phrases with keygen (#7210) (#7249)
automerge
2019-12-03 21:56:06 -08:00
mergify[bot]
9596e7772c commission as percent (#7239) (#7251)
automerge
2019-12-03 21:42:01 -08:00
mergify[bot]
5294fe6292 Remove extra installation options for paper wallet (#7245) (#7247)
automerge
2019-12-03 20:12:57 -08:00
Justin Starry
571cf53827 Add Paper Wallet Installation page to sidebar (#7242) (#7243) 2019-12-03 22:13:20 -05:00
Justin Starry
35ae76532a Use procedural macro to generate static public keys (bp #7219) (#7241)
automerge
2019-12-03 19:07:19 -08:00
mergify[bot]
57dce86d5e Update paper wallet documentation (#7223) (#7237)
automerge
2019-12-03 17:32:55 -08:00
mergify[bot]
797cb01bb8 enforce proper range for rent burn_percent (#7217) (#7224)
automerge
2019-12-03 11:59:16 -08:00
mergify[bot]
9eded7a227 Prevent passphrase mistakes with confirmation prompt (#7207) (#7211)
(cherry picked from commit b874441a47)
2019-12-03 11:48:13 -07:00
mergify[bot]
a8d32103d1 Ensure IpEchoServerMessage is not fragmented (#7214) (#7215)
automerge
2019-12-02 23:00:56 -08:00
mergify[bot]
49d4925856 Fix typo (#7202) (#7205)
automerge
2019-12-02 19:26:42 -08:00
mergify[bot]
f5fad5b43d Correctly parse ip echo server response and fix broken test (#7196) (#7200)
automerge
2019-12-02 18:11:10 -08:00
mergify[bot]
4c40f9dbc9 Drop default signature fee by 10x (#7192) (#7193)
automerge
2019-12-02 14:17:37 -08:00
mergify[bot]
17db734783 Improve error handling when the user mixes up gossip (8001) and RPC (8899) ports (#7158) (#7184)
automerge
2019-12-02 11:52:57 -08:00
mergify[bot]
6ce9f97254 More conservative purge_zero_lamport_accounts purge logic (#7157) (#7190)
automerge
2019-12-02 11:46:46 -08:00
mergify[bot]
1688dd6b5c Add Paper Wallet documentation to the book (#7147) (#7161)
automerge
2019-11-26 21:11:18 -08:00
Dan Albert
07ffcab857 Update cargo.toml file versions to 0.21.1 (#7156) 2019-11-26 19:11:07 -05:00
134 changed files with 2999 additions and 1692 deletions

600
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

@@ -2,7 +2,7 @@
authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-bench-exchange"
version = "0.21.0"
version = "0.21.1"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -23,19 +23,19 @@ serde = "1.0.102"
serde_derive = "1.0.102"
serde_json = "1.0.41"
serde_yaml = "0.8.11"
solana-clap-utils = { path = "../clap-utils", version = "0.21.0" }
solana-core = { path = "../core", version = "0.21.0" }
solana-genesis = { path = "../genesis", version = "0.21.0" }
solana-client = { path = "../client", version = "0.21.0" }
solana-drone = { path = "../drone", version = "0.21.0" }
solana-exchange-program = { path = "../programs/exchange", version = "0.21.0" }
solana-logger = { path = "../logger", version = "0.21.0" }
solana-metrics = { path = "../metrics", version = "0.21.0" }
solana-net-utils = { path = "../net-utils", version = "0.21.0" }
solana-runtime = { path = "../runtime", version = "0.21.0" }
solana-sdk = { path = "../sdk", version = "0.21.0" }
solana-clap-utils = { path = "../clap-utils", version = "0.21.1" }
solana-core = { path = "../core", version = "0.21.1" }
solana-genesis = { path = "../genesis", version = "0.21.1" }
solana-client = { path = "../client", version = "0.21.1" }
solana-drone = { path = "../drone", version = "0.21.1" }
solana-exchange-program = { path = "../programs/exchange", version = "0.21.1" }
solana-logger = { path = "../logger", version = "0.21.1" }
solana-metrics = { path = "../metrics", version = "0.21.1" }
solana-net-utils = { path = "../net-utils", version = "0.21.1" }
solana-runtime = { path = "../runtime", version = "0.21.1" }
solana-sdk = { path = "../sdk", version = "0.21.1" }
untrusted = "0.7.0"
ws = "0.9.1"
[dev-dependencies]
solana-local-cluster = { path = "../local-cluster", version = "0.21.0" }
solana-local-cluster = { path = "../local-cluster", version = "0.21.1" }

View File

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

View File

@@ -2,7 +2,7 @@
authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-bench-tps"
version = "0.21.0"
version = "0.21.1"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -16,24 +16,24 @@ serde = "1.0.102"
serde_derive = "1.0.102"
serde_json = "1.0.41"
serde_yaml = "0.8.11"
solana-clap-utils = { path = "../clap-utils", version = "0.21.0" }
solana-core = { path = "../core", version = "0.21.0" }
solana-genesis = { path = "../genesis", version = "0.21.0" }
solana-client = { path = "../client", version = "0.21.0" }
solana-drone = { path = "../drone", version = "0.21.0" }
solana-librapay-api = { path = "../programs/librapay_api", version = "0.21.0", optional = true }
solana-logger = { path = "../logger", version = "0.21.0" }
solana-metrics = { path = "../metrics", version = "0.21.0" }
solana-measure = { path = "../measure", version = "0.21.0" }
solana-net-utils = { path = "../net-utils", version = "0.21.0" }
solana-runtime = { path = "../runtime", version = "0.21.0" }
solana-sdk = { path = "../sdk", version = "0.21.0" }
solana-move-loader-program = { path = "../programs/move_loader", version = "0.21.0", optional = true }
solana-clap-utils = { path = "../clap-utils", version = "0.21.1" }
solana-core = { path = "../core", version = "0.21.1" }
solana-genesis = { path = "../genesis", version = "0.21.1" }
solana-client = { path = "../client", version = "0.21.1" }
solana-drone = { path = "../drone", version = "0.21.1" }
solana-librapay-api = { path = "../programs/librapay_api", version = "0.21.1", optional = true }
solana-logger = { path = "../logger", version = "0.21.1" }
solana-metrics = { path = "../metrics", version = "0.21.1" }
solana-measure = { path = "../measure", version = "0.21.1" }
solana-net-utils = { path = "../net-utils", version = "0.21.1" }
solana-runtime = { path = "../runtime", version = "0.21.1" }
solana-sdk = { path = "../sdk", version = "0.21.1" }
solana-move-loader-program = { path = "../programs/move_loader", version = "0.21.1", optional = true }
[dev-dependencies]
serial_test = "0.2.0"
serial_test_derive = "0.2.0"
solana-local-cluster = { path = "../local-cluster", version = "0.21.0" }
solana-local-cluster = { path = "../local-cluster", version = "0.21.1" }
[features]
move = ["solana-librapay-api", "solana-move-loader-program"]

View File

@@ -36,6 +36,10 @@
* [Troubleshooting](running-validator/validator-troubleshoot.md)
* [FAQ](running-validator/validator-faq.md)
* [Running an Archiver](running-archiver.md)
* [Paper Wallet](paper-wallet/README.md)
* [Installation](paper-wallet/installation.md)
* [Creating and Using a Seed Phrase](paper-wallet/keypair.md)
* [Paper Wallet Usage](paper-wallet/usage.md)
* [API Reference](api-reference/README.md)
* [Transaction](api-reference/transaction-api.md)
* [Instruction](api-reference/instruction-api.md)

View File

@@ -177,7 +177,7 @@ $ solana send-timestamp <PUBKEY> <PROCESS_ID> --date 2018-12-24T23:59:00
## Usage
### solana-cli
```text
solana-cli 0.21.0
solana-cli 0.21.1
Blockchain, Rebuilt for Scale
USAGE:
@@ -398,8 +398,8 @@ OPTIONS:
-k, --keypair <PATH> /path/to/id.json
ARGS:
<STORAGE ACCOUNT OWNER PUBKEY>
<STORAGE ACCOUNT PUBKEY>
<STORAGE ACCOUNT OWNER PUBKEY>
<STORAGE ACCOUNT PUBKEY>
```
#### solana-create-stake-account
@@ -448,8 +448,8 @@ OPTIONS:
-k, --keypair <PATH> /path/to/id.json
ARGS:
<STORAGE ACCOUNT OWNER PUBKEY>
<STORAGE ACCOUNT PUBKEY>
<STORAGE ACCOUNT OWNER PUBKEY>
<STORAGE ACCOUNT PUBKEY>
```
#### solana-create-vote-account
@@ -467,7 +467,7 @@ FLAGS:
OPTIONS:
--authorized-voter <PUBKEY> Public key of the authorized voter (defaults to vote account)
--authorized-withdrawer <PUBKEY> Public key of the authorized withdrawer (defaults to cli config pubkey)
--commission <NUM> The commission taken on reward redemption (0-255), default: 0
--commission <NUM> The commission taken on reward redemption (0-100), default: 0
-C, --config <PATH> Configuration file to use [default:
~/.config/solana/cli/config.yml]
-u, --url <URL> JSON RPC URL for the solana cluster
@@ -674,7 +674,7 @@ USAGE:
solana pay [FLAGS] [OPTIONS] <PUBKEY> <AMOUNT> [--] [UNIT]
FLAGS:
--cancelable
--cancelable
-h, --help Prints help information
-V, --version Prints version information

View File

@@ -156,7 +156,7 @@ The result value will be an RpcResponse JSON object containing an AccountInfo JS
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0", "id":1, "method":"getAccountInfo", "params":["2gVkYWexTHR5Hb2aLeQN3tnngvWzisFKXDUPrgMHpdST"]}' http://localhost:8899
// Result
{"jsonrpc":"2.0","result":{"context":{"slot":1},"value":{"executable":false,"owner":[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"lamports":1,"data":[3,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0.21.0,0,0,0,0,0,0,50,48,53,48,45,48,49,45,48,49,84,48,48,58,48,48,58,48,48,90,252,10,7,28,246,140,88,177,98,82,10,227,89,81,18,30,194,101,199,16,11,73,133,20,246,62,114,39,20,113,189,32,50,0,0,0,0,0,0,0,247,15,36,102,167,83,225,42,133,127,82,34,36,224,207,130,109,230,224,188,163,33,213,13,5,117,211,251,65,159,197,51,0,0,0,0,0,0]}},"id":1}
{"jsonrpc":"2.0","result":{"context":{"slot":1},"value":{"executable":false,"owner":[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"lamports":1,"data":[3,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0.21.1,0,0,0,0,0,0,50,48,53,48,45,48,49,45,48,49,84,48,48,58,48,48,58,48,48,90,252,10,7,28,246,140,88,177,98,82,10,227,89,81,18,30,194,101,199,16,11,73,133,20,246,62,114,39,20,113,189,32,50,0,0,0,0,0,0,0,247,15,36,102,167,83,225,42,133,127,82,34,36,224,207,130,109,230,224,188,163,33,213,13,5,117,211,251,65,159,197,51,0,0,0,0,0,0]}},"id":1}
```
### getBalance
@@ -713,7 +713,7 @@ The result field will be a JSON object of `current` and `delinquent` accounts, e
* `nodePubkey` - Node public key, as base-58 encoded string
* `activatedStake` - the stake, in lamports, delegated to this vote account and active in this epoch
* `epochVoteAccount` - bool, whether the vote account is staked for this epoch
* `commission`, an 8-bit integer used as a fraction \(commission/MAX\_U8\) for rewards payout
* `commission`, percentage (0-100) of rewards payout owed to the vote account
* `lastVote` - Most recent slot voted on by this vote account
#### Example:
@@ -824,7 +824,7 @@ Subscribe to an account to receive notifications when the lamports or data for a
#### Notification Format:
```bash
{"jsonrpc": "2.0","method": "accountNotification", "params": {"result": {"executable":false,"owner":[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"lamports":1,"data":[3,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0.21.0,0,0,0,0,0,0,50,48,53,48,45,48,49,45,48,49,84,48,48,58,48,48,58,48,48,90,252,10,7,28,246,140,88,177,98,82,10,227,89,81,18,30,194,101,199,16,11,73,133,20,246,62,114,39,20,113,189,32,50,0,0,0,0,0,0,0,247,15,36,102,167,83,225,42,133,127,82,34,36,224,207,130,109,230,224,188,163,33,213,13,5,117,211,251,65,159,197,51,0,0,0,0,0,0]},"subscription":0}}
{"jsonrpc": "2.0","method": "accountNotification", "params": {"result": {"executable":false,"owner":[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"lamports":1,"data":[3,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0.21.1,0,0,0,0,0,0,50,48,53,48,45,48,49,45,48,49,84,48,48,58,48,48,58,48,48,90,252,10,7,28,246,140,88,177,98,82,10,227,89,81,18,30,194,101,199,16,11,73,133,20,246,62,114,39,20,113,189,32,50,0,0,0,0,0,0,0,247,15,36,102,167,83,225,42,133,127,82,34,36,224,207,130,109,230,224,188,163,33,213,13,5,117,211,251,65,159,197,51,0,0,0,0,0,0]},"subscription":0}}
```
### accountUnsubscribe
@@ -882,7 +882,7 @@ Subscribe to a program to receive notifications when the lamports or data for a
* `object` - account info JSON object \(see [getAccountInfo](jsonrpc-api.md#getaccountinfo) for field details\)
```bash
{"jsonrpc":"2.0","method":"programNotification","params":{{"result":["8Rshv2oMkPu5E4opXTRyuyBeZBqQ4S477VG26wUTFxUM",{"executable":false,"lamports":1,"owner":[129,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"data":[1,1,1,0,0,0,0,0,0,0.21.0,0,0,0,0,0,0,50,48,49,56,45,49,50,45,50,52,84,50,51,58,53,57,58,48,48,90,235,233,39,152,15,44,117,176,41,89,100,86,45,61,2,44,251,46,212,37,35,118,163,189,247,84,27,235,178,62,55,89,0,0,0,0,50,0,0,0,0,0,0,0,235,233,39,152,15,44,117,176,41,89,100,86,45,61,2,44,251,46,212,37,35,118,163,189,247,84,27,235,178,62,45,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}],"subscription":0}}
{"jsonrpc":"2.0","method":"programNotification","params":{{"result":["8Rshv2oMkPu5E4opXTRyuyBeZBqQ4S477VG26wUTFxUM",{"executable":false,"lamports":1,"owner":[129,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"data":[1,1,1,0,0,0,0,0,0,0.21.1,0,0,0,0,0,0,50,48,49,56,45,49,50,45,50,52,84,50,51,58,53,57,58,48,48,90,235,233,39,152,15,44,117,176,41,89,100,86,45,61,2,44,251,46,212,37,35,118,163,189,247,84,27,235,178,62,55,89,0,0,0,0,50,0,0,0,0,0,0,0,235,233,39,152,15,44,117,176,41,89,100,86,45,61,2,44,251,46,212,37,35,118,163,189,247,84,27,235,178,62,45,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}],"subscription":0}}
```
### programUnsubscribe

View File

@@ -16,7 +16,7 @@ The total stake allocated to a Vote account can be calculated by the sum of all
## Vote and Stake accounts
The rewards process is split into two on-chain programs. The Vote program solves the problem of making stakes slashable. The Stake account acts as custodian of the rewards pool, and provides passive delegation. The Stake program is responsible for paying out each staker once the staker proves to the Stake program that its delegate has participated in validating the ledger.
The rewards process is split into two on-chain programs. The Vote program solves the problem of making stakes slashable. The Stake program acts as custodian of the rewards pool and provides for passive delegation. The Stake program is responsible for paying rewards to staker and voter when shown that a staker's delegate has participated in validating the ledger.
### VoteState
@@ -228,4 +228,4 @@ Only lamports in excess of effective+activating stake may be withdrawn at any ti
### Lock-up
Stake accounts support the notion of lock-up, wherein the stake account balance is unavailable for withdrawal until a specified time. Lock-up is specified as a slot height, i.e. the minimum slot height that must be reached by the network before the stake account balance is available for withdrawal, except to a specified custodian. This information is gathered when the stake account is created.
Stake accounts support the notion of lock-up, wherein the stake account balance is unavailable for withdrawal until a specified time. Lock-up is specified as an epoch height, i.e. the minimum epoch height that must be reached by the network before the stake account balance is available for withdrawal, unless the transaction is also signed by a specified custodian. This information is gathered when the stake account is created, and stored in the Lockup field of the stake account's state.

View File

@@ -0,0 +1,24 @@
# Paper Wallet
This document describes how to create and use a paper wallet with the Solana CLI
tools.
{% hint style="info" %}
We do not intend to advise on how to *securely* create or manage paper wallets.
Please research the security concerns carefully.
{% endhint %}
## Overview
Solana provides a key generation tool to derive keys from BIP39 compliant seed
phrases. Solana CLI commands for running a validator and staking tokens all
support keypair input via seed phrases.
To learn more about the BIP39 standard, visit the Bitcoin BIPs Github repository
[here](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki).
{% page-ref page="installation.md" %}
{% page-ref page="keypair.md" %}
{% page-ref page="usage.md" %}

View File

@@ -0,0 +1,51 @@
# Installation Guide
Follow this guide to setup Solana's key generation tool called `solana-keygen`
{% hint style="warn" %}
After installation, ensure your version is `0.21.1` or higher by running `solana-keygen -V`
{% endhint %}
## Download
First, download the latest release tarball from GitHub.
1. Setup download url
```bash
solana_downloads=https://github.com/solana-labs/solana/releases/latest/download
```
2. Specify the download file based on your machine
**MacOS**
```bash
solana_release=solana-release-x86_64-apple-darwin.tar.bz2
```
**Linux**
```bash
solana_release=solana-release-x86_64-unknown-linux-gnu.tar.bz2
```
3. Download
```bash
curl -L -sSf -o solana-release.tar.bz2 $solana_downloads/$solana_release
```
## Extract
Next, extract the tarball
```bash
tar xf solana-release.tar.bz2
```
## Add to "PATH"
Now add the tool to your PATH environment variable with the following command
```bash
export PATH="$(pwd)/solana-release/bin:${PATH}"
```
## Check
Finally, check that `solana-keygen` can be run by running
```bash
solana-keygen -V
```

View File

@@ -0,0 +1,70 @@
# Creating a Paper Wallet
Using the `solana-keygen` tool, it is possible to generate new seed phrases as
well as derive a keypair from an existing seed phrase and (optional) passphrase.
The seed phrase and passphrase can be used together as a paper wallet. As long
as you keep your seed phrase and passphrase stored safely, you can use them to
access your account.
{% hint style="info" %}
For more information about how seed phrases work, review this
[Bitcoin Wiki page](https://en.bitcoin.it/wiki/Seed_phrase).
{% endhint %}
## Seed Phrase Generation
Generating a new keypair can be done using the `solana-keygen new` command. The
command will generate a random seed phrase, ask you to enter an optional
passphrase, and then will display the derived public key and the generated seed
phrase for your paper wallet.
```bash
solana-keygen new --no-outfile
```
{% hint style="warning" %}
If the `--no-outfile` flag is **omitted**, the default behavior is to write the
keypair to `~/.config/solana/id.json`
{% endhint %}
{% hint style="info" %}
For added security, increase the seed phrase word count using the `--word-count`
argument
{% endhint %}
For full usage details run:
```bash
solana-keygen new --help
```
## Public Key Derivation
Public keys can be derived from a seed phrase and a passphrase if you choose to
use one. This is useful for using using an offline-generated seed phrase to
derive a valid public key. The `solana-keygen pubkey` command will walk you
through entering your seed phrase and a passphrase if you chose to use one.
```bash
solana-keygen pubkey ASK
```
{% hint style="info" %}
Note that you could potentially use different passphrases for the same seed
phrase. Each unique passphrase will yield a different keypair.
{% endhint %}
The `solana-keygen` tool assumes the use of the BIP39 standard English word
list. If you chose to deviate from the word list or used a different language
for your seed phrase, you can still derive a valid public key but will need to
explicitly skip seed phrase validation.
```bash
solana-keygen pubkey ASK --skip-seed-phrase-validation
```
For full usage details run:
```bash
solana-keygen pubkey --help
```

View File

@@ -0,0 +1,73 @@
# Paper Wallet Usage
Solana commands can be run without ever saving a keypair to disk on a machine.
If avoiding writing a private key to disk is a security concern of yours, you've
come to the right place.
{% hint style="warning" %}
Even using this secure input method, it's still possible that a private key gets
written to disk by unencrypted memory swaps. It is the user's responsibility to
protect against this scenario.
{% endhint %}
## Running a Validator
In order to run a validator, you will need to specify an "identity keypair"
which will be used to fund all of the vote transactions signed by your validator.
Rather than specifying a path with `--identity-keypair <PATH>` you can use the
`--ask-seed-phrase` option.
```bash
solana-validator --ask-seed-phrase identity-keypair --ledger ...
[identity-keypair] seed phrase: 🔒
[identity-keypair] If this seed phrase has an associated passphrase, enter it now. Otherwise, press ENTER to continue:
```
The `--ask-seed-phrase` option accepts multiple keypairs. If you wish to use this
input method for your voting keypair as well you can do the following:
```bash
solana-validator --ask-seed-phrase identity-keypair voting-keypair --ledger ...
[identity-keypair] seed phrase: 🔒
[identity-keypair] If this seed phrase has an associated passphrase, enter it now. Otherwise, press ENTER to continue:
[voting-keypair] seed phrase: 🔒
[voting-keypair] If this seed phrase has an associated passphrase, enter it now. Otherwise, press ENTER to continue:
```
Refer to the following page for a comprehensive guide on running a validator:
{% page-ref page="../running-validator/README.md" %}
## Delegating Stake
Solana CLI tooling supports secure keypair input for stake delegation. To do so,
first create a stake account with some SOL. Use the special `ASK` keyword to
trigger a seed phrase input prompt for the stake account and use
`--ask-seed-phrase keypair` to securely input the funding keypair.
```bash
solana create-stake-account ASK 1 SOL --ask-seed-phrase keypair
[stake_account] seed phrase: 🔒
[stake_account] If this seed phrase has an associated passphrase, enter it now. Otherwise, press ENTER to continue:
[keypair] seed phrase: 🔒
[keypair] If this seed phrase has an associated passphrase, enter it now. Otherwise, press ENTER to continue:
```
Then, to delegate that stake to a validator, use `--ask-seed-phrase keypair` to
securely input the funding keypair.
```bash
solana delegate-stake --ask-seed-phrase keypair <STAKE_ACCOUNT_PUBKEY> <VOTE_ACCOUNT_PUBKEY>
[keypair] seed phrase: 🔒
[keypair] If this seed phrase has an associated passphrase, enter it now. Otherwise, press ENTER to continue:
```
Refer to the following page for a comprehensive guide on delegating stake:
{% page-ref page="../running-validator/validator-stake.md" %}
---
{% page-ref page="../api-reference/cli.md" %}

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-chacha-sys"
version = "0.21.0"
version = "0.21.1"
description = "Solana chacha-sys"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"

View File

@@ -86,17 +86,19 @@ nodes=(
--rpc-port 18899"
)
for i in $(seq 1 $extraNodes); do
portStart=$((8100 + i * 50))
portEnd=$((portStart + 49))
nodes+=(
"multinode-demo/validator.sh \
--no-restart \
--dynamic-port-range $portStart-$portEnd
--label dyn$i \
--init-complete-file init-complete-node$((2 + i)).log"
)
done
if [[ extraNodes -gt 0 ]]; then
for i in $(seq 1 $extraNodes); do
portStart=$((8100 + i * 50))
portEnd=$((portStart + 49))
nodes+=(
"multinode-demo/validator.sh \
--no-restart \
--dynamic-port-range $portStart-$portEnd
--label dyn$i \
--init-complete-file init-complete-node$((2 + i)).log"
)
done
fi
numNodes=$((2 + extraNodes))
pids=()
@@ -313,7 +315,7 @@ flag_error() {
if ! $skipSetup; then
clear_config_dir "$SOLANA_CONFIG_DIR"
multinode-demo/setup.sh
multinode-demo/setup.sh --hashes-per-tick sleep
else
verifyLedger
fi
@@ -365,7 +367,7 @@ while [[ $iteration -le $iterations ]]; do
echo "--- Wallet sanity ($iteration)"
(
set -x
timeout 90s scripts/wallet-sanity.sh --url http://127.0.0.1"$walletRpcPort"
timeout 60s scripts/wallet-sanity.sh --url http://127.0.0.1"$walletRpcPort"
) || flag_error
iteration=$((iteration + 1))

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-clap-utils"
version = "0.21.0"
version = "0.21.1"
description = "Solana utilities for the clap"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -12,7 +12,7 @@ edition = "2018"
clap = "2.33.0"
rpassword = "4.0"
semver = "0.9.0"
solana-sdk = { path = "../sdk", version = "0.21.0" }
solana-sdk = { path = "../sdk", version = "0.21.1" }
tiny-bip39 = "0.6.2"
url = "2.1.0"

View File

@@ -36,7 +36,7 @@ pub fn keypair_of(matches: &ArgMatches<'_>, name: &str) -> Option<Keypair> {
if let Some(value) = matches.value_of(name) {
if value == ASK_KEYWORD {
let skip_validation = matches.is_present(SKIP_SEED_PHRASE_VALIDATION_ARG.name);
keypair_from_seed_phrase(name, skip_validation).ok()
keypair_from_seed_phrase(name, skip_validation, true).ok()
} else {
read_keypair_file(value).ok()
}

View File

@@ -97,3 +97,24 @@ pub fn is_port(port: String) -> Result<(), String> {
.map(|_| ())
.map_err(|e| format!("{:?}", e))
}
pub fn is_valid_percentage(percentage: String) -> Result<(), String> {
percentage
.parse::<u8>()
.map_err(|e| {
format!(
"Unable to parse input percentage, provided: {}, err: {:?}",
percentage, e
)
})
.and_then(|v| {
if v > 100 {
Err(format!(
"Percentage must be in range of 0 to 100, provided: {}",
v
))
} else {
Ok(())
}
})
}

View File

@@ -2,11 +2,18 @@ use crate::ArgConstant;
use bip39::{Language, Mnemonic, Seed};
use clap::values_t;
use rpassword::prompt_password_stderr;
use solana_sdk::signature::{
keypair_from_seed, keypair_from_seed_phrase_and_passphrase, read_keypair_file, Keypair,
KeypairUtil,
use solana_sdk::{
pubkey::Pubkey,
signature::{
keypair_from_seed, keypair_from_seed_phrase_and_passphrase, read_keypair_file, Keypair,
KeypairUtil,
},
};
use std::{
error,
io::{stdin, stdout, Write},
process::exit,
};
use std::error;
// Keyword used to indicate that the user should be asked for a keypair seed phrase
pub const ASK_KEYWORD: &str = "ASK";
@@ -41,10 +48,25 @@ impl KeypairWithSource {
}
}
/// Prompts user for a passphrase and then asks for confirmirmation to check for mistakes
pub fn prompt_passphrase(prompt: &str) -> Result<String, Box<dyn error::Error>> {
let passphrase = prompt_password_stderr(&prompt)?;
if !passphrase.is_empty() {
let confirmed = rpassword::prompt_password_stderr("Enter same passphrase again: ")?;
if confirmed != passphrase {
return Err("Passphrases did not match".into());
}
}
Ok(passphrase)
}
/// Reads user input from stdin to retrieve a seed phrase and passphrase for keypair derivation
/// Optionally skips validation of seed phrase
/// Optionally confirms recovered public key
pub fn keypair_from_seed_phrase(
keypair_name: &str,
skip_validation: bool,
confirm_pubkey: bool,
) -> Result<Keypair, Box<dyn error::Error>> {
let seed_phrase = prompt_password_stderr(&format!("[{}] seed phrase: ", keypair_name))?;
let seed_phrase = seed_phrase.trim();
@@ -53,15 +75,30 @@ pub fn keypair_from_seed_phrase(
keypair_name,
);
if skip_validation {
let passphrase = prompt_password_stderr(&passphrase_prompt)?;
keypair_from_seed_phrase_and_passphrase(&seed_phrase, &passphrase)
let keypair = if skip_validation {
let passphrase = prompt_passphrase(&passphrase_prompt)?;
keypair_from_seed_phrase_and_passphrase(&seed_phrase, &passphrase)?
} else {
let mnemonic = Mnemonic::from_phrase(seed_phrase, Language::English)?;
let passphrase = prompt_password_stderr(&passphrase_prompt)?;
let sanitized = sanitize_seed_phrase(seed_phrase);
let mnemonic = Mnemonic::from_phrase(sanitized, Language::English)?;
let passphrase = prompt_passphrase(&passphrase_prompt)?;
let seed = Seed::new(&mnemonic, &passphrase);
keypair_from_seed(seed.as_bytes())
keypair_from_seed(seed.as_bytes())?
};
if confirm_pubkey {
let pubkey = Pubkey::new(keypair.public.as_ref());
print!("Recovered pubkey `{:?}`. Continue? (y/n): ", pubkey);
let _ignored = stdout().flush();
let mut input = String::new();
stdin().read_line(&mut input).expect("Unexpected input");
if input.to_lowercase().trim() != "y" {
println!("Exiting");
exit(1);
}
}
Ok(keypair)
}
/// Checks CLI arguments to determine whether a keypair should be:
@@ -91,7 +128,7 @@ pub fn keypair_input(
}
let skip_validation = matches.is_present(SKIP_SEED_PHRASE_VALIDATION_ARG.name);
keypair_from_seed_phrase(keypair_name, skip_validation)
keypair_from_seed_phrase(keypair_name, skip_validation, true)
.map(|keypair| KeypairWithSource::new(keypair, Source::SeedPhrase))
} else if let Some(keypair_file) = matches.value_of(keypair_match_name) {
read_keypair_file(keypair_file).map(|keypair| KeypairWithSource::new(keypair, Source::File))
@@ -100,6 +137,13 @@ pub fn keypair_input(
}
}
fn sanitize_seed_phrase(seed_phrase: &str) -> String {
seed_phrase
.split_whitespace()
.collect::<Vec<&str>>()
.join(" ")
}
#[cfg(test)]
mod tests {
use super::*;
@@ -111,4 +155,13 @@ mod tests {
let KeypairWithSource { source, .. } = keypair_input(&arg_matches, "").unwrap();
assert_eq!(source, Source::Generated);
}
#[test]
fn test_sanitize_seed_phrase() {
let seed_phrase = " Mary had\ta\u{2009}little \n\t lamb";
assert_eq!(
"Mary had a little lamb".to_owned(),
sanitize_seed_phrase(seed_phrase)
);
}
}

View File

@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-cli"
description = "Blockchain, Rebuilt for Scale"
version = "0.21.0"
version = "0.21.1"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -27,24 +27,24 @@ serde = "1.0.102"
serde_derive = "1.0.102"
serde_json = "1.0.41"
serde_yaml = "0.8.11"
solana-budget-program = { path = "../programs/budget", version = "0.21.0" }
solana-clap-utils = { path = "../clap-utils", version = "0.21.0" }
solana-client = { path = "../client", version = "0.21.0" }
solana-config-program = { path = "../programs/config", version = "0.21.0" }
solana-drone = { path = "../drone", version = "0.21.0" }
solana-logger = { path = "../logger", version = "0.21.0" }
solana-net-utils = { path = "../net-utils", version = "0.21.0" }
solana-runtime = { path = "../runtime", version = "0.21.0" }
solana-sdk = { path = "../sdk", version = "0.21.0" }
solana-stake-program = { path = "../programs/stake", version = "0.21.0" }
solana-storage-program = { path = "../programs/storage", version = "0.21.0" }
solana-vote-program = { path = "../programs/vote", version = "0.21.0" }
solana-vote-signer = { path = "../vote-signer", version = "0.21.0" }
solana-budget-program = { path = "../programs/budget", version = "0.21.1" }
solana-clap-utils = { path = "../clap-utils", version = "0.21.1" }
solana-client = { path = "../client", version = "0.21.1" }
solana-config-program = { path = "../programs/config", version = "0.21.1" }
solana-drone = { path = "../drone", version = "0.21.1" }
solana-logger = { path = "../logger", version = "0.21.1" }
solana-net-utils = { path = "../net-utils", version = "0.21.1" }
solana-runtime = { path = "../runtime", version = "0.21.1" }
solana-sdk = { path = "../sdk", version = "0.21.1" }
solana-stake-program = { path = "../programs/stake", version = "0.21.1" }
solana-storage-program = { path = "../programs/storage", version = "0.21.1" }
solana-vote-program = { path = "../programs/vote", version = "0.21.1" }
solana-vote-signer = { path = "../vote-signer", version = "0.21.1" }
url = "2.1.0"
[dev-dependencies]
solana-core = { path = "../core", version = "0.21.0" }
solana-budget-program = { path = "../programs/budget", version = "0.21.0" }
solana-core = { path = "../core", version = "0.21.1" }
solana-budget-program = { path = "../programs/budget", version = "0.21.1" }
tempfile = "3.1.0"
[[bin]]

View File

@@ -616,7 +616,7 @@ pub fn process_show_validators(rpc_client: &RpcClient, use_lamports_unit: bool)
}
}
println!(
"{} {:<44} {:<44} {:>3} ({:>4.1}%) {:>10} {:>11} {:>11}",
"{} {:<44} {:<44} {:>3}% {:>10} {:>11} {:>11}",
if delinquent {
WARNING.to_string()
} else {
@@ -625,7 +625,6 @@ pub fn process_show_validators(rpc_client: &RpcClient, use_lamports_unit: bool)
vote_account.node_pubkey,
vote_account.vote_pubkey,
vote_account.commission,
f64::from(vote_account.commission) * 100.0 / f64::from(std::u8::MAX),
non_zero_or_dash(vote_account.last_vote),
non_zero_or_dash(vote_account.root_slot),
if vote_account.activated_stake > 0 {

View File

@@ -47,7 +47,7 @@ impl VoteSubCommands for App<'_, '_> {
.long("commission")
.value_name("NUM")
.takes_value(true)
.help("The commission taken on reward redemption (0-255), default: 0"),
.help("The commission taken on reward redemption (0-100), default: 0"),
)
.arg(
Arg::with_name("authorized_voter")
@@ -345,10 +345,7 @@ pub fn process_show_vote_account(
vote_state.authorized_withdrawer
);
println!("credits: {}", vote_state.credits());
println!(
"commission: {}%",
f64::from(vote_state.commission) / f64::from(std::u32::MAX)
);
println!("commission: {}%", vote_state.commission);
println!(
"root slot: {}",
match vote_state.root_slot {

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-client"
version = "0.21.0"
version = "0.21.1"
description = "Solana Client"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -19,10 +19,10 @@ reqwest = { version = "0.9.22", default-features = false, features = ["rustls-tl
serde = "1.0.102"
serde_derive = "1.0.102"
serde_json = "1.0.41"
solana-net-utils = { path = "../net-utils", version = "0.21.0" }
solana-sdk = { path = "../sdk", version = "0.21.0" }
solana-net-utils = { path = "../net-utils", version = "0.21.1" }
solana-sdk = { path = "../sdk", version = "0.21.1" }
[dev-dependencies]
jsonrpc-core = "14.0.3"
jsonrpc-http-server = "14.0.3"
solana-logger = { path = "../logger", version = "0.21.0" }
solana-logger = { path = "../logger", version = "0.21.1" }

View File

@@ -56,6 +56,10 @@ impl GenericRpcClientRequest for RpcClientRequest {
.send()
{
Ok(mut response) => {
if !response.status().is_success() {
return Err(response.error_for_status().unwrap_err().into());
}
let json: serde_json::Value = serde_json::from_str(&response.text()?)?;
if json["error"].is_object() {
return Err(RpcError::RpcRequestError(format!(

View File

@@ -1,7 +1,7 @@
[package]
name = "solana-core"
description = "Blockchain, Rebuilt for Scale"
version = "0.21.0"
version = "0.21.1"
documentation = "https://docs.rs/solana"
homepage = "https://solana.com/"
readme = "../README.md"
@@ -41,25 +41,25 @@ rayon = "1.2.0"
serde = "1.0.102"
serde_derive = "1.0.102"
serde_json = "1.0.41"
solana-budget-program = { path = "../programs/budget", version = "0.21.0" }
solana-clap-utils = { path = "../clap-utils", version = "0.21.0" }
solana-chacha-sys = { path = "../chacha-sys", version = "0.21.0" }
solana-client = { path = "../client", version = "0.21.0" }
solana-drone = { path = "../drone", version = "0.21.0" }
solana-budget-program = { path = "../programs/budget", version = "0.21.1" }
solana-clap-utils = { path = "../clap-utils", version = "0.21.1" }
solana-chacha-sys = { path = "../chacha-sys", version = "0.21.1" }
solana-client = { path = "../client", version = "0.21.1" }
solana-drone = { path = "../drone", version = "0.21.1" }
ed25519-dalek = "1.0.0-pre.1"
solana-ledger = { path = "../ledger", version = "0.21.0" }
solana-logger = { path = "../logger", version = "0.21.0" }
solana-merkle-tree = { path = "../merkle-tree", version = "0.21.0" }
solana-metrics = { path = "../metrics", version = "0.21.0" }
solana-measure = { path = "../measure", version = "0.21.0" }
solana-net-utils = { path = "../net-utils", version = "0.21.0" }
solana-perf = { path = "../perf", version = "0.21.0" }
solana-runtime = { path = "../runtime", version = "0.21.0" }
solana-sdk = { path = "../sdk", version = "0.21.0" }
solana-stake-program = { path = "../programs/stake", version = "0.21.0" }
solana-storage-program = { path = "../programs/storage", version = "0.21.0" }
solana-vote-program = { path = "../programs/vote", version = "0.21.0" }
solana-vote-signer = { path = "../vote-signer", version = "0.21.0" }
solana-ledger = { path = "../ledger", version = "0.21.1" }
solana-logger = { path = "../logger", version = "0.21.1" }
solana-merkle-tree = { path = "../merkle-tree", version = "0.21.1" }
solana-metrics = { path = "../metrics", version = "0.21.1" }
solana-measure = { path = "../measure", version = "0.21.1" }
solana-net-utils = { path = "../net-utils", version = "0.21.1" }
solana-perf = { path = "../perf", version = "0.21.1" }
solana-runtime = { path = "../runtime", version = "0.21.1" }
solana-sdk = { path = "../sdk", version = "0.21.1" }
solana-stake-program = { path = "../programs/stake", version = "0.21.1" }
solana-storage-program = { path = "../programs/storage", version = "0.21.1" }
solana-vote-program = { path = "../programs/vote", version = "0.21.1" }
solana-vote-signer = { path = "../vote-signer", version = "0.21.1" }
symlink = "0.1.0"
sys-info = "0.5.8"
tempfile = "3.1.0"
@@ -68,7 +68,7 @@ tokio-codec = "0.1"
tokio-fs = "0.1"
tokio-io = "0.1"
untrusted = "0.7.0"
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "0.21.0" }
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "0.21.1" }
reed-solomon-erasure = { package = "solana-reed-solomon-erasure", version = "4.0.1-3", features = ["simd-accel"] }
[target."cfg(unix)".dependencies]

View File

@@ -295,7 +295,7 @@ mod tests {
..ProcessOptions::default()
};
let (bank_forks, _, cached_leader_schedule) =
process_blocktree(&genesis_config, &blocktree, None, opts).unwrap();
process_blocktree(&genesis_config, &blocktree, Vec::new(), opts).unwrap();
let leader_schedule_cache = Arc::new(cached_leader_schedule);
let bank_forks = Arc::new(RwLock::new(bank_forks));

View File

@@ -255,6 +255,10 @@ impl JsonRpcRequestProcessor {
last_vote,
}
})
.filter(|vote_account_info| {
// Remove vote accounts that have never voted and also have no stake
vote_account_info.last_vote == 0 && vote_account_info.activated_stake == 0
})
.partition(|vote_account_info| {
if bank.slot() >= MAX_LOCKOUT_HISTORY as u64 {
vote_account_info.last_vote > bank.slot() - MAX_LOCKOUT_HISTORY as u64

View File

@@ -87,7 +87,14 @@ impl SnapshotPackagerService {
// `storage_path` - The file path where the AppendVec itself is located
// `output_path` - The directory where the AppendVec will be placed in the staging directory.
symlink::symlink_dir(storage_path, output_path)?;
let storage_path =
fs::canonicalize(storage_path).expect("Could not get absolute path for accounts");
symlink::symlink_dir(storage_path, &output_path)?;
if !output_path.is_file() {
return Err(Self::get_io_error(
"Error trying to generate snapshot archive: storage path symlink is invalid",
));
}
}
// Tar the staging directory into the archive at `archive_path`
@@ -185,17 +192,42 @@ mod tests {
use super::*;
use solana_ledger::snapshot_utils;
use solana_runtime::accounts_db::AccountStorageEntry;
use std::fs::OpenOptions;
use std::io::Write;
use std::{
fs::{remove_dir_all, OpenOptions},
io::Write,
path::{Path, PathBuf},
};
use tempfile::TempDir;
// Create temporary placeholder directory for all test files
fn make_tmp_dir_path() -> PathBuf {
let out_dir = std::env::var("FARF_DIR").unwrap_or_else(|_| "farf".to_string());
let path = PathBuf::from(format!("{}/tmp/test_package_snapshots", out_dir));
// whack any possible collision
let _ignored = std::fs::remove_dir_all(&path);
// whack any possible collision
let _ignored = std::fs::remove_file(&path);
path
}
#[test]
fn test_package_snapshots_relative_ledger_path() {
let temp_dir = make_tmp_dir_path();
create_and_verify_snapshot(&temp_dir);
remove_dir_all(temp_dir).expect("should remove tmp dir");
}
#[test]
fn test_package_snapshots() {
// Create temporary placeholder directory for all test files
let temp_dir = TempDir::new().unwrap();
let accounts_dir = temp_dir.path().join("accounts");
let snapshots_dir = temp_dir.path().join("snapshots");
let snapshot_package_output_path = temp_dir.path().join("snapshots_output");
create_and_verify_snapshot(TempDir::new().unwrap().path())
}
fn create_and_verify_snapshot(temp_dir: &Path) {
let accounts_dir = temp_dir.join("accounts");
let snapshots_dir = temp_dir.join("snapshots");
let snapshot_package_output_path = temp_dir.join("snapshots_output");
fs::create_dir_all(&snapshot_package_output_path).unwrap();
// Create some storage entries
@@ -221,7 +253,7 @@ mod tests {
.collect();
// Create directory of hard links for snapshots
let link_snapshots_dir = tempfile::tempdir_in(temp_dir.path()).unwrap();
let link_snapshots_dir = tempfile::tempdir_in(&temp_dir).unwrap();
for snapshots_path in snapshots_paths {
let snapshot_file_name = snapshots_path.file_name().unwrap();
let link_path = link_snapshots_dir.path().join(snapshot_file_name);

View File

@@ -59,7 +59,7 @@ pub struct ValidatorConfig {
pub transaction_status_service_disabled: bool,
pub blockstream_unix_socket: Option<PathBuf>,
pub storage_slots_per_turn: u64,
pub account_paths: Option<String>,
pub account_paths: Vec<PathBuf>,
pub rpc_config: JsonRpcConfig,
pub snapshot_config: Option<SnapshotConfig>,
pub max_ledger_slots: Option<u64>,
@@ -78,7 +78,7 @@ impl Default for ValidatorConfig {
blockstream_unix_socket: None,
storage_slots_per_turn: DEFAULT_SLOTS_PER_TURN,
max_ledger_slots: None,
account_paths: None,
account_paths: Vec::new(),
rpc_config: JsonRpcConfig::default(),
snapshot_config: None,
broadcast_stage_type: BroadcastStageType::Standard,
@@ -465,7 +465,7 @@ impl Validator {
pub fn new_banks_from_blocktree(
expected_genesis_hash: Option<Hash>,
blocktree_path: &Path,
account_paths: Option<String>,
account_paths: Vec<PathBuf>,
snapshot_config: Option<SnapshotConfig>,
poh_verify: bool,
dev_halt_at_slot: Option<Slot>,

View File

@@ -52,7 +52,7 @@ mod tests {
let genesis_config_info = create_genesis_config(10_000);
let bank0 = Bank::new_with_paths(
&genesis_config_info.genesis_config,
Some(accounts_dir.path().to_str().unwrap().to_string()),
vec![accounts_dir.path().to_path_buf()],
);
bank0.freeze();
let mut bank_forks = BankForks::new(0, bank0);
@@ -73,7 +73,7 @@ mod tests {
}
}
fn restore_from_snapshot(old_bank_forks: &BankForks, account_paths: String) {
fn restore_from_snapshot(old_bank_forks: &BankForks, account_paths: Vec<PathBuf>) {
let (snapshot_path, snapshot_package_output_path) = old_bank_forks
.snapshot_config
.as_ref()
@@ -81,7 +81,7 @@ mod tests {
.unwrap();
let deserialized_bank = snapshot_utils::bank_from_archive(
account_paths,
&account_paths,
&old_bank_forks
.snapshot_config
.as_ref()
@@ -151,10 +151,7 @@ mod tests {
.unwrap();
SnapshotPackagerService::package_snapshots(&snapshot_package).unwrap();
restore_from_snapshot(
bank_forks,
accounts_dir.path().to_str().unwrap().to_string(),
);
restore_from_snapshot(bank_forks, vec![accounts_dir.path().to_path_buf()]);
}
#[test]
@@ -237,7 +234,7 @@ mod tests {
let key1 = Keypair::new().pubkey();
let tx = system_transaction::transfer(&mint_keypair, &key1, 1, genesis_config.hash());
assert_eq!(bank.process_transaction(&tx), Ok(()));
bank.freeze();
bank.squash();
bank_forks.insert(bank);
let package_sender = {

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-crate-features"
version = "0.21.0"
version = "0.21.1"
description = "Solana Crate Features"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-drone"
version = "0.21.0"
version = "0.21.1"
description = "Solana Drone"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -19,10 +19,10 @@ clap = "2.33"
log = "0.4.8"
serde = "1.0.102"
serde_derive = "1.0.102"
solana-clap-utils = { path = "../clap-utils", version = "0.21.0" }
solana-logger = { path = "../logger", version = "0.21.0" }
solana-metrics = { path = "../metrics", version = "0.21.0" }
solana-sdk = { path = "../sdk", version = "0.21.0" }
solana-clap-utils = { path = "../clap-utils", version = "0.21.1" }
solana-logger = { path = "../logger", version = "0.21.1" }
solana-metrics = { path = "../metrics", version = "0.21.1" }
solana-sdk = { path = "../sdk", version = "0.21.1" }
tokio = "0.1"
tokio-codec = "0.1"

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-fixed-buf"
version = "0.21.0"
version = "0.21.1"
description = "A fixed-size byte array that supports bincode serde"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-genesis-programs"
version = "0.21.0"
version = "0.21.1"
description = "Solana genesis programs"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -10,16 +10,16 @@ edition = "2018"
[dependencies]
log = { version = "0.4.8" }
solana-bpf-loader-program = { path = "../programs/bpf_loader", version = "0.21.0" }
solana-budget-program = { path = "../programs/budget", version = "0.21.0" }
solana-config-program = { path = "../programs/config", version = "0.21.0" }
solana-exchange-program = { path = "../programs/exchange", version = "0.21.0" }
solana-runtime = { path = "../runtime", version = "0.21.0" }
solana-sdk = { path = "../sdk", version = "0.21.0" }
solana-stake-program = { path = "../programs/stake", version = "0.21.0" }
solana-storage-program = { path = "../programs/storage", version = "0.21.0" }
solana-vest-program = { path = "../programs/vest", version = "0.21.0" }
solana-vote-program = { path = "../programs/vote", version = "0.21.0" }
solana-bpf-loader-program = { path = "../programs/bpf_loader", version = "0.21.1" }
solana-budget-program = { path = "../programs/budget", version = "0.21.1" }
solana-config-program = { path = "../programs/config", version = "0.21.1" }
solana-exchange-program = { path = "../programs/exchange", version = "0.21.1" }
solana-runtime = { path = "../runtime", version = "0.21.1" }
solana-sdk = { path = "../sdk", version = "0.21.1" }
solana-stake-program = { path = "../programs/stake", version = "0.21.1" }
solana-storage-program = { path = "../programs/storage", version = "0.21.1" }
solana-vest-program = { path = "../programs/vest", version = "0.21.1" }
solana-vote-program = { path = "../programs/vote", version = "0.21.1" }
[lib]
crate-type = ["lib"]

View File

@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-genesis"
description = "Blockchain, Rebuilt for Scale"
version = "0.21.0"
version = "0.21.1"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -16,11 +16,11 @@ serde = "1.0.102"
serde_derive = "1.0.102"
serde_json = "1.0.41"
serde_yaml = "0.8.11"
solana-clap-utils = { path = "../clap-utils", version = "0.21.0" }
solana-genesis-programs = { path = "../genesis-programs", version = "0.21.0" }
solana-ledger = { path = "../ledger", version = "0.21.0" }
solana-sdk = { path = "../sdk", version = "0.21.0" }
solana-stake-program = { path = "../programs/stake", version = "0.21.0" }
solana-storage-program = { path = "../programs/storage", version = "0.21.0" }
solana-vote-program = { path = "../programs/vote", version = "0.21.0" }
solana-clap-utils = { path = "../clap-utils", version = "0.21.1" }
solana-genesis-programs = { path = "../genesis-programs", version = "0.21.1" }
solana-ledger = { path = "../ledger", version = "0.21.1" }
solana-sdk = { path = "../sdk", version = "0.21.1" }
solana-stake-program = { path = "../programs/stake", version = "0.21.1" }
solana-storage-program = { path = "../programs/storage", version = "0.21.1" }
solana-vote-program = { path = "../programs/vote", version = "0.21.1" }
tempfile = "3.1.0"

View File

@@ -24,6 +24,7 @@ impl AddressGenerator {
.as_ref(),
)
}
#[allow(clippy::should_implement_trait)]
pub fn next(&mut self) -> Pubkey {
let nth = self.nth;
self.nth += 1;

View File

@@ -1,602 +1,501 @@
use crate::{
stakes::{create_and_add_stakes, StakerInfo},
unlocks::UnlockInfo,
validators::{create_and_add_validator, ValidatorInfo},
};
use solana_sdk::{genesis_config::GenesisConfig, native_token::sol_to_lamports};
// 30 "month" schedule is 1/5th at 6 months
// 1/24 at each 1/12 of a year thereafter
const BATCH_ONE_UNLOCK_INFO: UnlockInfo = UnlockInfo {
// 30 month schedule is 1/5th every 6 months for 30 months
const UNLOCKS_BY_FIFTHS_FOR_30_MONTHS: UnlockInfo = UnlockInfo {
cliff_fraction: 0.2,
cliff_years: 0.5,
unlocks: 24,
unlock_years: 1.0 / 12.0,
unlocks: 4,
unlock_years: 0.5,
custodian: "11111111111111111111111111111111",
};
// 60 month schedule is 1/10th every 6 months for 60 months
//const UNLOCKS_BY_TENTHS_FOR_60_MONTHS: UnlockInfo = UnlockInfo {
// cliff_fraction: 0.1,
// cliff_years: 0.5,
// unlocks: 9,
// unlock_years: 0.5,
// custodian: "11111111111111111111111111111111",
//};
// 60 month schedule is 1/10th every 6 months for 60 months
const UNLOCKS_BY_TENTHS_FOR_60_MONTHS: UnlockInfo = UnlockInfo {
cliff_fraction: 0.1,
cliff_years: 0.5,
unlocks: 9,
unlock_years: 0.5,
custodian: "11111111111111111111111111111111",
};
// 1st batch
const BATCH_ONE_STAKER_INFOS: &[StakerInfo] = &[
StakerInfo {
name: "diligent bridge",
staker: "ab22196afde08a090a3721eb20e3e1ea84d36e14d1a3f0815b236b300d9d33ef",
withdrawer: "a2a7ae9098f862f4b3ba7d102d174de5e84a560444c39c035f3eeecce442eadc",
staker: "BwwM47pLHwUgjJXKQKVNiRfGhtPNWfNLH27na2HJQHhd",
sol: 6_250_000.0,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "four wish",
staker: "6a56514c29f6b1de4d46164621d6bd25b337a711f569f9283c1143c7e8fb546e",
withdrawer: "b420af728f58d9f269d6e07fbbaecf6ed6535e5348538e3f39f2710351f2b940",
staker: "8A6ZEEW2odkqXNjTWHNG6tUk7uj6zCzHueTyEr9pM1tH",
sol: 10_000_000.0,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "simple friends",
staker: "ddf2e4c81eafae2d68ac99171b066c87bddb168d6b7c07333cd951f36640163d",
withdrawer: "312fa06ccf1b671b26404a34136161ed2aba9e66f248441b4fddb5c592fde560",
staker: "D89HyaBmr2WmrTehsfkQrY23wCXcDfsFnN9gMfUXHaDd",
sol: 1_250_000.0,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "noxious leather",
staker: "0cbf98cd35ceff84ca72b752c32cc3eeee4f765ca1bef1140927ebf5c6e74339",
withdrawer: "467e06fa25a9e06824eedc926ce431947ed99c728bed36be54561354c1330959",
staker: "FwPvDpvUmnco1CSfwXQDTbUbuhG5eP7h2vgCKYKVL7at",
sol: 6_250_000.0,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "worthless direction",
staker: "ef1562bf9edfd0f5e62530cce4244e8de544a3a30075a2cd5c9074edfbcbe78a",
withdrawer: "2ab26abb9d8131a30a4a63446125cf961ece4b926c31cce0eb84da4eac3f836e",
staker: "4K16iBoC9kAQRT8pUEKeD2h9WEx1zsRgEmJFssXcXmqq",
sol: 12_500_000.0,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "historical company",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "rmLpENW4V6QNeEhdJJVxo9Xt99oKgNUFZS4Y4375amW",
sol: 322_850.0,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "callous money",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "5kAztE3XtrpeyGZZxckSUt3ZWojNTmph1QSC9S2682z4",
sol: 5_927_155.25,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "outstanding jump",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "H6HMVuDR8XCw3EuhLvFG4EciVvGo76Agq1kSBL2ozoDs",
sol: 625_000.0,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "feeble toes",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "3sfv8tk5ZSDBWbTkFkvFxCvJUyW5yDJUu6VMJcUARQWq",
sol: 750_000.0,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "disillusioned deer",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 1_250_000.0,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "unwritten songs",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 4_250_000.0,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "overt dime",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 500_000.0,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "slow committee",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 625_000.0,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "curvy twig",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 625_000.0,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "gamy scissors",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 250_000.0,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "mushy key",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 1_250_000.0,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "marked silver",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 250_000.0,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "free sock",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 625_000.0,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "tremendous meeting",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 1_250_000.0,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "panoramic cloth",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 625_000.0,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "normal kick",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 2_500_000.0,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "unbecoming observation",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 250_000.0,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "cut beginner",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 250_000.0,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "alcoholic button",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 625_000.0,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "old-fashioned clover",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 750_000.0,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "expensive underwear",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 2_500_000.0,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "like dust",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 5_000_000.0,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "rapid straw",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 5_850_000.0,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "windy trousers",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 2_579_350.0,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "dramatic veil",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 3_611_110.50,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "incandescent skin",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 3_000_000.0,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "spiky love",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 3_250_000.0,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
];
// 30 "month" schedule is 1/5th at 6 months
// 1/24 at each 1/12 of a year thereafter
const BATCH_TWO_UNLOCK_INFO: UnlockInfo = UnlockInfo {
cliff_fraction: 0.2,
cliff_years: 0.5,
unlocks: 24,
unlock_years: 1.0 / 12.0,
};
const BATCH_TWO_STAKER_INFOS: &[StakerInfo] = &[
// 2nd batch
StakerInfo {
name: "macabre note",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 4_000_000.0,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "alcoholic letter",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 4_000_000.0,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "heady trucks",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 4_000_000.0,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "ten support",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 1_000_000.0,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "foregoing middle",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 800_000.0,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "ludicrous destruction",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 4_000_000.0,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "numberless wheel",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 4_000_000.0,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "short powder",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 4_000_000.0,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "cut name",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 4_000_000.0,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "six fly",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 4_000_000.0,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "mindless pickle",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 100_000.0,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "marked rabbit",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 38_741.36,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "jagged doctor",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 711_258.64,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "truthful pollution",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 1_587_300.0,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "unkempt activity",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 2_222_220.0,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "ritzy view",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 40_000.0,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "remarkable plant",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 300_000.0,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "busy value",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 100_000.0,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "imperfect slave",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 222_065.84,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "uneven drawer",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 400_000.0,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "far behavior",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 4_000_000.0,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "abaft memory",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 400_000.0,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "poor glove",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 2_000_000.0,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "strange iron",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 2_000_000.0,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "nonstop rail",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 1_000_000.0,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "milky bait",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 400_000.0,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "wandering start",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 1_200_000.0,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
];
// 30 "month" schedule is 1/5th at 6 months
// 1/24 at each 1/12 of a year thereafter
pub const BATCH_THREE_UNLOCK_INFO: UnlockInfo = UnlockInfo {
cliff_fraction: 0.2,
cliff_years: 0.5,
unlocks: 24,
unlock_years: 1.0 / 12.0,
};
pub const BATCH_THREE_STAKER_INFOS: &[StakerInfo] = &[
// 3rd batch
StakerInfo {
name: "dusty dress",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 1_212_121.21,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "godly bed",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 151_515.15,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "innocent property",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 227_272.73,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "responsible bikes",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 3_030_303.03,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "learned market",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 3_030_303.03,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "jumpy school",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 303_030.30,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "sticky houses",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 1_515_151.52,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "bustling basketball",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 1_515_152.52,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "ordinary dad",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 606_060.61,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "absurd bat",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 90_909.09,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "cloudy ocean",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 67_945.45,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "black-and-white fold",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 757_575.76,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "stale part",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 45_454.55,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "available health",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 2_797_575.76,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "afraid visitor",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 481_818.18,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "arrogant front",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 151_515.15,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "juvenile zinc",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 151_515.15,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "disturbed box",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 303_030.30,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "disagreeable skate",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 454_545.45,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "miscreant sidewalk",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 75_757.58,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
StakerInfo {
name: "shy play",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: 303_030.30,
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
];
pub const BATCH_FOUR_STAKER_INFOS: &[StakerInfo] = &[
StakerInfo {
name: "deserted window",
staker: "XTeBBZextvHkoRqDF8yb4hihjcraKQDwTEXhzjd8fip",
sol: 3_655_292.0,
},
StakerInfo {
name: "hard cousin",
staker: "9MYDzj7QuAX9QAK7da1GhzPB4gA3qbPNWsW3MMSZobru",
sol: 5_000_000.0,
},
];
pub const POOL_STAKER_INFOS: &[StakerInfo] = &[
StakerInfo {
name: "shrill charity",
staker: "BzuqQFnu7oNUeok9ZoJezpqu2vZJU7XR1PxVLkk6wwUD",
sol: 5_000_000.0,
},
StakerInfo {
name: "legal gate",
staker: "FwMbkDZUb78aiMWhZY4BEroAcqmnrXZV77nwrg71C57d",
sol: 21_086_641.0,
},
StakerInfo {
name: "cluttered complaint",
staker: "4h1rt2ic4AXwG7p3Qqhw57EMDD4c3tLYb5J3QstGA2p5",
sol: 153_333_633.41,
},
StakerInfo {
name: "one thanks",
staker: "3b7akieYUyCgz3Cwt5sTSErMWjg8NEygD6mbGjhGkduB",
sol: 157_613_284.59,
},
StakerInfo {
name: "lyrical supermarket",
staker: "GRZwoJGisLTszcxtWpeREJ98EGg8pZewhbtcrikoU7b3",
sol: 5_000_000.0,
},
StakerInfo {
name: "frequent description",
staker: "J51tinoLdmEdUR27LUVymrb2LB3xQo1aSHSgmbSGdj58",
sol: 57_500_000.0,
},
StakerInfo {
name: "rightful agreement",
staker: "DNaKiBwwbbqk1wVoC5AQxWQbuDhvaDVbAtXzsVos9mrc",
sol: 5_000_000.0,
},
StakerInfo {
name: "tasty location",
staker: "HvXQPXAijjG1vnQs6HXVtUUtFVzi5HNgXV9LGnHvYF85",
sol: 15_000_000.0,
},
];
@@ -614,23 +513,209 @@ fn add_stakes(
.sum::<u64>()
}
pub(crate) fn add_genesis_accounts(genesis_config: &mut GenesisConfig) -> u64 {
pub const VALIDATOR_INFOS: &[ValidatorInfo] = &[
ValidatorInfo {
name: "01Node",
node: "5n8KCdzqtvTnhkvCrFR7errH6ZUp11kL97r2awXkfzFe",
vote: "4uYMbY5Ae5ZSRNxQ3RWVyXS9rzW7E3AMZYHuUEotxu6K",
node_sol: 500.0,
commission: 0,
},
ValidatorInfo {
name: "Bison Trails",
node: "7suRNpX7bJsXphHJtBv4ZsLjJZ1dTGeX256pLqJZdEAm",
vote: "DfirEZ9Up1xbE7sQji9UwtcRGe5uCcRqQtnaGpha5KNY",
node_sol: 500.0,
commission: 0,
},
ValidatorInfo {
name: "ChainFlow",
node: "2te46rxywMdCNdkvjumiBBPQoVczJFxhxEaxFavQNqe3",
vote: "8bRCnytB7bySmqxodNGbZuUAtncKkB8T733DD1Dm9WMb",
node_sol: 500.0,
commission: 0,
},
ValidatorInfo {
name: "ChorusOne",
node: "ChorusXqjLC2NbiStKR6k9WoD7wu6TVTtFG8qCL5XBVa",
vote: "ChorusvBuPwukqgDvYfWtEg8j4T1NcMgSTQ4b1UbAwgQ",
node_sol: 500.0,
commission: 0,
},
ValidatorInfo {
name: "P2P.ORG - Secure Non-custodial Staking",
node: "44e8VyWoyZSE2oYHxMHMedAiHkGJqJgPd3tdt6iKoAFL",
vote: "BwwpzEpo1wzgV9N1987ntgNG6jLt3C9532C68pswT7Gp",
node_sol: 500.0,
commission: 0,
},
ValidatorInfo {
name: "Dokia Capital",
node: "GeZ5PrJi9muVCJiJAaFBNGoCEdxGEqTp7L2BmT2WTTy1",
vote: "7ZdRx2EBYoRuPfyeoNbuHodMUXcAQRcC37MUw3kP6akn",
node_sol: 500.0,
commission: 0,
},
ValidatorInfo {
name: "RockX",
node: "Ez4iUU87ViJLCnmSy1t1Ti3DLoysFXiBseNfnRfoehyY",
vote: "GUdGALCHQBeqkNc2ZAht3tBXab1N5u9qJC3PAzpL54r7",
node_sol: 500.0,
commission: 0,
},
ValidatorInfo {
name: "Staking Facilities",
node: "pbAxyqHHPMwgEjv8kmjGxysk9rhNtN7q22eAjReq6Hj",
vote: "4VZ3pJX19PpuGjoSB1qeN9sVQfrqgLVNg16is37adiFp",
node_sol: 500.0,
commission: 0,
},
];
fn add_validators(genesis_config: &mut GenesisConfig, validator_infos: &[ValidatorInfo]) -> u64 {
validator_infos
.iter()
.map(|validator_info| create_and_add_validator(genesis_config, validator_info))
.sum::<u64>()
}
fn add_spare_validators(genesis_config: &mut GenesisConfig) -> u64 {
let node_pubkeys = [
"id2GQ6YwsjTCCHJ9pJaffC3MEezPscNLjPdGPSfaN46",
"id2QqCczwAMoDuG4sVZFjooysAqhs6hzMgGigg2rbMV",
"id4PaxnDQwH6mLjrXZ7S56DoLxKLFdkSBmr6vma6sBf",
"id7U3WaKEeWgGAyNydEHZFiitkc1bL5VzYmxZXTYfVY",
"id7ywnFUjQ27BueJJc1U4inAWEvWpMaBX1fXbBKWz2J",
"idB6NCyjMBTfdMuC9yj8vd8iiajNd9Mbk2AXp8a5xHe",
"idBpZi4KcCoV5t88BSrnJ98zv9dZkLZQBk54TFyAdaZ",
"idCfrfPBhvPWxj1N29n7gbMMejPraDsATyWQPFAXJuZ",
"idEfgYfaLCvtWA7attVbBNgnfokJNpjbXpqLuTSPjUp",
"idF6btoY9VHbnU5sCYpZ1Bu8yBAL3bKfN2k47ukan3n",
"idGi3LekrrcVzvnQiydodwM86eqZSo8mWN59ytxZdH5",
"idGxeLFcK36ZQmaF249uPTZZGnRn7FpXoPJR5LKhv1v",
"idJ8bnEkJf5CL7FngrM4zm1BHMLT1iMoQnJkL6sbq3B",
"idKsePUfNbUALy2qiCEh1gFKgjuLc6p6pekmto9R5Cb",
"idLdNwPPV5Zikk3sVANyXzUquXzQzwmWbib6m15WT8t",
"idMC8bibeXspJphRNK5HpwK3Lh744fDtksrT2cULH9q",
"idMi1g3V87WNYa3SXGLzsHeKNFaJVrryF6on5dU7DA2",
"idNFd41HQWr5NmPrZRwFwxXUnR4YqHpGC3CGke2KBRW",
"idQwur4HP41cWqDxktp1UeT1PiG6KcTYKEbQeWyQ4BU",
"idSM4aD8kSQmRxm12yvzaYES3esUeMiFmJdxaPEVYPT",
"idSMbfe8Up3syM8sgn8Ubzd1FYc77KptdMDbufBv3GS",
"idSPToD3qXCvFnJiQ5qRHaTQTqh2pFXmXZFZ5XkvYzV",
"idSn2FMj47RAWVoCb2pgt8YCnfnfwY2vReQMNSPceMA",
"idVXGKsb7F2nFRW51anXiyHPJTFVmnusnHr5zYJaABA",
"idVcb8J66gCuAwFjLoKGuuvpxxFnhhfpENhUzR4u7tQ",
"idVo6gQWhf1qptvnt1YwD6thehshDfzN9GZajC6nXkC",
"idY8iDUV2VeMqeBCRCHgzNPiASXkJKQhDqWMBqH26c9",
"idZwgtd3r3MX7kriLRX6q3nuPqtb24ZtthS9L23SR6A",
"idbdSGgRFPQdrsz7wtc2Tbx7MaL4xA6r98yuxrtqEyS",
"ideNfZLPpeySDZXUnnwmzhaYTh7DX62i2C52icbaEAv",
"idgxuQoRvB4nP9jj5HshoYWBTQk13pAisn1d96vEap4",
"idh5GBgrpiay2jgERL61YhfgurjvxbAG7RzPTimHahQ",
"idjgVqqz9K7qL3eMGApzuoPsZBpUyjd3EDjBwJZPMmF",
"idmWehGyjwQKmyw4AKG74srqW32Z8ecMMAzJM4pFami",
"idrpuShZXt12i7tGrN2gfYQPD7Xvak4Ai23WkqYeSPt",
"idsdFzMbYy9D2YmFm9QmFMi73FsKN4nV7WV8zMUcMEq",
"iduRkR7DKVWz34HEPAQXVUhh1tVC9wdwTNXcif4CVdq",
"iduwx2nrXM6WmHSF7AtxdV4LbZgEdXN866xYdZDx9wB",
"idxVaEn8v3zGTxqJbevTzjJhHdkA5p68ahcXfBqrka8",
"idz77S9k24pczEcgB4edV9uQag8ZuzZ3NK3DjxroaLq",
"idzabijKtknbbsmXVB65wrb4PaMdgGjpHhGJ9psD4d2",
"ide8fez9zNJBJwaESdAo5xtuk9FuWQRVjUjcaXWnm3D",
];
let vote_pubkeys = [
"vt1LGG2pV9hDVSKorVcwRnQLSdFepduiNVwynkQUStL",
"vt24vGJHuoverSX5mA2ibuHuJ2JLZqjQZd8PX11d6UL",
"vt2W6R7hBSCPEua6YxQ8ocRMkNHtrdsRpYd4cYTonUJ",
"vt2cVaESGQNDi7bEZ4PcKpyZu8QefgsLZTsDZKAWY1m",
"vt2v2yrw98Ysimde7pPqsLpfYWMNbdiHGioyF5LvMtR",
"vt5AnXUoNMTuMXcBf2jFTELDp5RTNNgZB7pwyR5ju74",
"vtA5iZY8eEkzuwqB899rvoz87fLL1UCqdFQLonpo8Yq",
"vtAJxXc55YtmZyDT3VZv1gHAMe4B5y4rXstD4pbTtMg",
"vtBHFdgKyuT9DwGEUyyz6Egczj7Ae7iSAQRaJ3oWVuw",
"vtFMV55GAPEwyeehSzujxE9SeY6goHiRVExm8rTU3e9",
"vtGN4RNrcviL3sj13gQSp13227ebGfTxJVLYzFbvVoT",
"vtGmxDTT5kX9DFDN2ENLAyviZx5tUZShK5PqjZFAcUt",
"vtJdFE1feE1egNUYYY13XV4DsVPKK3Y16bTSi4QaDMP",
"vtJpR6DcdmHuTQHqqXzPY9D5M6q7Kayw1Qnyjc2s17i",
"vtMnzXbg4QvVfDaKS9k3gAWuDzXLa5ihciZgjRjreQ3",
"vtQeWJmcnBSciJxHQ2G3a79JWi5UYUReYfxx9GsbvzX",
"vtR9U36uMJwRJnT1pPsQeNZT9KE16M5E4zRz6PzqvFJ",
"vtTvfuJsYu1VJHVJsh4kyzvu6vSR3fiugxNr9VGFMK9",
"vtWt9vvYxNt6SLPJaJ2L4jSCyNjSNpyTSZ4HMQpYv5L",
"vtZLhvVTiXKwdwh5mc5jfh9JSMuFaiQ7gp8VwnbyA9e",
"vtZS3zch9n4u5ToXJBGdUUkt7iqXJv8yZWmnVkSQrmX",
"vtaXTjzBJuswneaW6GGizm5n2VmUBeBH2FoVkyjPfBk",
"vtbhFdJagDUdod27WuAwfduoUvEQLJ3CkqyhyuSuU22",
"vtdDUSd4gmmgwb35oxeMW2H2ptgEzyPnJt2jqRkNSLU",
"vtdtwJAqWEaxoHEc593ia2bYvNdXjUFrt6A3qtJLcSj",
"vte2QxwLx4B8E3ndaExZKaTbLvHpr12xvjxEXWkENcb",
"vtedxropBTfkRVAeQiMi2bmAmVwKhqq6hUTW3ikZi1t",
"vtgTbGjVT4EeMfc43K3ANCzjF2HRpXFAeQ8crfxLwMK",
"vtivkBCoKFe7MsoCoiLharA9dHNg9ZaTH376F5kVE9k",
"vtjWWWJqBVeuRDFL2z2cwR9rnEK1YUoYzmR9ALEQdz4",
"vtmmRiGQzQRo1gUFyj7TTyFrX2oRbDe3cYJ4gxmkMAF",
"vtnA4s2T2qikmL5n1UMxfxjyFJFpqxycZFtVepF4F29",
"vtnG7CkL5cakMt4wm2eV23rZsWb89bwkVRsiS7Lb3Kt",
"vtoGcgxrUYWvi8coDRiEeBDMY1TCJMKL3mZnadjKtjC",
"vtppBusuaWNvEU4KUvNXf6wtJB8YcybxA498Zvq3Vf5",
"vtqfoB3SuNvJQGGXrnkdLQ6yr6XcAP1weoLX5WaugAb",
"vtsFGh8cwM1SEF8W4F6a5zxPk9TNbTWuWJrJre2apQ6",
"vtvdwEKJyCBmAG25mrXKCgTY4PtDHLjpTnngBorGBqj",
"vtwJMJBWGocQL7ggJ5t8vm1dW3qfHKaYMTRnmRvnK1T",
"vtwsS4uDrkoRV5Ed91GJ17XPnRLkRW6ysep695u4CiU",
"vtww7Nu3ChKXs9BU2QLuUJXVK8upvWrq8r1QfgAkMg7",
"vtyfj9nLUpcneGQhmp5v6Q8Nt7i1cENi6WoFgZEDCwE",
];
node_pubkeys
.iter()
.zip(vote_pubkeys.iter())
.map(|(node, vote)| {
create_and_add_validator(
genesis_config,
&ValidatorInfo {
name: "elvis",
node,
vote,
node_sol: 500.0,
commission: 0,
},
)
})
.sum::<u64>()
}
pub fn add_genesis_accounts(genesis_config: &mut GenesisConfig) -> u64 {
add_stakes(
genesis_config,
&BATCH_ONE_STAKER_INFOS,
&BATCH_ONE_UNLOCK_INFO,
&UNLOCKS_BY_FIFTHS_FOR_30_MONTHS,
sol_to_lamports(1_000_000.0),
) + add_stakes(
genesis_config,
&BATCH_TWO_STAKER_INFOS,
&BATCH_TWO_UNLOCK_INFO,
&UNLOCKS_BY_FIFTHS_FOR_30_MONTHS,
sol_to_lamports(1_000_000.0),
) + add_stakes(
genesis_config,
&BATCH_THREE_STAKER_INFOS,
&BATCH_THREE_UNLOCK_INFO,
&UNLOCKS_BY_FIFTHS_FOR_30_MONTHS,
sol_to_lamports(1_000_000.0),
)
) + add_stakes(
genesis_config,
&BATCH_FOUR_STAKER_INFOS,
&UNLOCKS_BY_FIFTHS_FOR_30_MONTHS,
sol_to_lamports(1_000_000.0),
) + add_stakes(
genesis_config,
&POOL_STAKER_INFOS,
&UNLOCKS_BY_TENTHS_FOR_60_MONTHS,
sol_to_lamports(1_000_000.0),
) + add_validators(genesis_config, &VALIDATOR_INFOS)
+ add_spare_validators(genesis_config)
}
#[cfg(test)]
@@ -650,15 +735,5 @@ mod tests {
.sum::<u64>();
assert_eq!(issued_lamports, lamports);
genesis_config
.accounts
.sort_by(|(ka, _), (kb, _)| ka.cmp(kb));
let len = genesis_config.accounts.len();
genesis_config
.accounts
.dedup_by(|(ka, _), (kb, _)| ka == kb);
assert_eq!(genesis_config.accounts.len(), len);
}
}

View File

@@ -1,3 +1,9 @@
pub mod address_generator;
pub mod genesis_accounts;
pub mod stakes;
pub mod unlocks;
pub mod validators;
use serde::{Deserialize, Serialize};
/// An account where the data is encoded as a Base64 string.

View File

@@ -1,14 +1,9 @@
//! A command-line executable for generating the chain's genesis config.
mod address_generator;
mod genesis_accounts;
mod stakes;
mod unlocks;
use crate::genesis_accounts::add_genesis_accounts;
use clap::{crate_description, crate_name, value_t, value_t_or_exit, App, Arg, ArgMatches};
use solana_clap_utils::input_parsers::pubkey_of;
use solana_genesis::Base64Account;
use solana_clap_utils::input_validators::is_valid_percentage;
use solana_genesis::{genesis_accounts::add_genesis_accounts, Base64Account};
use solana_ledger::{blocktree::create_new_ledger, poh::compute_hashes_per_tick};
use solana_sdk::{
account::Account,
@@ -27,7 +22,15 @@ use solana_sdk::{
use solana_stake_program::stake_state;
use solana_storage_program::storage_contract;
use solana_vote_program::vote_state;
use std::{collections::HashMap, error, fs::File, io, path::PathBuf, str::FromStr, time::Duration};
use std::{
collections::{BTreeMap, HashMap},
error,
fs::File,
io,
path::PathBuf,
str::FromStr,
time::Duration,
};
pub enum AccountFileFormat {
Pubkey,
@@ -241,7 +244,8 @@ fn main() -> Result<(), Box<dyn error::Error>> {
.value_name("NUMBER")
.takes_value(true)
.default_value(default_rent_burn_percentage)
.help("amount of rent to burn, as a fraction of std::u8::MAX."),
.help("percentage of collected rent to burn")
.validator(is_valid_percentage),
)
.arg(
Arg::with_name("target_signatures_per_slot")
@@ -342,7 +346,7 @@ fn main() -> Result<(), Box<dyn error::Error>> {
bootstrap_leader_stake_lamports,
);
let mut accounts = vec![
let mut accounts: BTreeMap<Pubkey, Account> = [
// node needs an account to issue votes from
(
bootstrap_leader_pubkey,
@@ -352,13 +356,16 @@ fn main() -> Result<(), Box<dyn error::Error>> {
(bootstrap_vote_pubkey, bootstrap_leader_vote_account),
// bootstrap leader stake
(bootstrap_stake_pubkey, bootstrap_leader_stake_account),
];
]
.iter()
.cloned()
.collect();
if let Some(bootstrap_storage_pubkey) = bootstrap_storage_pubkey {
accounts.push((
accounts.insert(
bootstrap_storage_pubkey,
storage_contract::create_validator_storage_account(bootstrap_leader_pubkey, 1),
));
);
}
let ticks_per_slot = value_t_or_exit!(matches, "ticks_per_slot", u64);
@@ -537,27 +544,28 @@ mod tests {
assert_eq!(genesis_config.accounts.len(), genesis_accounts.len());
// Test account data matches
(0..genesis_accounts.len()).for_each(|i| {
for (pubkey_str, b64_account) in genesis_accounts.iter() {
let pubkey = pubkey_str.parse().unwrap();
assert_eq!(
genesis_accounts[&genesis_config.accounts[i].0.to_string()].owner,
genesis_config.accounts[i].1.owner.to_string()
b64_account.owner,
genesis_config.accounts[&pubkey].owner.to_string()
);
assert_eq!(
genesis_accounts[&genesis_config.accounts[i].0.to_string()].balance,
genesis_config.accounts[i].1.lamports
b64_account.balance,
genesis_config.accounts[&pubkey].lamports
);
assert_eq!(
genesis_accounts[&genesis_config.accounts[i].0.to_string()].executable,
genesis_config.accounts[i].1.executable
b64_account.executable,
genesis_config.accounts[&pubkey].executable
);
assert_eq!(
genesis_accounts[&genesis_config.accounts[i].0.to_string()].data,
base64::encode(&genesis_config.accounts[i].1.data)
b64_account.data,
base64::encode(&genesis_config.accounts[&pubkey].data)
);
});
}
}
// Test more accounts can be appended
@@ -610,54 +618,37 @@ mod tests {
);
// Test old accounts are still there
(0..genesis_accounts.len()).for_each(|i| {
for (pubkey_str, b64_account) in genesis_accounts.iter() {
let pubkey = &pubkey_str.parse().unwrap();
assert_eq!(
genesis_accounts[&genesis_config.accounts[i].0.to_string()].balance,
genesis_config.accounts[i].1.lamports,
b64_account.balance,
genesis_config.accounts[&pubkey].lamports,
);
});
}
// Test new account data matches
(0..genesis_accounts1.len()).for_each(|i| {
for (pubkey_str, b64_account) in genesis_accounts1.iter() {
let pubkey = pubkey_str.parse().unwrap();
assert_eq!(
genesis_accounts1[&genesis_config.accounts[genesis_accounts.len() + i]
.0
.to_string()]
.owner,
genesis_config.accounts[genesis_accounts.len() + i]
.1
.owner
.to_string(),
b64_account.owner,
genesis_config.accounts[&pubkey].owner.to_string()
);
assert_eq!(
genesis_accounts1[&genesis_config.accounts[genesis_accounts.len() + i]
.0
.to_string()]
.balance,
genesis_config.accounts[genesis_accounts.len() + i]
.1
.lamports,
b64_account.balance,
genesis_config.accounts[&pubkey].lamports,
);
assert_eq!(
genesis_accounts1[&genesis_config.accounts[genesis_accounts.len() + i]
.0
.to_string()]
.executable,
genesis_config.accounts[genesis_accounts.len() + i]
.1
.executable,
b64_account.executable,
genesis_config.accounts[&pubkey].executable,
);
assert_eq!(
genesis_accounts1[&genesis_config.accounts[genesis_accounts.len() + i]
.0
.to_string()]
.data,
base64::encode(&genesis_config.accounts[genesis_accounts.len() + i].1.data),
b64_account.data,
base64::encode(&genesis_config.accounts[&pubkey].data),
);
});
}
// Test accounts from keypairs can be appended
let account_keypairs: Vec<_> = (0..3).map(|_| Keypair::new()).collect();
@@ -712,89 +703,60 @@ mod tests {
);
// Test old accounts are still there
(0..genesis_accounts.len()).for_each(|i| {
for (pubkey_str, b64_account) in genesis_accounts {
let pubkey = pubkey_str.parse().unwrap();
assert_eq!(
genesis_accounts[&genesis_config.accounts[i].0.to_string()].balance,
genesis_config.accounts[i].1.lamports,
b64_account.balance,
genesis_config.accounts[&pubkey].lamports,
);
});
}
// Test new account data matches
(0..genesis_accounts1.len()).for_each(|i| {
for (pubkey_str, b64_account) in genesis_accounts1 {
let pubkey = pubkey_str.parse().unwrap();
assert_eq!(
genesis_accounts1[&genesis_config.accounts[genesis_accounts.len() + i]
.0
.to_string()]
.owner,
genesis_config.accounts[genesis_accounts.len() + i]
.1
.owner
.to_string(),
b64_account.owner,
genesis_config.accounts[&pubkey].owner.to_string(),
);
assert_eq!(
genesis_accounts1[&genesis_config.accounts[genesis_accounts.len() + i]
.0
.to_string()]
.balance,
genesis_config.accounts[genesis_accounts.len() + i]
.1
.lamports,
b64_account.balance,
genesis_config.accounts[&pubkey].lamports,
);
assert_eq!(
genesis_accounts1[&genesis_config.accounts[genesis_accounts.len() + i]
.0
.to_string()]
.executable,
genesis_config.accounts[genesis_accounts.len() + i]
.1
.executable,
b64_account.executable,
genesis_config.accounts[&pubkey].executable,
);
assert_eq!(
genesis_accounts1[&genesis_config.accounts[genesis_accounts.len() + i]
.0
.to_string()]
.data,
base64::encode(&genesis_config.accounts[genesis_accounts.len() + i].1.data),
b64_account.data,
base64::encode(&genesis_config.accounts[&pubkey].data),
);
});
}
let offset = genesis_accounts.len() + genesis_accounts1.len();
// Test account data for keypairs matches
account_keypairs.iter().for_each(|keypair| {
let mut i = 0;
(offset..(offset + account_keypairs.len())).for_each(|n| {
if keypair.pubkey() == genesis_config.accounts[n].0 {
i = n;
}
});
assert_ne!(i, 0);
let keypair_str = serde_json::to_string(&keypair.to_bytes().to_vec()).unwrap();
let pubkey = keypair.pubkey();
assert_eq!(
genesis_accounts2[&serde_json::to_string(&keypair.to_bytes().to_vec()).unwrap()]
.owner,
genesis_config.accounts[i].1.owner.to_string(),
genesis_accounts2[&keypair_str].owner,
genesis_config.accounts[&pubkey].owner.to_string(),
);
assert_eq!(
genesis_accounts2[&serde_json::to_string(&keypair.to_bytes().to_vec()).unwrap()]
.balance,
genesis_config.accounts[i].1.lamports,
genesis_accounts2[&keypair_str].balance,
genesis_config.accounts[&pubkey].lamports,
);
assert_eq!(
genesis_accounts2[&serde_json::to_string(&keypair.to_bytes().to_vec()).unwrap()]
.executable,
genesis_config.accounts[i].1.executable,
genesis_accounts2[&keypair_str].executable,
genesis_config.accounts[&pubkey].executable,
);
assert_eq!(
genesis_accounts2[&serde_json::to_string(&keypair.to_bytes().to_vec()).unwrap()]
.data,
base64::encode(&genesis_config.accounts[i].1.data),
genesis_accounts2[&keypair_str].data,
base64::encode(&genesis_config.accounts[&pubkey].data),
);
});
}

View File

@@ -8,30 +8,27 @@ use solana_sdk::{
pubkey::Pubkey, system_program, timing::years_as_slots,
};
use solana_stake_program::stake_state::{
create_lockup_stake_account, get_stake_rent_exempt_reserve, Authorized, Lockup,
create_lockup_stake_account, Authorized, Lockup, StakeState,
};
#[derive(Debug)]
pub struct StakerInfo {
pub name: &'static str,
pub staker: &'static str,
pub withdrawer: &'static str,
pub sol: f64,
pub custodian: &'static str,
}
// lamports required to run staking operations for one year
// the staker account needs to be rent exempt *and* carry enough
// the staker account needs carry enough
// lamports to cover TX fees (delegation) for one year,
// and we support one delegation per epoch
fn calculate_staker_lamports(genesis_config: &GenesisConfig) -> u64 {
genesis_config.rent.minimum_balance(0).max(1)
+ genesis_config.fee_calculator.max_lamports_per_signature
* genesis_config.epoch_schedule.get_epoch(years_as_slots(
1.0,
&genesis_config.poh_config.target_tick_duration,
genesis_config.ticks_per_slot,
) as Slot)
fn calculate_staker_fees(genesis_config: &GenesisConfig, years: f64) -> u64 {
genesis_config.fee_calculator.max_lamports_per_signature
* genesis_config.epoch_schedule.get_epoch(years_as_slots(
years,
&genesis_config.poh_config.target_tick_duration,
genesis_config.ticks_per_slot,
) as Slot)
}
/// create stake accounts for lamports with at most stake_granularity in each
@@ -45,27 +42,38 @@ pub fn create_and_add_stakes(
// the largest each stake account should be, in lamports
granularity: u64,
) -> u64 {
let authorized = Authorized {
staker: Pubkey::new(&hex::decode(staker_info.staker).expect("hex")),
withdrawer: Pubkey::new(&hex::decode(staker_info.withdrawer).expect("hex")),
};
let custodian = Pubkey::new(&hex::decode(staker_info.custodian).expect("hex"));
let authorized = Authorized::auto(
&staker_info
.staker
.parse::<Pubkey>()
.expect("invalid staker"),
);
let custodian = unlock_info
.custodian
.parse::<Pubkey>()
.expect("invalid custodian");
let total_lamports = sol_to_lamports(staker_info.sol);
let staker_lamports = calculate_staker_lamports(genesis_config);
let staker_account = (
authorized.staker,
Account::new(staker_lamports, 0, &system_program::id()),
);
// staker is a system account
let staker_rent_reserve = genesis_config.rent.minimum_balance(0).max(1);
let staker_fees = calculate_staker_fees(genesis_config, 1.0);
let stakes_lamports = if !genesis_config.accounts.contains(&staker_account) {
genesis_config.accounts.push(staker_account);
let mut stakes_lamports = total_lamports - staker_fees;
total_lamports - staker_lamports
} else {
total_lamports
};
// lamports required to run staking operations for one year
// the staker account needs to be rent exempt *and* carry enough
// lamports to cover TX fees (delegation) for one year,
// and we support one delegation per epoch
// a single staker may administer any number of accounts
genesis_config
.accounts
.entry(authorized.staker)
.or_insert_with(|| {
stakes_lamports -= staker_rent_reserve;
Account::new(staker_rent_reserve, 0, &system_program::id())
})
.lamports += staker_fees;
// the staker account needs to be rent exempt *and* carry enough
// lamports to cover TX fees (delegation) for one year
@@ -82,7 +90,7 @@ pub fn create_and_add_stakes(
let mut address_generator = AddressGenerator::new(&authorized.staker, staker_info.name);
let stake_rent_exempt_reserve = get_stake_rent_exempt_reserve(&genesis_config.rent);
let stake_rent_reserve = StakeState::get_rent_exempt_reserve(&genesis_config.rent);
for unlock in unlocks {
let lamports = unlock.amount(stakes_lamports);
@@ -108,7 +116,7 @@ pub fn create_and_add_stakes(
),
);
}
if remainder <= stake_rent_exempt_reserve {
if remainder <= stake_rent_reserve {
genesis_config.add_account(
address_generator.next(),
create_lockup_stake_account(
@@ -150,11 +158,10 @@ mod tests {
granularity: u64,
len: usize,
) {
assert!(
total_lamports
== create_and_add_stakes(genesis_config, staker_info, unlock_info, granularity)
assert_eq!(
total_lamports,
create_and_add_stakes(genesis_config, staker_info, unlock_info, granularity)
);
assert_eq!(genesis_config.accounts.len(), len);
assert_eq!(
genesis_config
@@ -169,9 +176,41 @@ mod tests {
.iter()
.all(|(_pubkey, account)| account.lamports <= granularity
|| account.lamports - granularity
< get_stake_rent_exempt_reserve(&genesis_config.rent)));
<= StakeState::get_rent_exempt_reserve(&genesis_config.rent)));
}
// #[ignore]
// #[test]
// fn hex_test_keys_to_bs58() {
// vec![
// "ab22196afde08a090a3721eb20e3e1ea84d36e14d1a3f0815b236b300d9d33ef", // CX2sgoat51bnDgCN2YeesrTcscgVhnhWnwxtWEEEqBs4
// "a2a7ae9098f862f4b3ba7d102d174de5e84a560444c39c035f3eeecce442eadc", // BwwM47pLHwUgjJXKQKVNiRfGhtPNWfNLH27na2HJQHhd
// "6a56514c29f6b1de4d46164621d6bd25b337a711f569f9283c1143c7e8fb546e", // 8A6ZEEW2odkqXNjTWHNG6tUk7uj6zCzHueTyEr9pM1tH
// "b420af728f58d9f269d6e07fbbaecf6ed6535e5348538e3f39f2710351f2b940", // D89HyaBmr2WmrTehsfkQrY23wCXcDfsFnN9gMfUXHaDd
// "ddf2e4c81eafae2d68ac99171b066c87bddb168d6b7c07333cd951f36640163d", // FwPvDpvUmnco1CSfwXQDTbUbuhG5eP7h2vgCKYKVL7at
// "312fa06ccf1b671b26404a34136161ed2aba9e66f248441b4fddb5c592fde560", // 4K16iBoC9kAQRT8pUEKeD2h9WEx1zsRgEmJFssXcXmqq
// "0cbf98cd35ceff84ca72b752c32cc3eeee4f765ca1bef1140927ebf5c6e74339", // rmLpENW4V6QNeEhdJJVxo9Xt99oKgNUFZS4Y4375amW
// "467e06fa25a9e06824eedc926ce431947ed99c728bed36be54561354c1330959", // 5kAztE3XtrpeyGZZxckSUt3ZWojNTmph1QSC9S2682z4
// "ef1562bf9edfd0f5e62530cce4244e8de544a3a30075a2cd5c9074edfbcbe78a", // H6HMVuDR8XCw3EuhLvFG4EciVvGo76Agq1kSBL2ozoDs
// "2ab26abb9d8131a30a4a63446125cf961ece4b926c31cce0eb84da4eac3f836e", // 3sfv8tk5ZSDBWbTkFkvFxCvJUyW5yDJUu6VMJcUARQWq
// ]
// .iter()
// .for_each(|_hex| {
// print(
// "\n\"{}\", // {:?}",
// hex,
// Pubkey::new(&hex::decode(hex).unwrap())
// );
// });
// println();
// println(
// "{:?}",
// "P1aceHo1derPubkey11111111111111111111111111"
// .parse::<Pubkey>()
// .unwrap()
// );
//}
#[test]
fn test_create_stakes() {
// 2 unlocks
@@ -182,11 +221,12 @@ mod tests {
..Rent::default()
};
let reserve = get_stake_rent_exempt_reserve(&rent);
let reserve = StakeState::get_rent_exempt_reserve(&rent);
let staker_reserve = rent.minimum_balance(0);
// verify that a small remainder ends up in the last stake
let granularity = reserve;
let total_lamports = reserve + reserve * 2 + 1;
let total_lamports = staker_reserve + reserve * 2 + 1;
create_and_check_stakes(
&mut GenesisConfig {
rent,
@@ -194,16 +234,15 @@ mod tests {
},
&StakerInfo {
name: "fun",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: lamports_to_sol(total_lamports),
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
&UnlockInfo {
cliff_fraction: 0.5,
cliff_years: 0.5,
unlocks: 1,
unlock_years: 0.5,
custodian: "11111111111111111111111111111111",
},
total_lamports,
granularity,
@@ -212,7 +251,7 @@ mod tests {
// huge granularity doesn't blow up
let granularity = std::u64::MAX;
let total_lamports = reserve + reserve * 2 + 1;
let total_lamports = staker_reserve + reserve * 2 + 1;
create_and_check_stakes(
&mut GenesisConfig {
rent,
@@ -220,25 +259,24 @@ mod tests {
},
&StakerInfo {
name: "fun",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: lamports_to_sol(total_lamports),
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
&UnlockInfo {
cliff_fraction: 0.5,
cliff_years: 0.5,
unlocks: 1,
unlock_years: 0.5,
custodian: "11111111111111111111111111111111",
},
total_lamports,
granularity,
2 + 1,
);
// exactly reserve as a remainder
// exactly reserve as a remainder, reserve gets folded in
let granularity = reserve * 3;
let total_lamports = reserve + (granularity + reserve) * 2;
let total_lamports = staker_reserve + (granularity + reserve) * 2;
create_and_check_stakes(
&mut GenesisConfig {
rent,
@@ -246,16 +284,39 @@ mod tests {
},
&StakerInfo {
name: "fun",
staker: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
withdrawer: "cafebabedeadbeef000000000000000000000000000000000000000000000000",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: lamports_to_sol(total_lamports),
custodian: "0000000000000000000000000000000000000000000000000000000000000000",
},
&UnlockInfo {
cliff_fraction: 0.5,
cliff_years: 0.5,
unlocks: 1,
unlock_years: 0.5,
custodian: "11111111111111111111111111111111",
},
total_lamports,
granularity,
2 + 1,
);
// exactly reserve + 1 as a remainder, reserve + 1 gets its own stake
let granularity = reserve * 3;
let total_lamports = staker_reserve + (granularity + reserve + 1) * 2;
create_and_check_stakes(
&mut GenesisConfig {
rent,
..GenesisConfig::default()
},
&StakerInfo {
name: "fun",
staker: "P1aceHo1derPubkey11111111111111111111111111",
sol: lamports_to_sol(total_lamports),
},
&UnlockInfo {
cliff_fraction: 0.5,
cliff_years: 0.5,
unlocks: 1,
unlock_years: 0.5,
custodian: "11111111111111111111111111111111",
},
total_lamports,
granularity,

View File

@@ -8,6 +8,7 @@ pub struct UnlockInfo {
pub cliff_years: f64,
pub unlocks: usize,
pub unlock_years: f64,
pub custodian: &'static str,
}
#[derive(Debug, Default, Clone)]

209
genesis/src/validators.rs Normal file
View File

@@ -0,0 +1,209 @@
//! validators generator
use solana_sdk::{
account::Account, genesis_config::GenesisConfig, native_token::sol_to_lamports, pubkey::Pubkey,
system_program, timing::years_as_slots,
};
use solana_vote_program::vote_state::{self, VoteState};
#[derive(Debug)]
pub struct ValidatorInfo {
pub name: &'static str,
pub node: &'static str,
pub node_sol: f64,
pub vote: &'static str,
pub commission: u8,
}
// the node's account needs carry enough
// lamports to cover TX fees for voting for one year,
// validators can vote once per slot
fn calculate_voting_fees(genesis_config: &GenesisConfig, years: f64) -> u64 {
genesis_config.fee_calculator.max_lamports_per_signature
* years_as_slots(
years,
&genesis_config.poh_config.target_tick_duration,
genesis_config.ticks_per_slot,
) as u64
}
/// create and add vote and node id accounts for a validator
pub fn create_and_add_validator(
genesis_config: &mut GenesisConfig,
// information about this validator
validator_info: &ValidatorInfo,
) -> u64 {
let node: Pubkey = validator_info.node.parse().expect("invalid node");
let vote: Pubkey = validator_info.vote.parse().expect("invalid vote");
let node_lamports = sol_to_lamports(validator_info.node_sol);
// node is the system account from which votes will be issued
let node_rent_reserve = genesis_config.rent.minimum_balance(0).max(1);
let node_voting_fees = calculate_voting_fees(genesis_config, 1.0);
let vote_rent_reserve = VoteState::get_rent_exempt_reserve(&genesis_config.rent).max(1);
let mut total_lamports = node_voting_fees + vote_rent_reserve + node_lamports;
genesis_config
.accounts
.entry(node)
.or_insert_with(|| {
total_lamports += node_rent_reserve;
Account::new(node_rent_reserve, 0, &system_program::id())
})
.lamports += node_voting_fees + node_lamports;
assert!(
genesis_config.accounts.get(&vote).is_none(),
"{} is already in genesis",
vote
);
genesis_config.add_account(
vote,
vote_state::create_account(&vote, &node, validator_info.commission, vote_rent_reserve),
);
total_lamports
}
#[cfg(test)]
mod tests {
use super::*;
use solana_sdk::rent::Rent;
fn create_and_check_validators(
genesis_config: &mut GenesisConfig,
validator_infos: &[ValidatorInfo],
total_lamports: u64,
len: usize,
) {
assert_eq!(
validator_infos
.iter()
.map(|validator_info| create_and_add_validator(genesis_config, validator_info))
.sum::<u64>(),
total_lamports
);
assert_eq!(genesis_config.accounts.len(), len);
assert_eq!(
genesis_config
.accounts
.iter()
.map(|(_pubkey, account)| account.lamports)
.sum::<u64>(),
total_lamports,
);
assert!(genesis_config
.accounts
.iter()
.all(|(_pubkey, account)| account.lamports
>= genesis_config.rent.minimum_balance(0).max(1)));
}
#[test]
fn test_create_one_validator() {
let rent = Rent {
lamports_per_byte_year: 1,
exemption_threshold: 1.0,
..Rent::default()
};
let mut genesis_config = GenesisConfig {
rent,
..GenesisConfig::default()
};
let total_lamports = VoteState::get_rent_exempt_reserve(&rent)
+ calculate_voting_fees(&genesis_config, 1.0)
+ rent.minimum_balance(0);
create_and_check_validators(
&mut genesis_config,
&[ValidatorInfo {
name: "fun",
node: "AiTDdNHW2vNtHt7PqWMHx3B8cMPRDNgc7kMiLPJM25QC", // random pubkeys
node_sol: 0.0,
vote: "77TQYZTHodhnxJcSuVjUvx8GYRCkykPyHtmFTFLjj1Rc",
commission: 50,
}],
total_lamports,
2,
);
}
#[test]
fn test_create_one_validator_two_votes() {
let rent = Rent {
lamports_per_byte_year: 1,
exemption_threshold: 1.0,
..Rent::default()
};
let mut genesis_config = GenesisConfig {
rent,
..GenesisConfig::default()
};
let total_lamports = VoteState::get_rent_exempt_reserve(&rent) * 2
+ calculate_voting_fees(&genesis_config, 1.0) * 2 // two vote accounts
+ rent.minimum_balance(0) // one node account
+ sol_to_lamports(1.0); // 2nd vote account ask has SOL
// weird case, just wanted to verify that the duplicated node account gets double fees
create_and_check_validators(
&mut genesis_config,
&[
ValidatorInfo {
name: "fun",
node: "3VTm54dw8w6jTTsPH4BfoV5vo6mF985JAMtNDRYcaGFc", // random pubkeys
node_sol: 0.0,
vote: "GTKWbUoLw3Bv7Ld92crhyXcEk9zUu3VEKfzeuWJZdnfW",
commission: 50,
},
ValidatorInfo {
name: "unfun",
node: "3VTm54dw8w6jTTsPH4BfoV5vo6mF985JAMtNDRYcaGFc", // random pubkeys, same node
node_sol: 1.0,
vote: "8XrFPRULg98kSm535kFaLV4GMnK5JQSuAymyrCHXsUcy",
commission: 50,
},
],
total_lamports,
3,
);
}
#[test]
#[should_panic]
fn test_vote_collision() {
let rent = Rent {
lamports_per_byte_year: 1,
exemption_threshold: 1.0,
..Rent::default()
};
let mut genesis_config = GenesisConfig {
rent,
..GenesisConfig::default()
};
create_and_check_validators(
&mut genesis_config,
&[
ValidatorInfo {
name: "fun",
node: "3VTm54dw8w6jTTsPH4BfoV5vo6mF985JAMtNDRYcaGFc", // random pubkeys
node_sol: 0.0,
vote: "GTKWbUoLw3Bv7Ld92crhyXcEk9zUu3VEKfzeuWJZdnfW",
commission: 50,
},
ValidatorInfo {
name: "unfun",
node: "3VTm54dw8w6jTTsPH4BfoV5vo6mF985JAMtNDRYcaGFc", // random pubkeys, same node
node_sol: 0.0,
vote: "GTKWbUoLw3Bv7Ld92crhyXcEk9zUu3VEKfzeuWJZdnfW", // duplicate vote, bad juju
commission: 50,
},
],
0,
0,
);
}
}

View File

@@ -3,19 +3,19 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-gossip"
description = "Blockchain, Rebuilt for Scale"
version = "0.21.0"
version = "0.21.1"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
[dependencies]
clap = "2.33.0"
solana-clap-utils = { path = "../clap-utils", version = "0.21.0" }
solana-core = { path = "../core", version = "0.21.0" }
solana-client = { path = "../client", version = "0.21.0" }
solana-logger = { path = "../logger", version = "0.21.0" }
solana-net-utils = { path = "../net-utils", version = "0.21.0" }
solana-sdk = { path = "../sdk", version = "0.21.0" }
solana-clap-utils = { path = "../clap-utils", version = "0.21.1" }
solana-core = { path = "../core", version = "0.21.1" }
solana-client = { path = "../client", version = "0.21.1" }
solana-logger = { path = "../logger", version = "0.21.1" }
solana-net-utils = { path = "../net-utils", version = "0.21.1" }
solana-sdk = { path = "../sdk", version = "0.21.1" }

View File

@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-install"
description = "The solana cluster software installer"
version = "0.21.0"
version = "0.21.1"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -26,11 +26,11 @@ reqwest = { version = "0.9.22", default-features = false, features = ["rustls-tl
serde = "1.0.102"
serde_derive = "1.0.102"
serde_yaml = "0.8.11"
solana-clap-utils = { path = "../clap-utils", version = "0.21.0" }
solana-client = { path = "../client", version = "0.21.0" }
solana-config-program = { path = "../programs/config", version = "0.21.0" }
solana-logger = { path = "../logger", version = "0.21.0" }
solana-sdk = { path = "../sdk", version = "0.21.0" }
solana-clap-utils = { path = "../clap-utils", version = "0.21.1" }
solana-client = { path = "../client", version = "0.21.1" }
solana-config-program = { path = "../programs/config", version = "0.21.1" }
solana-logger = { path = "../logger", version = "0.21.1" }
solana-sdk = { path = "../sdk", version = "0.21.1" }
tar = "0.4.26"
tempdir = "0.3.7"
url = "2.1.0"

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-keygen"
version = "0.21.0"
version = "0.21.1"
description = "Solana key generation utility"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -14,8 +14,8 @@ clap = "2.33"
dirs = "2.0.2"
num_cpus = "1.11.1"
rpassword = "4.0"
solana-clap-utils = { path = "../clap-utils", version = "0.21.0" }
solana-sdk = { path = "../sdk", version = "0.21.0" }
solana-clap-utils = { path = "../clap-utils", version = "0.21.1" }
solana-sdk = { path = "../sdk", version = "0.21.1" }
tiny-bip39 = "0.6.2"
[[bin]]

View File

@@ -1,17 +1,18 @@
use bip39::{Language, Mnemonic, MnemonicType, Seed};
use bs58;
use clap::{
crate_description, crate_name, values_t_or_exit, App, AppSettings, Arg, ArgMatches, SubCommand,
crate_description, crate_name, value_t, values_t_or_exit, App, AppSettings, Arg, ArgMatches,
SubCommand,
};
use num_cpus;
use solana_clap_utils::keypair::{
keypair_from_seed_phrase, ASK_KEYWORD, SKIP_SEED_PHRASE_VALIDATION_ARG,
keypair_from_seed_phrase, prompt_passphrase, ASK_KEYWORD, SKIP_SEED_PHRASE_VALIDATION_ARG,
};
use solana_sdk::{
pubkey::write_pubkey_file,
signature::{
keypair_from_seed, read_keypair, read_keypair_file, write_keypair, write_keypair_file,
Keypair, KeypairUtil,
Keypair, KeypairUtil, Signature,
},
};
use std::{
@@ -37,6 +38,26 @@ fn check_for_overwrite(outfile: &str, matches: &ArgMatches) {
}
}
fn get_keypair_from_matches(matches: &ArgMatches) -> Result<Keypair, Box<dyn error::Error>> {
let mut path = dirs::home_dir().expect("home directory");
let infile = if matches.is_present("infile") {
matches.value_of("infile").unwrap()
} else {
path.extend(&[".config", "solana", "id.json"]);
path.to_str().unwrap()
};
if infile == "-" {
let mut stdin = std::io::stdin();
read_keypair(&mut stdin)
} else if infile == ASK_KEYWORD {
let skip_validation = matches.is_present(SKIP_SEED_PHRASE_VALIDATION_ARG.name);
keypair_from_seed_phrase("pubkey recovery", skip_validation, false)
} else {
read_keypair_file(infile)
}
}
fn output_keypair(
keypair: &Keypair,
outfile: &str,
@@ -57,6 +78,24 @@ fn main() -> Result<(), Box<dyn error::Error>> {
.about(crate_description!())
.version(solana_clap_utils::version!())
.setting(AppSettings::SubcommandRequiredElseHelp)
.subcommand(
SubCommand::with_name("verify")
.about("Verify a keypair can sign and verify a message.")
.arg(
Arg::with_name("infile")
.index(1)
.value_name("PATH")
.takes_value(true)
.help("Path to keypair file"),
)
.arg(
Arg::with_name("pubkey")
.index(2)
.value_name("BASE58_PUBKEY")
.takes_value(true)
.help("Public key"),
)
)
.subcommand(
SubCommand::with_name("new")
.about("Generate new keypair file from a passphrase and random seed phrase")
@@ -75,6 +114,15 @@ fn main() -> Result<(), Box<dyn error::Error>> {
.long("force")
.help("Overwrite the output file if it exists"),
)
.arg(
Arg::with_name("word_count")
.long("word-count")
.possible_values(&["12", "15", "18", "21", "24"])
.default_value("12")
.value_name("NUM")
.takes_value(true)
.help("Specify the number of words that will be present in the generated seed phrase"),
)
.arg(
Arg::with_name("no_passphrase")
.long("no-passphrase")
@@ -189,22 +237,7 @@ fn main() -> Result<(), Box<dyn error::Error>> {
match matches.subcommand() {
("pubkey", Some(matches)) => {
let mut path = dirs::home_dir().expect("home directory");
let infile = if matches.is_present("infile") {
matches.value_of("infile").unwrap()
} else {
path.extend(&[".config", "solana", "id.json"]);
path.to_str().unwrap()
};
let keypair = if infile == "-" {
let mut stdin = std::io::stdin();
read_keypair(&mut stdin)?
} else if infile == ASK_KEYWORD {
let skip_validation = matches.is_present(SKIP_SEED_PHRASE_VALIDATION_ARG.name);
keypair_from_seed_phrase("pubkey recovery", skip_validation)?
} else {
read_keypair_file(infile)?
};
let keypair = get_keypair_from_matches(matches)?;
if matches.is_present("outfile") {
let outfile = matches.value_of("outfile").unwrap();
@@ -231,13 +264,15 @@ fn main() -> Result<(), Box<dyn error::Error>> {
None => (),
}
let mnemonic = Mnemonic::new(MnemonicType::Words12, Language::English);
let word_count = value_t!(matches.value_of("word_count"), usize).unwrap();
let mnemonic_type = MnemonicType::for_word_count(word_count)?;
let mnemonic = Mnemonic::new(mnemonic_type, Language::English);
let passphrase = if matches.is_present("no_passphrase") {
NO_PASSPHRASE.to_string()
} else {
eprintln!("Generating a new keypair");
rpassword::prompt_password_stderr(
"For added security, enter a passphrase (empty for no passphrase):",
prompt_passphrase(
"For added security, enter a passphrase (empty for no passphrase): ",
)?
};
let seed = Seed::new(&mnemonic, &passphrase);
@@ -271,7 +306,7 @@ fn main() -> Result<(), Box<dyn error::Error>> {
}
let skip_validation = matches.is_present(SKIP_SEED_PHRASE_VALIDATION_ARG.name);
let keypair = keypair_from_seed_phrase("recover", skip_validation)?;
let keypair = keypair_from_seed_phrase("recover", skip_validation, true)?;
output_keypair(&keypair, &outfile, "recovered")?;
}
("grind", Some(matches)) => {
@@ -353,6 +388,19 @@ fn main() -> Result<(), Box<dyn error::Error>> {
.collect::<Vec<_>>();
thread::park();
}
("verify", Some(matches)) => {
let keypair = get_keypair_from_matches(matches)?;
let test_data = b"test";
let signature = Signature::new(&keypair.sign(test_data).to_bytes());
let pubkey_bs58 = matches.value_of("pubkey").unwrap();
let pubkey = bs58::decode(pubkey_bs58).into_vec().unwrap();
if signature.verify(&pubkey, test_data) {
println!("Verification for public key: {}: Success", pubkey_bs58);
} else {
println!("Verification for public key: {}: Failed", pubkey_bs58);
exit(1);
}
}
_ => unreachable!(),
}

View File

@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-ledger-tool"
description = "Blockchain, Rebuilt for Scale"
version = "0.21.0"
version = "0.21.1"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -15,12 +15,12 @@ serde = "1.0.102"
serde_derive = "1.0.102"
serde_json = "1.0.41"
serde_yaml = "0.8.11"
solana-clap-utils = { path = "../clap-utils", version = "0.21.0" }
solana-ledger = { path = "../ledger", version = "0.21.0" }
solana-logger = { path = "../logger", version = "0.21.0" }
solana-runtime = { path = "../runtime", version = "0.21.0" }
solana-sdk = { path = "../sdk", version = "0.21.0" }
solana-vote-program = { path = "../programs/vote", version = "0.21.0" }
solana-clap-utils = { path = "../clap-utils", version = "0.21.1" }
solana-ledger = { path = "../ledger", version = "0.21.1" }
solana-logger = { path = "../logger", version = "0.21.1" }
solana-runtime = { path = "../runtime", version = "0.21.1" }
solana-sdk = { path = "../sdk", version = "0.21.1" }
solana-vote-program = { path = "../programs/vote", version = "0.21.1" }
[dev-dependencies]
assert_cmd = "0.11"

View File

@@ -581,9 +581,9 @@ fn main() {
})
};
let account_paths = if let Some(account_paths) = matches.value_of("account_paths") {
Some(account_paths.to_string())
account_paths.split(',').map(PathBuf::from).collect()
} else {
Some(ledger_path.join("accounts").to_str().unwrap().to_string())
vec![ledger_path.join("accounts")]
};
let process_options = blocktree_processor::ProcessOptions {

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-ledger"
version = "0.21.0"
version = "0.21.1"
description = "Solana ledger"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -29,19 +29,19 @@ rayon = "1.2.0"
reed-solomon-erasure = { package = "solana-reed-solomon-erasure", version = "4.0.1-3", features = ["simd-accel"] }
serde = "1.0.102"
serde_derive = "1.0.102"
solana-client = { path = "../client", version = "0.21.0" }
solana-genesis-programs = { path = "../genesis-programs", version = "0.21.0" }
solana-logger = { path = "../logger", version = "0.21.0" }
solana-measure = { path = "../measure", version = "0.21.0" }
solana-merkle-tree = { path = "../merkle-tree", version = "0.21.0" }
solana-metrics = { path = "../metrics", version = "0.21.0" }
solana-perf = { path = "../perf", version = "0.21.0" }
solana-client = { path = "../client", version = "0.21.1" }
solana-genesis-programs = { path = "../genesis-programs", version = "0.21.1" }
solana-logger = { path = "../logger", version = "0.21.1" }
solana-measure = { path = "../measure", version = "0.21.1" }
solana-merkle-tree = { path = "../merkle-tree", version = "0.21.1" }
solana-metrics = { path = "../metrics", version = "0.21.1" }
solana-perf = { path = "../perf", version = "0.21.1" }
ed25519-dalek = "1.0.0-pre.1"
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "0.21.0" }
solana-runtime = { path = "../runtime", version = "0.21.0" }
solana-sdk = { path = "../sdk", version = "0.21.0" }
solana-stake-program = { path = "../programs/stake", version = "0.21.0" }
solana-vote-program = { path = "../programs/vote", version = "0.21.0" }
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "0.21.1" }
solana-runtime = { path = "../runtime", version = "0.21.1" }
solana-sdk = { path = "../sdk", version = "0.21.1" }
solana-stake-program = { path = "../programs/stake", version = "0.21.1" }
solana-vote-program = { path = "../programs/vote", version = "0.21.1" }
sys-info = "0.5.8"
tar = "0.4.26"
tempfile = "3.1.0"
@@ -55,7 +55,7 @@ features = ["lz4"]
[dev-dependencies]
matches = "0.1.6"
solana-budget-program = { path = "../programs/budget", version = "0.21.0" }
solana-budget-program = { path = "../programs/budget", version = "0.21.1" }
[lib]
crate-type = ["lib"]

View File

@@ -7,12 +7,12 @@ use crate::{
};
use log::*;
use solana_sdk::genesis_config::GenesisConfig;
use std::{fs, sync::Arc};
use std::{fs, path::PathBuf, sync::Arc};
pub fn load(
genesis_config: &GenesisConfig,
blocktree: &Blocktree,
account_paths: Option<String>,
account_paths: Vec<PathBuf>,
snapshot_config: Option<&SnapshotConfig>,
process_options: ProcessOptions,
) -> Result<(BankForks, Vec<BankForksInfo>, LeaderScheduleCache), BlocktreeProcessorError> {
@@ -30,10 +30,13 @@ pub fn load(
if tar.exists() {
info!("Loading snapshot package: {:?}", tar);
// Fail hard here if snapshot fails to load, don't silently continue
if account_paths.is_empty() {
panic!("Account paths not present when booting from snapshot")
}
let deserialized_bank = snapshot_utils::bank_from_archive(
account_paths
.clone()
.expect("Account paths not present when booting from snapshot"),
&account_paths,
&snapshot_config.snapshot_path,
&tar,
)

View File

@@ -27,6 +27,7 @@ use solana_sdk::{
};
use std::{
cell::RefCell,
path::PathBuf,
result,
sync::Arc,
time::{Duration, Instant},
@@ -253,7 +254,7 @@ pub struct ProcessOptions {
pub fn process_blocktree(
genesis_config: &GenesisConfig,
blocktree: &Blocktree,
account_paths: Option<String>,
account_paths: Vec<PathBuf>,
opts: ProcessOptions,
) -> result::Result<(BankForks, Vec<BankForksInfo>, LeaderScheduleCache), BlocktreeProcessorError> {
if let Some(num_threads) = opts.override_num_threads {
@@ -662,7 +663,7 @@ pub mod tests {
..ProcessOptions::default()
};
assert_eq!(
process_blocktree(&genesis_config, &blocktree, None, opts).err(),
process_blocktree(&genesis_config, &blocktree, Vec::new(), opts).err(),
Some(BlocktreeProcessorError::InvalidBlock(
BlockError::InvalidTickHashCount
)),
@@ -703,7 +704,7 @@ pub mod tests {
..ProcessOptions::default()
};
assert_eq!(
process_blocktree(&genesis_config, &blocktree, None, opts).err(),
process_blocktree(&genesis_config, &blocktree, Vec::new(), opts).err(),
Some(BlocktreeProcessorError::InvalidBlock(
BlockError::InvalidTickCount
)),
@@ -755,7 +756,7 @@ pub mod tests {
..ProcessOptions::default()
};
assert_eq!(
process_blocktree(&genesis_config, &blocktree, None, opts).err(),
process_blocktree(&genesis_config, &blocktree, Vec::new(), opts).err(),
Some(BlocktreeProcessorError::InvalidBlock(
BlockError::TrailingEntry
)),
@@ -822,7 +823,7 @@ pub mod tests {
..ProcessOptions::default()
};
let (mut _bank_forks, bank_forks_info, _) =
process_blocktree(&genesis_config, &blocktree, None, opts).unwrap();
process_blocktree(&genesis_config, &blocktree, Vec::new(), opts).unwrap();
assert_eq!(bank_forks_info.len(), 1);
assert_eq!(
@@ -884,7 +885,7 @@ pub mod tests {
..ProcessOptions::default()
};
let (bank_forks, bank_forks_info, _) =
process_blocktree(&genesis_config, &blocktree, None, opts).unwrap();
process_blocktree(&genesis_config, &blocktree, Vec::new(), opts).unwrap();
assert_eq!(bank_forks_info.len(), 1); // One fork, other one is ignored b/c not a descendant of the root
@@ -958,7 +959,7 @@ pub mod tests {
..ProcessOptions::default()
};
let (bank_forks, bank_forks_info, _) =
process_blocktree(&genesis_config, &blocktree, None, opts).unwrap();
process_blocktree(&genesis_config, &blocktree, Vec::new(), opts).unwrap();
assert_eq!(bank_forks_info.len(), 2); // There are two forks
assert_eq!(
@@ -1022,9 +1023,13 @@ pub mod tests {
blocktree.set_dead_slot(2).unwrap();
fill_blocktree_slot_with_ticks(&blocktree, ticks_per_slot, 3, 1, slot1_blockhash);
let (bank_forks, bank_forks_info, _) =
process_blocktree(&genesis_config, &blocktree, None, ProcessOptions::default())
.unwrap();
let (bank_forks, bank_forks_info, _) = process_blocktree(
&genesis_config,
&blocktree,
Vec::new(),
ProcessOptions::default(),
)
.unwrap();
assert_eq!(bank_forks_info.len(), 1);
assert_eq!(bank_forks_info[0], BankForksInfo { bank_slot: 3 });
@@ -1054,7 +1059,7 @@ pub mod tests {
Blocktree::open(&ledger_path).expect("Expected to successfully open database ledger");
// Let last_slot be the number of slots in the first two epochs
let epoch_schedule = get_epoch_schedule(&genesis_config, None);
let epoch_schedule = get_epoch_schedule(&genesis_config, Vec::new());
let last_slot = epoch_schedule.get_last_slot_in_epoch(1);
// Create a single chain of slots with all indexes in the range [0, last_slot + 1]
@@ -1081,7 +1086,7 @@ pub mod tests {
..ProcessOptions::default()
};
let (bank_forks, bank_forks_info, _) =
process_blocktree(&genesis_config, &blocktree, None, opts).unwrap();
process_blocktree(&genesis_config, &blocktree, Vec::new(), opts).unwrap();
assert_eq!(bank_forks_info.len(), 1); // There is one fork
assert_eq!(
@@ -1229,7 +1234,7 @@ pub mod tests {
..ProcessOptions::default()
};
let (bank_forks, bank_forks_info, _) =
process_blocktree(&genesis_config, &blocktree, None, opts).unwrap();
process_blocktree(&genesis_config, &blocktree, Vec::new(), opts).unwrap();
assert_eq!(bank_forks_info.len(), 1);
assert_eq!(bank_forks.root(), 0);
@@ -1258,7 +1263,7 @@ pub mod tests {
..ProcessOptions::default()
};
let (bank_forks, bank_forks_info, _) =
process_blocktree(&genesis_config, &blocktree, None, opts).unwrap();
process_blocktree(&genesis_config, &blocktree, Vec::new(), opts).unwrap();
assert_eq!(bank_forks_info.len(), 1);
assert_eq!(bank_forks_info[0], BankForksInfo { bank_slot: 0 });
@@ -1276,7 +1281,7 @@ pub mod tests {
override_num_threads: Some(1),
..ProcessOptions::default()
};
process_blocktree(&genesis_config, &blocktree, None, opts).unwrap();
process_blocktree(&genesis_config, &blocktree, Vec::new(), opts).unwrap();
PAR_THREAD_POOL.with(|pool| {
assert_eq!(pool.borrow().current_num_threads(), 1);
});
@@ -1293,7 +1298,7 @@ pub mod tests {
..ProcessOptions::default()
};
let (_bank_forks, _bank_forks_info, cached_leader_schedule) =
process_blocktree(&genesis_config, &blocktree, None, opts).unwrap();
process_blocktree(&genesis_config, &blocktree, Vec::new(), opts).unwrap();
assert_eq!(cached_leader_schedule.max_schedules(), std::usize::MAX);
}
@@ -1353,7 +1358,7 @@ pub mod tests {
entry_callback: Some(entry_callback),
..ProcessOptions::default()
};
process_blocktree(&genesis_config, &blocktree, None, opts).unwrap();
process_blocktree(&genesis_config, &blocktree, Vec::new(), opts).unwrap();
assert_eq!(*callback_counter.write().unwrap(), 2);
}
@@ -2188,7 +2193,7 @@ pub mod tests {
fn get_epoch_schedule(
genesis_config: &GenesisConfig,
account_paths: Option<String>,
account_paths: Vec<PathBuf>,
) -> EpochSchedule {
let bank = Bank::new_with_paths(&genesis_config, account_paths);
bank.epoch_schedule().clone()

View File

@@ -86,7 +86,7 @@ pub fn package_snapshot<P: AsRef<Path>, Q: AsRef<Path>>(
// Get a reference to all the relevant AccountStorageEntries
let account_storage_entries: Vec<_> = bank
.rc
.get_storage_entries()
.get_rooted_storage_entries()
.into_iter()
.filter(|x| x.slot_id() <= bank.slot())
.collect();
@@ -207,7 +207,7 @@ pub fn bank_slot_from_archive<P: AsRef<Path>>(snapshot_tar: P) -> Result<u64> {
}
pub fn bank_from_archive<P: AsRef<Path>>(
account_paths: String,
account_paths: &[PathBuf],
snapshot_path: &PathBuf,
snapshot_tar: P,
) -> Result<Bank> {
@@ -266,7 +266,7 @@ pub fn untar_snapshot_in<P: AsRef<Path>, Q: AsRef<Path>>(
}
fn rebuild_bank_from_snapshots<P>(
local_account_paths: String,
local_account_paths: &[PathBuf],
unpacked_snapshots_dir: &PathBuf,
append_vecs_path: P,
) -> Result<Bank>

View File

@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-local-cluster"
description = "Blockchain, Rebuilt for Scale"
version = "0.21.0"
version = "0.21.1"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -11,23 +11,23 @@ homepage = "https://solana.com/"
[dependencies]
log = "0.4.8"
rand = "0.6.5"
solana-config-program = { path = "../programs/config", version = "0.21.0" }
solana-core = { path = "../core", version = "0.21.0" }
solana-client = { path = "../client", version = "0.21.0" }
solana-drone = { path = "../drone", version = "0.21.0" }
solana-exchange-program = { path = "../programs/exchange", version = "0.21.0" }
solana-genesis-programs = { path = "../genesis-programs", version = "0.21.0" }
solana-ledger = { path = "../ledger", version = "0.21.0" }
solana-logger = { path = "../logger", version = "0.21.0" }
solana-runtime = { path = "../runtime", version = "0.21.0" }
solana-sdk = { path = "../sdk", version = "0.21.0" }
solana-stake-program = { path = "../programs/stake", version = "0.21.0" }
solana-storage-program = { path = "../programs/storage", version = "0.21.0" }
solana-vest-program = { path = "../programs/vest", version = "0.21.0" }
solana-vote-program = { path = "../programs/vote", version = "0.21.0" }
solana-config-program = { path = "../programs/config", version = "0.21.1" }
solana-core = { path = "../core", version = "0.21.1" }
solana-client = { path = "../client", version = "0.21.1" }
solana-drone = { path = "../drone", version = "0.21.1" }
solana-exchange-program = { path = "../programs/exchange", version = "0.21.1" }
solana-genesis-programs = { path = "../genesis-programs", version = "0.21.1" }
solana-ledger = { path = "../ledger", version = "0.21.1" }
solana-logger = { path = "../logger", version = "0.21.1" }
solana-runtime = { path = "../runtime", version = "0.21.1" }
solana-sdk = { path = "../sdk", version = "0.21.1" }
solana-stake-program = { path = "../programs/stake", version = "0.21.1" }
solana-storage-program = { path = "../programs/storage", version = "0.21.1" }
solana-vest-program = { path = "../programs/vest", version = "0.21.1" }
solana-vote-program = { path = "../programs/vote", version = "0.21.1" }
symlink = "0.1.0"
tempfile = "3.1.0"
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "0.21.0" }
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "0.21.1" }
[dev-dependencies]
serial_test = "0.2.0"

View File

@@ -151,7 +151,10 @@ impl LocalCluster {
match genesis_config.operating_mode {
OperatingMode::SoftLaunch => {
genesis_config.native_instruction_processors =
solana_genesis_programs::get_programs(genesis_config.operating_mode, 0).unwrap()
solana_genesis_programs::get_programs(genesis_config.operating_mode, 0)
.unwrap()
.into_iter()
.collect()
}
// create_genesis_config_with_leader() assumes OperatingMode::Development so do
// nothing...
@@ -169,18 +172,13 @@ impl LocalCluster {
.push(solana_storage_program!());
let storage_keypair = Keypair::new();
genesis_config.accounts.push((
genesis_config.add_account(
storage_keypair.pubkey(),
storage_contract::create_validator_storage_account(leader_pubkey, 1),
));
);
// Replace staking config
genesis_config.accounts = genesis_config
.accounts
.into_iter()
.filter(|(pubkey, _)| *pubkey != stake_config::id())
.collect();
genesis_config.accounts.push((
genesis_config.add_account(
stake_config::id(),
stake_config::create_account(
1,
@@ -189,7 +187,7 @@ impl LocalCluster {
slash_penalty: std::u8::MAX,
},
),
));
);
let (leader_ledger_path, _blockhash) = create_new_tmp_ledger!(&genesis_config);
let leader_contact_info = leader_node.info.clone();

View File

@@ -14,7 +14,6 @@ use solana_local_cluster::{
cluster_tests,
local_cluster::{ClusterConfig, LocalCluster},
};
use solana_runtime::accounts_db::AccountsDB;
use solana_sdk::timing::timestamp;
use solana_sdk::{
client::SyncClient,
@@ -648,7 +647,7 @@ fn test_snapshots_restart_validity() {
let (new_account_storage_dirs, new_account_storage_paths) =
generate_account_paths(num_account_paths);
all_account_storage_dirs.push(new_account_storage_dirs);
snapshot_test_config.validator_config.account_paths = Some(new_account_storage_paths);
snapshot_test_config.validator_config.account_paths = new_account_storage_paths;
// Restart node
trace!("Restarting cluster from snapshot");
@@ -903,15 +902,14 @@ fn wait_for_next_snapshot<P: AsRef<Path>>(cluster: &LocalCluster, tar: P) {
}
}
fn generate_account_paths(num_account_paths: usize) -> (Vec<TempDir>, String) {
fn generate_account_paths(num_account_paths: usize) -> (Vec<TempDir>, Vec<PathBuf>) {
let account_storage_dirs: Vec<TempDir> = (0..num_account_paths)
.map(|_| TempDir::new().unwrap())
.collect();
let account_storage_paths: Vec<_> = account_storage_dirs
.iter()
.map(|a| a.path().to_str().unwrap().to_string())
.map(|a| a.path().to_path_buf())
.collect();
let account_storage_paths = AccountsDB::format_paths(account_storage_paths);
(account_storage_dirs, account_storage_paths)
}
@@ -942,7 +940,7 @@ fn setup_snapshot_validator_config(
let mut validator_config = ValidatorConfig::default();
validator_config.rpc_config.enable_validator_exit = true;
validator_config.snapshot_config = Some(snapshot_config);
validator_config.account_paths = Some(account_storage_paths);
validator_config.account_paths = account_storage_paths;
SnapshotValidatorConfig {
_snapshot_dir: snapshot_dir,

View File

@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-log-analyzer"
description = "The solana cluster network analysis tool"
version = "0.1.0"
version = "0.21.1"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -17,8 +17,8 @@ semver = "0.9.0"
serde = "1.0.102"
serde_derive = "1.0.102"
serde_json = "1.0.41"
solana-clap-utils = { path = "../clap-utils", version = "0.21.0" }
solana-logger = { path = "../logger", version = "0.21.0" }
solana-clap-utils = { path = "../clap-utils", version = "0.21.1" }
solana-logger = { path = "../logger", version = "0.21.1" }
[[bin]]
name = "solana-log-analyzer"

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-logger"
version = "0.21.0"
version = "0.21.1"
description = "Solana Logger"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"

View File

@@ -1,7 +1,7 @@
[package]
name = "solana-measure"
description = "Blockchain, Rebuilt for Scale"
version = "0.21.0"
version = "0.21.1"
documentation = "https://docs.rs/solana"
homepage = "https://solana.com/"
readme = "../README.md"
@@ -11,4 +11,4 @@ license = "Apache-2.0"
edition = "2018"
[dependencies]
solana-sdk = { path = "../sdk", version = "0.21.0" }
solana-sdk = { path = "../sdk", version = "0.21.1" }

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-merkle-tree"
version = "0.21.0"
version = "0.21.1"
description = "Solana Merkle Tree"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -9,7 +9,7 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-sdk = { path = "../sdk", version = "0.21.0" }
solana-sdk = { path = "../sdk", version = "0.21.1" }
[dev-dependencies]
hex = "0.4.0"

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-metrics"
version = "0.21.0"
version = "0.21.1"
description = "Solana Metrics"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -13,7 +13,7 @@ env_logger = "0.7.1"
lazy_static = "1.4.0"
log = "0.4.8"
reqwest = { version = "0.9.22", default-features = false, features = ["rustls-tls"] }
solana-sdk = { path = "../sdk", version = "0.21.0" }
solana-sdk = { path = "../sdk", version = "0.21.1" }
sys-info = "0.5.8"
[dev-dependencies]

View File

@@ -262,7 +262,7 @@ setup_validator_accounts() {
fi
echo "Creating validator vote account"
wallet create-vote-account "$voting_keypair_path" "$identity_keypair_path" --commission 127 || return $?
wallet create-vote-account "$voting_keypair_path" "$identity_keypair_path" --commission 50 || return $?
fi
echo "Validator vote account configured"

View File

@@ -3,7 +3,7 @@ authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-net-shaper"
description = "The solana cluster network shaping tool"
version = "0.1.0"
version = "0.21.1"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
@@ -16,8 +16,8 @@ semver = "0.9.0"
serde = "1.0.102"
serde_derive = "1.0.102"
serde_json = "1.0.41"
solana-clap-utils = { path = "../clap-utils", version = "0.21.0" }
solana-logger = { path = "../logger", version = "0.21.0" }
solana-clap-utils = { path = "../clap-utils", version = "0.21.1" }
solana-logger = { path = "../logger", version = "0.21.1" }
rand = "0.6.5"
[[bin]]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-net-utils"
version = "0.21.0"
version = "0.21.1"
description = "Solana Network Utilities"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -18,8 +18,8 @@ rand = "0.6.1"
serde = "1.0.102"
serde_derive = "1.0.102"
socket2 = "0.3.11"
solana-clap-utils = { path = "../clap-utils", version = "0.21.0" }
solana-logger = { path = "../logger", version = "0.21.0" }
solana-clap-utils = { path = "../clap-utils", version = "0.21.1" }
solana-logger = { path = "../logger", version = "0.21.1" }
tokio = "0.1"
tokio-codec = "0.1"

View File

@@ -42,83 +42,145 @@ pub fn ip_echo_server(tcp: std::net::TcpListener) -> IpEchoServer {
.incoming()
.map_err(|err| warn!("accept failed: {:?}", err))
.for_each(move |socket| {
let ip = socket.peer_addr().expect("Expect peer_addr()").ip();
info!("connection from {:?}", ip);
let peer_addr = socket.peer_addr().expect("Expect peer_addr()");
info!("connection from {:?}", peer_addr);
let framed = BytesCodec::new().framed(socket);
let (writer, reader) = framed.split();
let processor = reader
.and_then(move |bytes| {
bincode::deserialize::<IpEchoServerMessage>(&bytes).or_else(|err| {
Err(io::Error::new(
.and_then(move |data| {
if data.len() < 4 {
return Err(io::Error::new(
io::ErrorKind::Other,
format!("Failed to deserialize IpEchoServerMessage: {:?}", err),
))
})
format!("Request too short, received {} bytes", data.len()),
));
}
let request_header: String = data[0..4].iter().map(|b| *b as char).collect();
if request_header != "\0\0\0\0" {
// Explicitly check for HTTP GET/POST requests to more gracefully handle
// the case where a user accidentally tried to use a gossip entrypoint in
// place of a JSON RPC URL:
if request_header == "GET " || request_header == "POST" {
return Ok(None); // None -> Send HTTP error response
}
return Err(io::Error::new(
io::ErrorKind::Other,
format!("Bad request header: {}", request_header),
));
}
let expected_len =
bincode::serialized_size(&IpEchoServerMessage::default()).unwrap() as usize;
let actual_len = data[4..].len();
if actual_len < expected_len {
return Err(io::Error::new(
io::ErrorKind::Other,
format!(
"Request too short, actual {} < expected {}",
actual_len, expected_len
),
));
}
bincode::deserialize::<IpEchoServerMessage>(&data[4..])
.map(Some)
.or_else(|err| {
Err(io::Error::new(
io::ErrorKind::Other,
format!("Failed to deserialize IpEchoServerMessage: {:?}", err),
))
})
})
.and_then(move |msg| {
// Fire a datagram at each non-zero UDP port
if !msg.udp_ports.is_empty() {
match std::net::UdpSocket::bind("0.0.0.0:0") {
Ok(udp_socket) => {
for udp_port in &msg.udp_ports {
if *udp_port != 0 {
match udp_socket
.send_to(&[0], SocketAddr::from((ip, *udp_port)))
{
Ok(_) => debug!("Successful send_to udp/{}", udp_port),
Err(err) => {
info!("Failed to send_to udp/{}: {}", udp_port, err)
.and_then(move |maybe_msg| {
match maybe_msg {
None => None, // Send HTTP error response
Some(msg) => {
// Fire a datagram at each non-zero UDP port
if !msg.udp_ports.is_empty() {
match std::net::UdpSocket::bind("0.0.0.0:0") {
Ok(udp_socket) => {
for udp_port in &msg.udp_ports {
if *udp_port != 0 {
match udp_socket.send_to(
&[0],
SocketAddr::from((peer_addr.ip(), *udp_port)),
) {
Ok(_) => debug!(
"Successful send_to udp/{}",
udp_port
),
Err(err) => info!(
"Failed to send_to udp/{}: {}",
udp_port, err
),
}
}
}
}
Err(err) => {
warn!("Failed to bind local udp socket: {}", err);
}
}
}
Err(err) => {
warn!("Failed to bind local udp socket: {}", err);
}
// Try to connect to each non-zero TCP port
let tcp_futures: Vec<_> =
msg.tcp_ports
.iter()
.filter_map(|tcp_port| {
let tcp_port = *tcp_port;
if tcp_port == 0 {
None
} else {
Some(
tokio::net::TcpStream::connect(&SocketAddr::new(
peer_addr.ip(),
tcp_port,
))
.and_then(move |tcp_stream| {
debug!(
"Connection established to tcp/{}",
tcp_port
);
let _ = tcp_stream
.shutdown(std::net::Shutdown::Both);
Ok(())
})
.timeout(Duration::from_secs(5))
.or_else(move |err| {
Err(io::Error::new(
io::ErrorKind::Other,
format!(
"Connection timeout to {}: {:?}",
tcp_port, err
),
))
}),
)
}
})
.collect();
Some(future::join_all(tcp_futures))
}
}
// Try to connect to each non-zero TCP port
let tcp_futures: Vec<_> = msg
.tcp_ports
.iter()
.filter_map(|tcp_port| {
let tcp_port = *tcp_port;
if tcp_port == 0 {
None
} else {
Some(
tokio::net::TcpStream::connect(&SocketAddr::new(ip, tcp_port))
.and_then(move |tcp_stream| {
debug!("Connection established to tcp/{}", tcp_port);
let _ = tcp_stream.shutdown(std::net::Shutdown::Both);
Ok(())
})
.timeout(Duration::from_secs(5))
.or_else(move |err| {
Err(io::Error::new(
io::ErrorKind::Other,
format!(
"Connection timeout to {}: {:?}",
tcp_port, err
),
))
}),
)
}
})
.collect();
future::join_all(tcp_futures)
})
.and_then(move |_| {
let ip = bincode::serialize(&ip).unwrap_or_else(|err| {
warn!("Failed to serialize: {:?}", err);
vec![]
});
Ok(Bytes::from(ip))
.and_then(move |valid_request| {
if valid_request.is_none() {
Ok(Bytes::from(
"HTTP/1.1 400 Bad Request\nContent-length: 0\n\n",
))
} else {
// "\0\0\0\0" header is added to ensure a valid response will never
// conflict with the first four bytes of a valid HTTP response.
let mut bytes = vec![
0;
4 + bincode::serialized_size(&peer_addr.ip()).unwrap()
as usize
];
bincode::serialize_into(&mut bytes[4..], &peer_addr.ip()).unwrap();
Ok(Bytes::from(bytes))
}
});
let connection = writer

View File

@@ -29,8 +29,15 @@ fn ip_echo_server_request(
let timeout = Duration::new(5, 0);
TcpStream::connect_timeout(ip_echo_server_addr, timeout)
.and_then(|mut stream| {
let msg = bincode::serialize(&msg).expect("serialize IpEchoServerMessage");
stream.write_all(&msg)?;
let mut bytes = vec![0; 4]; // Start with 4 null bytes to avoid looking like an HTTP GET/POST request
bytes.append(&mut bincode::serialize(&msg).expect("serialize IpEchoServerMessage"));
// End with '\n' to make this request look HTTP-ish and tickle an error response back
// from an HTTP server
bytes.push(b'\n');
stream.write_all(&bytes)?;
stream.shutdown(std::net::Shutdown::Write)?;
stream
.set_read_timeout(Some(Duration::new(10, 0)))
@@ -38,7 +45,38 @@ fn ip_echo_server_request(
stream.read_to_end(&mut data)
})
.and_then(|_| {
bincode::deserialize(&data).map_err(|err| {
// It's common for users to accidentally confuse the validator's gossip port and JSON
// RPC port. Attempt to detect when this occurs by looking for the standard HTTP
// response header and provide the user with a helpful error message
if data.len() < 4 {
return Err(io::Error::new(
io::ErrorKind::Other,
format!("Response too short, received {} bytes", data.len()),
));
}
let response_header: String = data[0..4].iter().map(|b| *b as char).collect();
if response_header != "\0\0\0\0" {
if response_header == "HTTP" {
let http_response = data.iter().map(|b| *b as char).collect::<String>();
return Err(io::Error::new(
io::ErrorKind::Other,
format!(
"Invalid gossip entrypoint. {} looks to be an HTTP port: {}",
ip_echo_server_addr, http_response
),
));
}
return Err(io::Error::new(
io::ErrorKind::Other,
format!(
"Invalid gossip entrypoint. {} provided an invalid response header: '{}'",
ip_echo_server_addr, response_header
),
));
}
bincode::deserialize(&data[4..]).map_err(|err| {
io::Error::new(
io::ErrorKind::Other,
format!("Failed to deserialize: {:?}", err),
@@ -102,7 +140,7 @@ pub fn verify_reachable_ports(
);
std::process::exit(1);
});
info!("tdp/{} is reachable", port);
info!("tcp/{} is reachable", port);
}
// Wait for a datagram to arrive at each UDP port
@@ -435,6 +473,7 @@ mod tests {
#[test]
fn test_get_public_ip_addr() {
solana_logger::setup();
let (_server_port, (server_udp_socket, server_tcp_listener)) =
bind_common_in_range((3200, 3250)).unwrap();
let (client_port, (client_udp_socket, client_tcp_listener)) =
@@ -443,7 +482,10 @@ mod tests {
let _runtime = ip_echo_server(server_tcp_listener);
let ip_echo_server_addr = server_udp_socket.local_addr().unwrap();
get_public_ip_addr(&ip_echo_server_addr).unwrap();
assert_eq!(
get_public_ip_addr(&ip_echo_server_addr),
parse_host("127.0.0.1"),
);
verify_reachable_ports(
&ip_echo_server_addr,

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-perf"
version = "0.21.0"
version = "0.21.1"
description = "Solana Performance APIs"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -18,11 +18,11 @@ serde_derive = "1.0.102"
dlopen_derive = "0.1.4"
lazy_static = "1.4.0"
log = "0.4.8"
solana-sdk = { path = "../sdk", version = "0.21.0" }
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "0.21.0" }
solana-budget-program = { path = "../programs/budget", version = "0.21.0" }
solana-logger = { path = "../logger", version = "0.21.0" }
solana-metrics = { path = "../metrics", version = "0.21.0" }
solana-sdk = { path = "../sdk", version = "0.21.1" }
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "0.21.1" }
solana-budget-program = { path = "../programs/budget", version = "0.21.1" }
solana-logger = { path = "../logger", version = "0.21.1" }
solana-metrics = { path = "../metrics", version = "0.21.1" }
[lib]
name = "solana_perf"

203
programs/bpf/Cargo.lock generated
View File

@@ -245,12 +245,12 @@ dependencies = [
[[package]]
name = "chrono"
version = "0.4.9"
version = "0.4.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
"num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -822,7 +822,7 @@ dependencies = [
[[package]]
name = "itertools"
version = "0.8.1"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1117,7 +1117,7 @@ version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
"chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1585,156 +1585,157 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "solana-bpf-loader-program"
version = "0.21.0"
version = "0.21.1"
dependencies = [
"bincode 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
"solana-logger 0.21.0",
"solana-sdk 0.21.0",
"solana-logger 0.21.1",
"solana-sdk 0.21.1",
"solana_rbpf 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "solana-bpf-programs"
version = "0.21.0"
version = "0.21.1"
dependencies = [
"bincode 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"elf 0.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
"solana-bpf-loader-program 0.21.0",
"solana-logger 0.21.0",
"solana-runtime 0.21.0",
"solana-sdk 0.21.0",
"solana-bpf-loader-program 0.21.1",
"solana-logger 0.21.1",
"solana-runtime 0.21.1",
"solana-sdk 0.21.1",
"solana_rbpf 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)",
"walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "solana-bpf-rust-128bit"
version = "0.21.0"
version = "0.21.1"
dependencies = [
"solana-bpf-rust-128bit-dep 0.21.0",
"solana-sdk 0.21.0",
"solana-sdk-bpf-test 0.21.0",
"solana-bpf-rust-128bit-dep 0.21.1",
"solana-sdk 0.21.1",
"solana-sdk-bpf-test 0.21.1",
]
[[package]]
name = "solana-bpf-rust-128bit-dep"
version = "0.21.0"
version = "0.21.1"
dependencies = [
"solana-sdk 0.21.0",
"solana-sdk-bpf-test 0.21.0",
"solana-sdk 0.21.1",
"solana-sdk-bpf-test 0.21.1",
]
[[package]]
name = "solana-bpf-rust-alloc"
version = "0.21.0"
version = "0.21.1"
dependencies = [
"solana-sdk 0.21.0",
"solana-sdk-bpf-test 0.21.0",
"solana-sdk 0.21.1",
"solana-sdk-bpf-test 0.21.1",
]
[[package]]
name = "solana-bpf-rust-dep-crate"
version = "0.21.0"
version = "0.21.1"
dependencies = [
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"solana-sdk 0.21.0",
"solana-sdk-bpf-test 0.21.0",
"solana-sdk 0.21.1",
"solana-sdk-bpf-test 0.21.1",
]
[[package]]
name = "solana-bpf-rust-external-spend"
version = "0.21.0"
version = "0.21.1"
dependencies = [
"solana-sdk 0.21.0",
"solana-sdk-bpf-test 0.21.0",
"solana-sdk 0.21.1",
"solana-sdk-bpf-test 0.21.1",
]
[[package]]
name = "solana-bpf-rust-iter"
version = "0.21.0"
version = "0.21.1"
dependencies = [
"solana-sdk 0.21.0",
"solana-sdk-bpf-test 0.21.0",
"solana-sdk 0.21.1",
"solana-sdk-bpf-test 0.21.1",
]
[[package]]
name = "solana-bpf-rust-many-args"
version = "0.21.0"
version = "0.21.1"
dependencies = [
"solana-bpf-rust-many-args-dep 0.21.0",
"solana-sdk 0.21.0",
"solana-sdk-bpf-test 0.21.0",
"solana-bpf-rust-many-args-dep 0.21.1",
"solana-sdk 0.21.1",
"solana-sdk-bpf-test 0.21.1",
]
[[package]]
name = "solana-bpf-rust-many-args-dep"
version = "0.21.0"
version = "0.21.1"
dependencies = [
"solana-sdk 0.21.0",
"solana-sdk-bpf-test 0.21.0",
"solana-sdk 0.21.1",
"solana-sdk-bpf-test 0.21.1",
]
[[package]]
name = "solana-bpf-rust-noop"
version = "0.21.0"
version = "0.21.1"
dependencies = [
"solana-sdk 0.21.0",
"solana-sdk-bpf-test 0.21.0",
"solana-sdk 0.21.1",
"solana-sdk-bpf-test 0.21.1",
]
[[package]]
name = "solana-bpf-rust-panic"
version = "0.21.0"
version = "0.21.1"
dependencies = [
"solana-sdk 0.21.0",
"solana-sdk-bpf-test 0.21.0",
"solana-sdk 0.21.1",
"solana-sdk-bpf-test 0.21.1",
]
[[package]]
name = "solana-bpf-rust-param-passing"
version = "0.21.0"
version = "0.21.1"
dependencies = [
"solana-bpf-rust-param-passing-dep 0.21.0",
"solana-sdk 0.21.0",
"solana-sdk-bpf-test 0.21.0",
"solana-bpf-rust-param-passing-dep 0.21.1",
"solana-sdk 0.21.1",
"solana-sdk-bpf-test 0.21.1",
]
[[package]]
name = "solana-bpf-rust-param-passing-dep"
version = "0.21.0"
version = "0.21.1"
dependencies = [
"solana-sdk 0.21.0",
"solana-sdk-bpf-test 0.21.0",
"solana-sdk 0.21.1",
"solana-sdk-bpf-test 0.21.1",
]
[[package]]
name = "solana-bpf-rust-sysval"
version = "0.21.0"
version = "0.21.1"
dependencies = [
"solana-sdk 0.21.0",
"solana-sdk-bpf-test 0.21.0",
"solana-sdk 0.21.1",
"solana-sdk-bpf-test 0.21.1",
]
[[package]]
name = "solana-config-program"
version = "0.21.0"
version = "0.21.1"
dependencies = [
"bincode 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
"solana-logger 0.21.0",
"solana-sdk 0.21.0",
"solana-logger 0.21.1",
"solana-sdk 0.21.1",
]
[[package]]
name = "solana-crate-features"
version = "0.21.0"
version = "0.21.1"
dependencies = [
"backtrace 0.3.37 (registry+https://github.com/rust-lang/crates.io-index)",
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1757,7 +1758,7 @@ dependencies = [
[[package]]
name = "solana-logger"
version = "0.21.0"
version = "0.21.1"
dependencies = [
"env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1766,26 +1767,26 @@ dependencies = [
[[package]]
name = "solana-measure"
version = "0.21.0"
version = "0.21.1"
dependencies = [
"solana-sdk 0.21.0",
"solana-sdk 0.21.1",
]
[[package]]
name = "solana-metrics"
version = "0.21.0"
version = "0.21.1"
dependencies = [
"env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"reqwest 0.9.22 (registry+https://github.com/rust-lang/crates.io-index)",
"solana-sdk 0.21.0",
"solana-sdk 0.21.1",
"sys-info 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "solana-rayon-threadlimit"
version = "0.21.0"
version = "0.21.1"
dependencies = [
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"sys-info 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1793,14 +1794,14 @@ dependencies = [
[[package]]
name = "solana-runtime"
version = "0.21.0"
version = "0.21.1"
dependencies = [
"bincode 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bv 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"fs_extra 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"itertools 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
"libloading 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1811,22 +1812,22 @@ dependencies = [
"serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)",
"solana-bpf-loader-program 0.21.0",
"solana-logger 0.21.0",
"solana-measure 0.21.0",
"solana-metrics 0.21.0",
"solana-rayon-threadlimit 0.21.0",
"solana-sdk 0.21.0",
"solana-stake-program 0.21.0",
"solana-storage-program 0.21.0",
"solana-vote-program 0.21.0",
"solana-bpf-loader-program 0.21.1",
"solana-logger 0.21.1",
"solana-measure 0.21.1",
"solana-metrics 0.21.1",
"solana-rayon-threadlimit 0.21.1",
"solana-sdk 0.21.1",
"solana-stake-program 0.21.1",
"solana-storage-program 0.21.1",
"solana-vote-program 0.21.1",
"sys-info 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
"tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "solana-sdk"
version = "0.21.0"
version = "0.21.1"
dependencies = [
"assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bincode 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1836,8 +1837,7 @@ dependencies = [
"generic-array 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)",
"hex 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"itertools 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"num-derive 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1850,17 +1850,28 @@ dependencies = [
"serde_derive 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)",
"sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"solana-crate-features 0.21.0",
"solana-logger 0.21.0",
"solana-crate-features 0.21.1",
"solana-logger 0.21.1",
"solana-sdk-macro 0.21.1",
]
[[package]]
name = "solana-sdk-bpf-test"
version = "0.21.0"
version = "0.21.1"
[[package]]
name = "solana-sdk-macro"
version = "0.21.1"
dependencies = [
"bs58 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "solana-stake-program"
version = "0.21.0"
version = "0.21.1"
dependencies = [
"bincode 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1869,16 +1880,16 @@ dependencies = [
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
"solana-config-program 0.21.0",
"solana-logger 0.21.0",
"solana-metrics 0.21.0",
"solana-sdk 0.21.0",
"solana-vote-program 0.21.0",
"solana-config-program 0.21.1",
"solana-logger 0.21.1",
"solana-metrics 0.21.1",
"solana-sdk 0.21.1",
"solana-vote-program 0.21.1",
]
[[package]]
name = "solana-storage-program"
version = "0.21.0"
version = "0.21.1"
dependencies = [
"bincode 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1887,13 +1898,13 @@ dependencies = [
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
"solana-logger 0.21.0",
"solana-sdk 0.21.0",
"solana-logger 0.21.1",
"solana-sdk 0.21.1",
]
[[package]]
name = "solana-vote-program"
version = "0.21.0"
version = "0.21.1"
dependencies = [
"bincode 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1901,9 +1912,9 @@ dependencies = [
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
"solana-logger 0.21.0",
"solana-metrics 0.21.0",
"solana-sdk 0.21.0",
"solana-logger 0.21.1",
"solana-metrics 0.21.1",
"solana-sdk 0.21.1",
]
[[package]]
@@ -2601,7 +2612,7 @@ dependencies = [
"checksum cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)" = "4fc9a35e1f4290eb9e5fc54ba6cf40671ed2a2514c3eeb2b2a908dda2ea5a1be"
"checksum cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b486ce3ccf7ffd79fdeb678eac06a9e6c09fc88d33836340becb8fffe87c5e33"
"checksum cgmath 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)" = "64a4b57c8f4e3a2e9ac07e0f6abc9c24b6fc9e1b54c3478cfb598f3d0023e51c"
"checksum chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e8493056968583b0193c1bb04d6f7684586f3726992d6c573261941a895dbd68"
"checksum chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "31850b4a4d6bae316f7a09e691c944c28299298837edc0a03f755618c23cbc01"
"checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9"
"checksum clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "97276801e127ffb46b66ce23f35cc96bd454fa311294bced4bbace7baa8b1d17"
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
@@ -2662,7 +2673,7 @@ dependencies = [
"checksum indexmap 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a61202fbe46c4a951e9404a720a0180bcf3212c750d735cb5c4ba4dc551299f3"
"checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08"
"checksum itertools 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)" = "0d47946d458e94a1b7bcabbf6521ea7c037062c81f534615abcad76e84d4970d"
"checksum itertools 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "87fa75c9dea7b07be3138c49abbb83fd4bea199b5cdc76f9804458edc5da0d6e"
"checksum itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484"
"checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f"
"checksum jobserver 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "f2b1d42ef453b30b7387e113da1c83ab1605d90c5b4e0eb8e96d016ed3b8c160"
"checksum js-sys 0.3.27 (registry+https://github.com/rust-lang/crates.io-index)" = "1efc4f2a556c58e79c5500912e221dd826bec64ff4aabd8ce71ccef6da02d7d4"

View File

@@ -1,7 +1,7 @@
[package]
name = "solana-bpf-programs"
description = "Blockchain, Rebuilt for Scale"
version = "0.21.0"
version = "0.21.1"
documentation = "https://docs.rs/solana"
homepage = "https://solana.com/"
readme = "README.md"
@@ -22,10 +22,10 @@ walkdir = "2"
bincode = "1.1.4"
byteorder = "1.3.2"
elf = "0.0.10"
solana-bpf-loader-program = { path = "../bpf_loader", version = "0.21.0" }
solana-logger = { path = "../../logger", version = "0.21.0" }
solana-runtime = { path = "../../runtime", version = "0.21.0" }
solana-sdk = { path = "../../sdk", version = "0.21.0" }
solana-bpf-loader-program = { path = "../bpf_loader", version = "0.21.1" }
solana-logger = { path = "../../logger", version = "0.21.1" }
solana-runtime = { path = "../../runtime", version = "0.21.1" }
solana-sdk = { path = "../../sdk", version = "0.21.1" }
solana_rbpf = "=0.1.19"
[[bench]]

View File

@@ -3,7 +3,7 @@
[package]
name = "solana-bpf-rust-128bit"
version = "0.21.0"
version = "0.21.1"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -12,11 +12,11 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-sdk = { path = "../../../../sdk/", version = "0.21.0", default-features = false }
solana-bpf-rust-128bit-dep = { path = "../128bit_dep", version = "0.21.0" }
solana-sdk = { path = "../../../../sdk/", version = "0.21.1", default-features = false }
solana-bpf-rust-128bit-dep = { path = "../128bit_dep", version = "0.21.1" }
[dev_dependencies]
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "0.21.0" }
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "0.21.1" }
[features]
program = ["solana-sdk/program"]

View File

@@ -3,7 +3,7 @@
[package]
name = "solana-bpf-rust-128bit-dep"
version = "0.21.0"
version = "0.21.1"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -12,10 +12,10 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-sdk = { path = "../../../../sdk/", version = "0.21.0", default-features = false }
solana-sdk = { path = "../../../../sdk/", version = "0.21.1", default-features = false }
[dev_dependencies]
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "0.21.0" }
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "0.21.1" }
[features]
program = ["solana-sdk/program"]

View File

@@ -3,7 +3,7 @@
[package]
name = "solana-bpf-rust-alloc"
version = "0.21.0"
version = "0.21.1"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -12,10 +12,10 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-sdk = { path = "../../../../sdk/", version = "0.21.0", default-features = false }
solana-sdk = { path = "../../../../sdk/", version = "0.21.1", default-features = false }
[dev_dependencies]
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "0.21.0" }
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "0.21.1" }
[features]
program = ["solana-sdk/program"]

View File

@@ -3,7 +3,7 @@
[package]
name = "solana-bpf-rust-dep-crate"
version = "0.21.0"
version = "0.21.1"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -13,10 +13,10 @@ edition = "2018"
[dependencies]
byteorder = { version = "1", default-features = false }
solana-sdk = { path = "../../../../sdk/", version = "0.21.0", default-features = false }
solana-sdk = { path = "../../../../sdk/", version = "0.21.1", default-features = false }
[dev_dependencies]
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "0.21.0" }
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "0.21.1" }
[features]
program = ["solana-sdk/program"]

View File

@@ -3,7 +3,7 @@
[package]
name = "solana-bpf-rust-external-spend"
version = "0.21.0"
version = "0.21.1"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -12,10 +12,10 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-sdk = { path = "../../../../sdk/", version = "0.21.0", default-features = false }
solana-sdk = { path = "../../../../sdk/", version = "0.21.1", default-features = false }
[dev_dependencies]
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "0.21.0" }
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "0.21.1" }
[features]
program = ["solana-sdk/program"]

View File

@@ -3,7 +3,7 @@
[package]
name = "solana-bpf-rust-iter"
version = "0.21.0"
version = "0.21.1"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -12,10 +12,10 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-sdk = { path = "../../../../sdk/", version = "0.21.0", default-features = false }
solana-sdk = { path = "../../../../sdk/", version = "0.21.1", default-features = false }
[dev_dependencies]
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "0.21.0" }
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "0.21.1" }
[features]
program = ["solana-sdk/program"]

View File

@@ -3,7 +3,7 @@
[package]
name = "solana-bpf-rust-many-args"
version = "0.21.0"
version = "0.21.1"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -12,11 +12,11 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-sdk = { path = "../../../../sdk/", version = "0.21.0", default-features = false }
solana-bpf-rust-many-args-dep = { path = "../many_args_dep", version = "0.21.0" }
solana-sdk = { path = "../../../../sdk/", version = "0.21.1", default-features = false }
solana-bpf-rust-many-args-dep = { path = "../many_args_dep", version = "0.21.1" }
[dev_dependencies]
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "0.21.0" }
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "0.21.1" }
[features]
program = ["solana-sdk/program"]

View File

@@ -3,7 +3,7 @@
[package]
name = "solana-bpf-rust-many-args-dep"
version = "0.21.0"
version = "0.21.1"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -12,10 +12,10 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-sdk = { path = "../../../../sdk/", version = "0.21.0", default-features = false }
solana-sdk = { path = "../../../../sdk/", version = "0.21.1", default-features = false }
[dev_dependencies]
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "0.21.0" }
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "0.21.1" }
[features]
program = ["solana-sdk/program"]

View File

@@ -3,7 +3,7 @@
[package]
name = "solana-bpf-rust-noop"
version = "0.21.0"
version = "0.21.1"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -12,10 +12,10 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-sdk = { path = "../../../../sdk/", version = "0.21.0", default-features = false }
solana-sdk = { path = "../../../../sdk/", version = "0.21.1", default-features = false }
[dev_dependencies]
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "0.21.0" }
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "0.21.1" }
[features]
program = ["solana-sdk/program"]

View File

@@ -3,7 +3,7 @@
[package]
name = "solana-bpf-rust-panic"
version = "0.21.0"
version = "0.21.1"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -12,10 +12,10 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-sdk = { path = "../../../../sdk/", version = "0.21.0", default-features = false }
solana-sdk = { path = "../../../../sdk/", version = "0.21.1", default-features = false }
[dev_dependencies]
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "0.21.0" }
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "0.21.1" }
[features]
program = ["solana-sdk/program"]

View File

@@ -3,7 +3,7 @@
[package]
name = "solana-bpf-rust-param-passing"
version = "0.21.0"
version = "0.21.1"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -12,11 +12,11 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-sdk = { path = "../../../../sdk/", version = "0.21.0", default-features = false }
solana-bpf-rust-param-passing-dep = { path = "../param_passing_dep", version = "0.21.0" }
solana-sdk = { path = "../../../../sdk/", version = "0.21.1", default-features = false }
solana-bpf-rust-param-passing-dep = { path = "../param_passing_dep", version = "0.21.1" }
[dev_dependencies]
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "0.21.0" }
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "0.21.1" }
[features]
program = ["solana-sdk/program"]

View File

@@ -3,7 +3,7 @@
[package]
name = "solana-bpf-rust-param-passing-dep"
version = "0.21.0"
version = "0.21.1"
description = "Solana BPF program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -12,10 +12,10 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-sdk = { path = "../../../../sdk/", version = "0.21.0", default-features = false }
solana-sdk = { path = "../../../../sdk/", version = "0.21.1", default-features = false }
[dev_dependencies]
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "0.21.0" }
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "0.21.1" }
[features]
program = ["solana-sdk/program"]

View File

@@ -3,7 +3,7 @@
[package]
name = "solana-bpf-rust-sysval"
version = "0.21.0"
version = "0.21.1"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -12,10 +12,10 @@ homepage = "https://solana.com/"
edition = "2018"
[dependencies]
solana-sdk = { path = "../../../../sdk/", version = "0.21.0", default-features = false }
solana-sdk = { path = "../../../../sdk/", version = "0.21.1", default-features = false }
[dev_dependencies]
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "0.21.0" }
solana-sdk-bpf-test = { path = "../../../../sdk/bpf/rust/test", version = "0.21.1" }
[features]
program = ["solana-sdk/program"]

View File

@@ -6,10 +6,11 @@ use solana_sdk::{
clock::{get_segment_from_slot, DEFAULT_SLOTS_PER_EPOCH, DEFAULT_SLOTS_PER_SEGMENT},
entrypoint,
entrypoint::SUCCESS,
info,
pubkey::Pubkey,
rent,
sysvar::{
clock::Clock, fees::Fees, rent::Rent, rewards::Rewards, slot_hashes::SlotHashes,
self, clock::Clock, fees::Fees, rent::Rent, rewards::Rewards, slot_hashes::SlotHashes,
stake_history::StakeHistory, Sysvar,
},
};
@@ -17,6 +18,8 @@ use solana_sdk::{
entrypoint!(process_instruction);
fn process_instruction(_program_id: &Pubkey, accounts: &mut [AccountInfo], _data: &[u8]) -> u32 {
// Clock
info!("Clock identifier:");
sysvar::clock::id().log();
let clock = Clock::from_account_info(&accounts[2]).expect("clock");
assert_eq!(clock.slot, DEFAULT_SLOTS_PER_EPOCH + 1);
assert_eq!(
@@ -25,18 +28,26 @@ fn process_instruction(_program_id: &Pubkey, accounts: &mut [AccountInfo], _data
);
// Fees
info!("Fees identifier:");
sysvar::fees::id().log();
let fees = Fees::from_account_info(&accounts[3]).expect("fees");
let burn = fees.fee_calculator.burn(42);
assert_eq!(burn, (21, 21));
// Rewards
info!("Rewards identifier:");
sysvar::rewards::id().log();
let _rewards = Rewards::from_account_info(&accounts[4]).expect("rewards");
// Slot Hashes
info!("SlotHashes identifier:");
sysvar::slot_hashes::id().log();
let slot_hashes = SlotHashes::from_account_info(&accounts[5]).expect("slot_hashes");
assert!(slot_hashes.len() >= 1);
// Stake History
info!("StakeHistory identifier:");
sysvar::stake_history::id().log();
let stake_history = StakeHistory::from_account_info(&accounts[6]).expect("stake_history");
assert!(stake_history.len() >= 1);

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-bpf-loader-program"
version = "0.21.0"
version = "0.21.1"
description = "Solana BPF loader"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -14,8 +14,8 @@ byteorder = "1.3.2"
libc = "0.2.65"
log = "0.4.8"
serde = "1.0.102"
solana-logger = { path = "../../logger", version = "0.21.0" }
solana-sdk = { path = "../../sdk", version = "0.21.0" }
solana-logger = { path = "../../logger", version = "0.21.1" }
solana-sdk = { path = "../../sdk", version = "0.21.1" }
solana_rbpf = "=0.1.19"
[lib]

View File

@@ -7,7 +7,6 @@ use byteorder::{ByteOrder, LittleEndian, WriteBytesExt};
use log::*;
use solana_rbpf::{memory_region::MemoryRegion, EbpfVm};
use solana_sdk::account::KeyedAccount;
use solana_sdk::bpf_loader;
use solana_sdk::instruction::InstructionError;
use solana_sdk::instruction_processor_utils::{limited_deserialize, next_keyed_account};
use solana_sdk::loader_instruction::LoaderInstruction;
@@ -19,7 +18,7 @@ use std::io::Error;
use std::mem;
solana_sdk::declare_program!(
bpf_loader::BS58_STRING,
solana_sdk::bpf_loader::ID,
solana_bpf_loader_program,
process_instruction
);

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-btc-spv-program"
version = "0.21.0"
version = "0.21.1"
description = "Solana Bitcoin spv parsing program"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -16,7 +16,7 @@ num-derive = "0.3"
num-traits = "0.2"
serde = "1.0.102"
serde_derive = "1.0.102"
solana-sdk = { path = "../../sdk", version = "0.21.0"}
solana-sdk = { path = "../../sdk", version = "0.21.1"}
hex = "0.3.2"
[lib]

View File

@@ -1,6 +1,6 @@
[package]
name = "btc_spv_bin"
version = "0.21.0"
version = "0.21.1"
description = "Solana Bitcoin spv parsing program"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-budget-program"
version = "0.21.0"
version = "0.21.1"
description = "Solana Budget program"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -16,10 +16,10 @@ num-derive = "0.3"
num-traits = "0.2"
serde = "1.0.102"
serde_derive = "1.0.102"
solana-sdk = { path = "../../sdk", version = "0.21.0" }
solana-sdk = { path = "../../sdk", version = "0.21.1" }
[dev-dependencies]
solana-runtime = { path = "../../runtime", version = "0.21.0" }
solana-runtime = { path = "../../runtime", version = "0.21.1" }
[lib]
crate-type = ["lib", "cdylib"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-config-program"
version = "0.21.0"
version = "0.21.1"
description = "Solana Config program"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -14,8 +14,8 @@ chrono = { version = "0.4.10", features = ["serde"] }
log = "0.4.8"
serde = "1.0.102"
serde_derive = "1.0.102"
solana-logger = { path = "../../logger", version = "0.21.0" }
solana-sdk = { path = "../../sdk", version = "0.21.0" }
solana-logger = { path = "../../logger", version = "0.21.1" }
solana-sdk = { path = "../../sdk", version = "0.21.1" }
[lib]
crate-type = ["lib", "cdylib"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-config-tests"
version = "0.21.0"
version = "0.21.1"
description = "Solana config api tests"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -13,11 +13,11 @@ bincode = "1.2.0"
log = "0.4.8"
serde = "1.0.102"
serde_derive = "1.0.102"
solana-logger = { path = "../../logger", version = "0.21.0" }
solana-sdk = { path = "../../sdk", version = "0.21.0" }
solana-config-program = { path = "../config", version = "0.21.0" }
solana-logger = { path = "../../logger", version = "0.21.1" }
solana-sdk = { path = "../../sdk", version = "0.21.1" }
solana-config-program = { path = "../config", version = "0.21.1" }
[dev-dependencies]
solana-runtime = { path = "../../runtime", version = "0.21.0" }
solana-runtime = { path = "../../runtime", version = "0.21.1" }
assert_matches = "1.3.0"

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-exchange-program"
version = "0.21.0"
version = "0.21.1"
description = "Solana Exchange program"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -13,12 +13,12 @@ bincode = "1.2.0"
log = "0.4.8"
serde = "1.0.102"
serde_derive = "1.0.102"
solana-logger = { path = "../../logger", version = "0.21.0" }
solana-metrics = { path = "../../metrics", version = "0.21.0" }
solana-sdk = { path = "../../sdk", version = "0.21.0" }
solana-logger = { path = "../../logger", version = "0.21.1" }
solana-metrics = { path = "../../metrics", version = "0.21.1" }
solana-sdk = { path = "../../sdk", version = "0.21.1" }
[dev-dependencies]
solana-runtime = { path = "../../runtime", version = "0.21.0" }
solana-runtime = { path = "../../runtime", version = "0.21.1" }
[lib]
crate-type = ["lib", "cdylib"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-failure-program"
version = "0.21.0"
version = "0.21.1"
description = "Solana failure program"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -10,10 +10,10 @@ edition = "2018"
[dependencies]
log = "0.4.8"
solana-sdk = { path = "../../sdk", version = "0.21.0" }
solana-sdk = { path = "../../sdk", version = "0.21.1" }
[dev-dependencies]
solana-runtime = { path = "../../runtime", version = "0.21.0" }
solana-runtime = { path = "../../runtime", version = "0.21.1" }
[lib]
crate-type = ["lib", "cdylib"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-librapay-api"
version = "0.21.0"
version = "0.21.1"
description = "Solana Libra Payment"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -11,10 +11,10 @@ edition = "2018"
[dependencies]
bincode = "1.2.0"
log = "0.4.8"
solana-logger = { path = "../../logger", version = "0.21.0" }
solana-move-loader-program = { path = "../move_loader", version = "0.21.0" }
solana-runtime = { path = "../../runtime", version = "0.21.0" }
solana-sdk = { path = "../../sdk", version = "0.21.0" }
solana-logger = { path = "../../logger", version = "0.21.1" }
solana-move-loader-program = { path = "../move_loader", version = "0.21.1" }
solana-runtime = { path = "../../runtime", version = "0.21.1" }
solana-sdk = { path = "../../sdk", version = "0.21.1" }
language_e2e_tests = { version = "0.0.1-sol4", package = "solana_libra_language_e2e_tests" }
types = { version = "0.0.1-sol4", package = "solana_libra_types" }

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-move-loader-program"
version = "0.21.0"
version = "0.21.1"
description = "Solana Move loader"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -18,8 +18,8 @@ serde = "1.0.102"
serde_bytes = "0.11"
serde_derive = "1.0.102"
serde_json = "1.0.41"
solana-logger = { path = "../../logger", version = "0.21.0" }
solana-sdk = { path = "../../sdk", version = "0.21.0" }
solana-logger = { path = "../../logger", version = "0.21.1" }
solana-sdk = { path = "../../sdk", version = "0.21.1" }
bytecode_verifier = { version = "0.0.1-sol4", package = "solana_libra_bytecode_verifier" }
canonical_serialization = { version = "0.0.1-sol4", package = "solana_libra_canonical_serialization" }

View File

@@ -4,10 +4,9 @@ pub mod error_mappers;
pub mod processor;
use crate::processor::process_instruction;
use solana_sdk::move_loader;
solana_sdk::declare_program!(
move_loader::BS58_STRING,
solana_sdk::move_loader::ID,
solana_move_loader_program,
process_instruction
);

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-noop-program"
version = "0.21.0"
version = "0.21.1"
description = "Solana Noop program"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -10,8 +10,8 @@ edition = "2018"
[dependencies]
log = "0.4.8"
solana-logger = { path = "../../logger", version = "0.21.0" }
solana-sdk = { path = "../../sdk", version = "0.21.0" }
solana-logger = { path = "../../logger", version = "0.21.1" }
solana-sdk = { path = "../../sdk", version = "0.21.1" }
[lib]
crate-type = ["lib", "cdylib"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-ownable-api"
version = "0.21.0"
version = "0.21.1"
description = "ownable program API"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -12,12 +12,12 @@ edition = "2018"
bincode = "1.2.0"
serde = "1.0.102"
serde_derive = "1.0.102"
solana-sdk = { path = "../../sdk", version = "0.21.0" }
solana-sdk = { path = "../../sdk", version = "0.21.1" }
num-derive = "0.3"
num-traits = "0.2"
[dev-dependencies]
solana-runtime = { path = "../../runtime", version = "0.21.0" }
solana-runtime = { path = "../../runtime", version = "0.21.1" }
[lib]
crate-type = ["lib"]

View File

@@ -1,6 +1,6 @@
[package]
name = "solana-stake-program"
version = "0.21.0"
version = "0.21.1"
description = "Solana Stake program"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
@@ -16,11 +16,11 @@ num-traits = "0.2"
rand = "0.6.5"
serde = "1.0.102"
serde_derive = "1.0.102"
solana-logger = { path = "../../logger", version = "0.21.0" }
solana-metrics = { path = "../../metrics", version = "0.21.0" }
solana-sdk = { path = "../../sdk", version = "0.21.0" }
solana-vote-program = { path = "../vote", version = "0.21.0" }
solana-config-program = { path = "../config", version = "0.21.0" }
solana-logger = { path = "../../logger", version = "0.21.1" }
solana-metrics = { path = "../../metrics", version = "0.21.1" }
solana-sdk = { path = "../../sdk", version = "0.21.1" }
solana-vote-program = { path = "../vote", version = "0.21.1" }
solana-config-program = { path = "../config", version = "0.21.1" }
[lib]
crate-type = ["lib", "cdylib"]

View File

@@ -106,11 +106,13 @@ pub enum StakeInstruction {
Split(u64),
/// Withdraw unstaked lamports from the stake account
/// requires Authorized::withdrawer signature
/// requires Authorized::withdrawer signature. If withdrawal
/// is before lockup has expired, also requires signature
/// of the lockup custodian.
///
/// Expects 4 Accounts:
/// 0 - StakeAccount from which to withdraw
/// 1 - System account to which the lamports will be transferred,
/// 1 - Account to which the lamports will be transferred
/// 2 - Syscall Account that carries epoch
/// 3 - StakeHistory sysvar that carries stake warmup/cooldown history
///
@@ -257,7 +259,7 @@ pub fn delegate_stake(
pub fn withdraw(
stake_pubkey: &Pubkey,
authorized_pubkey: &Pubkey,
withdrawer_pubkey: &Pubkey,
to_pubkey: &Pubkey,
lamports: u64,
) -> Instruction {
@@ -267,7 +269,27 @@ pub fn withdraw(
AccountMeta::new_readonly(sysvar::clock::id(), false),
AccountMeta::new_readonly(sysvar::stake_history::id(), false),
]
.with_signer(authorized_pubkey);
.with_signer(withdrawer_pubkey);
Instruction::new(id(), &StakeInstruction::Withdraw(lamports), account_metas)
}
pub fn withdraw_early(
stake_pubkey: &Pubkey,
withdrawer_pubkey: &Pubkey,
to_pubkey: &Pubkey,
lamports: u64,
custodian_pubkey: &Pubkey,
) -> Instruction {
let account_metas = vec![
AccountMeta::new(*stake_pubkey, false),
AccountMeta::new(*to_pubkey, false),
AccountMeta::new_readonly(sysvar::clock::id(), false),
AccountMeta::new_readonly(sysvar::stake_history::id(), false),
]
.with_signer(withdrawer_pubkey)
.with_signer(custodian_pubkey);
Instruction::new(id(), &StakeInstruction::Withdraw(lamports), account_metas)
}

View File

@@ -36,6 +36,10 @@ impl Default for StakeState {
}
impl StakeState {
pub fn get_rent_exempt_reserve(rent: &Rent) -> u64 {
rent.minimum_balance(std::mem::size_of::<StakeState>())
}
// utility function, used by Stakes, tests
pub fn from(account: &Account) -> Option<StakeState> {
account.state().ok()
@@ -750,9 +754,9 @@ impl<'a> StakeAccount for KeyedAccount<'a> {
_ => return Err(InstructionError::InvalidAccountData),
};
// verify that lockup has expired or that the withdrawal is going back
// to the custodian
if lockup.epoch > clock.epoch && lockup.custodian != *to.unsigned_key() {
// verify that lockup has expired or that the withdrawal is signed by
// the custodian
if lockup.epoch > clock.epoch && !signers.contains(&lockup.custodian) {
return Err(StakeError::LockupInForce.into());
}
@@ -801,10 +805,6 @@ where
}
}
pub fn get_stake_rent_exempt_reserve(rent: &Rent) -> u64 {
rent.minimum_balance(std::mem::size_of::<StakeState>())
}
// genesis investor accounts
pub fn create_lockup_stake_account(
authorized: &Authorized,
@@ -1394,7 +1394,7 @@ mod tests {
&Rent {
lamports_per_byte_year: 42,
..Rent::default()
}
},
),
Err(InstructionError::InsufficientFunds)
);
@@ -1792,20 +1792,20 @@ mod tests {
Err(StakeError::LockupInForce.into())
);
// but we *can* send to the custodian
let mut custodian_account = Account::new(1, 0, &system_program::id());
let mut custodian_keyed_account =
KeyedAccount::new(&custodian, false, &mut custodian_account);
assert_eq!(
stake_keyed_account.withdraw(
total_lamports,
&mut custodian_keyed_account,
&clock,
&StakeHistory::default(),
&signers,
),
Ok(())
);
{
let mut signers_with_custodian = signers.clone();
signers_with_custodian.insert(custodian);
assert_eq!(
stake_keyed_account.withdraw(
total_lamports,
&mut to_keyed_account,
&clock,
&StakeHistory::default(),
&signers_with_custodian,
),
Ok(())
);
}
// reset balance
stake_keyed_account.account.lamports = total_lamports;
@@ -1902,9 +1902,9 @@ mod tests {
None, // would be Some((0, 2 * 1 + 1 * 2, 3)),
stake.calculate_rewards(1.0, &vote_state, None)
);
vote_state.commission = std::u8::MAX - 1;
vote_state.commission = 99;
assert_eq!(
None, // would be pSome((0, 2 * 1 + 1 * 2, 3)),
None, // would be Some((0, 2 * 1 + 1 * 2, 3)),
stake.calculate_rewards(1.0, &vote_state, None)
);
}
@@ -1993,7 +1993,7 @@ mod tests {
let mut vote_state = VoteState::from(&vote_account).unwrap();
// split credits 3:1 between staker and voter
vote_state.commission = std::u8::MAX / 4;
vote_state.commission = 25;
// put in some credits in epoch 0 for which we should have a non-zero stake
for _i in 0..100 {
vote_state.increment_credits(1);
@@ -2033,7 +2033,7 @@ mod tests {
assert!(voter_commission > 0);
assert!(staker_rewards > 0);
assert!(
staker_rewards / 3 > voter_commission,
staker_rewards / 3 >= voter_commission,
"rewards should be split ~3:1"
);
// verify rewards are added to stake

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