-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
gossip_map: impl the gossip map basic types
Signed-off-by: Vincenzo Palazzo <[email protected]>
- Loading branch information
1 parent
9da1bbc
commit a8c4382
Showing
4 changed files
with
218 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,3 +4,4 @@ version = "0.1.0" | |
edition = "2021" | ||
|
||
[dependencies] | ||
byteorder = "1.4.3" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
//! Flag implementation for the gossip map types | ||
pub static GOSSIP_STORE_MAJOR_VERSION: u16 = 0 << 5; | ||
pub static GOSSIP_STORE_MAJOR_VERSION_MASK: u16 = 0xE0; | ||
|
||
/// Deleted fields should be ignored: on restart, they will be removed as the gossip_store is rewritten. | ||
pub static GOSSIP_STORE_LEN_DELETED_BIT: u32 = 0x80000000; | ||
/// The push flag indicates gossip which is generated locally: this is important for gossip timestamp filtering, | ||
/// where peers request gossip and we always send our own gossip messages even if the timestamp wasn't within their | ||
/// request.pub static GOSSIP_STORE_LEN_PUSH_BIT: u32 = 0x40000000; | ||
pub static GOSSIP_STORE_LEN_RATELIMIT_BIT: u32 = 0x20000000; | ||
/// The ratelimit flag indicates that this gossip message came too fast. | ||
/// The message are corded in the gossip map, but don't relay it to peers. | ||
pub static GOSSIP_STORE_LEN_MASK: u16 = 0x0000FFFF; | ||
|
||
// These duplicate constants in lightning/gossipd/gossip_store_wiregen.h | ||
pub const WIRE_GOSSIP_STORE_PRIVATE_CHANNEL: u16 = 4104; | ||
pub const WIRE_GOSSIP_STORE_PRIVATE_UPDATE: u16 = 4102; | ||
pub const WIRE_GOSSIP_STORE_DELETE_CHAN: u16 = 4103; | ||
pub const WIRE_GOSSIP_STORE_ENDED: u16 = 4105; | ||
pub const WIRE_GOSSIP_STORE_CHANNEL_AMOUNT: u16 = 4101; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,78 @@ | ||
struct GossipMap; | ||
use byteorder::{BigEndian, ReadBytesExt}; | ||
use flags::{ | ||
GOSSIP_STORE_MAJOR_VERSION, GOSSIP_STORE_MAJOR_VERSION_MASK, WIRE_GOSSIP_STORE_CHANNEL_AMOUNT, | ||
WIRE_GOSSIP_STORE_DELETE_CHAN, WIRE_GOSSIP_STORE_ENDED, WIRE_GOSSIP_STORE_PRIVATE_CHANNEL, | ||
WIRE_GOSSIP_STORE_PRIVATE_UPDATE, | ||
}; | ||
use std::{ | ||
fs::File, | ||
io::{BufReader, Error, ErrorKind}, | ||
}; | ||
use types::{GossipChannel, GossipNode}; | ||
|
||
mod flags; | ||
mod types; | ||
|
||
/// Gossip map implementation, that allow you to manage the gossip_store | ||
/// written by core lightning. | ||
struct GossipMap { | ||
version: u8, | ||
stream: Option<BufReader<File>>, | ||
} | ||
|
||
impl GossipMap { | ||
// Create a new instance of the gossip map. | ||
pub fn new() -> Self { | ||
GossipMap {} | ||
pub fn new(version: u8) -> Self { | ||
GossipMap { | ||
version, | ||
stream: None, | ||
} | ||
} | ||
|
||
pub fn get_channel(short_chananel_id: &str) -> Result<(), ()> { | ||
Ok(()) | ||
pub fn from_file(file_name: &str) -> Result<Self, std::io::Error> { | ||
let gossip_store = File::open(file_name)?; | ||
let stream = BufReader::new(gossip_store); | ||
let mut gossip_map = GossipMap { | ||
version: 0, | ||
stream: Some(stream), | ||
}; | ||
gossip_map.refresh()?; | ||
Ok(gossip_map) | ||
} | ||
|
||
pub fn get_node(node_id: &str) -> Result<(), ()> { | ||
Ok(()) | ||
pub fn get_channel(short_chananel_id: &str) -> Result<&'static GossipChannel, ()> { | ||
todo!() | ||
} | ||
|
||
pub fn refresh() -> Result<(), ()> { | ||
pub fn get_node(node_id: &str) -> Result<&'static GossipNode, ()> { | ||
todo!() | ||
} | ||
|
||
fn refresh(&mut self) -> Result<(), std::io::Error> { | ||
let version = self.stream.as_mut().unwrap().read_u8()? as u16; | ||
if (version & GOSSIP_STORE_MAJOR_VERSION_MASK) != GOSSIP_STORE_MAJOR_VERSION { | ||
return Err(Error::new( | ||
ErrorKind::Other, | ||
"Invalid gossip tore version {version}", | ||
)); | ||
} | ||
self.version = version as u8; | ||
|
||
while let Ok(chunk) = self.stream.as_mut().unwrap().read_u8() { | ||
match chunk as u16 { | ||
// channel announcement! | ||
256 => todo!(), | ||
WIRE_GOSSIP_STORE_PRIVATE_CHANNEL => todo!("parsing the private channel"), | ||
WIRE_GOSSIP_STORE_CHANNEL_AMOUNT => todo!("channel ammount"), | ||
WIRE_GOSSIP_STORE_PRIVATE_UPDATE => todo!("private update"), | ||
WIRE_GOSSIP_STORE_DELETE_CHAN => todo!("channel deleted"), | ||
WIRE_GOSSIP_STORE_ENDED => todo!("need to be reimplemented the open store"), | ||
257 => todo!("node announcment"), | ||
258 => todo!("channel update"), | ||
_ => continue, | ||
} | ||
} | ||
|
||
Ok(()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,136 @@ | ||
//! Gossip map types implementations. | ||
use byteorder::{BigEndian, ReadBytesExt}; | ||
use std::{collections::HashMap, io::BufRead, ops::Deref, str, str::Bytes, vec::Vec}; | ||
|
||
/// TODO: implement it. | ||
struct GossipNodeId; | ||
use crate::flags::{GOSSIP_STORE_LEN_DELETED_BIT, GOSSIP_STORE_LEN_MASK}; | ||
|
||
/// TODO: implement it. | ||
struct GossipNode; | ||
trait GossipType { | ||
/// Decode the gossip message from a sequence of bytes. | ||
fn decode(stream: &mut dyn BufRead) -> Result<Self, std::io::Error> | ||
where | ||
Self: Sized; | ||
|
||
/// TODO: implement it | ||
struct GossipChannel; | ||
/// Encode the gossip message in a sequence of bytes. | ||
fn encode(&self) -> Bytes; | ||
} | ||
|
||
/// TODO: implement it | ||
struct GossipPartialChannel; | ||
/// Node Id encoded for the gossip map | ||
pub struct GossipNodeId { | ||
node_id: String, | ||
} | ||
|
||
// TODO: implementing it | ||
struct GossipStoredHeader; | ||
impl GossipNodeId { | ||
pub(crate) fn from_bytes(buff: &[u8; 32]) -> GossipNodeId { | ||
GossipNodeId { | ||
node_id: String::from_utf8(buff.to_vec()).unwrap(), | ||
} | ||
} | ||
} | ||
|
||
impl GossipType for GossipNodeId { | ||
fn decode(stream: &mut dyn BufRead) -> Result<Self, std::io::Error> | ||
where | ||
Self: Sized, | ||
{ | ||
let mut node_id: String = String::new(); | ||
stream.read_to_string(&mut node_id)?; | ||
|
||
// FIXME: missed sanity check! | ||
let res = GossipNodeId { node_id }; | ||
Ok(res) | ||
} | ||
|
||
fn encode(&self) -> Bytes { | ||
todo!() | ||
} | ||
} | ||
|
||
pub struct GossipNode<'a> { | ||
node_id: GossipNodeId, | ||
announce_fileds: Option<HashMap<String, String>>, | ||
announce_offset: Option<u32>, | ||
channels: Vec<&'a GossipChannel<'a>>, | ||
} | ||
|
||
impl<'a> GossipNode<'a> { | ||
/// add a gossip channel inside the gossip map. | ||
pub fn add_channel(&'a mut self, channel: &'a GossipChannel) { | ||
self.channels.push(channel); | ||
} | ||
} | ||
|
||
impl GossipType for GossipNode<'_> { | ||
fn decode(stream: &mut dyn BufRead) -> Result<Self, std::io::Error> | ||
where | ||
Self: Sized, | ||
{ | ||
let mut buff = [0; 32]; | ||
stream.read_exact(&mut buff)?; | ||
let node_id = GossipNodeId::from_bytes(&buff); | ||
todo!() | ||
} | ||
|
||
fn encode(&self) -> Bytes { | ||
todo!() | ||
} | ||
} | ||
|
||
/// Channel Information stored inside the Gossip Map. | ||
pub struct GossipChannel<'a> { | ||
fileds: HashMap<String, String>, | ||
annound_offset: u32, | ||
scid: String, | ||
node_one: &'a GossipNode<'a>, | ||
node_two: &'a GossipNode<'a>, | ||
update_fields: Vec<HashMap<String, String>>, | ||
update_offset: Vec<u32>, | ||
satoshi: Option<u64>, | ||
half_channels: Vec<&'a GossipPartialChannel>, | ||
} | ||
|
||
impl GossipType for GossipChannel<'_> { | ||
fn decode(stream: &mut dyn BufRead) -> Result<Self, std::io::Error> | ||
where | ||
Self: Sized, | ||
{ | ||
todo!() | ||
} | ||
|
||
fn encode(&self) -> Bytes { | ||
todo!() | ||
} | ||
} | ||
|
||
/// One direction gossip map channel | ||
pub struct GossipPartialChannel {} | ||
|
||
/// Gossip map header, that contains the version | ||
/// of the gossip map. | ||
pub struct GossipStoredHeader { | ||
flags: bool, | ||
len: u16, | ||
crc: u32, | ||
timestamp: u32, | ||
} | ||
|
||
impl GossipType for GossipStoredHeader { | ||
fn decode(stream: &mut dyn BufRead) -> Result<Self, std::io::Error> | ||
where | ||
Self: Sized, | ||
{ | ||
let len = stream.read_u16::<BigEndian>()?; | ||
let crc = stream.read_u32::<BigEndian>()?; | ||
let timestamp = stream.read_u32::<BigEndian>()?; | ||
|
||
Ok(GossipStoredHeader { | ||
timestamp, | ||
crc, | ||
flags: (len as u32 & GOSSIP_STORE_LEN_DELETED_BIT) != 0, | ||
len: (len & GOSSIP_STORE_LEN_MASK), | ||
}) | ||
} | ||
|
||
fn encode(&self) -> Bytes { | ||
todo!() | ||
} | ||
} |