package Ġnet . cord a . core . flows Ċ Ċ import Ġco . parallel universe . fib ers . Suspend able Ċ import Ġnet . cord a . core . crypto . Transaction Signature Ċ import Ġnet . cord a . core . crypto . is Ful filled By Ċ import Ġnet . cord a . core . crypto . toString Short Ċ import Ġnet . cord a . core . identity . Anonymous Party Ċ import Ġnet . cord a . core . identity . Party Ċ import Ġnet . cord a . core . identity . group Public Keys By Well Known Party Ċ import Ġnet . cord a . core . internal . to Multi Map Ċ import Ġnet . cord a . core . node . Service Hub Ċ import Ġnet . cord a . core . transactions . Signed Transaction Ċ import Ġnet . cord a . core . transactions . Wire Transaction Ċ import Ġnet . cord a . core . utilities . Progress Tracker Ċ import Ġnet . cord a . core . utilities . unwrap Ċ import Ġjava . security . PublicKey Ċ Ċ /** Ċ Ġ* ĠThe Ġ[ Collect Signatures Flow ] Ġis Ġused Ġto Ġautomate Ġthe Ġcollection Ġof Ġcounter party Ġsignatures Ġfor Ġa Ġgiven Ġtransaction . Ċ Ġ* Ċ Ġ* ĠYou Ġwould Ġtypically Ġuse Ġthis Ġflow Ġafter Ġyou Ġhave Ġbuilt Ġa Ġtransaction Ġwith Ġthe ĠTransaction Builder Ġand Ġsigned Ġit Ġwith Ċ Ġ* Ġyour Ġkey Ġpair . ĠIf Ġthere Ġare Ġadditional Ġsignatures Ġto Ġcollect Ġthen Ġthey Ġcan Ġbe Ġcollected Ġusing Ġthis Ġflow . ĠSignature s Ċ Ġ* Ġare Ġcollected Ġbased Ġupon Ġthe Ġ[ Wire Transaction . required Signing Keys ] Ġproperty Ġwhich Ġcontains Ġthe Ġunion Ġof Ġall Ġthe ĠPublic Keys Ċ Ġ* Ġlisted Ġin Ġthe Ġtransaction 's Ġcommands Ġas Ġwell Ġas Ġa Ġnot ary 's Ġpublic Ġkey , Ġif Ġrequired . ĠThis Ġflow Ġreturns Ġa Ċ Ġ* Ġ[ Signed Transaction ] Ġwhich Ġcan Ġthen Ġbe Ġpassed Ġto Ġthe Ġ[ Final ity Flow ] Ġfor Ġnot ar isation . ĠThe Ġother Ġside Ġof Ġthis Ġflow Ġis Ċ Ġ* Ġthe Ġ[ Sign Transaction Flow ]. Ċ Ġ* Ċ Ġ* Ġ** WARNING **: ĠThis Ġflow ĠONLY Ġworks Ġwith Ġ[ Service Hub . legal Identity Key ] s Ġand ĠWILL Ġbreak Ġif Ġused Ġwith Ġrandomly Ġgenerated Ċ Ġ* Ġkeys Ġby Ġthe Ġ[ Service Hub . key Management Service ]. Ċ Ġ* Ċ Ġ* ĠUsage : Ċ Ġ* Ċ Ġ* Ġ- ĠCall Ġthe Ġ[ Collect Signatures Flow ] Ġflow Ġas Ġa Ġ[ sub Flow ] Ġand Ġpass Ġit Ġa Ġ[ Signed Transaction ] Ġwhich Ġhas Ġat Ġleast Ġbeen Ċ Ġ* ĠĠ Ġsigned Ġby Ġthe Ġtransaction Ġcreator Ġ( and Ġpossibly Ġan Ġoracle , Ġif Ġrequired ) Ċ Ġ* Ġ- ĠThe Ġflow Ġexpects Ġthat Ġthe Ġcalling Ġnode Ġhas Ġsigned Ġthe Ġprovided Ġtransaction , Ġif Ġnot Ġthe Ġflow Ġwill Ġfail Ċ Ġ* Ġ- ĠThe Ġflow Ġwill Ġalso Ġfail Ġif : Ċ Ġ* ĠĠĠ 1 . ĠThe Ġprovided Ġtransaction Ġis Ġinvalid Ċ Ġ* ĠĠĠ 2 . ĠAny Ġof Ġthe Ġrequired Ġsigning Ġparties Ġcannot Ġbe Ġfound Ġin Ġthe Ġ[ Service Hub . network Map Cache ] Ġof Ġthe Ġinit iator Ċ Ġ* ĠĠĠ 3 . ĠIf Ġthe Ġwrong Ġkey Ġhas Ġbeen Ġused Ġby Ġa Ġcounter party Ġto Ġsign Ġthe Ġtransaction Ċ Ġ* ĠĠĠ 4 . ĠThe Ġcounter party Ġreject s Ġthe Ġprovided Ġtransaction Ċ Ġ* Ġ- ĠThe Ġflow Ġwill Ġreturn Ġa Ġ[ Signed Transaction ] Ġwith Ġall Ġthe Ġcounter party Ġsignatures Ġ( but Ġnot Ġthe Ġnot ary 's !) Ċ Ġ* Ġ- ĠIf Ġthe Ġprovided Ġtransaction Ġhas Ġalready Ġbeen Ġsigned Ġby Ġall Ġcounter part ies Ġthen Ġthis Ġflow Ġsimply Ġreturns Ġthe Ċ Ġ* ĠĠ Ġprovided Ġtransaction Ġwithout Ġcontact ing Ġany Ġcounter part ies Ċ Ġ* Ġ- ĠCall Ġthe Ġ[ Final ity Flow ] Ġwith Ġthe Ġreturn Ġvalue Ġof Ġthis Ġflow Ċ Ġ* Ċ Ġ* ĠExample Ġ- Ġiss uing Ġa Ġmulti - l ateral Ġagreement Ġwhich Ġrequires ĠN Ġsignatures : Ċ Ġ* Ċ Ġ* ĠĠĠĠ Ġval Ġbuilder Ġ= ĠTransaction Builder ( not ary Ref ) Ċ Ġ* ĠĠĠĠ Ġval Ġissue Command Ġ= ĠCommand ( Agreement . Commands . Issue (), Ġstate . participants ) Ċ Ġ* Ċ Ġ* ĠĠĠĠ Ġbuilder . with Items ( state , Ġissue Command ) Ċ Ġ* ĠĠĠĠ Ġbuilder . to Wire Transaction (). to Ledger Transaction ( service Hub ). verify () Ċ Ġ* Ċ Ġ* ĠĠĠĠ Ġ// ĠTransaction Ġcreator Ġsigns Ġtransaction . Ċ Ġ* ĠĠĠĠ Ġval Ġp tx Ġ= Ġservice Hub . sign Initial Transaction ( builder ) Ċ Ġ* Ċ Ġ* ĠĠĠĠ Ġ// ĠCall Ġto ĠCollect Signatures Flow . Ċ Ġ* ĠĠĠĠ Ġ// ĠThe Ġreturned Ġsigned Ġtransaction Ġwill Ġhave Ġall Ġsignatures Ġappended Ġapart Ġfrom Ġthe Ġnot ary 's . Ċ Ġ* ĠĠĠĠ Ġval Ġst x Ġ= Ġsub Flow ( Collect Signatures Flow ( pt x )) Ċ Ġ* Ċ Ġ* Ġ@ param Ġpartially Signed Tx ĠTransaction Ġto Ġcollect Ġthe Ġremaining Ġsignatures Ġfor Ċ Ġ* Ġ@ param Ġsessions To Collect From ĠA Ġsession Ġfor Ġevery Ġparty Ġwe Ġneed Ġto Ġcollect Ġa Ġsignature Ġfrom . Ġ ĠMust Ġbe Ġan Ġexact Ġmatch . Ċ Ġ* Ġ@ param Ġmy Optional Keys Ġset Ġof Ġkeys Ġin Ġthe Ġtransaction Ġwhich Ġare Ġowned Ġby Ġthis Ġnode . ĠThis Ġincludes Ġkeys Ġused Ġon Ġcommands , Ġnot Ċ Ġ* Ġjust Ġin Ġthe Ġstates . ĠIf Ġnull , Ġthe Ġdefault Ġwell Ġknown Ġidentity Ġof Ġthe Ġnode Ġis Ġused . Ċ Ġ*/ Ċ // ĠTODO : ĠAbstract State Replacement Flow Ġneeds Ġupdating Ġto Ġuse Ġthis Ġflow . Ċ class ĠCollect Signatures Flow Ġ@ Jvm Over loads Ġconstructor ( val Ġpartially Signed Tx : ĠSigned Transaction , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsessions To Collect From : ĠCollection < Flow Session >, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmy Optional Keys : ĠIterable < PublicKey > ?, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġval Ġprogress Tracker : ĠProgress Tracker Ġ= ĠCollect Signatures Flow . tracker ()) Ġ: ĠFlow Logic < Signed Transaction >() Ġ{ ĊĠĠĠ Ġ@ Jvm Over loads ĊĠĠĠ Ġconstructor ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpartially Signed Tx : ĠSigned Transaction , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsessions To Collect From : ĠCollection < Flow Session >, ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprogress Tracker : ĠProgress Tracker Ġ= ĠCollect Signatures Flow . tracker () ĊĠĠĠ Ġ) Ġ: Ġthis ( part ially Signed Tx , Ġsessions To Collect From , Ġnull , Ġprogress Tracker ) ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġobject ĠCOL LECT ING Ġ: ĠProgress Tracker . Step (" Collect ing Ġsignatures Ġfrom Ġcounter part ies .") ĊĠĠĠĠĠĠĠ Ġobject ĠVERIFY ING Ġ: ĠProgress Tracker . Step (" Verify ing Ġcollected Ġsignatures .") ĊĊĠĠĠĠĠĠĠ Ġ@ Jvm Static ĊĠĠĠĠĠĠĠ Ġfun Ġtracker () Ġ= ĠProgress Tracker ( COLLECT ING , ĠVERIFY ING ) ĊĊĠĠĠĠĠĠĠ Ġ// ĠTODO : ĠMake Ġthe Ġprogress Ġtracker Ġadapt Ġto Ġthe Ġnumber Ġof Ġcounter part ies Ġto Ġcollect Ġfrom . ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Suspend able ĊĠĠĠ Ġoverride Ġfun Ġcall (): ĠSigned Transaction Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠCheck Ġthe Ġsignatures Ġwhich Ġhave Ġalready Ġbeen Ġprovided Ġand Ġthat Ġthe Ġtransaction Ġis Ġvalid . ĊĠĠĠĠĠĠĠ Ġ// ĠUsually Ġjust Ġthe ĠInit iator Ġand Ġpossibly Ġan Ġoracle Ġwould Ġhave Ġsigned Ġat Ġthis Ġpoint . ĊĠĠĠĠĠĠĠ Ġval Ġmy Keys : ĠIterable < PublicKey > Ġ= Ġmy Optional Keys Ġ?: ĠlistOf ( our Identity . own ing Key ) ĊĠĠĠĠĠĠĠ Ġval Ġsigned Ġ= Ġpartially Signed Tx . sigs . map Ġ{ Ġit . by Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġnot Signed Ġ= Ġpartially Signed Tx . tx . required Signing Keys Ġ- Ġsigned ĊĊĠĠĠĠĠĠĠ Ġ// ĠOne Ġof Ġthe Ġsignatures Ġcollected Ġso Ġfar ĠMUST Ġbe Ġfrom Ġthe Ġinit iator Ġof Ġthis Ġflow . ĊĠĠĠĠĠĠĠ Ġrequire ( part ially Signed Tx . sigs . any Ġ{ Ġit . by Ġin Ġmy Keys Ġ}) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" The ĠInit iator Ġof ĠCollect Signatures Flow Ġmust Ġhave Ġsigned Ġthe Ġtransaction ." ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠThe Ġsignatures Ġmust Ġbe Ġvalid Ġand Ġthe Ġtransaction Ġmust Ġbe Ġvalid . ĊĠĠĠĠĠĠĠ Ġpartially Signed Tx . verify Signatures Except ( not Signed ) ĊĠĠĠĠĠĠĠ Ġpartially Signed Tx . tx . to Ledger Transaction ( service Hub ). verify () ĊĊĠĠĠĠĠĠĠ Ġ// ĠDetermine Ġwho Ġstill Ġneeds Ġto Ġsign . ĊĠĠĠĠĠĠĠ Ġprogress Tracker . current Step Ġ= ĠCOL LECT ING ĊĠĠĠĠĠĠĠ Ġval Ġnot ary Key Ġ= Ġpartially Signed Tx . tx . not ary ?. own ing Key ĊĠĠĠĠĠĠĠ Ġ// ĠIf Ġpresent , Ġwe Ġneed Ġto Ġexclude Ġthe Ġnot ary 's ĠPublicKey Ġas Ġthe Ġnot ary Ġsignature Ġis Ġcollected Ġseparately Ġwith ĊĠĠĠĠĠĠĠ Ġ// Ġthe ĠFinal ity Flow . ĊĠĠĠĠĠĠĠ Ġval Ġunsigned Ġ= Ġif Ġ( not ary Key Ġ!= Ġnull ) Ġnot Signed Ġ- Ġnot ary Key Ġelse Ġnot Signed ĊĊĠĠĠĠĠĠĠ Ġ// ĠIf Ġthe Ġunsigned Ġcounter part ies Ġlist Ġis Ġempty Ġthen Ġwe Ġdon 't Ġneed Ġto Ġcollect Ġany Ġmore Ġsignatures Ġhere . ĊĠĠĠĠĠĠĠ Ġif Ġ( unsigned . isEmpty ()) Ġreturn Ġpartially Signed Tx ĊĊĠĠĠĠĠĠĠ Ġval Ġset Of All Session Keys : ĠMap < PublicKey , ĠFlow Session > Ġ= Ġsessions To Collect From ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. groupBy Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdestination Ġ= Ġit . destination ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( destination ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠParty Ġ-> Ġdestination . own ing Key ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠAn onymous Party Ġ-> Ġdestination . own ing Key ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġthrow ĠIllegalArgumentException (" Signatures Ġcan Ġonly Ġbe Ġcollected Ġfrom ĠParty Ġor ĠAn onymous Party , Ġnot Ġ$ destination ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Values Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequire ( it . value . size Ġ== Ġ 1 ) Ġ{ Ġ" There Ġare Ġmultiple Ġsessions Ġinitiated Ġfor Ġparty Ġkey Ġ${ it . key . toString Short () }" Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . value . first () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġparty To Keys It Sign s For : ĠMap < Party , ĠList < PublicKey >> Ġ= Ġgroup Public Keys By Well Known Party ( service Hub , Ġunsigned ) ĊĠĠĠĠĠĠĠ Ġval Ġkey To Signing Party : ĠMap < PublicKey , ĠParty > Ġ= Ġparty To Keys It Sign s For ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. flatMap Ġ{ Ġ( well Known , Ġall Keys It Sign s For ) Ġ-> Ġall Keys It Sign s For . map Ġ{ Ġit Ġto Ġwell Known Ġ} Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. toMap () ĊĊĠĠĠĠĠĠĠ Ġval Ġunrelated Sessions Ġ= Ġsessions To Collect From . filter Not Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( it . destination Ġis ĠParty ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThe Ġsession Ġmust Ġhave Ġa Ġcorresponding Ġunsigned . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . destination Ġin Ġparty To Keys It Sign s For ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġset Of All Session Keys Ġhas Ġalready Ġchecked Ġfor Ġvalid Ġdestination Ġtypes Ġso Ġwe Ġcan Ġsafely Ġcast Ġto ĠAn ono y mous Party Ġhere . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThis Ġsession Ġwas Ġnot Ġinitiated Ġby Ġa Ġwell Known Party Ġso Ġmust Ġdirectly Ġexist Ġin Ġthe Ġunsigned . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( it . destination Ġas ĠAn onymous Party ). own ing Key Ġin Ġunsigned ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġkey To Session List Ġ= Ġunsigned . map Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsession Ġ= Ġset Of All Session Keys [ it ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( session Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThe Ġunsigned Ġkey Ġexists Ġdirectly Ġas Ġa Ġsession Key , Ġso Ġuse Ġthat Ġsession ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit Ġto Ġsession ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠIt Ġmight Ġbe Ġdeleg ated Ġto Ġa Ġwell Known Party ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġwell Known Party Ġ= ĠcheckNotNull ( key To Signing Party [ it ]) Ġ{ Ġ" Could Ġnot Ġfind Ġa Ġsession Ġor Ġwell Known Ġparty Ġfor Ġkey Ġ${ it . toString Short () }" Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThere Ġis Ġa Ġwell Known Party Ġfor Ġthis Ġkey , Ġcheck Ġif Ġit Ġhas Ġa Ġsession , Ġand Ġif Ġso Ġ- Ġuse Ġthat Ġsession ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsession For Well Known Party Ġ= ĠcheckNotNull ( set Of All Session Keys [ well Known Party . own ing Key ]) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" No Ġsession Ġavailable Ġto Ġrequest Ġsignature Ġfor Ġkey : Ġ${ it . toString Short () }" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit Ġto Ġsession For Well Known Party ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠNow Ġinvert Ġthe Ġmap Ġto Ġfind Ġthe Ġkeys Ġper Ġsession ĊĠĠĠĠĠĠĠ Ġval Ġsession To Keys Map Ġ= Ġkey To Session List . map Ġ{ Ġit . second Ġto Ġit . first Ġ}. to Multi Map () ĊĊĠĠĠĠĠĠĠ Ġrequire ( un related Sessions . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" The ĠInit iator Ġof ĠCollect Signatures Flow Ġmust Ġpass Ġin Ġexactly Ġthe Ġsessions Ġrequired Ġto Ġsign Ġthe Ġtransaction ." ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ// ĠCollect Ġsignatures Ġfrom Ġall Ġcounter part ies Ġand Ġappend Ġthem Ġto Ġthe Ġpartially Ġsigned Ġtransaction . ĊĠĠĠĠĠĠĠ Ġval Ġcounter party Signatures Ġ= Ġsession To Keys Map . flatMap Ġ{ Ġ( session , Ġkeys ) Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsub Flow ( Collect Signature Flow ( part ially Signed Tx , Ġsession , Ġkeys )) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġst x Ġ= Ġpartially Signed Tx Ġ+ Ġcounter party Signatures ĊĊĠĠĠĠĠĠĠ Ġ// ĠVerify Ġall Ġbut Ġthe Ġnot ary 's Ġsignature Ġif Ġthe Ġtransaction Ġrequires Ġa Ġnot ary , Ġotherwise Ġverify Ġall Ġsignatures . ĊĠĠĠĠĠĠĠ Ġprogress Tracker . current Step Ġ= ĠVERIFY ING ĊĠĠĠĠĠĠĠ Ġif Ġ( not ary Key Ġ!= Ġnull ) Ġst x . verify Signatures Except ( not ary Key ) Ġelse Ġst x . verify Required Signatures () ĊĊĠĠĠĠĠĠĠ Ġreturn Ġst x ĊĠĠĠ Ġ} Ċ } Ċ Ċ // ĠDOC START Ġ 1 Ċ /** Ċ Ġ* ĠGet Ġand Ġcheck Ġthe Ġrequired Ġsignature . Ċ Ġ* Ċ Ġ* Ġ@ param Ġpartially Signed Tx Ġthe Ġtransaction Ġto Ġsign . Ċ Ġ* Ġ@ param Ġsession Ġthe Ġ[ Flow Session ] Ġto Ġconnect Ġto Ġto Ġget Ġthe Ġsignature . Ċ Ġ* Ġ@ param Ġsigning Keys Ġthe Ġlist Ġof Ġkeys Ġthe Ġparty Ġshould Ġuse Ġto Ġsign Ġthe Ġtransaction . Ċ Ġ*/ Ċ @ Suspend able Ċ class ĠCollect Signature Flow ( val Ġpartially Signed Tx : ĠSigned Transaction , Ġval Ġsession : ĠFlow Session , Ġval Ġsigning Keys : ĠList < PublicKey >) Ġ: ĠFlow Logic < List < Transaction Signature >>() Ġ{ ĊĠĠĠ Ġconstructor ( part ially Signed Tx : ĠSigned Transaction , Ġsession : ĠFlow Session , Ġvar arg Ġsigning Keys : ĠPublicKey ) Ġ: ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis ( part ially Signed Tx , Ġsession , ĠlistOf (* signing Keys )) ĊĊĠĠĠ Ġ@ Suspend able ĊĠĠĠ Ġoverride Ġfun Ġcall (): ĠList < Transaction Signature > Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠSend Transaction Flow Ġallows Ġcounter party Ġto Ġaccess Ġour Ġdata Ġto Ġresolve Ġthe Ġtransaction . ĊĠĠĠĠĠĠĠ Ġsub Flow ( Send Transaction Flow ( session , Ġpartially Signed Tx )) ĊĠĠĠĠĠĠĠ Ġ// ĠSend Ġthe Ġkey Ġwe Ġexpect Ġthe Ġcounter party Ġto Ġsign Ġwith Ġ- Ġthis Ġis Ġimportant Ġwhere Ġthey Ġmay Ġhave Ġseveral ĊĠĠĠĠĠĠĠ Ġ// Ġkeys Ġto Ġsign Ġwith , Ġas Ġit Ġmakes Ġit Ġfaster Ġfor Ġthem Ġto Ġidentify Ġthe Ġkey Ġto Ġsign Ġwith , Ġand Ġmore Ġstraight Ġforward ĊĠĠĠĠĠĠĠ Ġ// Ġfor Ġus Ġto Ġcheck Ġwe Ġhave Ġthe Ġexpected Ġsignature Ġreturned . ĊĠĠĠĠĠĠĠ Ġsession . send ( signing Keys ) ĊĠĠĠĠĠĠĠ Ġreturn Ġsession . receive < List < Transaction Signature >> (). unwrap Ġ{ Ġsignatures Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrequire ( signatures . size Ġ== Ġsigning Keys . size ) Ġ{ Ġ" Need Ġsignature Ġfor Ġeach Ġsigning Ġkey " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsignatures . forEach Indexed Ġ{ Ġindex , Ġsignature Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequire ( signing Keys [ index ]. is Ful filled By ( signature . by )) Ġ{ Ġ" Not Ġsigned Ġby Ġthe Ġrequired Ġsigning Ġkey ." Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsignatures ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ // ĠDOC END Ġ 1 Ċ Ċ /** Ċ Ġ* ĠThe Ġ[ Sign Transaction Flow ] Ġshould Ġbe Ġcalled Ġin Ġresponse Ġto Ġthe Ġ[ Collect Signatures Flow ]. ĠIt Ġautom ates Ġthe Ġsigning Ġof Ċ Ġ* Ġa Ġtransaction Ġproviding Ġthe Ġtransaction : Ċ Ġ* Ċ Ġ* Ġ 1 . ĠShould Ġactually Ġbe Ġsigned Ġby Ġthe Ġ[ Party ] Ġinvoking Ġthis Ġflow Ċ Ġ* Ġ 2 . ĠIs Ġvalid Ġas Ġper Ġthe Ġcontracts Ġreferenced Ġin Ġthe Ġtransaction Ċ Ġ* Ġ 3 . ĠHas Ġbeen , Ġat Ġleast , Ġsigned Ġby Ġthe Ġcounter party Ġwhich Ġcreated Ġit Ċ Ġ* Ġ 4 . ĠCon forms Ġto Ġcustom Ġchecking Ġprovided Ġin Ġthe Ġ[ check Transaction ] Ġmethod Ġof Ġthe Ġ[ Sign Transaction Flow ] Ċ Ġ* Ċ Ġ* ĠUsage : Ċ Ġ* Ċ Ġ* Ġ- ĠSub class Ġ[ Sign Transaction Flow ] Ġ- Ġthis Ġcan Ġbe Ġdone Ġinside Ġan Ġexisting Ġflow Ġ( as Ġshown Ġbelow ) Ċ Ġ* Ġ- ĠOverride Ġthe Ġ[ check Transaction ] Ġmethod Ġto Ġadd Ġsome Ġcustom Ġverification Ġlogic Ċ Ġ* Ġ- ĠCall Ġthe Ġflow Ġvia Ġ[ Flow Logic . sub Flow ] Ċ Ġ* Ġ- ĠThe Ġflow Ġreturns Ġthe Ġtransaction Ġsigned Ġwith Ġthe Ġadditional Ġsignature . Ċ Ġ* Ċ Ġ* ĠExample Ġ- Ġchecking Ġand Ġsigning Ġa Ġtransaction Ġinvol ving Ġa Ġ[ net . cord a . core . contracts . Dummy Contract ], Ġsee Ċ Ġ* ĠCollect Signatures Flow Tests . kt Ġfor Ġfurther Ġexamples : Ċ Ġ* Ċ Ġ* ĠĠĠĠ Ġclass ĠRes pon der ( val Ġother Party Session : ĠFlow Session ): ĠFlow Logic < Signed Transaction >() Ġ{ Ċ Ġ* ĠĠĠĠĠĠĠĠĠ Ġ@ Suspend able Ġoverride Ġfun Ġcall (): ĠSigned Transaction Ġ{ Ċ Ġ* ĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġ[ Sign Transaction Flow ] Ġsub - cl assed Ġas Ġa Ġsingleton Ġobject . Ċ Ġ* ĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġflow Ġ= Ġobject Ġ: ĠSign Transaction Flow ( other Party Session ) Ġ{ Ċ Ġ* ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ@ Suspend able Ġoverride Ġfun Ġcheck Transaction ( st x : ĠSigned Transaction ) Ġ= Ġrequire That Ġ{ Ċ Ġ* ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtx Ġ= Ġst x . tx Ċ Ġ* ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmagic Number State Ġ= Ġtx . outputs . single (). data Ġas ĠDummy Contract . Multi Owner State Ċ Ġ* ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Must Ġbe Ġ 1 3 3 7 Ġor Ġgreater " Ġusing Ġ( magic Number State . magic Number Ġ>= Ġ 1 3 3 7 ) Ċ Ġ* ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ Ġ* ĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ Ġ* Ċ Ġ* ĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠInvoke Ġthe Ġsub Flow , Ġin Ġresponse Ġto Ġthe Ġcounter party Ġcalling Ġ[ Collect Signatures Flow ]. Ċ Ġ* ĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġexpected Tx Id Ġ= Ġsub Flow ( flow ). id Ċ Ġ* Ċ Ġ* ĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġsub Flow ( Receive Final ity Flow ( other Party Session , Ġexpected Tx Id )) Ċ Ġ* ĠĠĠĠĠĠĠĠĠ Ġ} Ċ Ġ* ĠĠĠĠĠ Ġ} Ċ Ġ* Ċ Ġ* Ġ@ param Ġother Side Session ĠThe Ġsession Ġwhich Ġis Ġproviding Ġyou Ġa Ġtransaction Ġto Ġsign . Ċ Ġ*/ Ċ abstract Ġclass ĠSign Transaction Flow Ġ@ Jvm Over loads Ġconstructor ( val Ġother Side Session : ĠFlow Session , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġval Ġprogress Tracker : ĠProgress Tracker Ġ= ĠSign Transaction Flow . tracker ()) Ġ: ĠFlow Logic < Signed Transaction >() Ġ{ ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġobject ĠRE CE IV ING Ġ: ĠProgress Tracker . Step (" Re ceiving Ġtransaction Ġproposal Ġfor Ġsigning .") ĊĠĠĠĠĠĠĠ Ġobject ĠVERIFY ING Ġ: ĠProgress Tracker . Step (" Verify ing Ġtransaction Ġproposal .") ĊĠĠĠĠĠĠĠ Ġobject ĠSIGN ING Ġ: ĠProgress Tracker . Step (" Signing Ġtransaction Ġproposal .") ĊĊĠĠĠĠĠĠĠ Ġ@ Jvm Static ĊĠĠĠĠĠĠĠ Ġfun Ġtracker () Ġ= ĠProgress Tracker ( RECE IV ING , ĠVERIFY ING , ĠSIGN ING ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Suspend able ĊĠĠĠ Ġoverride Ġfun Ġcall (): ĠSigned Transaction Ġ{ ĊĠĠĠĠĠĠĠ Ġprogress Tracker . current Step Ġ= ĠRE CE IV ING ĊĠĠĠĠĠĠĠ Ġ// ĠReceive Ġtransaction Ġand Ġresolve Ġdependencies , Ġcheck Ġsufficient Ġsignatures Ġis Ġdisabled Ġas Ġwe Ġdon 't Ġhave Ġall Ġsignatures . ĊĠĠĠĠĠĠĠ Ġval Ġst x Ġ= Ġsub Flow ( Receive Transaction Flow ( other Side Session , Ġcheck S ufficient Signatures Ġ= Ġfalse )) ĊĠĠĠĠĠĠĠ Ġ// ĠReceive Ġthe Ġsigning Ġkey Ġthat Ġthe Ġparty Ġrequesting Ġthe Ġsignature Ġexpects Ġus Ġto Ġsign Ġwith . ĠHaving Ġthis Ġprovided ĊĠĠĠĠĠĠĠ Ġ// Ġmeans Ġwe Ġonly Ġhave Ġto Ġcheck Ġwe Ġown Ġthat Ġone Ġkey , Ġrather Ġthan Ġmatching Ġall Ġkeys Ġin Ġthe Ġtransaction Ġagainst Ġall ĊĠĠĠĠĠĠĠ Ġ// Ġkeys Ġwe Ġown . ĊĠĠĠĠĠĠĠ Ġval Ġsigning Keys Ġ= Ġother Side Session . receive < List < PublicKey >> (). unwrap Ġ{ Ġkeys Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠTODO : ĠWe Ġshould Ġhave Ġa Ġfaster Ġway Ġof Ġverify ing Ġwe Ġown Ġa Ġsingle Ġkey ĊĠĠĠĠĠĠĠĠĠĠĠ Ġservice Hub . key Management Service . filter My Keys ( keys ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġprogress Tracker . current Step Ġ= ĠVERIFY ING ĊĠĠĠĠĠĠĠ Ġ// ĠCheck Ġthat Ġthe ĠRes pon der Ġactually Ġneeds Ġto Ġsign . ĊĠĠĠĠĠĠĠ Ġcheck My Signatures Required ( st x , Ġsigning Keys ) ĊĠĠĠĠĠĠĠ Ġ// ĠCheck Ġthe Ġsignatures Ġwhich Ġhave Ġalready Ġbeen Ġprovided . ĠUsually Ġthe ĠInit i ators Ġand Ġpossibly Ġan ĠOracle 's . ĊĠĠĠĠĠĠĠ Ġcheck Signatures ( st x ) ĊĠĠĠĠĠĠĠ Ġst x . tx . to Ledger Transaction ( service Hub ). verify () ĊĠĠĠĠĠĠĠ Ġ// ĠPerform Ġsome Ġcustom Ġverification Ġover Ġthe Ġtransaction . ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcheck Transaction ( st x ) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( e Ġis ĠIllegalStateException Ġ|| Ġe Ġis ĠIllegalArgumentException Ġ|| Ġe Ġis ĠAssertionError ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠFlow Exception ( e ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Ġe ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ// ĠSign Ġand Ġsend Ġback Ġour Ġsignature Ġto Ġthe ĠInit iator . ĊĠĠĠĠĠĠĠ Ġprogress Tracker . current Step Ġ= ĠSIGN ING ĊĠĠĠĠĠĠĠ Ġval Ġmy Signatures Ġ= Ġsigning Keys . map Ġ{ Ġkey Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġservice Hub . create Signature ( st x , Ġkey ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġother Side Session . send ( my Signatures ) ĊĊĠĠĠĠĠĠĠ Ġ// ĠReturn Ġthe Ġaddition ally Ġsigned Ġtransaction . ĊĠĠĠĠĠĠĠ Ġreturn Ġst x Ġ+ Ġmy Signatures ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Suspend able ĊĠĠĠ Ġprivate Ġfun Ġcheck Signatures ( st x : ĠSigned Transaction ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġsigned Ġ= Ġst x . sigs . map Ġ{ Ġit . by Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġall Sign ers Ġ= Ġst x . tx . required Signing Keys ĊĠĠĠĠĠĠĠ Ġval Ġnot Signed Ġ= Ġall Sign ers Ġ- Ġsigned ĊĠĠĠĠĠĠĠ Ġst x . verify Signatures Except ( not Signed ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThe Ġ[ check Transaction ] Ġmethod Ġallows Ġthe Ġcaller Ġof Ġthis Ġflow Ġto Ġprovide Ġsome Ġadditional Ġchecks Ġover Ġthe Ġproposed ĊĠĠĠĠ Ġ* Ġtransaction Ġreceived Ġfrom Ġthe Ġcounter party . ĠFor Ġexample : ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ- ĠEns uring Ġthat Ġthe Ġtransaction Ġyou Ġare Ġreceiving Ġis Ġthe Ġtransaction Ġyou Ġ* EXPECT * Ġto Ġreceive . ĠI . e . Ġis Ġhas Ġthe ĊĠĠĠĠ Ġ* ĠĠ Ġexpected Ġtype Ġand Ġnumber Ġof Ġinputs Ġand Ġoutputs ĊĠĠĠĠ Ġ* Ġ- ĠChecking Ġthat Ġthe Ġproperties Ġof Ġthe Ġoutputs Ġare Ġas Ġyou Ġwould Ġexpect . ĠLink ing Ġinto Ġany Ġreference Ġdata Ġsources ĊĠĠĠĠ Ġ* ĠĠ Ġmight Ġbe Ġappropriate Ġhere ĊĠĠĠĠ Ġ* Ġ- ĠChecking Ġthat Ġthe Ġtransaction Ġis Ġnot Ġincorrectly Ġs pending Ġ( per haps Ġm alic iously ) Ġone Ġof Ġyour Ġasset Ġstates , Ġas ĊĠĠĠĠ Ġ* ĠĠ Ġpotentially Ġthe Ġtransaction Ġcreator Ġhas Ġaccess Ġto Ġsome Ġof Ġyour Ġstate Ġreferences ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ** WARNING **: ĠIf Ġappropriate Ġchecks , Ġsuch Ġas Ġthe Ġones Ġlisted Ġabove , Ġare Ġnot Ġdefined Ġthen Ġit Ġis Ġlikely Ġthat Ġyour ĊĠĠĠĠ Ġ* Ġnode Ġwill Ġsign Ġany Ġtransaction Ġif Ġit Ġcon forms Ġto Ġthe Ġcontract Ġcode Ġin Ġthe Ġtransaction 's Ġreferenced Ġcontracts . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ[ IllegalArgumentException ], Ġ[ IllegalStateException ] Ġand Ġ[ AssertionError ] Ġwill Ġbe Ġcaught Ġand Ġre throw n Ġas Ġflow ĊĠĠĠĠ Ġ* Ġexceptions Ġi . e . Ġthe Ġother Ġside Ġwill Ġbe Ġgiven Ġinformation Ġabout Ġwhat Ġexact Ġcheck Ġfailed . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġst x Ġa Ġpartially Ġsigned Ġtransaction Ġreceived Ġfrom Ġyour Ġcounter party . ĊĠĠĠĠ Ġ* Ġ@ throws ĠFlow Exception Ġif Ġthe Ġproposed Ġtransaction Ġfails Ġthe Ġchecks . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Suspend able ĊĠĠĠ Ġ@ Throws ( Flow Exception :: class ) ĊĠĠĠ Ġprotected Ġabstract Ġfun Ġcheck Transaction ( st x : ĠSigned Transaction ) ĊĊĠĠĠ Ġ@ Suspend able ĊĠĠĠ Ġprivate Ġfun Ġcheck My Signatures Required ( st x : ĠSigned Transaction , Ġsigning Keys : ĠIterable < PublicKey >) Ġ{ ĊĠĠĠĠĠĠĠ Ġrequire ( signing Keys . all Ġ{ Ġit Ġin Ġst x . tx . required Signing Keys Ġ}) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" A Ġsignature Ġwas Ġrequested Ġfor Ġa Ġkey Ġthat Ġisn 't Ġpart Ġof Ġthe Ġrequired Ġsigning Ġkeys Ġfor Ġtransaction Ġ${ st x . id }" ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ