From 8a7ce2372a135e6545fa63f0d56e5d3c73819572 Mon Sep 17 00:00:00 2001 From: bennyhodl Date: Mon, 20 Oct 2025 10:27:11 -0400 Subject: [PATCH] fix: handle oracle messages as a tlv --- ddk/src/ddk.rs | 15 ++++ dlc-messages/src/oracle_msgs.rs | 117 ++++++++++++++++++++++--- testconfig/contract_binaries/Accepted | Bin 2108 -> 2262 bytes testconfig/contract_binaries/Closed | Bin 3161 -> 3318 bytes testconfig/contract_binaries/Confirmed | Bin 2606 -> 2760 bytes testconfig/contract_binaries/Offered | Bin 754 -> 908 bytes testconfig/contract_binaries/PreClosed | Bin 3021 -> 3178 bytes testconfig/contract_binaries/Signed | Bin 2606 -> 2760 bytes 8 files changed, 119 insertions(+), 13 deletions(-) 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 878d96ce04e4462fe6dbb78d222bb40deaffbc9d..fe1709b69f431a75695cbeb310db9d75919848ff 100644 GIT binary patch literal 2262 zcmbVNc|4Ts9)I6=7+a(mVhl4iIks#u(qPnZ#*(!hQqrx9!Lbb*gt3$@Wf!?+qQ#Oe zO^QngbyQLu)TAtNOir#jQ??kBGc$B=fB1a5_db8TzxVTef6s6IKEDTALMSP=Rb%@M zxQ>UbuDrro9{n1`gXa;vT_g-ATS-z>n=7%Vp-jXKAN#07W*KN3g$J}lTfExR0 z#|OtxrUe=>*{&hLZVWrv5 z!3-b#j)5c3{6m1BBm@s1*(sXfdQJ;PAo)!n7bD0A*8KB4CbGv5+~G2i*>FR=DG|#N zn}`Q11_`2bA)%NWV`V7cP4BZOzh>Zi{eA|3pA!uR-#-+AggfvH)Pyyt(^)75rTwbG z11Ul+5R#=y{B&+Z+3uG5hjN+%Z= zp(YY8J$0REiLyU`;|7FQfzPr6D7cT4YAAW@nx)x=ox_~$>@+EK8`M-Y=J`8_fpRdo ztqdgfX#`4jgmRu%&k#f2%u2L*ttG+!68Nbgea%(8ZS0vCscX?*IyY~pkB&NhK*mLy za2d=55IO$X4C7wVs5woM?`ltht^BRg zWQ+av$-e;}*tNSOnN?j!y3rhkD3JLIA1vupO?}b^XQiR+5F7l}c zl2^mBq2hPD@W--gfEUw~QCY_;Iz>&{@^Y#3HI|tx_Cr>_VK&3MGdi_HgI*O?0(Cn+ zH<&naXWyu{m=Sn2OSS9$2rSk+?06kqkulSVkd@~G_h>#6)qjveb&`Ku%ux7M`l6ul zBF`5%7)?${>O7Q=B%RTY#xe1Jg>3+nxW!w56Hk6Q<^H=UkcX}P98fT)bl3H95S0m5 zs++vUf{j_#)3#0iSLzy+k1n`p*hsb3kqhK>)XZ>Ymg?|?_Vttmf}iPf2C)ZGwt8Q< z`zVNc_+=d;Uxl8yD!@i+VlHX08 zi&3qdXXTq5@LnQ=F*jJZ%xs2(1@8EXEafhk9PaSI<(m>Ln-)8mw+r5J*V>NpzWY-7 zmXiwf72Qs(I-`Hyeb?*%Q%H~)5i40dncVG$bS}QM zcs;de`bMnU_eZJOZ>2$sZqYoqEWw|1vSB{vE_594Dj830ZH+4&tv|JlC2D2l6=^NB z>$Oz2z#bitG$fx*zO(znV$=};S0-v;<-UA9{x-G45@{dm!GZNuX))82f=YR|*XYeJ zOGS2u)Lhk$ll#J`Ruqe`Jb=`;DE$G^4LfZOPF+m$Bt6bVJ+R1j&?eTu9XjW8U+R8o zP&RsxlZlmRj_**?>7AKAH(#4DF7KYbCxL&ALOR(9)E5_ oV*KwGA?Hp(X2PqxQH3Am+PIw`(o%7hkrc%>V!Z literal 2108 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 literal 2606 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 aoU#oeeNvjypudRBqW|iqf8l%m1n@V)i*Y#s diff --git a/testconfig/contract_binaries/Offered b/testconfig/contract_binaries/Offered index bb4e80c60b9a741134d588cb7261ac004732d88f..0f55e0cb25a2a13d4f065678db7af6e58b6a4919 100644 GIT binary patch delta 832 zcmeyw+QY8M_)}C;eBWx7i-y1bB3I2jKPj!b#4f--OVZ@5o^wf<==q6?y7hl=sLcIi zs`2fhG1G3lB;IH5HD&f*e5V=wdqdtU+sV>?k%2rNO)C~(T|BLbW%H$T&fb=(x9Zih zBR(uHxVYgl!|_`d+E<(^V=EN4{x<%-qxQ1R6iZJ2BeG`tKQ%x2i@3;N2)(=U?+qnO z21X61`h=^Gf<8p>{K#gT<+Mu4Yj1f9|ANlUFKh}oJg@L=&iH07F!6>={Ui<7YfV@7 z*S_;Ll$P{#X|r0iD?RD(;;`TO_ZEv)o$+E2V-T5gJKXg5GrhU`Mf}HpRrvnd<>hN* zo%e97S;pHrAo*nbyt~n=tPMfkTC(=;>8}&m?M1TJ?&(!5J)6#`9C)Q?<1&uzjVd45 zAJ;LixN6V(CBHy%t*I2#lu&(%A5jbp42(bw0y#j`Xn6Jc5f-M&-HcN8FwS4bA|{YL zBNJEAXNNbx1tvAD1e;`=NruKqE?N40b zE|s+m91+fqEDnFN&KBu@d0m(nps)^XB}gGty-zq;7tka7?md!g(c-qg9a8+ETx(su z$FDM}kcRR;Hjo0Kyx&2AN0a1!`Fe|sX6@4te7mmnS2vTpfeVvDMjG=0CTW9r7p|Vu zIn-0IAY&DFjOgbzD_&yS%{b*M&o3`Sx=edl*C~ zW~y|VUSKrY)gcbF%VMgh$eR1jc1|0bU&p+A7a^4<^Wv>?e5>o_)t8?NaW8Z>Wnf4H z`kE0GmY|4X@SS|wirKZj2ox4Tzz9r1j2Zt6Cos)?sB0ZJp`Ic3M%31o>;KLuD{m9L z_Ve&fl^c`T)%&LyP1x#sxU&6_#)4H9vzbo&oilu#w8inhHoFPq!hX5q&+h>MCjMn| delta 677 zcmeBS|HP`uSo!npK32Oo{4-3fHA3tHpF0TeK6U$m)h}bi`p#*ZM{Z42)U7x8YPrg8 zg3K#>L$;_Ey^oB0k16Rr>v*$^ci+bhmDZ0>D`S*$O=fZJ)!)bVJNV+tJm&r-D=jxS z3s~E4EIxgvV(Giy9eNLT#vVJOn5g_t$4))vdyD9m(@IYJ)%uHHZ+ao|_lA-s1EX{C zy7*NL);*I_{xD1oxw9>7=k}a`p;h^dxji#@dY+w&&A4~+^u#+d_2Ef>zusKABJ>Vh z!Rl>dr!F1pSA2N6zU`6J{rN)wyIJiS#27?4oR?nt%bFXtVJWK*k6hiAj^G^?tN(Zl z{JxhU2$H|RH;2J)6UUc{RW0X>8a>SNS-6+f=crHK6|8oe@n7<#?W-<$v&g&dQ+1L# zIyG``MwzkS)-?+2H-s#jD$%IHfB-oR3^%S;73**|rD6>?bhs8*x_pEG~u2UY%u;`+aCGb!*YOqj*ADRo2AT-J|O|J8Ze z4!)JkE-}^@aB`k;YA$~^qaw4^XPuj0WuJ1rW{$bNt2N^D#*ZuJdMj5OO0s1!OHQ^f zc@1(V5CC2Mp8*&E4BQSm%~xF4e_&wn2TL#lqiRpa3l?wYhtI+{nf1q6zwtdQ!1i#T zR diff --git a/testconfig/contract_binaries/PreClosed b/testconfig/contract_binaries/PreClosed index 828e8e816cc25121e38921bbcce14c7fcfff3117..255da8da9fdd57c6b465b6b730b3a24e189d827d 100644 GIT binary patch literal 3178 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 diff --git a/testconfig/contract_binaries/Signed b/testconfig/contract_binaries/Signed index 4707cd2057a9ebdd670b332f6aaabb0f5fa54d4d..ac64741233327312ad418fa444b8befd0c5f7b42 100644 GIT binary patch literal 2760 zcmbVNc{r5q8lU%_v6p>pW0}z;TUlZxW69FkMTwM@vL}pXP#BcG>=Mb8Ldh0`_$X9J ziY6M$9x0#gvt`Sf8Ffy7xUSAQ&mZsoUeE7-?)CTF4|D}CEZ9(l?owJaKk@MP+Z5+W zKdmF$?!qb^`}F*d!{0&x2nfUb`}#rX3y2~yB<%ybc>VfiNE!reP|-Q-s?tl1`@uRb z$DQLdGNSce(=tcb$}WD>OhuTVu-p+7QJB}Amw|^>ynCZ(qVCieCgou}o9EqCHVSF! zJ0SO7H^@E^NnYE(Rue+Orm3@WJr~0$tjNq-@as!-TKAW4P$ktNfV6JdneGv*S=$}o zJ(#m}A4(e66V8)j-4>XURHOHt6|PHa+#6J8_MgGif`$1x{Y-+E1~f(5peN$}(~xO1 zC4{h%e$>IcwJwg$dB@kh2J!@gUmHUNApB_`ZB*CB_vI+yxn8aYnyuFwn_)FB4wEsi zQ@7~&Iqi%6CwDUut>R_Hv~ezzXIQlPJ&OOjhVt)l0d`rwPbkl4tqw=evW$iTh27dr z3trx+VpS0^&068R9j#`-&-z_}KrVzUb$@vd0~tHa*9pWesQCy((o6eGV*|i5v;dGD zKd4G=j-BwS~v z<22a3k$WUXeAUcE5boZfU^!LdzZwtX6!k%*t26W&h)|sF?0zHPl;BNry_qRCO3Zp? zHCh*FaxFg}M2a%ckGtbBb7K->{07A<^Gmz?XOog*IFJosb@7nhX8;8zqcFT=1mTsR znD_wxT38vG1yPU~ZrCf!HvPlnpY+%*SD{9iuLN`43$m9lcpN)8Xz>jZ;;)w6-B(>Q zu958CsR<&FBCKM%k%uWH6S%K zo|>Mv6>%1wnA+uV)qqk&8RO-+qo>L!2|zC-gw`sESt{iq)F2wq*rs)nMm4~7(B&I1Rkqw%IqMM{i4+FEocJnt%qmGq_ z2IW{(fIEreEnfzpmmPf0lrjsFrz+sw{A-Y!FekR6uQ+e{$al+e0xx&opcfwYW@#2B zGwT(-2*x6CSLA{)R1KGm1_)J;$AOOPo%<1B^O*^fiZ1!?p1vSlW!36QpaKu1)IOns zio~KxqiVO?rR5^0mTck-IqFMY)A{5ju$a3#Qq080pDED=Ez{LFy$<-@%_ofA-$@Dl zLI$>|2&{`QD&sCecjD(HUPKC@vK!BiiQYV=IA=d5gdUu#(*6&_exp!?OM(22!1~$O zc{|KB>|x!(`QwkUhW!`m?r4duq%5hOXtKqmscY+0FE>#irw^}fwH@V9)g$uALKJMp zWF@F6hqI~(n?~}*4x!AQq9sNi`hrMK3!nC|Aw|~Cu_J7*Gnv`GRFt}?EeAy|!>l^& zX6jA=1f=DV_jIP^clCvTUM%~?a$`Dd=X@vHP56Jd9rEwC10V>!2D#Q{4}DB%(m|Mb+s;Be9?DW~O6KVo$Y_%;faSKJ~>rJ>htg>zRZ+ zV4*@HhpuMMYh2};cI>B+cqWf3jL7wUCLjvnf*2R=%vd~+9 zg=`5qO-*YZzD2ye>QTEm+&CW*OJ^MTr{T)r8@+S?72)ZMQ2UB&zh>KZbKf|cVG|+= zK_(&{WXH?n!)m&u`3|*xC@;B3k~DDfU2WT#K+7t(iTq}1yUR+aH%QL{m@4Tv8Y(O+ z6cNF66(x_H&egaP+dD3^xv!;fV_q%Bp5gHaEjWM_wdI|5Ew+1f0JSC8|KH+v6XSok z2p(ysXU4d?+r{`Byq&`&pG{W?&I`%uPb+?GSjKhtq~#573O*A!+xUDg zsC_`?Ymo!x{J}!`Z01xV70bI}YKb2eziQ8WxfCNx!U?2pdSS#lCwr`s186bw-@C=Zn!z)|Ffi5GhP(k$q;a zgwYC{I7-| literal 2606 zcmbVNc|25m8$WYq%#}TvEKzn7im_gFO^sY#Q;3n0iA1K5WbBoatt6T3jOr4FY(PM%?NT+dQfhq*aTTU*YPU54GY_2Oi{o{zKuIY zCirNY73WIl7vTPkyNTS?H#Y#Fb^BfN4gD;(z6-zSdt(ExwOEgww*JVVgPbi0WFcs+ zxpPX2X5JWeIe{!<7CMB=OTF8ZrG5AM2cK2NI0z?=wYIhf-tfH#=RB|(A6TU8$IL(v z9F~ZMjn&70gvF42<~}wFa+2Awb^7B^6Ml@r4o$ddZ*ZITZlF#dG*LecN+Xh?NurV3 z)ByCD(I;H3!dvB2>HF=Q5co^9H70%1j0<^**zi@}K5ZCupY-@D;pNf#2Ln2>dV!q??!VNJ z3|vyu%0C826H~mXoNiR=eq~;(vT{0ClV%brm(e4h#C@gW>A}02lI@8coRwLgAo>kQ zbQy)D2uU~X9J<;iF!H!swx3#)z7I#dy%Z2sCC?&yJaG4)pE8!wrxf#;GX?~;lEn4cNs_ZIw7yk+sUiSU_faN^Aep*t@L89%SGVe30)Ph3pREg5nUJ>D^M z4Ak{+CcRS-MIOz7IVgW?fo3)*#yWM*&JFfi&#L6ko4W*~`0vTbwVQghhkKIU9YEKM z(HY(M2P=LpXu+1ZzA4%})s?rLCR4Md=U;`f#b>ljbx(=Rci!4#bmu;1<|O`nv5_^< zGd|Direp%)!vpE@D_B$;ZDdlo@4)^`xvr-z1U-7QzJ0o;c{Qn=bm6Rng|71r8T)Ai zBR7iTbQqO^GjdNlliw9}aU`FbLEsnR6F?P|3Y%@CWWBxq{)1HNs~GpA$OS%^q|?km z?F^#Ip#??xPVdNvW`c=NzeFHT1yZCwF5Grz(kO;G&$q{Oj0XJK9IwwCN4fvX?>LE2 z)9{VSmj$G4D-TicJhIx&Xyp#kwD&W)TFk;{>Bb5T@eo5(vRq>DFQR@}*H&h{3Et|k za^?!;Q~{A+@JsWA3?oQ*S(5FDeFXop9emF}VsMY&DuZU~)fYIKz$%*@4g9Pjaxa!|NchMqIR7x$Ah-wxC!3sgIL%E0Wh(Y`KbrW{PZVjnFoN-2AkPZ zyo5=7xW_(?>8HY1qqg056#k;XFBqNEpnsH92&E9NXq`VPp=#;5&A@f6gRi)G1tFQ4 z%J|L7r$c_y_G^eF;qi?nXEAS7scwWaUfFh~U^YFLQ3eHm@sb!4m{u(G5=InQdxuvw zA`v&~fP`b-nJWdl=gx{y)J8S7KM=?!Pw&tV9vj{#f2LH?7ofY$ zg@w$d-147r1=~+9b7$^9oH9aeY?g>zt;rgk9G0UQco_xV;ydfPmVyDy^};_ZBy zo@WUOsrZ^{W{3X)HGf^4&WGXfKq=3)32b1*AuD6y*T4O%(oXrC2GM09T;|9fVcA0! zZw6l#2<03F+8q-E7K08+P(>%6Z-|~t%MEOq aRmKt1C#9JU`U}V``mZkf7rxg|0Dl9xU2!-7