Add JSON deposit data to create

This commit is contained in:
Paul Hauner
2022-08-15 14:31:01 +10:00
parent 96692b8e43
commit 9503e338b5
5 changed files with 113 additions and 2 deletions

View File

@@ -6,11 +6,12 @@ use deposit_contract::decode_eth1_tx_data;
use derivative::Derivative;
use eth2_keystore::{Error as KeystoreError, Keystore, PlainText};
use lockfile::{Lockfile, LockfileError};
use serde::{Deserialize, Serialize};
use std::fs::{read, write, File};
use std::io;
use std::path::{Path, PathBuf};
use tree_hash::TreeHash;
use types::{DepositData, Hash256, Keypair};
use types::*;
/// The file used to save the Eth1 transaction hash from a deposit.
pub const ETH1_DEPOSIT_TX_HASH_FILE: &str = "eth1-deposit-tx-hash.txt";
@@ -41,6 +42,8 @@ pub enum Error {
Eth1DepositRootMismatch,
#[cfg(feature = "unencrypted_keys")]
SszKeypairError(String),
DepositDataMissing,
ConfigNameUnspecified,
}
/// Information required to submit a deposit to the Eth1 deposit contract.
@@ -54,6 +57,26 @@ pub struct Eth1DepositData {
pub root: Hash256,
}
/// The structure generated by the `staking-deposit-cli` which has become a quasi-standard for
/// browser-based deposit submission tools (e.g., the Ethereum Launchpad and Lido).
///
/// We assume this code as the canonical definition:
///
/// https://github.com/ethereum/staking-deposit-cli/blob/76ed78224fdfe3daca788d12442b3d1a37978296/staking_deposit/credentials.py#L131-L144
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct StandardDepositDataJson {
pub pubkey: PublicKeyBytes,
pub withdrawal_credentials: Hash256,
#[serde(with = "eth2_serde_utils::quoted_u64")]
pub amount: u64,
pub signature: SignatureBytes,
#[serde(with = "eth2_serde_utils::bytes_4_hex")]
pub fork_version: [u8; 4],
pub eth2_network_name: String,
pub deposit_message_root: Hash256,
pub deposit_data_root: Hash256,
}
/// Provides a wrapper around a directory containing validator information.
///
/// Holds a lockfile in `self.dir` to attempt to prevent concurrent access from multiple
@@ -203,6 +226,46 @@ impl ValidatorDir {
root,
}))
}
/// Calls `Self::eth1_deposit_data` and then builds a `StandardDepositDataJson` from the result.
///
/// The provided `spec` must match the value that was used to create the deposit, otherwise
/// an inconsistent result may be returned.
pub fn standard_deposit_data_json(
&self,
spec: &ChainSpec,
) -> Result<StandardDepositDataJson, Error> {
let deposit_data = self.eth1_deposit_data()?.ok_or(Error::DepositDataMissing)?;
let domain = spec.get_deposit_domain();
let deposit_message_root = deposit_data
.deposit_data
.as_deposit_message()
.signing_root(domain);
let deposit_data_root = deposit_data.deposit_data.tree_hash_root();
let DepositData {
pubkey,
withdrawal_credentials,
amount,
signature,
} = deposit_data.deposit_data;
Ok(StandardDepositDataJson {
pubkey,
withdrawal_credentials,
amount,
signature,
fork_version: spec.genesis_fork_version,
eth2_network_name: spec
.config_name
.clone()
.ok_or(Error::ConfigNameUnspecified)?,
deposit_message_root,
deposit_data_root,
})
}
}
/// Attempts to load and decrypt a Keypair given path to the keystore.