feat: Allow chainsync to start from origin (#56)

This commit is contained in:
Santiago Carmuega 2022-02-23 19:52:49 -03:00 committed by GitHub
parent eaa6bcc7e1
commit 3317100f5d
6 changed files with 47 additions and 49 deletions

View file

@ -23,12 +23,12 @@ fn main() {
println!("{:?}", last); println!("{:?}", last);
let range = ( let range = (
Point( Point::Specific(
43847831u64, 43847831u64,
hex::decode("15b9eeee849dd6386d3770b0745e0450190f7560e5159b1b3ab13b14b2684a45") hex::decode("15b9eeee849dd6386d3770b0745e0450190f7560e5159b1b3ab13b14b2684a45")
.unwrap(), .unwrap(),
), ),
Point( Point::Specific(
43847831u64, 43847831u64,
hex::decode("15b9eeee849dd6386d3770b0745e0450190f7560e5159b1b3ab13b14b2684a45") hex::decode("15b9eeee849dd6386d3770b0745e0450190f7560e5159b1b3ab13b14b2684a45")
.unwrap(), .unwrap(),

View file

@ -40,13 +40,13 @@ fn main() {
println!("last hanshake state: {:?}", last); println!("last hanshake state: {:?}", last);
// some random known-point in the chain to use as starting point for the sync // some random known-point in the chain to use as starting point for the sync
let known_points = vec![Point( let known_points = vec![Point::Specific(
45147459, 45147459,
hex::decode("bee16ef28ac02abb50c340a7deff085a77f3a7b84c66250b3318dcb125c19a10").unwrap(), hex::decode("bee16ef28ac02abb50c340a7deff085a77f3a7b84c66250b3318dcb125c19a10").unwrap(),
)]; )];
let mut cs_channel = muxer.use_channel(5); let mut cs_channel = muxer.use_channel(5);
let cs = Consumer::<Content, _>::initial(known_points, NoopObserver {}); let cs = Consumer::<Content, _>::initial(Some(known_points), NoopObserver {});
let cs = run_agent(cs, &mut cs_channel).unwrap(); let cs = run_agent(cs, &mut cs_channel).unwrap();
println!("{:?}", cs); println!("{:?}", cs);
} }

View file

@ -1,43 +1,17 @@
use minicbor::data::Tag;
use net2::TcpStreamExt; use net2::TcpStreamExt;
use pallas_primitives::alonzo::Header; use pallas_primitives::alonzo::Header;
use pallas_primitives::Fragment;
use pallas_miniprotocols::Point; use pallas_miniprotocols::Point;
use std::net::TcpStream; use std::net::TcpStream;
use pallas_miniprotocols::chainsync::{Consumer, NoopObserver}; use pallas_miniprotocols::chainsync::{Consumer, HeaderContent, NoopObserver};
use pallas_miniprotocols::handshake::n2n::{Client, VersionTable}; use pallas_miniprotocols::handshake::n2n::{Client, VersionTable};
use pallas_miniprotocols::{ use pallas_miniprotocols::{run_agent, MAINNET_MAGIC};
run_agent, DecodePayload, EncodePayload, PayloadDecoder, PayloadEncoder, MAINNET_MAGIC,
};
use pallas_multiplexer::Multiplexer; use pallas_multiplexer::Multiplexer;
#[derive(Debug)] #[derive(Debug)]
pub struct Content(u32, Header); pub struct Content(u32, Header);
impl EncodePayload for Content {
fn encode_payload(&self, e: &mut PayloadEncoder) -> Result<(), Box<dyn std::error::Error>> {
e.array(2)?;
e.u32(self.0)?;
e.tag(Tag::Cbor)?;
e.bytes(&self.1.encode_fragment()?)?;
Ok(())
}
}
impl DecodePayload for Content {
fn decode_payload(d: &mut PayloadDecoder) -> Result<Self, Box<dyn std::error::Error>> {
d.array()?;
let unknown = d.u32()?; // WTF is this value?
d.tag()?;
let bytes = d.bytes()?;
let header = Header::decode_fragment(bytes)?;
Ok(Content(unknown, header))
}
}
fn main() { fn main() {
env_logger::init(); env_logger::init();
@ -52,14 +26,14 @@ fn main() {
let last = run_agent(Client::initial(versions), &mut hs_channel).unwrap(); let last = run_agent(Client::initial(versions), &mut hs_channel).unwrap();
println!("{:?}", last); println!("{:?}", last);
let known_points = vec![Point( let known_points = vec![Point::Specific(
43847831u64, 43847831u64,
hex::decode("15b9eeee849dd6386d3770b0745e0450190f7560e5159b1b3ab13b14b2684a45").unwrap(), hex::decode("15b9eeee849dd6386d3770b0745e0450190f7560e5159b1b3ab13b14b2684a45").unwrap(),
)]; )];
let mut cs_channel = muxer.use_channel(2); let mut cs_channel = muxer.use_channel(2);
let cs = Consumer::<Content, _>::initial(known_points, NoopObserver {}); let cs = Consumer::<HeaderContent, _>::initial(Some(known_points), NoopObserver {});
let cs = run_agent(cs, &mut cs_channel).unwrap(); let cs = run_agent(cs, &mut cs_channel).unwrap();
println!("{:?}", cs); println!("{:?}", cs);

View file

@ -52,7 +52,7 @@ where
O: Observer<C>, O: Observer<C>,
{ {
pub state: State, pub state: State,
pub known_points: Vec<Point>, pub known_points: Option<Vec<Point>>,
pub intersect: Option<Point>, pub intersect: Option<Point>,
pub tip: Option<Tip>, pub tip: Option<Tip>,
@ -66,7 +66,7 @@ where
O: Observer<C>, O: Observer<C>,
C: DecodePayload + EncodePayload, C: DecodePayload + EncodePayload,
{ {
pub fn initial(known_points: Vec<Point>, observer: O) -> Self { pub fn initial(known_points: Option<Vec<Point>>, observer: O) -> Self {
Self { Self {
state: State::Idle, state: State::Idle,
intersect: None, intersect: None,
@ -80,7 +80,12 @@ where
fn send_find_intersect(self, tx: &impl MachineOutput) -> Transition<Self> { fn send_find_intersect(self, tx: &impl MachineOutput) -> Transition<Self> {
debug!("requesting find intersect"); debug!("requesting find intersect");
let msg = Message::<C>::FindIntersect(self.known_points.clone()); let points = match &self.known_points {
Some(x) => x.clone(),
None => return Err("can't find intersect without known points".into()),
};
let msg = Message::<C>::FindIntersect(points);
tx.send_msg(&msg)?; tx.send_msg(&msg)?;
@ -189,8 +194,14 @@ where
fn send_next(self, tx: &impl MachineOutput) -> Transition<Self> { fn send_next(self, tx: &impl MachineOutput) -> Transition<Self> {
match self.state { match self.state {
State::Idle => match self.intersect { State::Idle => match self.intersect {
// keep going from pointer
Some(_) => self.send_request_next(tx), Some(_) => self.send_request_next(tx),
None => self.send_find_intersect(tx), _ => match self.known_points {
// need to find instersection first
Some(_) => self.send_find_intersect(tx),
// start from genesis
None => self.send_request_next(tx),
},
}, },
_ => panic!("I don't have agency, don't know what to do"), _ => panic!("I don't have agency, don't know what to do"),
} }

View file

@ -3,17 +3,27 @@ use super::payloads::*;
impl EncodePayload for Point { impl EncodePayload for Point {
fn encode_payload(&self, e: &mut PayloadEncoder) -> Result<(), Box<dyn std::error::Error>> { fn encode_payload(&self, e: &mut PayloadEncoder) -> Result<(), Box<dyn std::error::Error>> {
e.array(2)?.u64(self.0)?.bytes(&self.1)?; match self {
Point::Origin => e.array(0)?,
Point::Specific(slot, hash) => e.array(2)?.u64(*slot)?.bytes(hash)?,
};
Ok(()) Ok(())
} }
} }
impl DecodePayload for Point { impl DecodePayload for Point {
fn decode_payload(d: &mut PayloadDecoder) -> Result<Self, Box<dyn std::error::Error>> { fn decode_payload(d: &mut PayloadDecoder) -> Result<Self, Box<dyn std::error::Error>> {
d.array()?; let size = d.array()?;
let slot = d.u64()?;
let hash = d.bytes()?;
Ok(Point(slot, Vec::from(hash))) match size {
Some(0) => Ok(Point::Origin),
Some(2) => {
let slot = d.u64()?;
let hash = d.bytes()?;
Ok(Point::Specific(slot, Vec::from(hash)))
}
_ => Err("can't decode Point from array of size".into()),
}
} }
} }

View file

@ -8,19 +8,22 @@ pub const MAINNET_MAGIC: u64 = 764824073;
/// A point within a chain /// A point within a chain
#[derive(Clone, Eq, PartialEq, Hash)] #[derive(Clone, Eq, PartialEq, Hash)]
pub struct Point(pub u64, pub Vec<u8>); pub enum Point {
Origin,
Specific(u64, Vec<u8>),
}
impl Debug for Point { impl Debug for Point {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_tuple("Point") match self {
.field(&self.0) Self::Origin => write!(f, "Origin"),
.field(&hex::encode(&self.1)) Self::Specific(arg0, arg1) => write!(f, "({}, {})", arg0, hex::encode(arg1)),
.finish() }
} }
} }
impl Point { impl Point {
pub fn new(slot: u64, hash: Vec<u8>) -> Self { pub fn new(slot: u64, hash: Vec<u8>) -> Self {
Point(slot, hash) Point::Specific(slot, hash)
} }
} }