Fixes Tracker serialization for get_all_appointments

close #64
This commit is contained in:
Sergi Delgado Segura 2022-06-16 17:21:05 +02:00
parent 4b70825adc
commit 7e7dc973f5
3 changed files with 79 additions and 2 deletions

View file

@ -7,6 +7,9 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
.field_attribute("user_id", "#[serde(with = \"hex::serde\")]")
.field_attribute("locator", "#[serde(with = \"hex::serde\")]")
.field_attribute("encrypted_blob", "#[serde(with = \"hex::serde\")]")
.field_attribute("dispute_txid", "#[serde(with = \"crate::ser::serde_be\")]")
.field_attribute("penalty_txid", "#[serde(with = \"crate::ser::serde_be\")]")
.field_attribute("penalty_rawtx", "#[serde(with = \"hex::serde\")]")
.field_attribute(
"GetAppointmentResponse.status",
"#[serde(with = \"crate::ser::serde_status\")]",

View file

@ -15,9 +15,50 @@ where
seq.end()
}
pub mod serde_status {
pub mod serde_be {
use super::*;
use serde::de::{self, Deserializer};
pub fn serialize<S>(v: &[u8], s: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut v = v.to_owned();
v.reverse();
hex::serialize(v, s)
}
pub fn deserialize<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error>
where
D: Deserializer<'de>,
{
struct BEVisitor;
impl<'de> de::Visitor<'de> for BEVisitor {
type Value = Vec<u8>;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("a hex encoded string")
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
let mut v =
hex::decode(v).map_err(|_| E::custom("cannot deserialize the given value"))?;
v.reverse();
Ok(v)
}
}
deserializer.deserialize_any(BEVisitor)
}
}
pub mod serde_status {
use super::*;
use serde::de::{self, Deserializer};
use serde::ser::Serializer;
use std::str::FromStr;
use crate::appointment::AppointmentStatus;

View file

@ -156,3 +156,36 @@ def test_misbehaving_watchtower(node_factory, bitcoind, teosd, directory):
l1.rpc.pay(l2.rpc.invoice(25000000, "lbl1", "desc1")["bolt11"])
assert l2.rpc.gettowerinfo(tower_id)["status"] == "misbehaving"
assert l2.rpc.gettowerinfo(tower_id)["misbehaving_proof"]
def test_get_appointment(node_factory, bitcoind, teosd, directory):
l1, l2 = node_factory.line_graph(2, opts=[{"allow_broken_log": True}, {"plugin": "watchtower-client"}])
# We need to register l2 with the tower
tower_id = teosd.cli.get_tower_info()["tower_id"]
l2.rpc.registertower(tower_id)
# Force a new commitment
l1.rpc.pay(l2.rpc.invoice(25000000, "lbl1", "desc1")["bolt11"])
tx = l1.rpc.dev_sign_last_tx(l2.info["id"])["tx"]
# Now make sure it is out of date
l1.rpc.pay(l2.rpc.invoice(25000000, "lbl2", "desc2")["bolt11"])
# Now l1 cheats
dispute_txid = bitcoind.rpc.sendrawtransaction(tx)
locator = change_endianness(dispute_txid[32:])
# Check the appointment before mining a block
appointment = l2.rpc.getappointment(tower_id, locator)["appointment"]
assert "locator" in appointment and "encrypted_blob" in appointment and "to_self_delay" in appointment
bitcoind.generate_block(1)
time.sleep(1)
# And after. Now this should be a tracker
tracker = l2.rpc.getappointment(tower_id, locator)["appointment"]
assert "dispute_txid" in tracker and "penalty_txid" in tracker and "penalty_rawtx" in tracker
# Manually stop l2, otherwise the tower may be stopped before the tower client and we may get some BROKEN logs.
l2.stop()