Bonding as a Validator
It is recommended that a bonding request be sent once the node has completed the synchronization process. In a Casper network, bonding takes place through the auction contract via the add_bid.wasm
contract. The auction runs for a future era, every era. The chainspec.toml
specifies the number of slots available, and the auction will take the top N slots and create the validator set for the future era.
In the Testnet, era durations are approximately two hours. The entire process takes approximately 3 eras. Therefore, the time for bid submission to inclusion in the validator set is a minimum of six hours. Bonding requests (bids) are transactions like any other. Because they are generic transactions, they are more resistant to censorship.
The Bonding Process
The most secure way to send a bonding transaction is to compile the contract and send the request to the network. Because the transaction authorizes the token to be locked into the auction contract, it is essential to compile the contract yourself. Here are the steps to take:
- Clone the
casper-node
repository - Install these prerequisites, which are also listed here.
- Rust
- CMake
pkg-config
- On Ubuntu, usesudo apt-get install pkg-config
openssl
- On Ubuntu, usesudo apt-get install openssl
libssl-dev
- On Ubuntu, usesudo apt-get install libssl-dev
- Install the Rust casper-client and fund the keys you will use for bonding
- Build the contracts
- Send a bonding request
- Check the status of the auction to see if you have won a validator slot
Building the Contracts
Because bonding transactions are generic transactions, it is necessary to build the contract that submits a bid. Build the contracts in release mode:
cd casper-node
make setup-rs
make build-client-contracts
These commands build all the necessary contracts, including add_bid.wasm
for placing a bid.
Example Bonding Request
The following example deploys a bonding request on the network:
sudo -u casper casper-client put-deploy \
--chain-name <CHAIN_NAME> \
--node-address http://<HOST:PORT> \
--secret-key /etc/casper/validator_keys/secret_key.pem \
--session-path $HOME/casper-node/target/wasm32-unknown-unknown/release/add_bid.wasm \
--payment-amount 3000000000 \
--session-arg="public_key:public_key='<PUBLIC_KEY_HEX>'" \
--session-arg="amount:u512='<BID-AMOUNT>'" \
--session-arg="delegation_rate:u8='<PERCENT_TO_KEEP_FROM_DELEGATORS>'"
Note the following command options above:
- The chain name for Mainnet is
casper
and for Testnet iscasper-test
- The default port for node address is 7777
- The session arguments need to be encased in double-quotes, with the parameter values in single quotes
- The payment amount is specified in motes, where 1 CSPR is 1,000,000,000 motes
Contract Arguments
The add_bid contract accepts 3 arguments:
public_key
: The hexadecimal public key of the account to bond. This must be the one paired with the secret key used in the--secret-key
argumentamount
: This is the amount being bid. If the bid wins, this will be the validator's initial bonded amountdelegation_rate
: The percentage of rewards that the validator retains from delegators that delegate their tokens to the node
Example Request
Here is an example request to bond as a validator:
sudo -u casper casper-client put-deploy \
--chain-name casper-test \
--node-address http://65.21.235.219:7777 \
--secret-key /etc/casper/validator_keys/secret_key.pem \
--session-path $HOME/casper-node/target/wasm32-unknown-unknown/release/add_bid.wasm \
--payment-amount 3000000000 \
--session-arg="public_key:public_key='01da0e438afc74181beb2afae798e9e6851bdf897117a306eb32caafe46c1c0bc8'" \
--session-arg="amount:u512='25000000000000'" \
--session-arg="delegation_rate:u8='3'"
Example Response
{
"id": -3351398263238778586,
"jsonrpc": "2.0",
"result": {
"api_version": "1.4.8",
"deploy_hash": "4754c3135d8f074a6aeab40007012d7b3c7b65d02cebfefd94e04dff16971fb5"
}
}
Bid Status
Since this is a deploy like any other, perform get-deploy
using the casper-client
, to see the execution status.
casper-client get-deploy --node-address http://<HOST:PORT> <DEPLOY_HASH>
If the bid wins the auction, the public key and associated bonded amount will appear in the auction contract as part of the validator set for a future era. To determine if the bid was accepted, query the auction contract:
casper-client get-auction-info --node-address http://<HOST:PORT>
Example auction info response
{
"jsonrpc": "2.0",
"result": {
"bids": [
{
"bid": {
"bonding_purse": "uref-488a0bbc3c3729f5696965da7a3aeee83805392944e36157909da273255fdb85-007",
"delegation_rate": 0,
"delegators": [],
"release_era": null,
"reward": "93328432442428418861229954179737",
"staked_amount": "10000000000000000"
},
"public_key": "013f774a58f4d40bd9b6cce7e306e53646913860ef2a111d00f0fe7794010c4012"
},
{
"bid": {
"bonding_purse": "uref-14e128b099b0c3680100520226e6999b322989586cc22db0630db5ec1329f0a7-007",
"delegation_rate": 10,
"delegators": [],
"release_era": null,
"reward": "0",
"staked_amount": "9000000000000000"
},
"public_key": "01405133e73ef2946fe3a2d76a4c75d305a04ad6b969f3c4a8a0d27235eb260f87"
},
{
"bid": {
"bonding_purse": "uref-6c0bf8cee1c0749dd9766376910867a84b2e826eaf6c118fcb0224c7d8d229dd-007",
"delegation_rate": 10,
"delegators": [],
"release_era": null,
"reward": "266185120443441810685787",
"staked_amount": "100000000"
},
"public_key": "01524a5f3567d7b5ea17ca518c9d0320fb4a75a28a5eab58d06c755c388f20a19f"
},
{
"bid": {
"bonding_purse": "uref-3880b3daf95f962f57e6a4b1589564abf7deef58a1fb0753d1108316bba7b3d7-007",
"delegation_rate": 10,
"delegators": [],
"release_era": null,
"reward": "0",
"staked_amount": "9000000000000000"
},
"public_key": "01a6901408eda702a653805f50060bfe00d5e962747ee7133df64bd7bab50b4643"
},
{
"bid": {
"bonding_purse": "uref-5a777c9cd53456b49eecf25dcc13e12ddff4106175a69f8e24a7c9a4c135df0d-007",
"delegation_rate": 0,
"delegators": [],
"release_era": null,
"reward": "93328432442428418861229954179737",
"staked_amount": "10000000000000000"
},
"public_key": "01d62fc9b894218bfbe8eebcc4a28a1fc4cb3a5c6120bb0027207ba8214439929e"
}
],
"block_height": 318,
"era_validators": [
{
"era_id": 20,
"validator_weights": [
{
"public_key": "013f774a58f4d40bd9b6cce7e306e53646913860ef2a111d00f0fe7794010c4012",
"weight": "10000000000000000"
},
{
"public_key": "01405133e73ef2946fe3a2d76a4c75d305a04ad6b969f3c4a8a0d27235eb260f87",
"weight": "9000000000000000"
},
{
"public_key": "01524a5f3567d7b5ea17ca518c9d0320fb4a75a28a5eab58d06c755c388f20a19f",
"weight": "100000000"
},
{
"public_key": "01a6901408eda702a653805f50060bfe00d5e962747ee7133df64bd7bab50b4643",
"weight": "9000000000000000"
},
{
"public_key": "01d62fc9b894218bfbe8eebcc4a28a1fc4cb3a5c6120bb0027207ba8214439929e",
"weight": "10000000000000000"
}
]
},
{
"era_id": 21,
"validator_weights": [
{
"public_key": "013f774a58f4d40bd9b6cce7e306e53646913860ef2a111d00f0fe7794010c4012",
"weight": "10000000000000000"
},
{
"public_key": "01405133e73ef2946fe3a2d76a4c75d305a04ad6b969f3c4a8a0d27235eb260f87",
"weight": "9000000000000000"
},
{
"public_key": "01524a5f3567d7b5ea17ca518c9d0320fb4a75a28a5eab58d06c755c388f20a19f",
"weight": "100000000"
},
{
"public_key": "01a6901408eda702a653805f50060bfe00d5e962747ee7133df64bd7bab50b4643",
"weight": "9000000000000000"
},
{
"public_key": "01d62fc9b894218bfbe8eebcc4a28a1fc4cb3a5c6120bb0027207ba8214439929e",
"weight": "10000000000000000"
}
]
},
{
"era_id": 22,
"validator_weights": [
{
"public_key": "013f774a58f4d40bd9b6cce7e306e53646913860ef2a111d00f0fe7794010c4012",
"weight": "10000000000000000"
},
{
"public_key": "01405133e73ef2946fe3a2d76a4c75d305a04ad6b969f3c4a8a0d27235eb260f87",
"weight": "9000000000000000"
},
{
"public_key": "01524a5f3567d7b5ea17ca518c9d0320fb4a75a28a5eab58d06c755c388f20a19f",
"weight": "100000000"
},
{
"public_key": "01a6901408eda702a653805f50060bfe00d5e962747ee7133df64bd7bab50b4643",
"weight": "9000000000000000"
},
{
"public_key": "01d62fc9b894218bfbe8eebcc4a28a1fc4cb3a5c6120bb0027207ba8214439929e",
"weight": "10000000000000000"
}
]
},
{
"era_id": 23,
"validator_weights": [
{
"public_key": "013f774a58f4d40bd9b6cce7e306e53646913860ef2a111d00f0fe7794010c4012",
"weight": "10000000000000000"
},
{
"public_key": "01405133e73ef2946fe3a2d76a4c75d305a04ad6b969f3c4a8a0d27235eb260f87",
"weight": "9000000000000000"
},
{
"public_key": "01524a5f3567d7b5ea17ca518c9d0320fb4a75a28a5eab58d06c755c388f20a19f",
"weight": "100000000"
},
{
"public_key": "01a6901408eda702a653805f50060bfe00d5e962747ee7133df64bd7bab50b4643",
"weight": "9000000000000000"
},
{
"public_key": "01d62fc9b894218bfbe8eebcc4a28a1fc4cb3a5c6120bb0027207ba8214439929e",
"weight": "10000000000000000"
}
]
}
],
"state_root_hash": "c16ba80ea200d786008f8100ea79f9cfeb8d7d5ee8b133eda5a50dcf1c7131e8"
},
"id": -3624528661787095850
}
Note the era_id
and the validator_weights
in the response above. The current era is the one with the lowest ID in the era_validators
array. For a given era_id
, a set of validators is defined. If the public key associated with a bid appears in the validator_weights
structure for an era, then the account is bonded in that era.
A Losing Bid
If a bid doesn't win a slot in the auction, it is too low. The resolution is to increase the bid amount. It is possible to submit additional bids, to increase the odds of winning a slot. It is also possible to encourage token holders to delegate stake to you for bonding.
Avoiding Ejection
To stay bonded and avoid ejection, each validator must keep their node running and in sync with the rest of the network. To recover from ejection, you will find more details here.
Withdrawing a Bid
Follow the steps in Unbonding to withdraw a bid.