/* Ċ Ġ* ĠLicensed Ġto Ġthe ĠApache ĠSoftware ĠFoundation Ġ( ASF ) Ġunder Ġone Ġor Ġmore Ċ Ġ* Ġcontributor Ġlicense Ġagreements . Ġ ĠSee Ġthe ĠNOTICE Ġfile Ġdistributed Ġwith Ċ Ġ* Ġthis Ġwork Ġfor Ġadditional Ġinformation Ġregarding Ġcopyright Ġownership . Ċ Ġ* ĠThe ĠASF Ġlicenses Ġthis Ġfile Ġto ĠYou Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ċ Ġ* Ġ( the Ġ" License "); Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ċ Ġ* Ġthe ĠLicense . Ġ ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ġ* Ċ Ġ* ĠĠĠĠĠ Ġhttp :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ Ġ* Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ Ġ* ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ Ġ* ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ Ġ* Ġlimitations Ġunder Ġthe ĠLicense . Ċ Ġ*/ Ċ package Ġorg . apache . tu w eni . dev p 2 p . eth Ċ Ċ import Ġorg . apache . tu w eni . bytes . Bytes Ċ import Ġorg . apache . tu w eni . eth . Block Ċ import Ġorg . apache . tu w eni . eth . Block Body Ċ import Ġorg . apache . tu w eni . eth . Block Header Ċ import Ġorg . apache . tu w eni . eth . Hash Ċ import Ġorg . apache . tu w eni . eth . Transaction Ċ import Ġorg . apache . tu w eni . eth . Transaction Receipt Ċ import Ġorg . apache . tu w eni . eth . repository . Blockchain Repository Ċ import Ġorg . apache . tu w eni . eth . repository . Transaction Pool Ċ import Ġorg . apache . tu w eni . rl px . wire . Wire Connection Ċ Ċ /** Ċ Ġ* ĠController Ġmanaging Ġthe Ġstate Ġof Ġthe ĠETH Ġor ĠL ES Ġsub protocol Ġhandlers . Ċ Ġ*/ Ċ class ĠE th Controller ( ĊĠ Ġval Ġrepository : ĠBlock chain Repository , ĊĠ Ġval Ġpending Transactions Pool : ĠTransaction Pool , ĊĠ Ġval Ġrequests Manager : ĠE th Requests Manager , ĊĠ Ġval Ġconnections Listener : Ġ( Wire Connection , ĠStatus ) Ġ-> ĠUnit Ġ= Ġ{ Ġ_, Ġ_ Ġ-> Ġ} Ċ ) Ġ{ ĊĊĠ Ġsuspend Ġfun Ġfind Transaction Receipt s ( hashes : ĠList < Hash >): ĠList < List < Transaction Receipt >> Ġ{ ĊĠĠĠ Ġval Ġreceipt s Ġ= ĠArrayList < List < Transaction Receipt >>() ĊĠĠĠ Ġhashes . forEach Ġ{ ĊĠĠĠĠĠ Ġreceipt s . add ( repository . retrieve Transaction Receipt s ( it )) ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġreceipt s ĊĠ Ġ} ĊĊĠ Ġsuspend Ġfun Ġadd New Block ( new Block : ĠBlock ) Ġ{ ĊĠĠĠ Ġrepository . store Block ( new Block ) ĊĠ Ġ} ĊĊĠ Ġsuspend Ġfun Ġfind Block B odies ( hashes : ĠList < Hash >): ĠList < Block Body > Ġ{ ĊĠĠĠ Ġval Ġbodies Ġ= ĠArrayList < Block Body >() ĊĠĠĠ Ġhashes . forEach Ġ{ Ġhash Ġ-> ĊĠĠĠĠĠ Ġrepository . retrieve Block Body ( hash )?. let Ġ{ ĊĠĠĠĠĠĠĠ Ġbodies . add ( it ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġbodies ĊĠ Ġ} ĊĊĠ Ġsuspend Ġfun Ġfind Headers ( block : ĠBytes , Ġmax Headers : ĠLong , Ġskip : ĠLong , Ġreverse : ĠBoolean ): ĠList < Block Header > Ġ{ ĊĠĠĠ Ġval Ġmatches Ġ= Ġrepository . find Block By Hash Or Number ( block ) ĊĠĠĠ Ġval Ġheaders Ġ= ĠArrayList < Block Header >() ĊĠĠĠ Ġif Ġ( matches . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠ Ġval Ġheader Ġ= Ġrepository . retrieve Block Header ( matches [ 0 ]) ĊĠĠĠĠĠ Ġheader ?. let Ġ{ ĊĠĠĠĠĠĠĠ Ġheaders . add ( it ) ĊĠĠĠĠĠĠĠ Ġvar Ġblock Number Ġ= Ġit . number ĊĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġ 2 .. max Headers ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġblock Number Ġ= Ġif Ġ( reverse ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġblock Number . subtract ( skip Ġ+ Ġ 1 ) ĊĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġblock Number . add ( skip Ġ+ Ġ 1 ) ĊĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġval Ġnext Matches Ġ= Ġrepository . find Block By Hash Or Number ( block Number . to Bytes ()) ĊĠĠĠĠĠĠĠĠĠ Ġif Ġ( next Matches . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbreak ĊĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġval Ġnext Header Ġ= Ġrepository . retrieve Block Header ( next Matches [ 0 ]) Ġ?: Ġbreak ĊĠĠĠĠĠĠĠĠĠ Ġheaders . add ( next Header ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġheaders ĊĠ Ġ} ĊĊĠ Ġsuspend Ġfun Ġadd New Block Hashes ( hashes : ĠList < Pair < Hash , ĠLong >>) Ġ{ ĊĠĠĠ Ġhashes . forEach Ġ{ Ġpair Ġ-> ĊĠĠĠĠĠ Ġrepository . retrieve Block Header ( pair . first ). take If Ġ{ Ġnull Ġ== Ġit Ġ}. apply Ġ{ ĊĠĠĠĠĠĠĠ Ġrequest Block Header ( pair . first ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġrepository . retrieve Block Body ( pair . first ). take If Ġ{ Ġnull Ġ== Ġit Ġ}. apply Ġ{ ĊĠĠĠĠĠĠĠ Ġrequest Block Body ( pair . first ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġfun Ġrequest Block Header ( block Hash : ĠHash ) Ġ{ ĊĠĠĠ Ġrequests Manager . request Block Header ( block Hash ) ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġrequest Block Body ( block Hash : ĠHash ) Ġ{ ĊĠĠĠ Ġrequests Manager . request Block B odies ( listOf ( block Hash )) ĊĠ Ġ} ĊĊĠ Ġsuspend Ġfun Ġadd New Block Headers ( connection : ĠWire Connection , Ġheaders : ĠList < Block Header >) Ġ{ ĊĠĠĠ Ġval Ġhandle Ġ= Ġrequests Manager . was Requested ( connection , Ġheaders . first ()) Ġ?: Ġreturn ĊĠĠĠ Ġval Ġbodies To Request Ġ= Ġmutable ListOf < Hash >() ĊĠĠĠ Ġval Ġheaders To Request Ġ= Ġmutable ListOf < Hash >() ĊĠĠĠ Ġheaders . forEach Ġ{ Ġheader Ġ-> ĊĠĠĠĠĠ Ġrepository . store Block Header ( header ) ĊĠĠĠĠĠ Ġif Ġ(! repository . has Block Body ( header . hash )) Ġ{ ĊĠĠĠĠĠĠĠ Ġbodies To Request . add ( header . hash ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġheader . parent Hash ?. let Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! repository . has Block Header ( it )) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġheaders To Request . add ( it ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġrequests Manager . request Block Headers ( headers To Request ) ĊĠĠĠ Ġrequests Manager . request Block B odies ( bodies To Request ) ĊĠĠĠ Ġhandle . complete () ĊĠ Ġ} ĊĊĠ Ġsuspend Ġfun Ġadd New Block B odies ( connection : ĠWire Connection , Ġbodies : ĠList < Block Body >) Ġ{ ĊĠĠĠ Ġval Ġrequest Ġ= Ġrequests Manager . was Requested ( connection , Ġbodies ) ĊĠĠĠ Ġif Ġ( request Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠ Ġval Ġhashes Ġ= Ġrequest . data Ġas ĠList < *> ĊĠĠĠĠĠ Ġfor Ġ( i Ġin Ġ 0 .. hashes . size ) Ġ{ ĊĠĠĠĠĠĠĠ Ġrepository . store Block Body ( hashes [ i ] Ġas ĠHash , Ġbodies [ i ]) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġfun Ġreceive Status ( connection : ĠWire Connection , Ġstatus : ĠStatus ) Ġ{ ĊĠĠĠ Ġconnections Listener ( connection , Ġstatus ) ĊĠ Ġ} ĊĊĠ Ġsuspend Ġfun Ġfind Node Data ( hashes : ĠList < Hash >) Ġ= Ġrepository . retrieve Node Data ( hashes ) ĊĊĠ Ġsuspend Ġfun Ġadd New Node Data ( connection : ĠWire Connection , Ġelements : ĠList < Bytes ?> ) Ġ{ ĊĠĠĠ Ġval Ġrequest Ġ= Ġrequests Manager . node Data Was Requested ( connection , Ġelements ) ĊĠĠĠ Ġif Ġ( request Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠ Ġval Ġhashes Ġ= Ġrequest . data Ġas ĠList < *> ĊĠĠĠĠĠ Ġfor Ġ( i Ġin Ġ 0 .. hashes . size ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġelt Ġ= Ġelements [ i ] ĊĠĠĠĠĠĠĠ Ġif Ġ( elt Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġrepository . store Node Data ( hashes [ i ] Ġas ĠHash , Ġelt ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġsuspend Ġfun Ġadd New Transaction Receipt s ( ĊĠĠĠ Ġconnection : ĠWire Connection , ĊĠĠĠ Ġtransaction Receipt s : ĠList < List < Transaction Receipt >> ĊĠ Ġ) Ġ{ ĊĠĠĠ Ġval Ġrequest Ġ= Ġrequests Manager . transaction Receipt s Requested ( connection , Ġtransaction Receipt s ) ĊĠĠĠ Ġif Ġ( request Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠ Ġval Ġhashes Ġ= Ġrequest . data Ġas ĠList < *> ĊĠĠĠĠĠ Ġfor Ġ( i Ġin Ġ 0 .. hashes . size ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġblock Body Ġ= Ġrepository . retrieve Block Body ( hashes [ i ] Ġas ĠHash ) ĊĠĠĠĠĠĠĠ Ġval Ġblock Receipt s Ġ= Ġtransaction Receipt s [ i ] ĊĠĠĠĠĠĠĠ Ġfor Ġ( j Ġin Ġ 0 .. block Receipt s . size ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġrepository . store Transaction Receipt ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġblock Receipt s [ j ], ĊĠĠĠĠĠĠĠĠĠĠĠ Ġj , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġblock Body ?. transactions ?. get ( j )?. hash Ġ?: ĠBytes . EMPTY , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhashes [ i ] Ġas ĠHash ĊĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġsuspend Ġfun Ġadd New Transactions ( transactions : ĠList < Transaction >) Ġ{ ĊĠĠĠ Ġtransactions . forEach Ġ{ ĊĠĠĠĠĠ Ġrepository . store Transaction ( it ) ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġsuspend Ġfun Ġadd New P ooled Transactions ( transactions : ĠList < Transaction >) Ġ{ ĊĠĠĠ Ġfor Ġ( tx Ġin Ġtransactions ) Ġ{ ĊĠĠĠĠĠ Ġpending Transactions Pool . add ( tx ) ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġsuspend Ġfun Ġfind P ooled Transactions ( hashes : ĠList < Hash >): ĠList < Transaction > Ġ{ ĊĠĠĠ Ġval Ġresult Ġ= ĠArrayList < Transaction >() ĊĠĠĠ Ġfor Ġ( hash Ġin Ġhashes ) Ġ{ ĊĠĠĠĠĠ Ġpending Transactions Pool . get ( hash )?. let Ġ{ ĊĠĠĠĠĠĠĠ Ġresult . add ( it ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġresult ĊĠ Ġ} Ċ } Ċ