// ĠVer i Block ĠNode Core Ċ // ĠCopyright Ġ 2 0 1 7 - 2 0 2 0 ĠX en ios ĠSE ZC Ċ // ĠAll Ġrights Ġreserved . Ċ // Ġhttps :// www . ver ib lock . org Ċ // ĠDistributed Ġunder Ġthe ĠMIT Ġsoftware Ġlicense , Ġsee Ġthe Ġaccompanying Ċ // Ġfile ĠLICENSE Ġor Ġhttp :// www . opensource . org / licenses / mit - license . php . Ċ package Ġorg . ver ib lock . core . alt chain Ċ Ċ import Ġorg . ver ib lock . core . Transaction Constants Ċ import Ġorg . ver ib lock . core . utilities . Utility Ċ import Ġorg . ver ib lock . core . utilities . extensions . to Hex Ċ import Ġjava . io . ByteArray InputStream Ċ Ċ /** Ċ Ġ* ĠAn ĠAlt chain ĠPo P ĠEnd orse ment Ġis Ġan Ġendorse ment Ġof Ġan Ġalt chain 's Ġstate Ġwhich Ġan Ġalt chain ĠPo P Ġminer Ġhas Ġpublished Ġto Ċ Ġ* ĠVer i Block . Ċ Ġ* Ċ Ġ* ĠThese Ġare Ġcreated Ġfrom Ġspec ially - formatted Ġdata Ġsections Ġin Ġstandard Ġtransactions , Ġand Ġpair Ġa Ġnetwork Ġidentifier Ċ Ġ* Ġ( each Ġalt chain Ġa do pts Ġa Ġdifferent Ġnetwork ĠID ) Ġwith Ġan Ġend or sed Ġblock . ĠBecause Ġalt chains Ġcan Ġhave Ġa Ġvariety Ġof Ċ Ġ* Ġformats , Ġthe Ġend or sed Ġblock Ġdata Ġis Ġfree - form : ĠPo W Ġblock chains Ġwill Ġlikely Ġpublish Ġjust Ġa Ġstandard Ġblock Ġheader , Ġbut Ċ Ġ* Ġother Ġconsensus Ġmechanisms Ġlike ĠPo S Ġmay Ġrequire Ġadditional Ġdata Ġbe Ġpublished Ġ( such Ġas Ġthat Ġwhich Ġpro ves Ġthat Ġa ĠPo S Ċ Ġ* Ġblock Ġwas Ġcreated Ġby Ġthe Ġconsumption Ġof Ġvalid Ġcoin age ). Ċ Ġ* Ċ Ġ* ĠNothing Ġprevents ĠPo P Ġmin ers Ġfrom Ġusing Ġarbitrary Ġidentifiers , Ġnor Ġdoes Ġanything Ġprevent Ġtwo Ġalt chains Ġfrom Ġusing Ġthe Ċ Ġ* Ġsame Ġidentifier . ĠThe Ġidentifier Ġis Ġsimply Ġa Ġconvenience Ġfor Ġeasy Ġparsing , Ġand Ġthe Ġendorse ment Ġdata Ġcontains Ġenough Ċ Ġ* Ġinformation Ġto Ġperform Ġpre limin ary Ġvalidation Ġ( such Ġas Ġhashing Ġthe Ġblock Ġheader Ġand Ġseeing Ġif Ġit Ġis Ġthe Ġappropriate Ċ Ġ* Ġdifficulty ). Ċ Ġ*/ Ċ class ĠAlt chain Po P End orse ment ( ĊĠĠĠ Ġprivate Ġval Ġraw Data : ĠByteArray Ċ ) Ġ{ ĊĠĠĠ Ġval Ġidentifier : ĠLong ĊĠĠĠ Ġprivate Ġval Ġheader : ĠByteArray ĊĠĠĠ Ġprivate Ġval Ġcontext Info : ĠByteArray ĊĠĠĠ Ġprivate Ġval Ġpay out Info : ĠByteArray ĊĊĠĠĠ Ġfun Ġget Header () Ġ= Ġheader . clone () ĊĊĠĠĠ Ġfun ĠgetContext Info () Ġ= Ġcontext Info . clone () ĊĊĠĠĠ Ġfun Ġget Pay out Info () Ġ= Ġpay out Info . clone () ĊĊĠĠĠ Ġfun Ġget RawData () Ġ= Ġraw Data . clone () ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġrequire ( raw Data . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" An ĠAlt chain Po P End orse ment Ġcannot Ġbe Ġcreated Ġwith Ġan Ġempty Ġdata Ġarray !" ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġrequire ( raw Data . size Ġ<= ĠTransaction Constants . MAX _ TRANSACTION _ DATA _ SIZE _ BYTES ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" An ĠAlt chain Po P End orse ment Ġcannot Ġbe Ġcreated Ġwith Ġraw Ġdata Ġthat Ġis Ġlonger Ġthan Ġ${ Transaction Constants . MAX _ TRANSACTION _ DATA _ SIZE _ BYTES }" ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġendorse ment DataStream Ġ= ĠByteArrayInputStream ( raw Data ) ĊĠĠĠĠĠĠĠ Ġval Ġid Size Ġ= Ġendorse ment DataStream . read (). to Byte () ĊĠĠĠĠĠĠĠ Ġrequire ( id Size Ġ<= ĠAlt chain Constants . MAX _ ALT CHAIN _ IDENTIFIER _ LENGTH ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" An ĠAlt chain Po P End orse ment Ġcannot Ġbe Ġcreated Ġwith Ġan Ġidentifier Ġthat Ġis Ġmore Ġthan Ġ 8 Ġbytes Ġlong Ġ($ id Size ) !" ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġrequire ( id Size Ġ>= Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" An ĠAlt chain Po P End orse ment Ġcannot Ġbe Ġcreated Ġwith Ġan Ġidentifier Ġthat Ġis Ġzero Ġor Ġnegative Ġ($ id Size ) !" ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġrequire ( endor sement DataStream . available () Ġ>= Ġid Size ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" An ĠAlt chain Po P End orse ment Ġwas Ġattempted Ġto Ġbe Ġcreated Ġwhich Ġclaimed Ġto Ġhave Ġ$ id Size Ġbytes Ġof ĠID Ġdata , Ġbut Ġonly Ġhad Ġ${ endor sement DataStream . available ()} Ġbytes Ġleft !" ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġthis . identifier Ġ= Ġendorse ment DataStream . read Variable Length Int (" identifier ", Ġid Size ) ĊĊĠĠĠĠĠĠĠ Ġ// ĠRead Ġthe Ġheader Ġdata Ġ( size Ġof Ġheader Ġsize , Ġsize Ġof Ġheader , Ġheader ) ĊĠĠĠĠĠĠĠ Ġrequire ( endor sement DataStream . available () Ġ!= Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" An ĠAlt chain Po P End orse ment Ġwas Ġattempted Ġto Ġbe Ġcreated Ġwith Ġno Ġheader , Ġcontext , Ġor Ġpay out Ġsections !" ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġthis . header Ġ= Ġendorse ment DataStream . read (" header ", ĠAlt chain Constants . MAX _ ALT CHAIN _ ENDOR SE MENT _ INFO _ SECTION _ LENGTH ) ĊĊĠĠĠĠĠĠĠ Ġ// ĠRead Ġthe Ġcontext Ġinfo Ġdata Ġ( size Ġof Ġcontext Ġinfo Ġsize , Ġsize Ġof Ġcontext Ġinfo , Ġcontext Ġinfo ) ĊĠĠĠĠĠĠĠ Ġrequire ( endor sement DataStream . available () Ġ!= Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" An ĠAlt chain Po P End orse ment Ġwas Ġattempted Ġto Ġbe Ġcreated Ġwith Ġno Ġcontext Ġinfo , Ġor Ġpay out Ġsections !" ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġcontext Info Ġ= Ġendorse ment DataStream . read (" context Ġinfo ", ĠAlt chain Constants . MAX _ ALT CHAIN _ ENDOR SE MENT _ INFO _ SECTION _ LENGTH , Ġtrue ) ĊĊĠĠĠĠĠĠĠ Ġ// ĠRead Ġthe Ġpay out Ġdata Ġ( size Ġof Ġcontext Ġinfo Ġsize , Ġsize Ġof Ġcontext Ġinfo , Ġcontext Ġinfo ) ĊĠĠĠĠĠĠĠ Ġrequire ( endor sement DataStream . available () Ġ!= Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" An ĠAlt chain Po P End orse ment Ġwas Ġattempted Ġto Ġbe Ġcreated Ġwith Ġno Ġor Ġpay out Ġsection !" ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġpay out Info Ġ= Ġendorse ment DataStream . read (" pay out Ġinfo ", ĠAlt chain Constants . MAX _ ALT CHAIN _ ENDOR SE MENT _ INFO _ SECTION _ LENGTH , Ġtrue ) ĊĊĠĠĠĠĠĠĠ Ġif Ġ( endor sement DataStream . available () Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalArgumentException (" While Ġcreating Ġan ĠAlt chain Po P End orse ment , Ġunexpected Ġadditional Ġdata Ġwas Ġpresent Ġafter Ġthe Ġspecified Ġheader , Ġcontext Ġinfo , Ġand Ġpay out Ġinfo Ġsections !" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" ĠExtra Ġavailable Ġbytes : Ġ${ Utility . bytes To Hex ( ByteArray ( endor sement DataStream . available ()). also Ġ{ Ġendorse ment DataStream . read ( it ) Ġ})} !") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠByteArrayInputStream . read ( name : ĠString , ĠmaxLength Size : ĠInt , Ġcan Be O mitted : ĠBoolean Ġ= Ġfalse ): ĠByteArray Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠRead Ġlength Ġof Ġsize ĊĠĠĠĠĠĠĠ Ġval Ġlength Of Size Ġ= Ġread (). to Byte () ĊĠĠĠĠĠĠĠ Ġrequire ( length Of Size Ġ<= ĠmaxLength Size ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" An ĠAlt chain Po P End orse ment Ġcannot Ġbe Ġcreated Ġwith Ġa Ġ$ name Ġsize Ġlength Ġthat Ġis Ġmore Ġthan Ġ$ maxLength Size Ġbytes Ġlong Ġ($ length Of Size ) !" ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( can Be O mitted ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrequire ( length Of Size Ġ>= Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" An ĠAlt chain Po P End orse ment Ġcannot Ġbe Ġcreated Ġwith Ġa Ġ$ name Ġsize Ġlength Ġthat Ġis Ġnegative Ġ($ length Of Size ) !" ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠIf Ġit Ġcan Ġbe Ġomitted , Ġa Ġsize Ġof Ġsize Ġequals Ġto Ġ 0 Ġmeans Ġo mission ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( length Of Size . toInt () Ġ== Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠByteArray ( 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġrequire ( length Of Size Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" An ĠAlt chain Po P End orse ment Ġcannot Ġbe Ġcreated Ġwith Ġa Ġ$ name Ġsize Ġlength Ġthat Ġis Ġzero Ġor Ġnegative Ġ($ length Of Size ) !" ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġlength Ġ= Ġread Variable Length Int ( name , Ġlength Of Size ). toInt () ĊĠĠĠĠĠĠĠ Ġrequire ( length Ġ>= Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" An ĠAlt chain Po P End orse ment Ġwas Ġattempted Ġto Ġbe Ġcreated Ġwhich Ġcontained Ġa Ġ$ name Ġlength Ġthat Ġwas Ġnegative Ġ($ length ) !" ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġdata Ġ= ĠByteArray ( length ) ĊĠĠĠĠĠĠĠ Ġif Ġ( data . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġdata ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ// ĠRead Ġactual Ġdata ĊĠĠĠĠĠĠĠ Ġval Ġread Result Ġ= Ġread ( data ) ĊĠĠĠĠĠĠĠ Ġrequire ( read Result Ġ>= Ġdata . size ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" While Ġcreating Ġan ĠAlt chain Po P End orse ment , Ġthe Ġ$ name Ġbytes Ġwere Ġunable Ġto Ġbe Ġread Ġin Ġfull Ġfrom Ġthe Ġendorse ment : Ġ${ raw Data . to Hex () }" ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġdata ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠByteArrayInputStream . read Variable Length Int ( name : ĠString , Ġlength : ĠByte ): ĠLong Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġbytes Ġ= ĠByteArray ( length . toInt ()) ĊĠĠĠĠĠĠĠ Ġ// ĠRead Ġactual Ġsize ĊĠĠĠĠĠĠĠ Ġrequire ( read ( bytes ) Ġ>= Ġbytes . size ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" While Ġcreating Ġan ĠAlt chain Po P End orse ment , Ġthe Ġ$ name Ġsize Ġwas Ġunable Ġto Ġbe Ġread Ġin Ġfull Ġfrom Ġthe Ġendorse ment : Ġ${ raw Data . to Hex () }" ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġvar Ġresult Ġ= Ġ 0 L ĊĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġbytes . indices ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresult Ġ= Ġ( result Ġshl Ġ 8 ) Ġor Ġ( 0 xFF L Ġand Ġbytes [ i ]. to Long ()) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġresult ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġ@ Jvm Static ĊĠĠĠĠĠĠĠ Ġfun ĠisValid End orse ment ( raw Data : ĠByteArray ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠAlt chain Po P End orse ment ( raw Data ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ inline Ġfun ĠByteArray . check For Valid End orse ment ( error Handler : Ġ( Exception ) Ġ-> ĠUnit ) Ġ{ ĊĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠ ĠAlt chain Po P End orse ment ( this ) ĊĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠ ĠerrorHandler ( e ) ĊĠĠĠ Ġ} Ċ } Ċ