diff --git a/ddk/src/ddk.rs b/ddk/src/ddk.rs index c22054a..c318fcc 100644 --- a/ddk/src/ddk.rs +++ b/ddk/src/ddk.rs @@ -415,3 +415,18 @@ where }) } } + +#[cfg(test)] +mod tests { + use ddk_messages::oracle_msgs::OracleAnnouncement; + use lightning::{io::Cursor, util::ser::Readable}; + + #[test] + fn oracle_announcement_tlv() { + let bytes = hex::decode("fdd824fd012a6d9f8eb0ad220690c328fc3bf0a5f063687bdd5e40ddcf37e8ad1fad86c2dc71eb891df5cb225af2085ec2e1767c724b0f0e2a47e3defdb4d9716ea5baba0421ba9ead06ccc4aa156fb6f7e014951413ca47194c6c8fecca83a1e28830c061d0fdd822c600016961420d0edf1d96ad8c376634d797a46d8b25886e61716bb3c63ddfed260b8668eefda5fdd8064e0004086e6f742d70616964067265706169641d6c6971756964617465642d62792d6d617475726174696f6e2d646174651d6c6971756964617465642d62792d70726963652d7468726573686f6c644d6c6f616e2d6d6174757265642d31653665356635383537333866383036343338623833333134623932653161303739366462353432646237643636323630656564306530666239623530616538").unwrap(); + let mut cursor = Cursor::new(bytes); + let announcement = OracleAnnouncement::read(&mut cursor); + println!("{:?}", announcement); + assert!(announcement.is_ok()) + } +} diff --git a/dlc-messages/src/oracle_msgs.rs b/dlc-messages/src/oracle_msgs.rs index e20521c..4743365 100644 --- a/dlc-messages/src/oracle_msgs.rs +++ b/dlc-messages/src/oracle_msgs.rs @@ -1,8 +1,8 @@ //! Structs containing oracle information. use crate::ser_impls::{ - read_as_tlv, read_i32, read_schnorr_pubkey, read_schnorrsig, read_strings_u16, write_as_tlv, - write_i32, write_schnorr_pubkey, write_schnorrsig, write_strings_u16, BigSize, + read_as_tlv, read_i32, read_schnorr_pubkey, read_strings_u16, write_as_tlv, write_i32, + write_schnorr_pubkey, write_schnorrsig, write_strings_u16, BigSize, }; use bitcoin::hashes::{Hash, HashEngine}; use ddk_dlc::{Error, OracleInfo as DlcOracleInfo}; @@ -224,11 +224,18 @@ impl OracleAnnouncement { } } -impl_dlc_writeable!(OracleAnnouncement, { - (announcement_signature, {cb_writeable, write_schnorrsig, read_schnorrsig}), - (oracle_public_key, {cb_writeable, write_schnorr_pubkey, read_schnorr_pubkey}), - (oracle_event, {cb_writeable, write_as_tlv, read_as_tlv}) -}); +// fn read_oracle_message(msg: MagnoliaResponse) -> Result { +// let bytes = hex::decode(msg.hex).map_err(|e| Error::OracleError(e.to_string()))?; +// let mut cursor = Cursor::new(bytes); +// let _type_id: u64 = lightning::util::ser::BigSize::read(&mut cursor).unwrap().0; +// let _length: u64 = lightning::util::ser::BigSize::read(&mut cursor).unwrap().0; +// T::read(&mut cursor).map_err(|e| Error::OracleError(e.to_string())) +// } +// impl_dlc_writeable!(OracleAnnouncement, { +// (announcement_signature, {cb_writeable, write_schnorrsig, read_schnorrsig}), +// (oracle_public_key, {cb_writeable, write_schnorr_pubkey, read_schnorr_pubkey}), +// (oracle_event, {cb_writeable, write_as_tlv, read_as_tlv}) +// }); impl From<&OracleAnnouncement> for DlcOracleInfo { fn from(input: &OracleAnnouncement) -> DlcOracleInfo { @@ -239,6 +246,49 @@ impl From<&OracleAnnouncement> for DlcOracleInfo { } } +impl Readable for OracleAnnouncement { + fn read(reader: &mut R) -> Result { + let _type_id: u64 = BigSize::read(reader)?.0; + let _length: u64 = BigSize::read(reader)?.0; + + let announcement_signature = crate::ser_impls::read_schnorrsig(reader)?; + let oracle_public_key = crate::ser_impls::read_schnorr_pubkey(reader)?; + let _type_id: u64 = BigSize::read(reader)?.0; + let _length: u64 = BigSize::read(reader)?.0; + let oracle_event = OracleEvent::read(reader)?; + + Ok(Self { + announcement_signature, + oracle_public_key, + oracle_event, + }) + } +} + +impl Writeable for OracleAnnouncement { + fn write(&self, writer: &mut W) -> Result<(), lightning::io::Error> { + BigSize(self.type_id() as u64).write(writer)?; + BigSize(self.serialized_length() as u64).write(writer)?; + write_schnorrsig(&self.announcement_signature, writer)?; + write_schnorr_pubkey(&self.oracle_public_key, writer)?; + write_as_tlv(&self.oracle_event, writer)?; + Ok(()) + } + + fn serialized_length(&self) -> usize { + // Calculate size without the outer TLV wrapper (type + length) + 64 + // announcement_signature + 32 + // oracle_public_key + { + // oracle_event as TLV + let event_size = self.oracle_event.serialized_length(); + BigSize(self.oracle_event.type_id() as u64).serialized_length() + + BigSize(event_size as u64).serialized_length() + + event_size + } + } +} + #[derive(Clone, Eq, PartialEq, Debug)] #[cfg_attr( feature = "use-serde", @@ -446,12 +496,53 @@ impl Type for OracleAttestation { } } -impl_dlc_writeable!(OracleAttestation, { - (event_id, string), - (oracle_public_key, {cb_writeable, write_schnorr_pubkey, read_schnorr_pubkey}), - (signatures, {vec_u16_cb, write_schnorrsig, read_schnorrsig}), - (outcomes, {cb_writeable, write_strings_u16, read_strings_u16}) -}); +impl Readable for OracleAttestation { + fn read(reader: &mut R) -> Result { + let _type_id: u64 = BigSize::read(reader)?.0; + let _length: u64 = BigSize::read(reader)?.0; + + Ok(Self { + event_id: Readable::read(reader)?, + oracle_public_key: crate::ser_impls::read_schnorr_pubkey(reader)?, + signatures: { + let len: u16 = Readable::read(reader)?; + let mut signatures = Vec::with_capacity(len as usize); + for _ in 0..len { + signatures.push(crate::ser_impls::read_schnorrsig(reader)?); + } + signatures + }, + outcomes: crate::ser_impls::read_strings_u16(reader)?, + }) + } +} + +impl Writeable for OracleAttestation { + fn write(&self, writer: &mut W) -> Result<(), lightning::io::Error> { + BigSize(self.type_id() as u64).write(writer)?; + BigSize(self.serialized_length() as u64).write(writer)?; + self.event_id.write(writer)?; + write_schnorr_pubkey(&self.oracle_public_key, writer)?; + (self.signatures.len() as u16).write(writer)?; + for sig in &self.signatures { + write_schnorrsig(sig, writer)?; + } + write_strings_u16(&self.outcomes, writer)?; + Ok(()) + } + + fn serialized_length(&self) -> usize { + // Calculate size without the outer TLV wrapper (type + length) + self.event_id.serialized_length() + + 32 + // oracle_public_key + 2 + // signatures length u16 + (64 * self.signatures.len()) + // each signature is 64 bytes + { + // outcomes as u16 length + strings + 2 + self.outcomes.iter().map(|s| s.len() + 2).sum::() + } + } +} #[cfg(test)] mod tests { diff --git a/testconfig/contract_binaries/Accepted b/testconfig/contract_binaries/Accepted index 878d96c..fe1709b 100644 Binary files a/testconfig/contract_binaries/Accepted and b/testconfig/contract_binaries/Accepted differ diff --git a/testconfig/contract_binaries/Closed b/testconfig/contract_binaries/Closed index 97c63d4..b7f9848 100644 Binary files a/testconfig/contract_binaries/Closed and b/testconfig/contract_binaries/Closed differ diff --git a/testconfig/contract_binaries/Confirmed b/testconfig/contract_binaries/Confirmed index ca31d83..66026a6 100644 Binary files a/testconfig/contract_binaries/Confirmed and b/testconfig/contract_binaries/Confirmed differ diff --git a/testconfig/contract_binaries/Offered b/testconfig/contract_binaries/Offered index bb4e80c..0f55e0c 100644 Binary files a/testconfig/contract_binaries/Offered and b/testconfig/contract_binaries/Offered differ diff --git a/testconfig/contract_binaries/PreClosed b/testconfig/contract_binaries/PreClosed index 828e8e8..255da8d 100644 Binary files a/testconfig/contract_binaries/PreClosed and b/testconfig/contract_binaries/PreClosed differ diff --git a/testconfig/contract_binaries/Signed b/testconfig/contract_binaries/Signed index 4707cd2..ac64741 100644 Binary files a/testconfig/contract_binaries/Signed and b/testconfig/contract_binaries/Signed differ