mirror of
https://github.com/sigp/lighthouse.git
synced 2026-04-20 06:18:31 +00:00
* Checkout serde_utils from rayonism
* Make eth1::http functions pub
* Add bones of execution_layer
* Modify decoding
* Expose Transaction, cargo fmt
* Add executePayload
* Add all minimal spec endpoints
* Start adding json rpc wrapper
* Finish custom JSON response handler
* Switch to new rpc sending method
* Add first test
* Fix camelCase
* Finish adding tests
* Begin threading execution layer into BeaconChain
* Fix clippy lints
* Fix clippy lints
* Thread execution layer into ClientBuilder
* Add CLI flags
* Add block processing methods to ExecutionLayer
* Add block_on to execution_layer
* Integrate execute_payload
* Add extra_data field
* Begin implementing payload handle
* Send consensus valid/invalid messages
* Fix minor type in task_executor
* Call forkchoiceUpdated
* Add search for TTD block
* Thread TTD into execution layer
* Allow producing block with execution payload
* Add LRU cache for execution blocks
* Remove duplicate 0x on ssz_types serialization
* Add tests for block getter methods
* Add basic block generator impl
* Add is_valid_terminal_block to EL
* Verify merge block in block_verification
* Partially implement --terminal-block-hash-override
* Add terminal_block_hash to ChainSpec
* Remove Option from terminal_block_hash in EL
* Revert merge changes to consensus/fork_choice
* Remove commented-out code
* Add bones for handling RPC methods on test server
* Add first ExecutionLayer tests
* Add testing for finding terminal block
* Prevent infinite loops
* Add insert_merge_block to block gen
* Add block gen test for pos blocks
* Start adding payloads to block gen
* Fix clippy lints
* Add execution payload to block gen
* Add execute_payload to block_gen
* Refactor block gen
* Add all routes to mock server
* Use Uint256 for base_fee_per_gas
* Add working execution chain build
* Remove unused var
* Revert "Use Uint256 for base_fee_per_gas"
This reverts commit 6c88f19ac4.
* Fix base_fee_for_gas Uint256
* Update execute payload handle
* Improve testing, fix bugs
* Fix default fee-recipient
* Fix fee-recipient address (again)
* Add check for terminal block, add comments, tidy
* Apply suggestions from code review
Co-authored-by: realbigsean <seananderson33@GMAIL.com>
* Fix is_none on handle Drop
* Remove commented-out tests
Co-authored-by: realbigsean <seananderson33@GMAIL.com>
135 lines
3.8 KiB
Rust
135 lines
3.8 KiB
Rust
//! Formats `u64` as a 0x-prefixed, big-endian hex string.
|
|
//!
|
|
//! E.g., `0` serializes as `"0x0000000000000000"`.
|
|
|
|
use serde::de::{self, Error, Visitor};
|
|
use serde::{Deserializer, Serializer};
|
|
use std::fmt;
|
|
|
|
const BYTES_LEN: usize = 8;
|
|
|
|
pub struct QuantityVisitor;
|
|
impl<'de> Visitor<'de> for QuantityVisitor {
|
|
type Value = Vec<u8>;
|
|
|
|
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
|
formatter.write_str("a hex string")
|
|
}
|
|
|
|
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
|
|
where
|
|
E: de::Error,
|
|
{
|
|
if !value.starts_with("0x") {
|
|
return Err(de::Error::custom("must start with 0x"));
|
|
}
|
|
|
|
let stripped = value.trim_start_matches("0x");
|
|
|
|
if stripped.is_empty() {
|
|
Err(de::Error::custom(format!(
|
|
"quantity cannot be {}",
|
|
stripped
|
|
)))
|
|
} else if stripped == "0" {
|
|
Ok(vec![0])
|
|
} else if stripped.starts_with('0') {
|
|
Err(de::Error::custom("cannot have leading zero"))
|
|
} else if stripped.len() % 2 != 0 {
|
|
hex::decode(&format!("0{}", stripped))
|
|
.map_err(|e| de::Error::custom(format!("invalid hex ({:?})", e)))
|
|
} else {
|
|
hex::decode(&stripped).map_err(|e| de::Error::custom(format!("invalid hex ({:?})", e)))
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn serialize<S>(num: &u64, serializer: S) -> Result<S::Ok, S::Error>
|
|
where
|
|
S: Serializer,
|
|
{
|
|
let raw = hex::encode(num.to_be_bytes());
|
|
let trimmed = raw.trim_start_matches('0');
|
|
|
|
let hex = if trimmed.is_empty() { "0" } else { &trimmed };
|
|
|
|
serializer.serialize_str(&format!("0x{}", &hex))
|
|
}
|
|
|
|
pub fn deserialize<'de, D>(deserializer: D) -> Result<u64, D::Error>
|
|
where
|
|
D: Deserializer<'de>,
|
|
{
|
|
let decoded = deserializer.deserialize_str(QuantityVisitor)?;
|
|
|
|
// TODO: this is not strict about byte length like other methods.
|
|
if decoded.len() > BYTES_LEN {
|
|
return Err(D::Error::custom(format!(
|
|
"expected max {} bytes for array, got {}",
|
|
BYTES_LEN,
|
|
decoded.len()
|
|
)));
|
|
}
|
|
|
|
let mut array = [0; BYTES_LEN];
|
|
array[BYTES_LEN - decoded.len()..].copy_from_slice(&decoded);
|
|
Ok(u64::from_be_bytes(array))
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod test {
|
|
use serde::{Deserialize, Serialize};
|
|
use serde_json;
|
|
|
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
|
#[serde(transparent)]
|
|
struct Wrapper {
|
|
#[serde(with = "super")]
|
|
val: u64,
|
|
}
|
|
|
|
#[test]
|
|
fn encoding() {
|
|
assert_eq!(
|
|
&serde_json::to_string(&Wrapper { val: 0 }).unwrap(),
|
|
"\"0x0\""
|
|
);
|
|
assert_eq!(
|
|
&serde_json::to_string(&Wrapper { val: 1 }).unwrap(),
|
|
"\"0x1\""
|
|
);
|
|
assert_eq!(
|
|
&serde_json::to_string(&Wrapper { val: 256 }).unwrap(),
|
|
"\"0x100\""
|
|
);
|
|
assert_eq!(
|
|
&serde_json::to_string(&Wrapper { val: 65 }).unwrap(),
|
|
"\"0x41\""
|
|
);
|
|
assert_eq!(
|
|
&serde_json::to_string(&Wrapper { val: 1024 }).unwrap(),
|
|
"\"0x400\""
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn decoding() {
|
|
assert_eq!(
|
|
serde_json::from_str::<Wrapper>("\"0x0\"").unwrap(),
|
|
Wrapper { val: 0 },
|
|
);
|
|
assert_eq!(
|
|
serde_json::from_str::<Wrapper>("\"0x41\"").unwrap(),
|
|
Wrapper { val: 65 },
|
|
);
|
|
assert_eq!(
|
|
serde_json::from_str::<Wrapper>("\"0x400\"").unwrap(),
|
|
Wrapper { val: 1024 },
|
|
);
|
|
serde_json::from_str::<Wrapper>("\"0x\"").unwrap_err();
|
|
serde_json::from_str::<Wrapper>("\"0x0400\"").unwrap_err();
|
|
serde_json::from_str::<Wrapper>("\"400\"").unwrap_err();
|
|
serde_json::from_str::<Wrapper>("\"ff\"").unwrap_err();
|
|
}
|
|
}
|