package Ġnet . cord a . node . services . network Ċ Ċ import Ġcom . google . common . util . concurrent . More Executors Ċ import Ġnet . cord a . core . C ord a RuntimeException Ċ import Ġnet . cord a . core . crypto . Secure Hash Ċ import Ġnet . cord a . core . crypto . Signed Data Ċ import Ġnet . cord a . core . internal . copy To Ċ import Ġnet . cord a . core . internal . div Ċ import Ġnet . cord a . core . internal . exists Ċ import Ġnet . cord a . core . internal . read Object Ċ import Ġnet . cord a . core . messaging . Data Feed Ċ import Ġnet . cord a . core . messaging . Parameters Update Info Ċ import Ġnet . cord a . core . serialization . serialize Ċ import Ġnet . cord a . core . utilities . context Logger Ċ import Ġnet . cord a . core . utilities . minutes Ċ import Ġnet . cord a . node . services . api . Network Map Cache Internal Ċ import Ġnet . cord a . node . utilities . Named Thread Factory Ċ import Ġnet . cord a . node api . exceptions . Out dated Network Parameter Hash Exception Ċ import Ġnet . cord a . node api . internal . network . NETWORK _ PARAMS _ FILE _ NAME Ċ import Ġnet . cord a . node api . internal . network . NETWORK _ PARAMS _ UPDATE _ FILE _ NAME Ċ import Ġnet . cord a . node api . internal . network . Network Map Ċ import Ġnet . cord a . node api . internal . network . Parameters Update Ċ import Ġnet . cord a . node api . internal . network . Signed Network Parameters Ċ import Ġnet . cord a . node api . internal . network . verified Network Map Cert Ċ import Ġrx . Subscription Ċ import Ġrx . subjects . Publish Subject Ċ import Ġjava . nio . file . Path Ċ import Ġjava . nio . file . Standard Copy Option Ċ import Ġjava . time . Duration Ċ import Ġjava . util .* Ċ import Ġjava . util . concurrent . Executors Ċ import Ġjava . util . concurrent . Scheduled ThreadPoolExecutor Ċ import Ġjava . util . concurrent . TimeUnit Ċ import Ġkotlin . system . exit Process Ċ Ċ class ĠNetwork Map Updater ( private Ġval Ġnetwork Map Cache : ĠNetwork Map Cache Internal , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġval Ġfile Watcher : ĠNode Info Watcher , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġval Ġnetwork Map Client : ĠNetwork Map Client ?, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġval Ġcurrent Parameters Hash : ĠSecure Hash , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġval Ġour NodeInfo Hash : ĠSecure Hash ?, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġval Ġbase Directory : ĠPath , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġval Ġextra Network Map Keys : ĠList < UUID > Ċ ) Ġ: ĠAuto Closeable Ġ{ ĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġlogger Ġ= Ġcontext Logger () ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġdefault Retry Interval Ġ= Ġ 1 . minutes ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġval Ġparameters Updates Track : ĠPublish Subject < Parameters Update Info > Ġ= ĠPublish Subject . create < Parameters Update Info >() ĊĠĠĠ Ġprivate Ġval Ġexecutor Ġ= ĠScheduled ThreadPoolExecutor ( 1 , ĠNamed Thread Factory (" Network ĠMap ĠUp dater ĠThread ", ĠExec utors . default Thread Factory ())) ĊĠĠĠ Ġprivate Ġvar Ġnew Network Parameters : ĠPair < Parameters Update , ĠSigned Network Parameters >? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġfile Watcher Subscription : ĠSubscription ? Ġ= Ġnull ĊĊĠĠĠ Ġoverride Ġfun Ġclose () Ġ{ ĊĠĠĠĠĠĠĠ Ġfile Watcher Subscription ?. unsubscribe () ĊĠĠĠĠĠĠĠ ĠMore Executors . shutdown And Await Termination ( executor , Ġ 5 0 , ĠTimeUnit . SECONDS ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġtrack Parameters Update (): ĠData Feed < Parameters Update Info ?, ĠParameters Update Info > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcurrent Update Info Ġ= Ġnew Network Parameters ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠParameters Update Info ( it . first . new Parameters Hash , Ġit . second . verified (), Ġit . first . description , Ġit . first . update Deadline ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn ĠData Feed ( current Update Info , Ġparameters Updates Track ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġsubscribe To Network Map () Ġ{ ĊĠĠĠĠĠĠĠ Ġrequire ( file Watcher Subscription Ġ== Ġnull ) Ġ{ Ġ" Should Ġnot Ġcall Ġthis Ġmethod Ġtwice ." Ġ} ĊĠĠĠĠĠĠĠ Ġ// ĠSubscribe Ġto Ġfile Ġbased Ġnetwork Map ĊĠĠĠĠĠĠĠ Ġfile Watcher Subscription Ġ= Ġfile Watcher . node Info Updates (). subscribe Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( it ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠNode Info Update . Add Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnetwork Map Cache . add Node ( it . node Info ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠNode Info Update . Remove Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( it . hash Ġ!= Ġour NodeInfo Hash ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnode Info Ġ= Ġnetwork Map Cache . getNode By Hash ( it . hash ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnode Info ?. let Ġ{ Ġnetwork Map Cache . remove Node ( it ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( network Map Client Ġ== Ġnull ) Ġreturn ĊĊĠĠĠĠĠĠĠ Ġ// ĠSubscribe Ġto Ġremote Ġnetwork Ġmap Ġif Ġconfigured . ĊĠĠĠĠĠĠĠ Ġexecutor . execute Existing Delayed Tasks After Shutdown Policy Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġexecutor . submit ( object Ġ: ĠRunnable Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġrun () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnext Schedule Delay Ġ= Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġupdate Network Map Cache () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( t : ĠThrowable ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . warn (" Error Ġencountered Ġwhile Ġupdating Ġnetwork Ġmap , Ġwill Ġretry Ġin Ġ$ default Retry Interval ", Ġt ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdefault Retry Interval ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠSchedule Ġthe Ġnext Ġupdate . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġexecutor . schedule ( this , Ġnext Schedule Delay . to Millis (), ĠTimeUnit . MILLISECONDS ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ}) Ġ// ĠThe Ġcheck Ġmay Ġbe Ġexpensive , Ġso Ġalways Ġrun Ġit Ġin Ġthe Ġbackground Ġeven Ġthe Ġfirst Ġtime . ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġupdate Network Map Cache (): ĠDuration Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( network Map Client Ġ== Ġnull ) Ġthrow ĠC ord a RuntimeException (" Network Ġmap Ġcache Ġcan Ġbe Ġupdated Ġonly Ġif Ġnetwork Ġmap / compatibility Ġzone ĠURL Ġis Ġspecified ") ĊĠĠĠĠĠĠĠ Ġval Ġ( global Network Map , Ġcache Timeout ) Ġ= Ġnetwork Map Client . get Network Map () ĊĠĠĠĠĠĠĠ Ġglobal Network Map . parameters Update ?. let Ġ{ Ġhandle Update Network Parameters ( network Map Client , Ġit ) Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġadditional Hashes Ġ= Ġextra Network Map Keys . flatMap Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnetwork Map Client . get Network Map ( it ). payload . node Info Hashes ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠFailure Ġto Ġretrieve Ġone Ġnetwork Ġmap Ġusing ĠUUID Ġshouldn 't Ġstop Ġthe Ġwhole Ġupdate . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . warn (" Error Ġencountered Ġwhen Ġdownloading Ġnetwork Ġmap Ġwith Ġuuid Ġ'$ it ', Ġskipping ...", Ġe ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġempty List < Secure Hash >() ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġall Hashes From Network Map Ġ= Ġ( global Network Map . node Info Hashes Ġ+ Ġadditional Hashes ). toSet () ĊĊĠĠĠĠĠĠĠ Ġif Ġ( current Parameters Hash Ġ!= Ġglobal Network Map . network Parameter Hash ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġexit On Parameters Mismatch ( global Network Map ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval ĠcurrentNode Hashes Ġ= Ġnetwork Map Cache . all Node Hashes ĊĊĠĠĠĠĠĠĠ Ġ// ĠRemove Ġnode Ġinfo Ġfrom Ġnetwork Ġmap . ĊĠĠĠĠĠĠĠ Ġ( currentNode Hashes Ġ- Ġall Hashes From Network Map Ġ- Ġfile Watcher . processed NodeInfo Hashes ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map NotNull Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( it Ġ!= Ġour NodeInfo Hash ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnetwork Map Cache . getNode By Hash ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}. forEach ( network Map Cache :: remove Node ) ĊĊĠĠĠĠĠĠĠ Ġ( all Hashes From Network Map Ġ- ĠcurrentNode Hashes ). map NotNull Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠDownload Ġnew Ġnode Ġinfo Ġfrom Ġnetwork Ġmap ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnetwork Map Client . getNode Info ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠFailure Ġto Ġretrieve Ġone Ġnode Ġinfo Ġshouldn 't Ġstop Ġthe Ġwhole Ġupdate , Ġlog Ġand Ġreturn Ġnull Ġinstead . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . warn (" Error Ġencountered Ġwhen Ġdownloading Ġnode Ġinfo Ġ'$ it ', Ġskipping ...", Ġe ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ}. forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠAdd Ġnew Ġnode Ġinfo Ġto Ġthe Ġnetwork Ġmap Ġcache , Ġthese Ġcould Ġbe Ġnew Ġnode Ġinfo Ġor Ġmodification Ġof Ġnode Ġinfo Ġfor Ġexisting Ġnodes . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnetwork Map Cache . add Node ( it ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġcache Timeout ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġexit On Parameters Mismatch ( network Map : ĠNetwork Map ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġupdates File Ġ= Ġbase Directory Ġ/ ĠNET WORK _ PARAMS _ UPDATE _ FILE _ NAME ĊĠĠĠĠĠĠĠ Ġval Ġaccepted Hash Ġ= Ġif Ġ( updates File . exists ()) Ġupdates File . read Object < Signed Network Parameters >(). raw . hash Ġelse Ġnull ĊĠĠĠĠĠĠĠ Ġval Ġexit Code Ġ= Ġif Ġ( accepted Hash Ġ== Ġnetwork Map . network Parameter Hash ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . info (" Flag Ġday Ġoccurred . ĠNetwork Ġmap Ġswitched Ġto Ġthe Ġnew Ġnetwork Ġparameters : Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"${ network Map . network Parameter Hash }. ĠNode Ġwill Ġshutdown Ġnow Ġand Ġneeds Ġto Ġbe Ġstarted Ġagain .") ĊĠĠĠĠĠĠĠĠĠĠĠĠ 0 ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠTODO ĠThis Ġneeds Ġspecial Ġhandling Ġ( node Ġomitted Ġupdate Ġprocess Ġor Ġdidn 't Ġaccept Ġnew Ġparameters ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . error ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ""" Node Ġis Ġusing Ġnetwork Ġparameters Ġwith Ġhash Ġ$ current Parameters Hash Ġbut Ġthe Ġnetwork Ġmap Ġis Ġadvertising Ġ${ network Map . network Parameter Hash }. Ċ To Ġresolve Ġthis Ġmismatch , Ġand Ġmove Ġto Ġthe Ġcurrent Ġparameters , Ġdelete Ġthe Ġ$ NETWORK _ PARAMS _ FILE _ NAME Ġfile Ġfrom Ġthe Ġnode 's Ġdirectory Ġand Ġrestart . Ċ The Ġnode Ġwill Ġshutdown Ġnow . """) ĊĠĠĠĠĠĠĠĠĠĠĠĠ 1 ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġexit Process ( exit Code ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġhandle Update Network Parameters ( network Map Client : ĠNetwork Map Client , Ġupdate : ĠParameters Update ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( update . new Parameters Hash Ġ== Ġnew Network Parameters ?. first ?. new Parameters Hash ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThis Ġupdate Ġwas Ġhandled Ġalready . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġnew Signed Net Params Ġ= Ġnetwork Map Client . get Network Parameters ( update . new Parameters Hash ) ĊĠĠĠĠĠĠĠ Ġval Ġnew Net Params Ġ= Ġnew Signed Net Params . verified Network Map Cert ( network Map Client . trusted Root ) ĊĠĠĠĠĠĠĠ Ġlogger . info (" Downloaded Ġnew Ġnetwork Ġparameters : Ġ$ new Net Params Ġfrom Ġthe Ġupdate : Ġ$ update ") ĊĠĠĠĠĠĠĠ Ġnew Network Parameters Ġ= ĠPair ( update , Ġnew Signed Net Params ) ĊĠĠĠĠĠĠĠ Ġval Ġupdate Info Ġ= ĠParameters Update Info ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġupdate . new Parameters Hash , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnew Net Params , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġupdate . description , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġupdate . update Deadline ) ĊĠĠĠĠĠĠĠ Ġparameters Updates Track . onNext ( update Info ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġaccept New Network Parameters ( parameters Hash : ĠSecure Hash , Ġsign : Ġ( Secure Hash ) Ġ-> ĠSigned Data < Secure Hash >) Ġ{ ĊĠĠĠĠĠĠĠ Ġnetwork Map Client Ġ?: Ġthrow ĠIllegalStateException (" Network Ġparameters Ġupdates Ġare Ġnot Ġsupported Ġwithout Ġcompatibility Ġzone Ġconfigured ") ĊĠĠĠĠĠĠĠ Ġ// ĠTODO ĠThis Ġscenario Ġwill Ġhappen Ġif Ġnode Ġwas Ġrestarted Ġand Ġdidn 't Ġdownload Ġparameters Ġyet , Ġbut Ġwe Ġaccepted Ġthem . ĊĠĠĠĠĠĠĠ Ġ// ĠAdd Ġpers isting Ġof Ġnewest Ġparameters Ġfrom Ġupdate . ĊĠĠĠĠĠĠĠ Ġval Ġ( update , Ġsigned New Net Params ) Ġ= Ġrequire NotNull ( new Network Parameters ) Ġ{ Ġ" Couldn 't Ġfind Ġparameters Ġupdate Ġfor Ġthe Ġhash : Ġ$ parameters Hash " Ġ} ĊĠĠĠĠĠĠĠ Ġ// ĠWe Ġshould Ġcheck Ġthat Ġwe Ġsign Ġthe Ġright Ġdata Ġstructure Ġhash . ĊĠĠĠĠĠĠĠ Ġval Ġnew Net Params Ġ= Ġsigned New Net Params . verified Network Map Cert ( network Map Client . trusted Root ) ĊĠĠĠĠĠĠĠ Ġval Ġnew Parameters Hash Ġ= Ġsigned New Net Params . raw . hash ĊĠĠĠĠĠĠĠ Ġif Ġ( parameters Hash Ġ== Ġnew Parameters Hash ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThe Ġlatest Ġparameters Ġhave Ġpriority . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsigned New Net Params . serialize () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. open () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. copy To ( base Directory Ġ/ ĠNET WORK _ PARAMS _ UPDATE _ FILE _ NAME , ĠStandard Copy Option . REPLACE _ EXIST ING ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnetwork Map Client . ack Network Parameters Update ( sign ( parameters Hash )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . info (" Accepted Ġnetwork Ġparameter Ġupdate Ġ$ update : Ġ$ new Net Params ") ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠOut dated Network Parameter Hash Exception ( parameters Hash , Ġnew Parameters Hash ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ