package Ġfr . ac in q . lightning . payment Ċ Ċ import Ġfr . ac in q . bitcoin .* Ċ import Ġfr . ac in q . bitcoin . io . ByteArray Input Ċ import Ġfr . ac in q . lightning .* Ċ import Ġfr . ac in q . lightning . Lightning . node Fee Ċ import Ġfr . ac in q . lightning . Lightning . random Bytes 3 2 Ċ import Ġfr . ac in q . lightning . Lightning . random Bytes 6 4 Ċ import Ġfr . ac in q . lightning . Lightning . random Key Ċ import Ġfr . ac in q . lightning . channel . Channel Ċ import Ġfr . ac in q . lightning . crypto . sphinx . S phinx Ċ import Ġfr . ac in q . lightning . router . Channel Hop Ċ import Ġfr . ac in q . lightning . router . Node Hop Ċ import Ġfr . ac in q . lightning . tests . utils . Lightning TestSuite Ċ import Ġfr . ac in q . lightning . utils .* Ċ import Ġfr . ac in q . lightning . wire .* Ċ import Ġkotlin . test .* Ċ Ċ class ĠPayment Packet Tests Common Ġ: ĠLight ning TestSuite () Ġ{ ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġpriv A Ġ= Ġrandom Key () ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġa Ġ= Ġpriv A . publicKey () ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġpriv B Ġ= Ġrandom Key () ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġb Ġ= Ġpriv B . publicKey () ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġpriv C Ġ= Ġrandom Key () ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġc Ġ= Ġpriv C . publicKey () ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġpriv D Ġ= Ġrandom Key () ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġd Ġ= Ġpriv D . publicKey () ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġpriv E Ġ= Ġrandom Key () ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġe Ġ= Ġpriv E . publicKey () ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġdefault Channel Update Ġ= ĠChannel Update ( random Bytes 6 4 (), ĠBlock . Reg test Genesis Block . hash , ĠShort Channel Id ( 0 ), Ġ 0 , Ġ 1 , Ġ 0 , ĠC lt v Expiry Delta ( 0 ), Ġ 4 2 0 0 0 . ms at , Ġ 0 . ms at , Ġ 0 , Ġ 5 0 0 0 0 0 0 0 0 . ms at ) ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġchannel Update AB Ġ= Ġdefault Channel Update . copy ( short Channel Id Ġ= ĠShort Channel Id ( 1 ), Ġcl tv Expiry Delta Ġ= ĠC lt v Expiry Delta ( 4 ), Ġfee Base Ms at Ġ= Ġ 6 4 2 0 0 0 . ms at , Ġfee Pro portional M illion ths Ġ= Ġ 7 ) ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġchannel Update BC Ġ= Ġdefault Channel Update . copy ( short Channel Id Ġ= ĠShort Channel Id ( 2 ), Ġcl tv Expiry Delta Ġ= ĠC lt v Expiry Delta ( 5 ), Ġfee Base Ms at Ġ= Ġ 1 5 3 0 0 0 . ms at , Ġfee Pro portional M illion ths Ġ= Ġ 4 ) ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġchannel Update CD Ġ= Ġdefault Channel Update . copy ( short Channel Id Ġ= ĠShort Channel Id ( 3 ), Ġcl tv Expiry Delta Ġ= ĠC lt v Expiry Delta ( 1 0 ), Ġfee Base Ms at Ġ= Ġ 6 0 0 0 0 . ms at , Ġfee Pro portional M illion ths Ġ= Ġ 1 ) ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġchannel Update DE Ġ= Ġdefault Channel Update . copy ( short Channel Id Ġ= ĠShort Channel Id ( 4 ), Ġcl tv Expiry Delta Ġ= ĠC lt v Expiry Delta ( 7 ), Ġfee Base Ms at Ġ= Ġ 7 6 6 0 0 0 . ms at , Ġfee Pro portional M illion ths Ġ= Ġ 1 0 ) ĊĊĠĠĠĠĠĠĠ Ġ// Ġsimple Ġroute Ġa Ġ-> Ġb Ġ-> Ġc Ġ-> Ġd Ġ-> Ġe ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġh ops Ġ= ĠlistOf ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠChannel Hop ( a , Ġb , Ġchannel Update AB ), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠChannel Hop ( b , Ġc , Ġchannel Update BC ), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠChannel Hop ( c , Ġd , Ġchannel Update CD ), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠChannel Hop ( d , Ġe , Ġchannel Update DE ) ĊĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġfinal Amount Ġ= Ġ 4 2 0 0 0 0 0 0 . ms at ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval Ġcurrent Block Count Ġ= Ġ 4 0 0 0 0 0 L ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġfinal Expiry Ġ= ĠC lt v Expiry ( current Block Count ) Ġ+ ĠChannel . MIN _ CL TV _ EXPI RY _ DELTA ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġpayment Pre image Ġ= Ġrandom Bytes 3 2 () ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġpayment Hash Ġ= ĠCrypto . sha 2 5 6 ( payment Pre image ). to Byte Vector 3 2 () ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġpayment Secret Ġ= Ġrandom Bytes 3 2 () ĊĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġexpiry DE Ġ= Ġfinal Expiry ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġamount DE Ġ= Ġfinal Amount ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġfee D Ġ= Ġnode Fee ( channel Update DE . fee Base Ms at , Ġchannel Update DE . fee Pro portional M illion ths , Ġamount DE ) ĊĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġexpiry CD Ġ= Ġexpiry DE Ġ+ Ġchannel Update DE . cl tv Expiry Delta ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġamount CD Ġ= Ġamount DE Ġ+ Ġfee D ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġfee C Ġ= Ġnode Fee ( channel Update CD . fee Base Ms at , Ġchannel Update CD . fee Pro portional M illion ths , Ġamount CD ) ĊĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġexpiry BC Ġ= Ġexpiry CD Ġ+ Ġchannel Update CD . cl tv Expiry Delta ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġamount BC Ġ= Ġamount CD Ġ+ Ġfee C ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġfee B Ġ= Ġnode Fee ( channel Update BC . fee Base Ms at , Ġchannel Update BC . fee Pro portional M illion ths , Ġamount BC ) ĊĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġexpiry AB Ġ= Ġexpiry BC Ġ+ Ġchannel Update BC . cl tv Expiry Delta ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġamount AB Ġ= Ġamount BC Ġ+ Ġfee B ĊĊĠĠĠĠĠĠĠ Ġ// Ġsimple Ġtr amp oline Ġroute Ġto Ġe : ĊĠĠĠĠĠĠĠ Ġ// ĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. -- . ĠĠ Ġ. -- . ĊĠĠĠĠĠĠĠ Ġ// ĠĠĠĠĠĠĠĠĠĠĠ Ġ/ ĠĠĠ Ġ\ Ġ/ ĠĠĠ Ġ\ ĊĠĠĠĠĠĠĠ Ġ// Ġa Ġ-> Ġb Ġ-> Ġc ĠĠĠĠĠ Ġd ĠĠĠĠĠ Ġe ĊĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġtr amp oline H ops Ġ= ĠlistOf ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠNode Hop ( a , Ġc , Ġchannel Update AB . cl tv Expiry Delta Ġ+ Ġchannel Update BC . cl tv Expiry Delta , Ġfee B ), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠNode Hop ( c , Ġd , Ġchannel Update CD . cl tv Expiry Delta , Ġfee C ), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠNode Hop ( d , Ġe , Ġchannel Update DE . cl tv Expiry Delta , Ġfee D ) ĊĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġtr amp oline Channel H ops Ġ= ĠlistOf ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠChannel Hop ( a , Ġb , Ġchannel Update AB ), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠChannel Hop ( b , Ġc , Ġchannel Update BC ) ĊĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġtest Build On ion () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfinal Payload Ġ= ĠFinal Payload ( T lv Stream ( listOf ( On ion T lv . Amount To Forward ( final Amount ), ĠOn ion T lv . Outgoing C lt v ( final Expiry ), ĠOn ion T lv . Payment Data ( payment Secret , Ġfinal Amount )))) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġ( first Amount , Ġfirst Expiry , Ġon ion ) Ġ= ĠOut going Packet . build Packet ( payment Hash , Ġh ops , Ġfinal Payload , ĠOn ion Routing Packet . Payment Packet Length ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( amount AB , Ġfirst Amount ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( expiry AB , Ġfirst Expiry ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( On ion Routing Packet . Payment Packet Length , Ġon ion . packet . payload . size ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġlet 's Ġpe el Ġthe Ġon ion ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtest Pe el On ion ( on ion . packet ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġtest Pe el On ion ( packet _ b : ĠOn ion Routing Packet ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġadd B Ġ= ĠUpdate Add H tl c ( random Bytes 3 2 (), Ġ 0 , Ġamount AB , Ġpayment Hash , Ġexpiry AB , Ġpacket _ b ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġ( payload B , Ġpacket C ) Ġ= Ġdecrypt Channel Relay ( add B , Ġpriv B ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( On ion Routing Packet . Payment Packet Length , Ġpacket C . payload . size ()) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( amount BC , Ġpayload B . amount To Forward ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( expiry BC , Ġpayload B . outgoing C lt v ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( channel Update BC . short Channel Id , Ġpayload B . outgoing Channel Id ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġadd C Ġ= ĠUpdate Add H tl c ( random Bytes 3 2 (), Ġ 1 , Ġamount BC , Ġpayment Hash , Ġexpiry BC , Ġpacket C ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġ( payload C , Ġpacket D ) Ġ= Ġdecrypt Channel Relay ( add C , Ġpriv C ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( On ion Routing Packet . Payment Packet Length , Ġpacket D . payload . size ()) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( amount CD , Ġpayload C . amount To Forward ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( expiry CD , Ġpayload C . outgoing C lt v ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( channel Update CD . short Channel Id , Ġpayload C . outgoing Channel Id ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġadd D Ġ= ĠUpdate Add H tl c ( random Bytes 3 2 (), Ġ 2 , Ġamount CD , Ġpayment Hash , Ġexpiry CD , Ġpacket D ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġ( payload D , Ġpacket E ) Ġ= Ġdecrypt Channel Relay ( add D , Ġpriv D ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( On ion Routing Packet . Payment Packet Length , Ġpacket E . payload . size ()) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( amount DE , Ġpayload D . amount To Forward ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( expiry DE , Ġpayload D . outgoing C lt v ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( channel Update DE . short Channel Id , Ġpayload D . outgoing Channel Id ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġadd E Ġ= ĠUpdate Add H tl c ( random Bytes 3 2 (), Ġ 2 , Ġamount DE , Ġpayment Hash , Ġexpiry DE , Ġpacket E ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpayload E Ġ= ĠIncoming Packet . decrypt ( add E , Ġpriv E ). right !! ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( final Amount , Ġpayload E . amount ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( final Amount , Ġpayload E . total Amount ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( final Expiry , Ġpayload E . expiry ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( payment Secret , Ġpayload E . payment Secret ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠWallet s Ġdon 't Ġneed Ġto Ġdecrypt Ġon ions Ġfor Ġintermediate Ġnodes , Ġbut Ġit 's Ġuseful Ġto Ġtest Ġthat Ġencryption Ġworks Ġcorrectly . ĊĠĠĠĠĠĠĠ Ġfun Ġdecrypt Channel Relay ( add : ĠUpdate Add H tl c , ĠprivateKey : ĠPrivate Key ): ĠPair < Channel Relay Payload , ĠOn ion Routing Packet > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdecrypted Ġ= ĠS phinx . pe el ( privateKey , Ġadd . payment Hash , Ġadd . on ion Routing Packet , ĠOn ion Routing Packet . Payment Packet Length ). right !! ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertFalse ( de crypted . is Last Packet ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdecoded Ġ= ĠChannel Relay Payload . read ( ByteArray Input ( de crypted . payload . toByteArray ())) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠPair ( decoded , Ġdecrypted . next Packet ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠWallet s Ġdon 't Ġneed Ġto Ġdecrypt Ġon ions Ġfor Ġintermediate Ġnodes , Ġbut Ġit 's Ġuseful Ġto Ġtest Ġthat Ġencryption Ġworks Ġcorrectly . ĊĠĠĠĠĠĠĠ Ġfun Ġdecrypt Node Relay ( add : ĠUpdate Add H tl c , ĠprivateKey : ĠPrivate Key ): ĠTrip le < Final Payload , ĠNode Relay Payload , ĠOn ion Routing Packet > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdecrypted Ġ= ĠS phinx . pe el ( privateKey , Ġadd . payment Hash , Ġadd . on ion Routing Packet , ĠOn ion Routing Packet . Payment Packet Length ). right !! ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertTrue ( de crypted . is Last Packet ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġouter Payload Ġ= ĠFinal Payload . read ( ByteArray Input ( de crypted . payload . toByteArray ())) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtr amp oline On ion Ġ= Ġouter Payload . records . get < On ion T lv . Tr amp oline On ion >() ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertNotNull ( tr amp oline On ion ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdecrypted Inner Ġ= ĠS phinx . pe el ( privateKey , Ġadd . payment Hash , Ġtr amp oline On ion . packet , ĠOn ion Routing Packet . Tr amp oline Packet Length ). right !! ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġinner Payload Ġ= ĠNode Relay Payload . read ( ByteArray Input ( de crypted Inner . payload . toByteArray ())) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠTrip le ( outer Payload , Ġinner Payload , Ġdecrypted Inner . next Packet ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` build Ġon ion `() Ġ{ ĊĠĠĠĠĠĠĠ Ġtest Build On ion () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` build Ġa Ġcommand Ġincluding Ġthe Ġon ion `() Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġ( add , Ġ_) Ġ= ĠOut going Packet . build Command ( UUID . randomUUID (), Ġpayment Hash , Ġh ops , ĠFinal Payload . create Single Part Payload ( final Amount , Ġfinal Expiry , Ġpayment Secret )) ĊĠĠĠĠĠĠĠ ĠassertTrue ( add . amount Ġ> Ġfinal Amount ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( add . cl tv Expiry , Ġfinal Expiry Ġ+ Ġchannel Update DE . cl tv Expiry Delta Ġ+ Ġchannel Update CD . cl tv Expiry Delta Ġ+ Ġchannel Update BC . cl tv Expiry Delta ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( add . payment Hash , Ġpayment Hash ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( add . on ion . payload . size (), ĠOn ion Routing Packet . Payment Packet Length ) ĊĊĠĠĠĠĠĠĠ Ġ// Ġlet 's Ġpe el Ġthe Ġon ion ĊĠĠĠĠĠĠĠ Ġtest Pe el On ion ( add . on ion ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` build Ġa Ġcommand Ġwith Ġno Ġh ops `() Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġpayment Secret Ġ= Ġrandom Bytes 3 2 () ĊĠĠĠĠĠĠĠ Ġval Ġ( add , Ġ_) Ġ= ĠOut going Packet . build Command ( UUID . randomUUID (), Ġpayment Hash , Ġh ops . take ( 1 ), ĠFinal Payload . create Single Part Payload ( final Amount , Ġfinal Expiry , Ġpayment Secret )) ĊĠĠĠĠĠĠĠ ĠassertEquals ( add . amount , Ġfinal Amount ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( add . cl tv Expiry , Ġfinal Expiry ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( add . payment Hash , Ġpayment Hash ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( add . on ion . payload . size (), ĠOn ion Routing Packet . Payment Packet Length ) ĊĊĠĠĠĠĠĠĠ Ġ// Ġlet 's Ġpe el Ġthe Ġon ion ĊĠĠĠĠĠĠĠ Ġval Ġadd B Ġ= ĠUpdate Add H tl c ( random Bytes 3 2 (), Ġ 0 , Ġfinal Amount , Ġpayment Hash , Ġfinal Expiry , Ġadd . on ion ) ĊĠĠĠĠĠĠĠ Ġval Ġfinal Payload Ġ= ĠIncoming Packet . decrypt ( add B , Ġpriv B ). right !! ĊĠĠĠĠĠĠĠ ĠassertEquals ( final Payload . amount , Ġfinal Amount ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( final Payload . total Amount , Ġfinal Amount ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( final Payload . expiry , Ġfinal Expiry ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( payment Secret , Ġfinal Payload . payment Secret ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` build Ġa Ġtr amp oline Ġpayment `() Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġsimple Ġtr amp oline Ġroute Ġto Ġe : ĊĠĠĠĠĠĠĠ Ġ// ĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. -- . ĠĠ Ġ. -- . ĊĠĠĠĠĠĠĠ Ġ// ĠĠĠĠĠĠĠĠĠĠĠ Ġ/ ĠĠĠ Ġ\ Ġ/ ĠĠĠ Ġ\ ĊĠĠĠĠĠĠĠ Ġ// Ġa Ġ-> Ġb Ġ-> Ġc ĠĠĠĠĠ Ġd ĠĠĠĠĠ Ġe ĊĊĠĠĠĠĠĠĠ Ġval Ġ( amount AC , Ġexpiry AC , Ġtr amp oline On ion ) Ġ= ĠOut going Packet . build Packet ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpayment Hash , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtr amp oline H ops , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠFinal Payload . create Multi Part Payload ( final Amount , Ġfinal Amount Ġ* Ġ 3 , Ġfinal Expiry , Ġpayment Secret ), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOn ion Routing Packet . Tr amp oline Packet Length ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( amount BC , Ġamount AC ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( expiry BC , Ġexpiry AC ) ĊĊĠĠĠĠĠĠĠ Ġval Ġ( first Amount , Ġfirst Expiry , Ġon ion ) Ġ= ĠOut going Packet . build Packet ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpayment Hash , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtr amp oline Channel H ops , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠFinal Payload . create Tr amp oline Payload ( amount AC , Ġamount AC , Ġexpiry AC , Ġrandom Bytes 3 2 (), Ġtr amp oline On ion . packet ), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOn ion Routing Packet . Payment Packet Length ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( amount AB , Ġfirst Amount ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( expiry AB , Ġfirst Expiry ) ĊĊĠĠĠĠĠĠĠ Ġval Ġadd B Ġ= ĠUpdate Add H tl c ( random Bytes 3 2 (), Ġ 1 , Ġfirst Amount , Ġpayment Hash , Ġfirst Expiry , Ġon ion . packet ) ĊĠĠĠĠĠĠĠ Ġval Ġ( payload B , Ġpacket C ) Ġ= Ġdecrypt Channel Relay ( add B , Ġpriv B ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( Channel Relay Payload . create ( channel Update BC . short Channel Id , Ġamount BC , Ġexpiry BC ), Ġpayload B ) ĊĊĠĠĠĠĠĠĠ Ġval Ġadd C Ġ= ĠUpdate Add H tl c ( random Bytes 3 2 (), Ġ 2 , Ġamount BC , Ġpayment Hash , Ġexpiry BC , Ġpacket C ) ĊĠĠĠĠĠĠĠ Ġval Ġ( outer C , Ġinner C , Ġpacket D ) Ġ= Ġdecrypt Node Relay ( add C , Ġpriv C ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( amount BC , Ġouter C . amount ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( amount BC , Ġouter C . total Amount ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( expiry BC , Ġouter C . expiry ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( amount CD , Ġinner C . amount To Forward ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( expiry CD , Ġinner C . outgoing C lt v ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( d , Ġinner C . outgoing NodeId ) ĊĠĠĠĠĠĠĠ ĠassertNull ( inner C . invoice Routing Info ) ĊĠĠĠĠĠĠĠ ĠassertNull ( inner C . invoice Features ) ĊĠĠĠĠĠĠĠ ĠassertNull ( inner C . payment Secret ) ĊĊĠĠĠĠĠĠĠ Ġ// Ġc Ġforwards Ġthe Ġtr amp oline Ġpayment Ġto Ġd . ĊĠĠĠĠĠĠĠ Ġval Ġ( amount D , Ġexpiry D , Ġon ion D ) Ġ= ĠOut going Packet . build Packet ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpayment Hash , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠlistOf ( Channel Hop ( c , Ġd , Ġchannel Update CD )), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠFinal Payload . create Tr amp oline Payload ( amount CD , Ġamount CD , Ġexpiry CD , Ġrandom Bytes 3 2 (), Ġpacket D ), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOn ion Routing Packet . Payment Packet Length ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( amount CD , Ġamount D ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( expiry CD , Ġexpiry D ) ĊĠĠĠĠĠĠĠ Ġval Ġadd D Ġ= ĠUpdate Add H tl c ( random Bytes 3 2 (), Ġ 3 , Ġamount D , Ġpayment Hash , Ġexpiry D , Ġon ion D . packet ) ĊĠĠĠĠĠĠĠ Ġval Ġ( outer D , Ġinner D , Ġpacket E ) Ġ= Ġdecrypt Node Relay ( add D , Ġpriv D ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( amount CD , Ġouter D . amount ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( amount CD , Ġouter D . total Amount ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( expiry CD , Ġouter D . expiry ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( amount DE , Ġinner D . amount To Forward ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( expiry DE , Ġinner D . outgoing C lt v ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( e , Ġinner D . outgoing NodeId ) ĊĠĠĠĠĠĠĠ ĠassertNull ( inner D . invoice Routing Info ) ĊĠĠĠĠĠĠĠ ĠassertNull ( inner D . invoice Features ) ĊĠĠĠĠĠĠĠ ĠassertNull ( inner D . payment Secret ) ĊĊĠĠĠĠĠĠĠ Ġ// Ġd Ġforwards Ġthe Ġtr amp oline Ġpayment Ġto Ġe . ĊĠĠĠĠĠĠĠ Ġval Ġ( amount E , Ġexpiry E , Ġon ion E ) Ġ= ĠOut going Packet . build Packet ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpayment Hash , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠlistOf ( Channel Hop ( d , Ġe , Ġchannel Update DE )), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠFinal Payload . create Tr amp oline Payload ( amount DE , Ġamount DE , Ġexpiry DE , Ġrandom Bytes 3 2 (), Ġpacket E ), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOn ion Routing Packet . Payment Packet Length ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( amount DE , Ġamount E ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( expiry DE , Ġexpiry E ) ĊĠĠĠĠĠĠĠ Ġval Ġadd E Ġ= ĠUpdate Add H tl c ( random Bytes 3 2 (), Ġ 4 , Ġamount E , Ġpayment Hash , Ġexpiry E , Ġon ion E . packet ) ĊĠĠĠĠĠĠĠ Ġval Ġpayload E Ġ= ĠIncoming Packet . decrypt ( add E , Ġpriv E ). right !! ĊĠĠĠĠĠĠĠ ĠassertEquals ( payload E , ĠFinal Payload ( T lv Stream ( listOf ( On ion T lv . Amount To Forward ( final Amount ), ĠOn ion T lv . Outgoing C lt v ( final Expiry ), ĠOn ion T lv . Payment Data ( payment Secret , Ġfinal Amount Ġ* Ġ 3 ))))) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` build Ġa Ġtr amp oline Ġpayment Ġwith Ġnon - tr amp oline Ġrecipient `() Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġsimple Ġtr amp oline Ġroute Ġto Ġe Ġwhere Ġe Ġdoesn 't Ġsupport Ġtr amp oline : ĊĠĠĠĠĠĠĠ Ġ// ĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. -- . ĊĠĠĠĠĠĠĠ Ġ// ĠĠĠĠĠĠĠĠĠĠĠ Ġ/ ĠĠĠ Ġ\ ĊĠĠĠĠĠĠĠ Ġ// Ġa Ġ-> Ġb Ġ-> Ġc ĠĠĠĠĠ Ġd Ġ-> Ġe ĊĊĠĠĠĠĠĠĠ Ġval Ġrouting Hints Ġ= ĠlistOf ( Payment Request . Tagged Field . Extra Hop ( random Key (). publicKey (), ĠShort Channel Id ( 4 2 ), Ġ 1 0 . ms at , Ġ 1 0 0 , ĠC lt v Expiry Delta ( 1 4 4 ))) ĊĠĠĠĠĠĠĠ Ġval Ġinvoice Features Ġ= ĠFeatures ( Feature . Variable Length On ion Ġto ĠFeature Support . Mandatory , ĠFeature . Payment Secret Ġto ĠFeature Support . Mandatory , ĠFeature . Basic Multi Part Payment Ġto ĠFeature Support . Optional ) ĊĠĠĠĠĠĠĠ Ġval Ġinvoice Ġ= ĠPayment Request ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" l nb crt ", Ġfinal Amount , Ġcurrent Timestamp Seconds (), Ġe , ĠlistOf ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠPayment Request . Tagged Field . Payment Hash ( payment Hash ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠPayment Request . Tagged Field . Payment Secret ( payment Secret ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠPayment Request . Tagged Field . Description Hash ( random Bytes 3 2 ()), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠPayment Request . Tagged Field . Features ( invoice Features . toByteArray (). to Byte Vector ()), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠPayment Request . Tagged Field . Routing Info ( routing Hints ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ), ĠByte Vector . empty ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġval Ġ( amount AC , Ġexpiry AC , Ġtr amp oline On ion ) Ġ= ĠOut going Packet . build Tr amp oline To Legacy Packet ( invoice , Ġtr amp oline H ops , ĠFinal Payload . create Single Part Payload ( final Amount , Ġfinal Expiry , Ġrandom Bytes 3 2 ())) ĊĠĠĠĠĠĠĠ ĠassertEquals ( amount BC , Ġamount AC ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( expiry BC , Ġexpiry AC ) ĊĊĠĠĠĠĠĠĠ Ġval Ġ( first Amount , Ġfirst Expiry , Ġon ion ) Ġ= ĠOut going Packet . build Packet ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpayment Hash , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtr amp oline Channel H ops , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠFinal Payload . create Tr amp oline Payload ( amount AC , Ġamount AC , Ġexpiry AC , Ġrandom Bytes 3 2 (), Ġtr amp oline On ion . packet ), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOn ion Routing Packet . Payment Packet Length ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( amount AB , Ġfirst Amount ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( expiry AB , Ġfirst Expiry ) ĊĊĠĠĠĠĠĠĠ Ġval Ġadd B Ġ= ĠUpdate Add H tl c ( random Bytes 3 2 (), Ġ 1 , Ġfirst Amount , Ġpayment Hash , Ġfirst Expiry , Ġon ion . packet ) ĊĠĠĠĠĠĠĠ Ġval Ġ(_, Ġpacket C ) Ġ= Ġdecrypt Channel Relay ( add B , Ġpriv B ) ĊĊĠĠĠĠĠĠĠ Ġval Ġadd C Ġ= ĠUpdate Add H tl c ( random Bytes 3 2 (), Ġ 2 , Ġamount BC , Ġpayment Hash , Ġexpiry BC , Ġpacket C ) ĊĠĠĠĠĠĠĠ Ġval Ġ( outer C , Ġinner C , Ġpacket D ) Ġ= Ġdecrypt Node Relay ( add C , Ġpriv C ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( amount BC , Ġouter C . amount ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( amount BC , Ġouter C . total Amount ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( expiry BC , Ġouter C . expiry ) ĊĠĠĠĠĠĠĠ Ġassert Not Equals ( invoice . payment Secret , Ġouter C . payment Secret ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( amount CD , Ġinner C . amount To Forward ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( expiry CD , Ġinner C . outgoing C lt v ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( d , Ġinner C . outgoing NodeId ) ĊĠĠĠĠĠĠĠ ĠassertNull ( inner C . invoice Routing Info ) ĊĠĠĠĠĠĠĠ ĠassertNull ( inner C . invoice Features ) ĊĠĠĠĠĠĠĠ ĠassertNull ( inner C . payment Secret ) ĊĊĠĠĠĠĠĠĠ Ġ// Ġc Ġforwards Ġthe Ġtr amp oline Ġpayment Ġto Ġd . ĊĠĠĠĠĠĠĠ Ġval Ġ( amount D , Ġexpiry D , Ġon ion D ) Ġ= ĠOut going Packet . build Packet ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpayment Hash , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠlistOf ( Channel Hop ( c , Ġd , Ġchannel Update CD )), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠFinal Payload . create Tr amp oline Payload ( amount CD , Ġamount CD , Ġexpiry CD , Ġrandom Bytes 3 2 (), Ġpacket D ), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOn ion Routing Packet . Payment Packet Length ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( amount CD , Ġamount D ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( expiry CD , Ġexpiry D ) ĊĠĠĠĠĠĠĠ Ġval Ġadd D Ġ= ĠUpdate Add H tl c ( random Bytes 3 2 (), Ġ 3 , Ġamount D , Ġpayment Hash , Ġexpiry D , Ġon ion D . packet ) ĊĠĠĠĠĠĠĠ Ġval Ġ( outer D , Ġinner D , Ġ_) Ġ= Ġdecrypt Node Relay ( add D , Ġpriv D ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( amount CD , Ġouter D . amount ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( amount CD , Ġouter D . total Amount ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( expiry CD , Ġouter D . expiry ) ĊĠĠĠĠĠĠĠ Ġassert Not Equals ( invoice . payment Secret , Ġouter D . payment Secret ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( final Amount , Ġinner D . amount To Forward ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( expiry DE , Ġinner D . outgoing C lt v ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( e , Ġinner D . outgoing NodeId ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( final Amount , Ġinner D . total Amount ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( invoice . payment Secret , Ġinner D . payment Secret ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( Byte Vector (" 0 2 4 1 0 0 "), Ġinner D . invoice Features ) Ġ// Ġvar _ on ion _ opt in , Ġpayment _ secret , Ġbasic _ mpp ĊĠĠĠĠĠĠĠ ĠassertEquals ( listOf ( routing Hints ), Ġinner D . invoice Routing Info ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` fail Ġto Ġbuild Ġa Ġtr amp oline Ġpayment Ġwhen Ġtoo Ġmuch Ġinvoice Ġdata Ġis Ġprovided `() Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġextra Hop Ġ= ĠPayment Request . Tagged Field . Extra Hop ( random Key (). publicKey (), ĠShort Channel Id ( 1 ), Ġ 1 0 . ms at , Ġ 1 0 0 , ĠC lt v Expiry Delta ( 1 2 )) ĊĠĠĠĠĠĠĠ Ġval Ġrouting Hint Overflow Ġ= ĠlistOf ( extra Hop , Ġextra Hop , Ġextra Hop , Ġextra Hop , Ġextra Hop , Ġextra Hop , Ġextra Hop ) ĊĠĠĠĠĠĠĠ Ġval Ġinvoice Ġ= ĠPayment Request ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" l nb crt ", Ġfinal Amount , Ġcurrent Timestamp Seconds (), Ġe , ĠlistOf ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠPayment Request . Tagged Field . Payment Hash ( payment Hash ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠPayment Request . Tagged Field . Payment Secret ( payment Secret ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠPayment Request . Tagged Field . Features ( Byte Vector (" 0 2 4 1 0 0 ")), Ġ// Ġvar _ on ion _ opt in , Ġpayment _ secret , Ġbasic _ mpp ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠPayment Request . Tagged Field . Description Hash ( random Bytes 3 2 ()), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠPayment Request . Tagged Field . Routing Info ( routing Hint Overflow ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ), ĠByte Vector . empty ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġassert Fails Ġ{ ĠOut going Packet . build Tr amp oline To Legacy Packet ( invoice , Ġtr amp oline H ops , ĠFinal Payload . create Single Part Payload ( final Amount , Ġfinal Expiry , Ġrandom Bytes 3 2 ())) Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` fail Ġto Ġdecrypt Ġwhen Ġthe Ġon ion Ġis Ġinvalid `() Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġ( first Amount , Ġfirst Expiry , Ġon ion ) Ġ= ĠOut going Packet . build Packet ( payment Hash , Ġh ops , ĠFinal Payload . create Single Part Payload ( final Amount , Ġfinal Expiry , Ġrandom Bytes 3 2 ()), ĠOn ion Routing Packet . Payment Packet Length ) ĊĠĠĠĠĠĠĠ Ġval Ġadd Ġ= ĠUpdate Add H tl c ( random Bytes 3 2 (), Ġ 1 , Ġfirst Amount , Ġpayment Hash , Ġfirst Expiry , Ġon ion . packet . copy ( payload Ġ= Ġon ion . packet . payload . reversed ())) ĊĠĠĠĠĠĠĠ Ġval Ġfailure Ġ= ĠIncoming Packet . decrypt ( add , Ġpriv B ) ĊĠĠĠĠĠĠĠ ĠassertTrue ( failure . is Left ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( Invalid On ion H mac . code , Ġfailure . left !!. code ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` fail Ġto Ġdecrypt Ġwhen Ġthe Ġtr amp oline Ġon ion Ġis Ġinvalid `() Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġ( amount AC , Ġexpiry AC , Ġtr amp oline On ion ) Ġ= ĠOut going Packet . build Packet ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpayment Hash , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtr amp oline H ops , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠFinal Payload . create Multi Part Payload ( final Amount , Ġfinal Amount Ġ* Ġ 2 , Ġfinal Expiry , Ġpayment Secret ), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOn ion Routing Packet . Tr amp oline Packet Length ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġval Ġ( first Amount , Ġfirst Expiry , Ġon ion ) Ġ= ĠOut going Packet . build Packet ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpayment Hash , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtr amp oline Channel H ops , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠFinal Payload . create Tr amp oline Payload ( amount AC , Ġamount AC , Ġexpiry AC , Ġrandom Bytes 3 2 (), Ġtr amp oline On ion . packet . copy ( payload Ġ= Ġtr amp oline On ion . packet . payload . reversed ())), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOn ion Routing Packet . Payment Packet Length ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġval Ġadd B Ġ= ĠUpdate Add H tl c ( random Bytes 3 2 (), Ġ 1 , Ġfirst Amount , Ġpayment Hash , Ġfirst Expiry , Ġon ion . packet ) ĊĠĠĠĠĠĠĠ Ġval Ġ(_, Ġpacket C ) Ġ= Ġdecrypt Channel Relay ( add B , Ġpriv B ) ĊĠĠĠĠĠĠĠ Ġval Ġadd C Ġ= ĠUpdate Add H tl c ( random Bytes 3 2 (), Ġ 2 , Ġamount BC , Ġpayment Hash , Ġexpiry BC , Ġpacket C ) ĊĠĠĠĠĠĠĠ Ġval Ġfailure Ġ= ĠIncoming Packet . decrypt ( add C , Ġpriv C ) ĊĠĠĠĠĠĠĠ ĠassertTrue ( failure . is Left ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( Invalid On ion H mac . code , Ġfailure . left !!. code ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` fail Ġto Ġdecrypt Ġwhen Ġpayment Ġhash Ġdoesn 't Ġmatch Ġassociated Ġdata `() Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġ( first Amount , Ġfirst Expiry , Ġon ion ) Ġ= ĠOut going Packet . build Packet ( payment Hash . reversed (), Ġh ops , ĠFinal Payload . create Single Part Payload ( final Amount , Ġfinal Expiry , Ġrandom Bytes 3 2 ()), ĠOn ion Routing Packet . Payment Packet Length ) ĊĠĠĠĠĠĠĠ Ġval Ġadd Ġ= ĠUpdate Add H tl c ( random Bytes 3 2 (), Ġ 1 , Ġfirst Amount , Ġpayment Hash , Ġfirst Expiry , Ġon ion . packet ) ĊĠĠĠĠĠĠĠ Ġval Ġfailure Ġ= ĠIncoming Packet . decrypt ( add , Ġpriv B ) ĊĠĠĠĠĠĠĠ ĠassertTrue ( failure . is Left ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( Invalid On ion H mac . code , Ġfailure . left !!. code ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` fail Ġto Ġdecrypt Ġat Ġthe Ġfinal Ġnode Ġwhen Ġamount Ġhas Ġbeen Ġmodified Ġby Ġnext - to - last Ġnode `() Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġ( first Amount , Ġfirst Expiry , Ġon ion ) Ġ= ĠOut going Packet . build Packet ( payment Hash , Ġh ops . take ( 1 ), ĠFinal Payload . create Single Part Payload ( final Amount , Ġfinal Expiry , Ġrandom Bytes 3 2 ()), ĠOn ion Routing Packet . Payment Packet Length ) ĊĠĠĠĠĠĠĠ Ġval Ġadd Ġ= ĠUpdate Add H tl c ( random Bytes 3 2 (), Ġ 1 , Ġfirst Amount Ġ- Ġ 1 0 0 . ms at , Ġpayment Hash , Ġfirst Expiry , Ġon ion . packet ) ĊĠĠĠĠĠĠĠ Ġval Ġfailure Ġ= ĠIncoming Packet . decrypt ( add , Ġpriv B ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( Either . Left ( Final Incorrect H tl c Amount ( first Amount Ġ- Ġ 1 0 0 . ms at )), Ġfailure ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` fail Ġto Ġdecrypt Ġat Ġthe Ġfinal Ġnode Ġwhen Ġexpiry Ġhas Ġbeen Ġmodified Ġby Ġnext - to - last Ġnode `() Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġ( first Amount , Ġfirst Expiry , Ġon ion ) Ġ= ĠOut going Packet . build Packet ( payment Hash , Ġh ops . take ( 1 ), ĠFinal Payload . create Single Part Payload ( final Amount , Ġfinal Expiry , Ġrandom Bytes 3 2 ()), ĠOn ion Routing Packet . Payment Packet Length ) ĊĠĠĠĠĠĠĠ Ġval Ġadd Ġ= ĠUpdate Add H tl c ( random Bytes 3 2 (), Ġ 1 , Ġfirst Amount , Ġpayment Hash , Ġfirst Expiry Ġ- ĠC lt v Expiry Delta ( 1 2 ), Ġon ion . packet ) ĊĠĠĠĠĠĠĠ Ġval Ġfailure Ġ= ĠIncoming Packet . decrypt ( add , Ġpriv B ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( Either . Left ( Final Incorrect C lt v Expiry ( first Expiry Ġ- ĠC lt v Expiry Delta ( 1 2 ))), Ġfailure ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` fail Ġto Ġdecrypt Ġat Ġthe Ġfinal Ġtr amp oline Ġnode Ġwhen Ġamount Ġhas Ġbeen Ġmodified Ġby Ġnext - to - last Ġtr amp oline `() Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġ( amount AC , Ġexpiry AC , Ġtr amp oline On ion ) Ġ= ĠOut going Packet . build Packet ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpayment Hash , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtr amp oline H ops , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠFinal Payload . create Multi Part Payload ( final Amount , Ġfinal Amount , Ġfinal Expiry , Ġpayment Secret ), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOn ion Routing Packet . Tr amp oline Packet Length ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġval Ġ( first Amount , Ġfirst Expiry , Ġon ion ) Ġ= ĠOut going Packet . build Packet ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpayment Hash , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtr amp oline Channel H ops , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠFinal Payload . create Tr amp oline Payload ( amount AC , Ġamount AC , Ġexpiry AC , Ġrandom Bytes 3 2 (), Ġtr amp oline On ion . packet ), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOn ion Routing Packet . Payment Packet Length ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġval Ġ(_, Ġpacket C ) Ġ= Ġdecrypt Channel Relay ( Update Add H tl c ( random Bytes 3 2 (), Ġ 1 , Ġfirst Amount , Ġpayment Hash , Ġfirst Expiry , Ġon ion . packet ), Ġpriv B ) ĊĠĠĠĠĠĠĠ Ġval Ġ(_, Ġ_, Ġpacket D ) Ġ= Ġdecrypt Node Relay ( Update Add H tl c ( random Bytes 3 2 (), Ġ 2 , Ġamount BC , Ġpayment Hash , Ġexpiry BC , Ġpacket C ), Ġpriv C ) ĊĠĠĠĠĠĠĠ Ġ// Ġc Ġforwards Ġthe Ġtr amp oline Ġpayment Ġto Ġd . ĊĠĠĠĠĠĠĠ Ġval Ġ( amount D , Ġexpiry D , Ġon ion D ) Ġ= ĠOut going Packet . build Packet ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpayment Hash , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠlistOf ( Channel Hop ( c , Ġd , Ġchannel Update CD )), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠFinal Payload . create Tr amp oline Payload ( amount CD , Ġamount CD , Ġexpiry CD , Ġrandom Bytes 3 2 (), Ġpacket D ), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOn ion Routing Packet . Payment Packet Length ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġval Ġ(_, Ġ_, Ġpacket E ) Ġ= Ġdecrypt Node Relay ( Update Add H tl c ( random Bytes 3 2 (), Ġ 3 , Ġamount D , Ġpayment Hash , Ġexpiry D , Ġon ion D . packet ), Ġpriv D ) ĊĠĠĠĠĠĠĠ Ġ// Ġd Ġforwards Ġan Ġinvalid Ġamount Ġto Ġe Ġ( the Ġouter Ġtotal Ġamount Ġdoesn 't Ġmatch Ġthe Ġinner Ġamount ). ĊĠĠĠĠĠĠĠ Ġval Ġinvalid Total Amount Ġ= Ġamount DE Ġ+ Ġ 1 0 0 . ms at ĊĠĠĠĠĠĠĠ Ġval Ġ( amount E , Ġexpiry E , Ġon ion E ) Ġ= ĠOut going Packet . build Packet ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpayment Hash , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠlistOf ( Channel Hop ( d , Ġe , Ġchannel Update DE )), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠFinal Payload . create Tr amp oline Payload ( amount DE , Ġinvalid Total Amount , Ġexpiry DE , Ġrandom Bytes 3 2 (), Ġpacket E ), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOn ion Routing Packet . Payment Packet Length ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġval Ġfailure Ġ= ĠIncoming Packet . decrypt ( Update Add H tl c ( random Bytes 3 2 (), Ġ 4 , Ġamount E , Ġpayment Hash , Ġexpiry E , Ġon ion E . packet ), Ġpriv E ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( Either . Left ( Final Incorrect H tl c Amount ( invalid Total Amount )), Ġfailure ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` fail Ġto Ġdecrypt Ġat Ġthe Ġfinal Ġtr amp oline Ġnode Ġwhen Ġexpiry Ġhas Ġbeen Ġmodified Ġby Ġnext - to - last Ġtr amp oline `() Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġ( amount AC , Ġexpiry AC , Ġtr amp oline On ion ) Ġ= ĠOut going Packet . build Packet ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpayment Hash , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtr amp oline H ops , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠFinal Payload . create Multi Part Payload ( final Amount , Ġfinal Amount , Ġfinal Expiry , Ġpayment Secret ), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOn ion Routing Packet . Tr amp oline Packet Length ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġval Ġ( first Amount , Ġfirst Expiry , Ġon ion ) Ġ= ĠOut going Packet . build Packet ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpayment Hash , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtr amp oline Channel H ops , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠFinal Payload . create Tr amp oline Payload ( amount AC , Ġamount AC , Ġexpiry AC , Ġrandom Bytes 3 2 (), Ġtr amp oline On ion . packet ), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOn ion Routing Packet . Payment Packet Length ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġval Ġ(_, Ġpacket C ) Ġ= Ġdecrypt Channel Relay ( Update Add H tl c ( random Bytes 3 2 (), Ġ 1 , Ġfirst Amount , Ġpayment Hash , Ġfirst Expiry , Ġon ion . packet ), Ġpriv B ) ĊĠĠĠĠĠĠĠ Ġval Ġ(_, Ġ_, Ġpacket D ) Ġ= Ġdecrypt Node Relay ( Update Add H tl c ( random Bytes 3 2 (), Ġ 2 , Ġamount BC , Ġpayment Hash , Ġexpiry BC , Ġpacket C ), Ġpriv C ) ĊĠĠĠĠĠĠĠ Ġ// Ġc Ġforwards Ġthe Ġtr amp oline Ġpayment Ġto Ġd . ĊĠĠĠĠĠĠĠ Ġval Ġ( amount D , Ġexpiry D , Ġon ion D ) Ġ= ĠOut going Packet . build Packet ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpayment Hash , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠlistOf ( Channel Hop ( c , Ġd , Ġchannel Update CD )), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠFinal Payload . create Tr amp oline Payload ( amount CD , Ġamount CD , Ġexpiry CD , Ġrandom Bytes 3 2 (), Ġpacket D ), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOn ion Routing Packet . Payment Packet Length ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġval Ġ(_, Ġ_, Ġpacket E ) Ġ= Ġdecrypt Node Relay ( Update Add H tl c ( random Bytes 3 2 (), Ġ 3 , Ġamount D , Ġpayment Hash , Ġexpiry D , Ġon ion D . packet ), Ġpriv D ) ĊĠĠĠĠĠĠĠ Ġ// Ġd Ġforwards Ġan Ġinvalid Ġexpiry Ġto Ġe Ġ( the Ġouter Ġexpiry Ġdoesn 't Ġmatch Ġthe Ġinner Ġexpiry ). ĊĠĠĠĠĠĠĠ Ġval Ġinvalid Expiry Ġ= Ġexpiry DE Ġ- ĠC lt v Expiry Delta ( 1 2 ) ĊĠĠĠĠĠĠĠ Ġval Ġ( amount E , Ġexpiry E , Ġon ion E ) Ġ= ĠOut going Packet . build Packet ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpayment Hash , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠlistOf ( Channel Hop ( d , Ġe , Ġchannel Update DE )), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠFinal Payload . create Tr amp oline Payload ( amount DE , Ġamount DE , Ġinvalid Expiry , Ġrandom Bytes 3 2 (), Ġpacket E ), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOn ion Routing Packet . Payment Packet Length ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġval Ġfailure Ġ= ĠIncoming Packet . decrypt ( Update Add H tl c ( random Bytes 3 2 (), Ġ 4 , Ġamount E , Ġpayment Hash , Ġexpiry E , Ġon ion E . packet ), Ġpriv E ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( Either . Left ( Final Incorrect C lt v Expiry ( invalid Expiry )), Ġfailure ) ĊĠĠĠ Ġ} Ċ } ĊĊ