Update testnet tooling (#1001)

* Add progress on new deposits

* Add deposited command to account manager

* Remove old lcli::helpers mod

* Clean clap_utils

* Refactor lcli deposit contract commands to use IPC

* Make testnet optional for environment

* Use dbg formatting for deploy address

* Add command to generate bootnode enr

* Ensure lcli returns with 1 on error

* Ensure account manager returns 1 on error

* Disallow deposits to the zero address

* Update web3 in eth1 crate

* Ensure correct lighthouse dir is created

* Reduce deposit gas requirement

* Update cargo.lock

* Add progress on new deposits

* Add deposited command to account manager

* Remove old lcli::helpers mod

* Clean clap_utils

* Refactor lcli deposit contract commands to use IPC

* Add command to generate bootnode enr

* Ensure lcli returns with 1 on error

* Ensure account manager returns 1 on error

* Update web3 in eth1 crate

* Update Cargo.lock

* Move lcli out of main install script

* Change --limit to --at-least

* Change --datadir to --validator-dir

* Remove duplication in docs
This commit is contained in:
Paul Hauner
2020-04-19 12:20:43 +10:00
committed by GitHub
parent f9e8dad1fb
commit 7b86c9a08f
30 changed files with 711 additions and 304 deletions

View File

@@ -1,31 +1,35 @@
use clap::ArgMatches;
use clap_utils;
use deposit_contract::{
testnet::{ABI, BYTECODE},
CONTRACT_DEPLOY_GAS,
};
use environment::Environment;
use eth1_test_rig::DepositContract;
use std::fs::File;
use std::io::Read;
use futures::{Future, IntoFuture};
use std::path::PathBuf;
use types::EthSpec;
use web3::{transports::Http, Web3};
use web3::{
contract::{Contract, Options},
transports::Ipc,
types::{Address, U256},
Web3,
};
pub fn run<T: EthSpec>(mut env: Environment<T>, matches: &ArgMatches) -> Result<(), String> {
let confirmations = matches
.value_of("confirmations")
.ok_or_else(|| "Confirmations not specified")?
.parse::<usize>()
.map_err(|e| format!("Failed to parse confirmations: {}", e))?;
let eth1_ipc_path: PathBuf = clap_utils::parse_required(matches, "eth1-ipc")?;
let from_address: Address = clap_utils::parse_required(matches, "from-address")?;
let confirmations: usize = clap_utils::parse_required(matches, "confirmations")?;
let password = parse_password(matches)?;
let (_event_loop_handle, transport) =
Ipc::new(eth1_ipc_path).map_err(|e| format!("Unable to connect to eth1 IPC: {:?}", e))?;
let web3 = Web3::new(transport);
let endpoint = matches
.value_of("eth1-endpoint")
.ok_or_else(|| "eth1-endpoint not specified")?;
let (_event_loop, transport) = Http::new(&endpoint).map_err(|e| {
let bytecode = String::from_utf8(BYTECODE.to_vec()).map_err(|e| {
format!(
"Failed to start HTTP transport connected to ganache: {:?}",
"Unable to parse deposit contract bytecode as utf-8: {:?}",
e
)
})?;
let web3 = Web3::new(transport);
// It's unlikely that this will be the _actual_ deployment block, however it'll be close
// enough to serve our purposes.
@@ -37,54 +41,26 @@ pub fn run<T: EthSpec>(mut env: Environment<T>, matches: &ArgMatches) -> Result<
.block_on(web3.eth().block_number())
.map_err(|e| format!("Failed to get block number: {}", e))?;
info!("Present eth1 block number is {}", deploy_block);
let address = env.runtime().block_on(
Contract::deploy(web3.eth(), &ABI)
.map_err(|e| format!("Unable to build contract deployer: {:?}", e))?
.confirmations(confirmations)
.options(Options {
gas: Some(U256::from(CONTRACT_DEPLOY_GAS)),
..Options::default()
})
.execute(bytecode, (), from_address)
.into_future()
.map_err(|e| format!("Unable to execute deployment: {:?}", e))
.and_then(|pending| {
pending.map_err(|e| format!("Unable to await pending contract: {:?}", e))
})
.map(|tx_receipt| tx_receipt.address())
.map_err(|e| format!("Failed to execute deployment: {:?}", e)),
)?;
info!("Deploying the bytecode at https://github.com/sigp/unsafe-eth2-deposit-contract",);
info!(
"Submitting deployment transaction, waiting for {} confirmations",
confirmations
);
let deposit_contract = env
.runtime()
.block_on(DepositContract::deploy_testnet(
web3,
confirmations,
password,
))
.map_err(|e| format!("Failed to deploy contract: {}", e))?;
info!(
"Deposit contract deployed. address: {}, deploy_block: {}",
deposit_contract.address(),
deploy_block
);
println!("deposit_contract_address: {:?}", address);
println!("deposit_contract_deploy_block: {}", deploy_block);
Ok(())
}
pub fn parse_password(matches: &ArgMatches) -> Result<Option<String>, String> {
if let Some(password_path) = matches.value_of("password") {
Ok(Some(
File::open(password_path)
.map_err(|e| format!("Unable to open password file: {:?}", e))
.and_then(|mut file| {
let mut password = String::new();
file.read_to_string(&mut password)
.map_err(|e| format!("Unable to read password file to string: {:?}", e))
.map(|_| password)
})
.map(|password| {
// Trim the linefeed from the end.
if password.ends_with('\n') {
password[0..password.len() - 1].to_string()
} else {
password
}
})?,
))
} else {
Ok(None)
}
}