local_cluster.rs 229 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953
  1. #![allow(clippy::arithmetic_side_effects)]
  2. use {
  3. assert_matches::assert_matches,
  4. crossbeam_channel::{unbounded, Receiver},
  5. gag::BufferRedirect,
  6. itertools::Itertools,
  7. log::*,
  8. rand::seq::SliceRandom,
  9. serial_test::serial,
  10. solana_account::AccountSharedData,
  11. solana_accounts_db::{
  12. hardened_unpack::open_genesis_config, utils::create_accounts_run_and_snapshot_dirs,
  13. },
  14. solana_client_traits::AsyncClient,
  15. solana_clock::{
  16. self as clock, Slot, DEFAULT_SLOTS_PER_EPOCH, DEFAULT_TICKS_PER_SLOT, MAX_PROCESSING_AGE,
  17. },
  18. solana_cluster_type::ClusterType,
  19. solana_commitment_config::CommitmentConfig,
  20. solana_core::{
  21. consensus::{
  22. tower_storage::FileTowerStorage, Tower, SWITCH_FORK_THRESHOLD, VOTE_THRESHOLD_DEPTH,
  23. },
  24. optimistic_confirmation_verifier::OptimisticConfirmationVerifier,
  25. replay_stage::DUPLICATE_THRESHOLD,
  26. validator::{BlockVerificationMethod, ValidatorConfig},
  27. },
  28. solana_download_utils::download_snapshot_archive,
  29. solana_entry::entry::create_ticks,
  30. solana_epoch_schedule::{MAX_LEADER_SCHEDULE_EPOCH_OFFSET, MINIMUM_SLOTS_PER_EPOCH},
  31. solana_gossip::{crds_data::MAX_VOTES, gossip_service::discover_validators},
  32. solana_hard_forks::HardForks,
  33. solana_hash::Hash,
  34. solana_keypair::Keypair,
  35. solana_ledger::{
  36. ancestor_iterator::AncestorIterator,
  37. bank_forks_utils,
  38. blockstore::{entries_to_test_shreds, Blockstore},
  39. blockstore_processor::ProcessOptions,
  40. leader_schedule::FixedSchedule,
  41. shred::{ProcessShredsStats, ReedSolomonCache, Shred, Shredder},
  42. use_snapshot_archives_at_startup::UseSnapshotArchivesAtStartup,
  43. },
  44. solana_local_cluster::{
  45. cluster::{Cluster, ClusterValidatorInfo, QuicTpuClient},
  46. cluster_tests,
  47. integration_tests::{
  48. copy_blocks, create_custom_leader_schedule,
  49. create_custom_leader_schedule_with_random_keys, farf_dir, generate_account_paths,
  50. last_root_in_tower, last_vote_in_tower, ms_for_n_slots, open_blockstore,
  51. purge_slots_with_count, remove_tower, remove_tower_if_exists, restore_tower,
  52. run_cluster_partition, run_kill_partition_switch_threshold, save_tower,
  53. setup_snapshot_validator_config, test_faulty_node, wait_for_duplicate_proof,
  54. wait_for_last_vote_in_tower_to_land_in_ledger, SnapshotValidatorConfig,
  55. ValidatorTestConfig, DEFAULT_NODE_STAKE, RUST_LOG_FILTER,
  56. },
  57. local_cluster::{ClusterConfig, LocalCluster, DEFAULT_MINT_LAMPORTS},
  58. validator_configs::*,
  59. },
  60. solana_poh_config::PohConfig,
  61. solana_pubkey::Pubkey,
  62. solana_pubsub_client::pubsub_client::PubsubClient,
  63. solana_rpc_client::rpc_client::RpcClient,
  64. solana_rpc_client_api::{
  65. config::{
  66. RpcBlockSubscribeConfig, RpcBlockSubscribeFilter, RpcProgramAccountsConfig,
  67. RpcSignatureSubscribeConfig,
  68. },
  69. response::RpcSignatureResult,
  70. },
  71. solana_runtime::{
  72. commitment::VOTE_THRESHOLD_SIZE,
  73. snapshot_archive_info::SnapshotArchiveInfoGetter,
  74. snapshot_bank_utils,
  75. snapshot_config::SnapshotConfig,
  76. snapshot_package::SnapshotKind,
  77. snapshot_utils::{self, SnapshotInterval, BANK_SNAPSHOTS_DIR},
  78. },
  79. solana_signer::Signer,
  80. solana_stake_interface::{self as stake, state::NEW_WARMUP_COOLDOWN_RATE},
  81. solana_streamer::socket::SocketAddrSpace,
  82. solana_system_interface::program as system_program,
  83. solana_system_transaction as system_transaction,
  84. solana_turbine::broadcast_stage::{
  85. broadcast_duplicates_run::{BroadcastDuplicatesConfig, ClusterPartition},
  86. BroadcastStageType,
  87. },
  88. solana_vote::{vote_parser, vote_transaction},
  89. solana_vote_interface::state::TowerSync,
  90. solana_vote_program::vote_state::MAX_LOCKOUT_HISTORY,
  91. std::{
  92. collections::{BTreeSet, HashMap, HashSet},
  93. fs,
  94. io::Read,
  95. iter,
  96. num::NonZeroU64,
  97. path::Path,
  98. sync::{
  99. atomic::{AtomicBool, AtomicUsize, Ordering},
  100. Arc, Mutex,
  101. },
  102. thread::{sleep, Builder, JoinHandle},
  103. time::{Duration, Instant},
  104. },
  105. strum::{EnumCount, IntoEnumIterator},
  106. };
  107. #[test]
  108. #[serial]
  109. fn test_local_cluster_start_and_exit() {
  110. solana_logger::setup();
  111. let num_nodes = 1;
  112. let cluster = LocalCluster::new_with_equal_stakes(
  113. num_nodes,
  114. DEFAULT_MINT_LAMPORTS,
  115. DEFAULT_NODE_STAKE,
  116. SocketAddrSpace::Unspecified,
  117. );
  118. assert_eq!(cluster.validators.len(), num_nodes);
  119. }
  120. #[test]
  121. #[serial]
  122. fn test_local_cluster_start_and_exit_with_config() {
  123. solana_logger::setup();
  124. const NUM_NODES: usize = 1;
  125. let mut config = ClusterConfig {
  126. validator_configs: make_identical_validator_configs(
  127. &ValidatorConfig::default_for_test(),
  128. NUM_NODES,
  129. ),
  130. node_stakes: vec![DEFAULT_NODE_STAKE; NUM_NODES],
  131. ticks_per_slot: 8,
  132. slots_per_epoch: MINIMUM_SLOTS_PER_EPOCH,
  133. stakers_slot_offset: MINIMUM_SLOTS_PER_EPOCH,
  134. ..ClusterConfig::default()
  135. };
  136. let cluster = LocalCluster::new(&mut config, SocketAddrSpace::Unspecified);
  137. assert_eq!(cluster.validators.len(), NUM_NODES);
  138. }
  139. #[test]
  140. #[serial]
  141. fn test_spend_and_verify_all_nodes_1() {
  142. solana_logger::setup_with_default(RUST_LOG_FILTER);
  143. error!("test_spend_and_verify_all_nodes_1");
  144. let num_nodes = 1;
  145. let local = LocalCluster::new_with_equal_stakes(
  146. num_nodes,
  147. DEFAULT_MINT_LAMPORTS,
  148. DEFAULT_NODE_STAKE,
  149. SocketAddrSpace::Unspecified,
  150. );
  151. cluster_tests::spend_and_verify_all_nodes(
  152. &local.entry_point_info,
  153. &local.funding_keypair,
  154. num_nodes,
  155. HashSet::new(),
  156. SocketAddrSpace::Unspecified,
  157. &local.connection_cache,
  158. );
  159. }
  160. #[test]
  161. #[serial]
  162. fn test_spend_and_verify_all_nodes_2() {
  163. solana_logger::setup_with_default(RUST_LOG_FILTER);
  164. error!("test_spend_and_verify_all_nodes_2");
  165. let num_nodes = 2;
  166. let local = LocalCluster::new_with_equal_stakes(
  167. num_nodes,
  168. DEFAULT_MINT_LAMPORTS,
  169. DEFAULT_NODE_STAKE,
  170. SocketAddrSpace::Unspecified,
  171. );
  172. cluster_tests::spend_and_verify_all_nodes(
  173. &local.entry_point_info,
  174. &local.funding_keypair,
  175. num_nodes,
  176. HashSet::new(),
  177. SocketAddrSpace::Unspecified,
  178. &local.connection_cache,
  179. );
  180. }
  181. #[test]
  182. #[serial]
  183. fn test_spend_and_verify_all_nodes_3() {
  184. solana_logger::setup_with_default(RUST_LOG_FILTER);
  185. error!("test_spend_and_verify_all_nodes_3");
  186. let num_nodes = 3;
  187. let local = LocalCluster::new_with_equal_stakes(
  188. num_nodes,
  189. DEFAULT_MINT_LAMPORTS,
  190. DEFAULT_NODE_STAKE,
  191. SocketAddrSpace::Unspecified,
  192. );
  193. cluster_tests::spend_and_verify_all_nodes(
  194. &local.entry_point_info,
  195. &local.funding_keypair,
  196. num_nodes,
  197. HashSet::new(),
  198. SocketAddrSpace::Unspecified,
  199. &local.connection_cache,
  200. );
  201. }
  202. #[test]
  203. #[serial]
  204. fn test_local_cluster_signature_subscribe() {
  205. solana_logger::setup_with_default(RUST_LOG_FILTER);
  206. let num_nodes = 2;
  207. let cluster = LocalCluster::new_with_equal_stakes(
  208. num_nodes,
  209. DEFAULT_MINT_LAMPORTS,
  210. DEFAULT_NODE_STAKE,
  211. SocketAddrSpace::Unspecified,
  212. );
  213. let nodes = cluster.get_node_pubkeys();
  214. // Get non leader
  215. let non_bootstrap_id = nodes
  216. .into_iter()
  217. .find(|id| id != cluster.entry_point_info.pubkey())
  218. .unwrap();
  219. let non_bootstrap_info = cluster.get_contact_info(&non_bootstrap_id).unwrap();
  220. let tx_client = cluster
  221. .build_validator_tpu_quic_client(cluster.entry_point_info.pubkey())
  222. .unwrap();
  223. let (blockhash, _) = tx_client
  224. .rpc_client()
  225. .get_latest_blockhash_with_commitment(CommitmentConfig::processed())
  226. .unwrap();
  227. let mut transaction = system_transaction::transfer(
  228. &cluster.funding_keypair,
  229. &solana_pubkey::new_rand(),
  230. 10,
  231. blockhash,
  232. );
  233. let (mut sig_subscribe_client, receiver) = PubsubClient::signature_subscribe(
  234. &format!("ws://{}", non_bootstrap_info.rpc_pubsub().unwrap()),
  235. &transaction.signatures[0],
  236. Some(RpcSignatureSubscribeConfig {
  237. commitment: Some(CommitmentConfig::processed()),
  238. enable_received_notification: Some(true),
  239. }),
  240. )
  241. .unwrap();
  242. LocalCluster::send_transaction_with_retries(
  243. &tx_client,
  244. &[&cluster.funding_keypair],
  245. &mut transaction,
  246. 5,
  247. )
  248. .unwrap();
  249. let mut got_received_notification = false;
  250. loop {
  251. let responses: Vec<_> = receiver.try_iter().collect();
  252. let mut should_break = false;
  253. for response in responses {
  254. match response.value {
  255. RpcSignatureResult::ProcessedSignature(_) => {
  256. should_break = true;
  257. break;
  258. }
  259. RpcSignatureResult::ReceivedSignature(_) => {
  260. got_received_notification = true;
  261. }
  262. }
  263. }
  264. if should_break {
  265. break;
  266. }
  267. sleep(Duration::from_millis(100));
  268. }
  269. // If we don't drop the cluster, the blocking web socket service
  270. // won't return, and the `sig_subscribe_client` won't shut down
  271. drop(cluster);
  272. sig_subscribe_client.shutdown().unwrap();
  273. assert!(got_received_notification);
  274. }
  275. #[test]
  276. #[serial]
  277. fn test_two_unbalanced_stakes() {
  278. solana_logger::setup_with_default(RUST_LOG_FILTER);
  279. error!("test_two_unbalanced_stakes");
  280. let validator_config = ValidatorConfig::default_for_test();
  281. let num_ticks_per_second = 100;
  282. let num_ticks_per_slot = 10;
  283. let num_slots_per_epoch = MINIMUM_SLOTS_PER_EPOCH;
  284. let mut cluster = LocalCluster::new(
  285. &mut ClusterConfig {
  286. node_stakes: vec![DEFAULT_NODE_STAKE * 100, DEFAULT_NODE_STAKE],
  287. mint_lamports: DEFAULT_MINT_LAMPORTS + DEFAULT_NODE_STAKE * 100,
  288. validator_configs: make_identical_validator_configs(&validator_config, 2),
  289. ticks_per_slot: num_ticks_per_slot,
  290. slots_per_epoch: num_slots_per_epoch,
  291. stakers_slot_offset: num_slots_per_epoch,
  292. poh_config: PohConfig::new_sleep(Duration::from_millis(1000 / num_ticks_per_second)),
  293. ..ClusterConfig::default()
  294. },
  295. SocketAddrSpace::Unspecified,
  296. );
  297. cluster_tests::sleep_n_epochs(
  298. 10.0,
  299. &cluster.genesis_config.poh_config,
  300. num_ticks_per_slot,
  301. num_slots_per_epoch,
  302. );
  303. cluster.close_preserve_ledgers();
  304. let leader_pubkey = *cluster.entry_point_info.pubkey();
  305. let leader_ledger = cluster.validators[&leader_pubkey].info.ledger_path.clone();
  306. cluster_tests::verify_ledger_ticks(&leader_ledger, num_ticks_per_slot as usize);
  307. }
  308. #[test]
  309. #[serial]
  310. fn test_forwarding() {
  311. solana_logger::setup_with_default(RUST_LOG_FILTER);
  312. // Set up a cluster where one node is never the leader, so all txs sent to this node
  313. // will be have to be forwarded in order to be confirmed
  314. let mut config = ClusterConfig {
  315. node_stakes: vec![DEFAULT_NODE_STAKE * 100, DEFAULT_NODE_STAKE],
  316. mint_lamports: DEFAULT_MINT_LAMPORTS + DEFAULT_NODE_STAKE * 100,
  317. validator_configs: make_identical_validator_configs(
  318. &ValidatorConfig::default_for_test(),
  319. 2,
  320. ),
  321. ..ClusterConfig::default()
  322. };
  323. let cluster = LocalCluster::new(&mut config, SocketAddrSpace::Unspecified);
  324. let cluster_nodes = discover_validators(
  325. &cluster.entry_point_info.gossip().unwrap(),
  326. 2,
  327. cluster.entry_point_info.shred_version(),
  328. SocketAddrSpace::Unspecified,
  329. )
  330. .unwrap();
  331. assert!(cluster_nodes.len() >= 2);
  332. let leader_pubkey = *cluster.entry_point_info.pubkey();
  333. let validator_info = cluster_nodes
  334. .iter()
  335. .find(|c| c.pubkey() != &leader_pubkey)
  336. .unwrap();
  337. // Confirm that transactions were forwarded to and processed by the leader.
  338. cluster_tests::send_many_transactions(
  339. validator_info,
  340. &cluster.funding_keypair,
  341. &cluster.connection_cache,
  342. 10,
  343. 20,
  344. );
  345. }
  346. #[test]
  347. #[serial]
  348. fn test_restart_node() {
  349. solana_logger::setup_with_default(RUST_LOG_FILTER);
  350. error!("test_restart_node");
  351. let slots_per_epoch = MINIMUM_SLOTS_PER_EPOCH * 2;
  352. let ticks_per_slot = 16;
  353. let validator_config = ValidatorConfig::default_for_test();
  354. let mut cluster = LocalCluster::new(
  355. &mut ClusterConfig {
  356. node_stakes: vec![DEFAULT_NODE_STAKE],
  357. validator_configs: vec![safe_clone_config(&validator_config)],
  358. ticks_per_slot,
  359. slots_per_epoch,
  360. stakers_slot_offset: slots_per_epoch,
  361. skip_warmup_slots: true,
  362. ..ClusterConfig::default()
  363. },
  364. SocketAddrSpace::Unspecified,
  365. );
  366. let nodes = cluster.get_node_pubkeys();
  367. cluster_tests::sleep_n_epochs(
  368. 1.0,
  369. &cluster.genesis_config.poh_config,
  370. clock::DEFAULT_TICKS_PER_SLOT,
  371. slots_per_epoch,
  372. );
  373. cluster.exit_restart_node(&nodes[0], validator_config, SocketAddrSpace::Unspecified);
  374. cluster_tests::sleep_n_epochs(
  375. 0.5,
  376. &cluster.genesis_config.poh_config,
  377. clock::DEFAULT_TICKS_PER_SLOT,
  378. slots_per_epoch,
  379. );
  380. cluster_tests::send_many_transactions(
  381. &cluster.entry_point_info,
  382. &cluster.funding_keypair,
  383. &cluster.connection_cache,
  384. 10,
  385. 1,
  386. );
  387. }
  388. #[test]
  389. #[serial]
  390. fn test_mainnet_beta_cluster_type() {
  391. solana_logger::setup_with_default(RUST_LOG_FILTER);
  392. let mut config = ClusterConfig {
  393. cluster_type: ClusterType::MainnetBeta,
  394. node_stakes: vec![DEFAULT_NODE_STAKE],
  395. validator_configs: make_identical_validator_configs(
  396. &ValidatorConfig::default_for_test(),
  397. 1,
  398. ),
  399. ..ClusterConfig::default()
  400. };
  401. let cluster = LocalCluster::new(&mut config, SocketAddrSpace::Unspecified);
  402. let cluster_nodes = discover_validators(
  403. &cluster.entry_point_info.gossip().unwrap(),
  404. 1,
  405. cluster.entry_point_info.shred_version(),
  406. SocketAddrSpace::Unspecified,
  407. )
  408. .unwrap();
  409. assert_eq!(cluster_nodes.len(), 1);
  410. let client = cluster
  411. .build_validator_tpu_quic_client(cluster.entry_point_info.pubkey())
  412. .unwrap();
  413. // Programs that are available at epoch 0
  414. for program_id in [
  415. &solana_sdk_ids::system_program::id(),
  416. &stake::program::id(),
  417. &solana_vote_program::id(),
  418. &solana_sdk_ids::bpf_loader_deprecated::id(),
  419. &solana_sdk_ids::bpf_loader::id(),
  420. &solana_sdk_ids::bpf_loader_upgradeable::id(),
  421. ]
  422. .iter()
  423. {
  424. assert_matches!(
  425. (
  426. program_id,
  427. client
  428. .rpc_client()
  429. .get_account_with_commitment(program_id, CommitmentConfig::processed())
  430. .unwrap()
  431. .value
  432. ),
  433. (_program_id, Some(_))
  434. );
  435. }
  436. // Programs that are not available at epoch 0
  437. for program_id in [].iter() {
  438. assert_eq!(
  439. (
  440. program_id,
  441. client
  442. .rpc_client()
  443. .get_account_with_commitment(program_id, CommitmentConfig::processed())
  444. .unwrap()
  445. .value
  446. ),
  447. (program_id, None)
  448. );
  449. }
  450. }
  451. #[test]
  452. #[serial]
  453. fn test_snapshot_download() {
  454. solana_logger::setup_with_default(RUST_LOG_FILTER);
  455. // First set up the cluster with 1 node
  456. let snapshot_interval_slots = NonZeroU64::new(50).unwrap();
  457. let num_account_paths = 3;
  458. let leader_snapshot_test_config =
  459. setup_snapshot_validator_config(snapshot_interval_slots, num_account_paths);
  460. let validator_snapshot_test_config =
  461. setup_snapshot_validator_config(snapshot_interval_slots, num_account_paths);
  462. let stake = DEFAULT_NODE_STAKE;
  463. let mut config = ClusterConfig {
  464. node_stakes: vec![stake],
  465. validator_configs: make_identical_validator_configs(
  466. &leader_snapshot_test_config.validator_config,
  467. 1,
  468. ),
  469. ..ClusterConfig::default()
  470. };
  471. let mut cluster = LocalCluster::new(&mut config, SocketAddrSpace::Unspecified);
  472. let full_snapshot_archives_dir = &leader_snapshot_test_config
  473. .validator_config
  474. .snapshot_config
  475. .full_snapshot_archives_dir;
  476. trace!("Waiting for snapshot");
  477. let full_snapshot_archive_info = cluster.wait_for_next_full_snapshot(
  478. full_snapshot_archives_dir,
  479. Some(Duration::from_secs(5 * 60)),
  480. );
  481. trace!("found: {}", full_snapshot_archive_info.path().display());
  482. // Download the snapshot, then boot a validator from it.
  483. download_snapshot_archive(
  484. &cluster.entry_point_info.rpc().unwrap(),
  485. &validator_snapshot_test_config
  486. .validator_config
  487. .snapshot_config
  488. .full_snapshot_archives_dir,
  489. &validator_snapshot_test_config
  490. .validator_config
  491. .snapshot_config
  492. .incremental_snapshot_archives_dir,
  493. (
  494. full_snapshot_archive_info.slot(),
  495. *full_snapshot_archive_info.hash(),
  496. ),
  497. SnapshotKind::FullSnapshot,
  498. validator_snapshot_test_config
  499. .validator_config
  500. .snapshot_config
  501. .maximum_full_snapshot_archives_to_retain,
  502. validator_snapshot_test_config
  503. .validator_config
  504. .snapshot_config
  505. .maximum_incremental_snapshot_archives_to_retain,
  506. false,
  507. &mut None,
  508. )
  509. .unwrap();
  510. cluster.add_validator(
  511. &validator_snapshot_test_config.validator_config,
  512. stake,
  513. Arc::new(Keypair::new()),
  514. None,
  515. SocketAddrSpace::Unspecified,
  516. );
  517. }
  518. #[test]
  519. #[serial]
  520. fn test_incremental_snapshot_download() {
  521. solana_logger::setup_with_default(RUST_LOG_FILTER);
  522. // First set up the cluster with 1 node
  523. let incremental_snapshot_interval = 9;
  524. let full_snapshot_interval = incremental_snapshot_interval * 3;
  525. let num_account_paths = 3;
  526. let leader_snapshot_test_config = SnapshotValidatorConfig::new(
  527. SnapshotInterval::Slots(NonZeroU64::new(full_snapshot_interval).unwrap()),
  528. SnapshotInterval::Slots(NonZeroU64::new(incremental_snapshot_interval).unwrap()),
  529. num_account_paths,
  530. );
  531. let validator_snapshot_test_config = SnapshotValidatorConfig::new(
  532. SnapshotInterval::Slots(NonZeroU64::new(full_snapshot_interval).unwrap()),
  533. SnapshotInterval::Slots(NonZeroU64::new(incremental_snapshot_interval).unwrap()),
  534. num_account_paths,
  535. );
  536. let stake = DEFAULT_NODE_STAKE;
  537. let mut config = ClusterConfig {
  538. node_stakes: vec![stake],
  539. validator_configs: make_identical_validator_configs(
  540. &leader_snapshot_test_config.validator_config,
  541. 1,
  542. ),
  543. ..ClusterConfig::default()
  544. };
  545. let mut cluster = LocalCluster::new(&mut config, SocketAddrSpace::Unspecified);
  546. let full_snapshot_archives_dir = &leader_snapshot_test_config
  547. .validator_config
  548. .snapshot_config
  549. .full_snapshot_archives_dir;
  550. let incremental_snapshot_archives_dir = &leader_snapshot_test_config
  551. .validator_config
  552. .snapshot_config
  553. .incremental_snapshot_archives_dir;
  554. debug!(
  555. "snapshot config:\n\tfull snapshot interval: {full_snapshot_interval}\n\tincremental \
  556. snapshot interval: {incremental_snapshot_interval}",
  557. );
  558. debug!(
  559. "leader config:\n\tbank snapshots dir: {}\n\tfull snapshot archives dir: \
  560. {}\n\tincremental snapshot archives dir: {}",
  561. leader_snapshot_test_config
  562. .bank_snapshots_dir
  563. .path()
  564. .display(),
  565. leader_snapshot_test_config
  566. .full_snapshot_archives_dir
  567. .path()
  568. .display(),
  569. leader_snapshot_test_config
  570. .incremental_snapshot_archives_dir
  571. .path()
  572. .display(),
  573. );
  574. debug!(
  575. "validator config:\n\tbank snapshots dir: {}\n\tfull snapshot archives dir: \
  576. {}\n\tincremental snapshot archives dir: {}",
  577. validator_snapshot_test_config
  578. .bank_snapshots_dir
  579. .path()
  580. .display(),
  581. validator_snapshot_test_config
  582. .full_snapshot_archives_dir
  583. .path()
  584. .display(),
  585. validator_snapshot_test_config
  586. .incremental_snapshot_archives_dir
  587. .path()
  588. .display(),
  589. );
  590. trace!("Waiting for snapshots");
  591. let (incremental_snapshot_archive_info, full_snapshot_archive_info) = cluster
  592. .wait_for_next_incremental_snapshot(
  593. full_snapshot_archives_dir,
  594. incremental_snapshot_archives_dir,
  595. Some(Duration::from_secs(5 * 60)),
  596. );
  597. trace!(
  598. "found: {} and {}",
  599. full_snapshot_archive_info.path().display(),
  600. incremental_snapshot_archive_info.path().display()
  601. );
  602. // Download the snapshots, then boot a validator from them.
  603. download_snapshot_archive(
  604. &cluster.entry_point_info.rpc().unwrap(),
  605. &validator_snapshot_test_config
  606. .validator_config
  607. .snapshot_config
  608. .full_snapshot_archives_dir,
  609. &validator_snapshot_test_config
  610. .validator_config
  611. .snapshot_config
  612. .incremental_snapshot_archives_dir,
  613. (
  614. full_snapshot_archive_info.slot(),
  615. *full_snapshot_archive_info.hash(),
  616. ),
  617. SnapshotKind::FullSnapshot,
  618. validator_snapshot_test_config
  619. .validator_config
  620. .snapshot_config
  621. .maximum_full_snapshot_archives_to_retain,
  622. validator_snapshot_test_config
  623. .validator_config
  624. .snapshot_config
  625. .maximum_incremental_snapshot_archives_to_retain,
  626. false,
  627. &mut None,
  628. )
  629. .unwrap();
  630. download_snapshot_archive(
  631. &cluster.entry_point_info.rpc().unwrap(),
  632. &validator_snapshot_test_config
  633. .validator_config
  634. .snapshot_config
  635. .full_snapshot_archives_dir,
  636. &validator_snapshot_test_config
  637. .validator_config
  638. .snapshot_config
  639. .incremental_snapshot_archives_dir,
  640. (
  641. incremental_snapshot_archive_info.slot(),
  642. *incremental_snapshot_archive_info.hash(),
  643. ),
  644. SnapshotKind::IncrementalSnapshot(incremental_snapshot_archive_info.base_slot()),
  645. validator_snapshot_test_config
  646. .validator_config
  647. .snapshot_config
  648. .maximum_full_snapshot_archives_to_retain,
  649. validator_snapshot_test_config
  650. .validator_config
  651. .snapshot_config
  652. .maximum_incremental_snapshot_archives_to_retain,
  653. false,
  654. &mut None,
  655. )
  656. .unwrap();
  657. cluster.add_validator(
  658. &validator_snapshot_test_config.validator_config,
  659. stake,
  660. Arc::new(Keypair::new()),
  661. None,
  662. SocketAddrSpace::Unspecified,
  663. );
  664. }
  665. /// Test the scenario where a node starts up from a snapshot and its blockstore has enough new
  666. /// roots that cross the full snapshot interval. In this scenario, the node needs to take a full
  667. /// snapshot while processing the blockstore so that once the background services start up, there
  668. /// is the correct full snapshot available to take subsequent incremental snapshots.
  669. ///
  670. /// For this test...
  671. /// - Start a leader node and run it long enough to take a full and incremental snapshot
  672. /// - Download those snapshots to a validator node
  673. /// - Copy the validator snapshots to a back up directory
  674. /// - Start up the validator node
  675. /// - Wait for the validator node to see enough root slots to cross the full snapshot interval
  676. /// - Delete the snapshots on the validator node and restore the ones from the backup
  677. /// - Restart the validator node to trigger the scenario we're trying to test
  678. /// - Wait for the validator node to generate a new incremental snapshot
  679. /// - Copy the new incremental snapshot (and its associated full snapshot) to another new validator
  680. /// - Start up this new validator to ensure the snapshots from ^^^ are good
  681. #[test]
  682. #[serial]
  683. fn test_incremental_snapshot_download_with_crossing_full_snapshot_interval_at_startup() {
  684. solana_logger::setup_with_default(RUST_LOG_FILTER);
  685. // If these intervals change, also make sure to change the loop timers accordingly.
  686. let incremental_snapshot_interval = 9;
  687. let full_snapshot_interval = incremental_snapshot_interval * 5;
  688. let num_account_paths = 3;
  689. let leader_snapshot_test_config = SnapshotValidatorConfig::new(
  690. SnapshotInterval::Slots(NonZeroU64::new(full_snapshot_interval).unwrap()),
  691. SnapshotInterval::Slots(NonZeroU64::new(incremental_snapshot_interval).unwrap()),
  692. num_account_paths,
  693. );
  694. let mut validator_snapshot_test_config = SnapshotValidatorConfig::new(
  695. SnapshotInterval::Slots(NonZeroU64::new(full_snapshot_interval).unwrap()),
  696. SnapshotInterval::Slots(NonZeroU64::new(incremental_snapshot_interval).unwrap()),
  697. num_account_paths,
  698. );
  699. // The test has asserts that require the validator always boots from snapshot archives
  700. validator_snapshot_test_config
  701. .validator_config
  702. .use_snapshot_archives_at_startup = UseSnapshotArchivesAtStartup::Always;
  703. let stake = DEFAULT_NODE_STAKE;
  704. let mut config = ClusterConfig {
  705. node_stakes: vec![stake],
  706. validator_configs: make_identical_validator_configs(
  707. &leader_snapshot_test_config.validator_config,
  708. 1,
  709. ),
  710. ..ClusterConfig::default()
  711. };
  712. let mut cluster = LocalCluster::new(&mut config, SocketAddrSpace::Unspecified);
  713. info!(
  714. "snapshot config:\n\tfull snapshot interval: {full_snapshot_interval:?}\n\tincremental \
  715. snapshot interval: {incremental_snapshot_interval:?}",
  716. );
  717. debug!(
  718. "leader config:\n\tbank snapshots dir: {}\n\tfull snapshot archives dir: \
  719. {}\n\tincremental snapshot archives dir: {}",
  720. leader_snapshot_test_config
  721. .bank_snapshots_dir
  722. .path()
  723. .display(),
  724. leader_snapshot_test_config
  725. .full_snapshot_archives_dir
  726. .path()
  727. .display(),
  728. leader_snapshot_test_config
  729. .incremental_snapshot_archives_dir
  730. .path()
  731. .display(),
  732. );
  733. debug!(
  734. "validator config:\n\tbank snapshots dir: {}\n\tfull snapshot archives dir: \
  735. {}\n\tincremental snapshot archives dir: {}",
  736. validator_snapshot_test_config
  737. .bank_snapshots_dir
  738. .path()
  739. .display(),
  740. validator_snapshot_test_config
  741. .full_snapshot_archives_dir
  742. .path()
  743. .display(),
  744. validator_snapshot_test_config
  745. .incremental_snapshot_archives_dir
  746. .path()
  747. .display(),
  748. );
  749. info!("Waiting for leader to create the next incremental snapshot...");
  750. let (incremental_snapshot_archive, full_snapshot_archive) =
  751. LocalCluster::wait_for_next_incremental_snapshot(
  752. &cluster,
  753. leader_snapshot_test_config
  754. .full_snapshot_archives_dir
  755. .path(),
  756. leader_snapshot_test_config
  757. .incremental_snapshot_archives_dir
  758. .path(),
  759. Some(Duration::from_secs(5 * 60)),
  760. );
  761. info!(
  762. "Found snapshots:\n\tfull snapshot: {}\n\tincremental snapshot: {}",
  763. full_snapshot_archive.path().display(),
  764. incremental_snapshot_archive.path().display()
  765. );
  766. assert_eq!(
  767. full_snapshot_archive.slot(),
  768. incremental_snapshot_archive.base_slot()
  769. );
  770. info!("Waiting for leader to create snapshots... DONE");
  771. // Download the snapshots, then boot a validator from them.
  772. info!("Downloading full snapshot to validator...");
  773. download_snapshot_archive(
  774. &cluster.entry_point_info.rpc().unwrap(),
  775. validator_snapshot_test_config
  776. .full_snapshot_archives_dir
  777. .path(),
  778. validator_snapshot_test_config
  779. .incremental_snapshot_archives_dir
  780. .path(),
  781. (full_snapshot_archive.slot(), *full_snapshot_archive.hash()),
  782. SnapshotKind::FullSnapshot,
  783. validator_snapshot_test_config
  784. .validator_config
  785. .snapshot_config
  786. .maximum_full_snapshot_archives_to_retain,
  787. validator_snapshot_test_config
  788. .validator_config
  789. .snapshot_config
  790. .maximum_incremental_snapshot_archives_to_retain,
  791. false,
  792. &mut None,
  793. )
  794. .unwrap();
  795. let downloaded_full_snapshot_archive = snapshot_utils::get_highest_full_snapshot_archive_info(
  796. validator_snapshot_test_config
  797. .full_snapshot_archives_dir
  798. .path(),
  799. )
  800. .unwrap();
  801. info!(
  802. "Downloaded full snapshot, slot: {}",
  803. downloaded_full_snapshot_archive.slot()
  804. );
  805. info!("Downloading incremental snapshot to validator...");
  806. download_snapshot_archive(
  807. &cluster.entry_point_info.rpc().unwrap(),
  808. validator_snapshot_test_config
  809. .full_snapshot_archives_dir
  810. .path(),
  811. validator_snapshot_test_config
  812. .incremental_snapshot_archives_dir
  813. .path(),
  814. (
  815. incremental_snapshot_archive.slot(),
  816. *incremental_snapshot_archive.hash(),
  817. ),
  818. SnapshotKind::IncrementalSnapshot(incremental_snapshot_archive.base_slot()),
  819. validator_snapshot_test_config
  820. .validator_config
  821. .snapshot_config
  822. .maximum_full_snapshot_archives_to_retain,
  823. validator_snapshot_test_config
  824. .validator_config
  825. .snapshot_config
  826. .maximum_incremental_snapshot_archives_to_retain,
  827. false,
  828. &mut None,
  829. )
  830. .unwrap();
  831. let downloaded_incremental_snapshot_archive =
  832. snapshot_utils::get_highest_incremental_snapshot_archive_info(
  833. validator_snapshot_test_config
  834. .incremental_snapshot_archives_dir
  835. .path(),
  836. full_snapshot_archive.slot(),
  837. )
  838. .unwrap();
  839. info!(
  840. "Downloaded incremental snapshot, slot: {}, base slot: {}",
  841. downloaded_incremental_snapshot_archive.slot(),
  842. downloaded_incremental_snapshot_archive.base_slot(),
  843. );
  844. assert_eq!(
  845. downloaded_full_snapshot_archive.slot(),
  846. downloaded_incremental_snapshot_archive.base_slot()
  847. );
  848. // closure to copy files in a directory to another directory
  849. let copy_files = |from: &Path, to: &Path| {
  850. trace!(
  851. "copying files from dir {}, to dir {}",
  852. from.display(),
  853. to.display()
  854. );
  855. for entry in fs::read_dir(from).unwrap() {
  856. let entry = entry.unwrap();
  857. if entry.file_type().unwrap().is_dir() {
  858. continue;
  859. }
  860. let from_file_path = entry.path();
  861. let to_file_path = to.join(from_file_path.file_name().unwrap());
  862. trace!(
  863. "\t\tcopying file from {} to {}...",
  864. from_file_path.display(),
  865. to_file_path.display()
  866. );
  867. fs::copy(from_file_path, to_file_path).unwrap();
  868. }
  869. };
  870. // closure to delete files in a directory
  871. let delete_files = |dir: &Path| {
  872. trace!("deleting files in dir {}", dir.display());
  873. for entry in fs::read_dir(dir).unwrap() {
  874. let entry = entry.unwrap();
  875. if entry.file_type().unwrap().is_dir() {
  876. continue;
  877. }
  878. let file_path = entry.path();
  879. trace!("\t\tdeleting file {}...", file_path.display());
  880. fs::remove_file(file_path).unwrap();
  881. }
  882. };
  883. let copy_files_with_remote = |from: &Path, to: &Path| {
  884. copy_files(from, to);
  885. let remote_from = snapshot_utils::build_snapshot_archives_remote_dir(from);
  886. let remote_to = snapshot_utils::build_snapshot_archives_remote_dir(to);
  887. let _ = fs::create_dir_all(&remote_from);
  888. let _ = fs::create_dir_all(&remote_to);
  889. copy_files(&remote_from, &remote_to);
  890. };
  891. let delete_files_with_remote = |from: &Path| {
  892. delete_files(from);
  893. let remote_dir = snapshot_utils::build_snapshot_archives_remote_dir(from);
  894. let _ = fs::create_dir_all(&remote_dir);
  895. delete_files(&remote_dir);
  896. };
  897. // After downloading the snapshots, copy them over to a backup directory. Later we'll need to
  898. // restart the node and guarantee that the only snapshots present are these initial ones. So,
  899. // the easiest way to do that is create a backup now, delete the ones on the node before
  900. // restart, then copy the backup ones over again.
  901. let backup_validator_full_snapshot_archives_dir = tempfile::tempdir_in(farf_dir()).unwrap();
  902. trace!(
  903. "Backing up validator full snapshots to dir: {}...",
  904. backup_validator_full_snapshot_archives_dir.path().display()
  905. );
  906. copy_files_with_remote(
  907. validator_snapshot_test_config
  908. .full_snapshot_archives_dir
  909. .path(),
  910. backup_validator_full_snapshot_archives_dir.path(),
  911. );
  912. let backup_validator_incremental_snapshot_archives_dir =
  913. tempfile::tempdir_in(farf_dir()).unwrap();
  914. trace!(
  915. "Backing up validator incremental snapshots to dir: {}...",
  916. backup_validator_incremental_snapshot_archives_dir
  917. .path()
  918. .display()
  919. );
  920. copy_files_with_remote(
  921. validator_snapshot_test_config
  922. .incremental_snapshot_archives_dir
  923. .path(),
  924. backup_validator_incremental_snapshot_archives_dir.path(),
  925. );
  926. info!("Starting the validator...");
  927. let validator_identity = Arc::new(Keypair::new());
  928. cluster.add_validator(
  929. &validator_snapshot_test_config.validator_config,
  930. stake,
  931. validator_identity.clone(),
  932. None,
  933. SocketAddrSpace::Unspecified,
  934. );
  935. info!("Starting the validator... DONE");
  936. // To ensure that a snapshot will be taken during startup, the blockstore needs to have roots
  937. // that cross a full snapshot interval.
  938. let starting_slot = incremental_snapshot_archive.slot();
  939. let next_full_snapshot_slot = starting_slot + full_snapshot_interval;
  940. info!(
  941. "Waiting for the validator to see enough slots to cross a full snapshot interval \
  942. ({next_full_snapshot_slot})..."
  943. );
  944. let timer = Instant::now();
  945. loop {
  946. let validator_current_slot = cluster
  947. .build_validator_tpu_quic_client(&validator_identity.pubkey())
  948. .unwrap()
  949. .rpc_client()
  950. .get_slot_with_commitment(CommitmentConfig::finalized())
  951. .unwrap();
  952. trace!("validator current slot: {validator_current_slot}");
  953. if validator_current_slot > next_full_snapshot_slot {
  954. break;
  955. }
  956. assert!(
  957. timer.elapsed() < Duration::from_secs(30),
  958. "It should not take longer than 30 seconds to cross the next full snapshot interval."
  959. );
  960. std::thread::yield_now();
  961. }
  962. info!(
  963. "Waited {:?} for the validator to see enough slots to cross a full snapshot interval... \
  964. DONE",
  965. timer.elapsed()
  966. );
  967. // Get the highest full snapshot archive info for the validator, now that it has crossed the
  968. // next full snapshot interval. We are going to use this to look up the same snapshot on the
  969. // leader, which we'll then use to compare to the full snapshot the validator will create
  970. // during startup. This ensures the snapshot creation process during startup is correct.
  971. //
  972. // Putting this all in its own block so its clear we're only intended to keep the leader's info
  973. let leader_full_snapshot_archive_for_comparison = {
  974. let validator_full_snapshot = snapshot_utils::get_highest_full_snapshot_archive_info(
  975. validator_snapshot_test_config
  976. .full_snapshot_archives_dir
  977. .path(),
  978. )
  979. .unwrap();
  980. // Now get the same full snapshot on the LEADER that we just got from the validator
  981. let mut leader_full_snapshots = snapshot_utils::get_full_snapshot_archives(
  982. leader_snapshot_test_config
  983. .full_snapshot_archives_dir
  984. .path(),
  985. );
  986. leader_full_snapshots.retain(|full_snapshot| {
  987. full_snapshot.slot() == validator_full_snapshot.slot()
  988. && full_snapshot.hash() == validator_full_snapshot.hash()
  989. });
  990. let leader_full_snapshot = leader_full_snapshots.first().unwrap();
  991. // And for sanity, the full snapshot from the leader and the validator MUST be the same
  992. assert_eq!(
  993. (
  994. validator_full_snapshot.slot(),
  995. validator_full_snapshot.hash()
  996. ),
  997. (leader_full_snapshot.slot(), leader_full_snapshot.hash())
  998. );
  999. leader_full_snapshot.clone()
  1000. };
  1001. info!(
  1002. "leader full snapshot archive for comparison: \
  1003. {leader_full_snapshot_archive_for_comparison:#?}"
  1004. );
  1005. // Stop the validator before we reset its snapshots
  1006. info!("Stopping the validator...");
  1007. let validator_info = cluster.exit_node(&validator_identity.pubkey());
  1008. info!("Stopping the validator... DONE");
  1009. info!("Delete all the snapshots on the validator and restore the originals from the backup...");
  1010. delete_files_with_remote(
  1011. validator_snapshot_test_config
  1012. .full_snapshot_archives_dir
  1013. .path(),
  1014. );
  1015. delete_files_with_remote(
  1016. validator_snapshot_test_config
  1017. .incremental_snapshot_archives_dir
  1018. .path(),
  1019. );
  1020. copy_files_with_remote(
  1021. backup_validator_full_snapshot_archives_dir.path(),
  1022. validator_snapshot_test_config
  1023. .full_snapshot_archives_dir
  1024. .path(),
  1025. );
  1026. copy_files_with_remote(
  1027. backup_validator_incremental_snapshot_archives_dir.path(),
  1028. validator_snapshot_test_config
  1029. .incremental_snapshot_archives_dir
  1030. .path(),
  1031. );
  1032. info!(
  1033. "Delete all the snapshots on the validator and restore the originals from the backup... \
  1034. DONE"
  1035. );
  1036. // Get the highest full snapshot slot *before* restarting, as a comparison
  1037. let validator_full_snapshot_slot_at_startup =
  1038. snapshot_utils::get_highest_full_snapshot_archive_slot(
  1039. validator_snapshot_test_config
  1040. .full_snapshot_archives_dir
  1041. .path(),
  1042. )
  1043. .unwrap();
  1044. info!(
  1045. "Restarting the validator with full snapshot {validator_full_snapshot_slot_at_startup}..."
  1046. );
  1047. cluster.restart_node(
  1048. &validator_identity.pubkey(),
  1049. validator_info,
  1050. SocketAddrSpace::Unspecified,
  1051. );
  1052. info!("Restarting the validator... DONE");
  1053. // Now, we want to ensure that the validator can make a new incremental snapshot based on the
  1054. // new full snapshot that was created during the restart.
  1055. info!("Waiting for the validator to make new snapshots...");
  1056. let validator_next_full_snapshot_slot =
  1057. validator_full_snapshot_slot_at_startup + full_snapshot_interval;
  1058. let validator_next_incremental_snapshot_slot =
  1059. validator_next_full_snapshot_slot + incremental_snapshot_interval;
  1060. info!("Waiting for validator next full snapshot slot: {validator_next_full_snapshot_slot}");
  1061. info!(
  1062. "Waiting for validator next incremental snapshot slot: \
  1063. {validator_next_incremental_snapshot_slot}"
  1064. );
  1065. let timer = Instant::now();
  1066. loop {
  1067. if let Some(full_snapshot_slot) = snapshot_utils::get_highest_full_snapshot_archive_slot(
  1068. validator_snapshot_test_config
  1069. .full_snapshot_archives_dir
  1070. .path(),
  1071. ) {
  1072. if full_snapshot_slot >= validator_next_full_snapshot_slot {
  1073. if let Some(incremental_snapshot_slot) =
  1074. snapshot_utils::get_highest_incremental_snapshot_archive_slot(
  1075. validator_snapshot_test_config
  1076. .incremental_snapshot_archives_dir
  1077. .path(),
  1078. full_snapshot_slot,
  1079. )
  1080. {
  1081. if incremental_snapshot_slot >= validator_next_incremental_snapshot_slot {
  1082. // specific incremental snapshot is not important, just that one was created
  1083. info!(
  1084. "Validator made new snapshots, full snapshot slot: \
  1085. {full_snapshot_slot}, incremental snapshot slot: \
  1086. {incremental_snapshot_slot}",
  1087. );
  1088. break;
  1089. }
  1090. }
  1091. }
  1092. }
  1093. assert!(
  1094. timer.elapsed() < Duration::from_secs(30),
  1095. "It should not take longer than 30 seconds to cross the next incremental snapshot \
  1096. interval."
  1097. );
  1098. std::thread::yield_now();
  1099. }
  1100. info!(
  1101. "Waited {:?} for the validator to make new snapshots... DONE",
  1102. timer.elapsed()
  1103. );
  1104. // Check to make sure that the full snapshot the validator created during startup is the same
  1105. // or one greater than the snapshot the leader created.
  1106. let validator_full_snapshot_archives = snapshot_utils::get_full_snapshot_archives(
  1107. validator_snapshot_test_config
  1108. .full_snapshot_archives_dir
  1109. .path(),
  1110. );
  1111. info!("validator full snapshot archives: {validator_full_snapshot_archives:#?}");
  1112. let validator_full_snapshot_archive_for_comparison = validator_full_snapshot_archives
  1113. .into_iter()
  1114. .find(|validator_full_snapshot_archive| {
  1115. validator_full_snapshot_archive.slot()
  1116. == leader_full_snapshot_archive_for_comparison.slot()
  1117. })
  1118. .expect("validator created an unexpected full snapshot");
  1119. info!(
  1120. "Validator full snapshot archive for comparison: \
  1121. {validator_full_snapshot_archive_for_comparison:#?}"
  1122. );
  1123. assert_eq!(
  1124. validator_full_snapshot_archive_for_comparison.hash(),
  1125. leader_full_snapshot_archive_for_comparison.hash(),
  1126. );
  1127. // And lastly, startup another node with the new snapshots to ensure they work
  1128. let final_validator_snapshot_test_config = SnapshotValidatorConfig::new(
  1129. SnapshotInterval::Slots(NonZeroU64::new(full_snapshot_interval).unwrap()),
  1130. SnapshotInterval::Slots(NonZeroU64::new(incremental_snapshot_interval).unwrap()),
  1131. num_account_paths,
  1132. );
  1133. // Copy over the snapshots to the new node that it will boot from
  1134. copy_files(
  1135. validator_snapshot_test_config
  1136. .full_snapshot_archives_dir
  1137. .path(),
  1138. final_validator_snapshot_test_config
  1139. .full_snapshot_archives_dir
  1140. .path(),
  1141. );
  1142. copy_files(
  1143. validator_snapshot_test_config
  1144. .incremental_snapshot_archives_dir
  1145. .path(),
  1146. final_validator_snapshot_test_config
  1147. .incremental_snapshot_archives_dir
  1148. .path(),
  1149. );
  1150. info!("Starting final validator...");
  1151. let final_validator_identity = Arc::new(Keypair::new());
  1152. cluster.add_validator(
  1153. &final_validator_snapshot_test_config.validator_config,
  1154. stake,
  1155. final_validator_identity,
  1156. None,
  1157. SocketAddrSpace::Unspecified,
  1158. );
  1159. info!("Starting final validator... DONE");
  1160. }
  1161. #[allow(unused_attributes)]
  1162. #[test]
  1163. #[serial]
  1164. fn test_snapshot_restart_tower() {
  1165. solana_logger::setup_with_default(RUST_LOG_FILTER);
  1166. // First set up the cluster with 2 nodes
  1167. let snapshot_interval_slots = NonZeroU64::new(10).unwrap();
  1168. let num_account_paths = 2;
  1169. let leader_snapshot_test_config =
  1170. setup_snapshot_validator_config(snapshot_interval_slots, num_account_paths);
  1171. let validator_snapshot_test_config =
  1172. setup_snapshot_validator_config(snapshot_interval_slots, num_account_paths);
  1173. let mut config = ClusterConfig {
  1174. node_stakes: vec![DEFAULT_NODE_STAKE * 100, DEFAULT_NODE_STAKE],
  1175. mint_lamports: DEFAULT_MINT_LAMPORTS + DEFAULT_NODE_STAKE * 100,
  1176. validator_configs: vec![
  1177. safe_clone_config(&leader_snapshot_test_config.validator_config),
  1178. safe_clone_config(&validator_snapshot_test_config.validator_config),
  1179. ],
  1180. skip_warmup_slots: true,
  1181. ..ClusterConfig::default()
  1182. };
  1183. let mut cluster = LocalCluster::new(&mut config, SocketAddrSpace::Unspecified);
  1184. // Let the nodes run for a while, then stop one of the validators
  1185. sleep(Duration::from_millis(5000));
  1186. let all_pubkeys = cluster.get_node_pubkeys();
  1187. let validator_id = all_pubkeys
  1188. .into_iter()
  1189. .find(|x| x != cluster.entry_point_info.pubkey())
  1190. .unwrap();
  1191. let validator_info = cluster.exit_node(&validator_id);
  1192. let full_snapshot_archives_dir = &leader_snapshot_test_config
  1193. .validator_config
  1194. .snapshot_config
  1195. .full_snapshot_archives_dir;
  1196. let full_snapshot_archive_info = cluster.wait_for_next_full_snapshot(
  1197. full_snapshot_archives_dir,
  1198. Some(Duration::from_secs(5 * 60)),
  1199. );
  1200. // Copy archive to validator's snapshot output directory
  1201. let validator_archive_path = snapshot_utils::build_full_snapshot_archive_path(
  1202. validator_snapshot_test_config
  1203. .full_snapshot_archives_dir
  1204. .keep(),
  1205. full_snapshot_archive_info.slot(),
  1206. full_snapshot_archive_info.hash(),
  1207. full_snapshot_archive_info.archive_format(),
  1208. );
  1209. fs::hard_link(full_snapshot_archive_info.path(), validator_archive_path).unwrap();
  1210. // Restart validator from snapshot, the validator's tower state in this snapshot
  1211. // will contain slots < the root bank of the snapshot. Validator should not panic.
  1212. cluster.restart_node(&validator_id, validator_info, SocketAddrSpace::Unspecified);
  1213. // Test cluster can still make progress and get confirmations in tower
  1214. // Use the restarted node as the discovery point so that we get updated
  1215. // validator's ContactInfo
  1216. let restarted_node_info = cluster.get_contact_info(&validator_id).unwrap();
  1217. cluster_tests::spend_and_verify_all_nodes(
  1218. restarted_node_info,
  1219. &cluster.funding_keypair,
  1220. 2,
  1221. HashSet::new(),
  1222. SocketAddrSpace::Unspecified,
  1223. &cluster.connection_cache,
  1224. );
  1225. }
  1226. #[test]
  1227. #[serial]
  1228. fn test_snapshots_blockstore_floor() {
  1229. solana_logger::setup_with_default(RUST_LOG_FILTER);
  1230. // First set up the cluster with 1 snapshotting leader
  1231. let snapshot_interval_slots = NonZeroU64::new(100).unwrap();
  1232. let num_account_paths = 4;
  1233. let leader_snapshot_test_config =
  1234. setup_snapshot_validator_config(snapshot_interval_slots, num_account_paths);
  1235. let mut validator_snapshot_test_config =
  1236. setup_snapshot_validator_config(snapshot_interval_slots, num_account_paths);
  1237. let full_snapshot_archives_dir = &leader_snapshot_test_config
  1238. .validator_config
  1239. .snapshot_config
  1240. .full_snapshot_archives_dir;
  1241. let mut config = ClusterConfig {
  1242. node_stakes: vec![DEFAULT_NODE_STAKE],
  1243. validator_configs: make_identical_validator_configs(
  1244. &leader_snapshot_test_config.validator_config,
  1245. 1,
  1246. ),
  1247. ..ClusterConfig::default()
  1248. };
  1249. let mut cluster = LocalCluster::new(&mut config, SocketAddrSpace::Unspecified);
  1250. trace!("Waiting for snapshot tar to be generated with slot",);
  1251. let archive_info = loop {
  1252. let archive =
  1253. snapshot_utils::get_highest_full_snapshot_archive_info(full_snapshot_archives_dir);
  1254. if archive.is_some() {
  1255. trace!("snapshot exists");
  1256. break archive.unwrap();
  1257. }
  1258. sleep(Duration::from_millis(5000));
  1259. };
  1260. // Copy archive to validator's snapshot output directory
  1261. let validator_archive_path = snapshot_utils::build_full_snapshot_archive_path(
  1262. validator_snapshot_test_config
  1263. .full_snapshot_archives_dir
  1264. .keep(),
  1265. archive_info.slot(),
  1266. archive_info.hash(),
  1267. validator_snapshot_test_config
  1268. .validator_config
  1269. .snapshot_config
  1270. .archive_format,
  1271. );
  1272. fs::hard_link(archive_info.path(), validator_archive_path).unwrap();
  1273. let slot_floor = archive_info.slot();
  1274. // Start up a new node from a snapshot
  1275. let cluster_nodes = discover_validators(
  1276. &cluster.entry_point_info.gossip().unwrap(),
  1277. 1,
  1278. cluster.entry_point_info.shred_version(),
  1279. SocketAddrSpace::Unspecified,
  1280. )
  1281. .unwrap();
  1282. let mut known_validators = HashSet::new();
  1283. known_validators.insert(*cluster_nodes[0].pubkey());
  1284. validator_snapshot_test_config
  1285. .validator_config
  1286. .known_validators = Some(known_validators);
  1287. cluster.add_validator(
  1288. &validator_snapshot_test_config.validator_config,
  1289. DEFAULT_NODE_STAKE,
  1290. Arc::new(Keypair::new()),
  1291. None,
  1292. SocketAddrSpace::Unspecified,
  1293. );
  1294. let all_pubkeys = cluster.get_node_pubkeys();
  1295. let validator_id = all_pubkeys
  1296. .into_iter()
  1297. .find(|x| x != cluster.entry_point_info.pubkey())
  1298. .unwrap();
  1299. let validator_client = cluster
  1300. .build_validator_tpu_quic_client(&validator_id)
  1301. .unwrap();
  1302. let mut current_slot = 0;
  1303. // Let this validator run a while with repair
  1304. let target_slot = slot_floor + 40;
  1305. while current_slot <= target_slot {
  1306. trace!("current_slot: {current_slot}");
  1307. if let Ok(slot) = validator_client
  1308. .rpc_client()
  1309. .get_slot_with_commitment(CommitmentConfig::processed())
  1310. {
  1311. current_slot = slot;
  1312. } else {
  1313. continue;
  1314. }
  1315. sleep(Duration::from_secs(1));
  1316. }
  1317. // Check the validator ledger doesn't contain any slots < slot_floor
  1318. cluster.close_preserve_ledgers();
  1319. let validator_ledger_path = &cluster.validators[&validator_id];
  1320. let blockstore = Blockstore::open(&validator_ledger_path.info.ledger_path).unwrap();
  1321. // Skip the zeroth slot in blockstore that the ledger is initialized with
  1322. let (first_slot, _) = blockstore.slot_meta_iterator(1).unwrap().next().unwrap();
  1323. assert_eq!(first_slot, slot_floor);
  1324. }
  1325. #[test]
  1326. #[serial]
  1327. fn test_snapshots_restart_validity() {
  1328. solana_logger::setup_with_default(RUST_LOG_FILTER);
  1329. let snapshot_interval_slots = NonZeroU64::new(100).unwrap();
  1330. let num_account_paths = 1;
  1331. let mut snapshot_test_config =
  1332. setup_snapshot_validator_config(snapshot_interval_slots, num_account_paths);
  1333. let full_snapshot_archives_dir = &snapshot_test_config
  1334. .validator_config
  1335. .snapshot_config
  1336. .full_snapshot_archives_dir;
  1337. // Set up the cluster with 1 snapshotting validator
  1338. let mut all_account_storage_dirs = vec![std::mem::take(
  1339. &mut snapshot_test_config.account_storage_dirs,
  1340. )];
  1341. let mut config = ClusterConfig {
  1342. node_stakes: vec![DEFAULT_NODE_STAKE],
  1343. validator_configs: make_identical_validator_configs(
  1344. &snapshot_test_config.validator_config,
  1345. 1,
  1346. ),
  1347. ..ClusterConfig::default()
  1348. };
  1349. // Create and reboot the node from snapshot `num_runs` times
  1350. let num_runs = 3;
  1351. let mut expected_balances = HashMap::new();
  1352. let mut cluster = LocalCluster::new(&mut config, SocketAddrSpace::Unspecified);
  1353. for i in 1..num_runs {
  1354. info!("run {i}");
  1355. // Push transactions to one of the nodes and confirm that transactions were
  1356. // forwarded to and processed.
  1357. trace!("Sending transactions");
  1358. let new_balances = cluster_tests::send_many_transactions(
  1359. &cluster.entry_point_info,
  1360. &cluster.funding_keypair,
  1361. &cluster.connection_cache,
  1362. 10,
  1363. 10,
  1364. );
  1365. expected_balances.extend(new_balances);
  1366. cluster.wait_for_next_full_snapshot(
  1367. full_snapshot_archives_dir,
  1368. Some(Duration::from_secs(5 * 60)),
  1369. );
  1370. // Create new account paths since validator exit is not guaranteed to cleanup RPC threads,
  1371. // which may delete the old accounts on exit at any point
  1372. let (new_account_storage_dirs, new_account_storage_paths) =
  1373. generate_account_paths(num_account_paths);
  1374. all_account_storage_dirs.push(new_account_storage_dirs);
  1375. snapshot_test_config.validator_config.account_paths = new_account_storage_paths;
  1376. // Restart node
  1377. trace!("Restarting cluster from snapshot");
  1378. let nodes = cluster.get_node_pubkeys();
  1379. cluster.exit_restart_node(
  1380. &nodes[0],
  1381. safe_clone_config(&snapshot_test_config.validator_config),
  1382. SocketAddrSpace::Unspecified,
  1383. );
  1384. // Verify account balances on validator
  1385. trace!("Verifying balances");
  1386. cluster_tests::verify_balances(
  1387. expected_balances.clone(),
  1388. &cluster.entry_point_info,
  1389. cluster.connection_cache.clone(),
  1390. );
  1391. // Check that we can still push transactions
  1392. trace!("Spending and verifying");
  1393. cluster_tests::spend_and_verify_all_nodes(
  1394. &cluster.entry_point_info,
  1395. &cluster.funding_keypair,
  1396. 1,
  1397. HashSet::new(),
  1398. SocketAddrSpace::Unspecified,
  1399. &cluster.connection_cache,
  1400. );
  1401. }
  1402. }
  1403. #[test]
  1404. #[serial]
  1405. #[allow(unused_attributes)]
  1406. #[ignore]
  1407. fn test_fail_entry_verification_leader() {
  1408. solana_logger::setup_with_default(RUST_LOG_FILTER);
  1409. let leader_stake = (DUPLICATE_THRESHOLD * 100.0) as u64 + 1;
  1410. let validator_stake1 = (100 - leader_stake) / 2;
  1411. let validator_stake2 = 100 - leader_stake - validator_stake1;
  1412. let (cluster, _) = test_faulty_node(
  1413. BroadcastStageType::FailEntryVerification,
  1414. vec![leader_stake, validator_stake1, validator_stake2],
  1415. None,
  1416. None,
  1417. );
  1418. cluster.check_for_new_roots(
  1419. 16,
  1420. "test_fail_entry_verification_leader",
  1421. SocketAddrSpace::Unspecified,
  1422. );
  1423. }
  1424. #[test]
  1425. #[serial]
  1426. #[ignore]
  1427. #[allow(unused_attributes)]
  1428. fn test_fake_shreds_broadcast_leader() {
  1429. solana_logger::setup_with_default(RUST_LOG_FILTER);
  1430. let node_stakes = vec![300, 100];
  1431. let (cluster, _) = test_faulty_node(
  1432. BroadcastStageType::BroadcastFakeShreds,
  1433. node_stakes,
  1434. None,
  1435. None,
  1436. );
  1437. cluster.check_for_new_roots(
  1438. 16,
  1439. "test_fake_shreds_broadcast_leader",
  1440. SocketAddrSpace::Unspecified,
  1441. );
  1442. }
  1443. #[test]
  1444. #[serial]
  1445. fn test_wait_for_max_stake() {
  1446. solana_logger::setup_with_default(RUST_LOG_FILTER);
  1447. let validator_config = ValidatorConfig::default_for_test();
  1448. let slots_per_epoch = MINIMUM_SLOTS_PER_EPOCH;
  1449. // Set this large enough to allow for skipped slots but still be able to
  1450. // make a root and derive the new leader schedule in time.
  1451. let stakers_slot_offset = slots_per_epoch.saturating_mul(MAX_LEADER_SCHEDULE_EPOCH_OFFSET);
  1452. // Reduce this so that we can complete the test faster by advancing through
  1453. // slots/epochs faster. But don't make it too small because it can cause the
  1454. // test to fail in two important ways:
  1455. // 1. Increase likelihood of skipped slots, which can prevent rooting and
  1456. // lead to not generating leader schedule in time and cluster getting
  1457. // stuck.
  1458. // 2. Make the cluster advance through too many epochs before all the
  1459. // validators spin up, which can lead to not properly observing gossip
  1460. // votes, not repairing missing slots, and some subset of nodes getting
  1461. // stuck.
  1462. let ticks_per_slot = 32;
  1463. let num_validators = 4;
  1464. let mut config = ClusterConfig {
  1465. node_stakes: vec![DEFAULT_NODE_STAKE; num_validators],
  1466. validator_configs: make_identical_validator_configs(&validator_config, num_validators),
  1467. slots_per_epoch,
  1468. stakers_slot_offset,
  1469. ticks_per_slot,
  1470. ..ClusterConfig::default()
  1471. };
  1472. let cluster = LocalCluster::new(&mut config, SocketAddrSpace::Unspecified);
  1473. let client = RpcClient::new_socket(cluster.entry_point_info.rpc().unwrap());
  1474. let num_validators_activating_stake = num_validators - 1;
  1475. // Number of epochs it is expected to take to completely activate the stake
  1476. // for all the validators.
  1477. let num_expected_epochs = (num_validators_activating_stake as f64)
  1478. .log(1. + NEW_WARMUP_COOLDOWN_RATE)
  1479. .ceil() as u32
  1480. + 1;
  1481. let expected_test_duration = config.poh_config.target_tick_duration
  1482. * ticks_per_slot as u32
  1483. * slots_per_epoch as u32
  1484. * num_expected_epochs;
  1485. // Make the timeout double the expected duration to provide some margin.
  1486. // Especially considering tests may be running in parallel.
  1487. let timeout = expected_test_duration * 2;
  1488. if let Err(err) = client.wait_for_max_stake_below_threshold_with_timeout(
  1489. CommitmentConfig::default(),
  1490. (100 / num_validators_activating_stake) as f32,
  1491. timeout,
  1492. ) {
  1493. panic!("wait_for_max_stake failed: {err:?}");
  1494. }
  1495. assert!(client.get_slot().unwrap() > 10);
  1496. }
  1497. #[test]
  1498. #[serial]
  1499. // Test that when a leader is leader for banks B_i..B_{i+n}, and B_i is not
  1500. // votable, then B_{i+1} still chains to B_i
  1501. fn test_no_voting() {
  1502. solana_logger::setup_with_default(RUST_LOG_FILTER);
  1503. let validator_config = ValidatorConfig {
  1504. voting_disabled: true,
  1505. ..ValidatorConfig::default_for_test()
  1506. };
  1507. let mut config = ClusterConfig {
  1508. node_stakes: vec![DEFAULT_NODE_STAKE],
  1509. validator_configs: vec![validator_config],
  1510. ..ClusterConfig::default()
  1511. };
  1512. let mut cluster = LocalCluster::new(&mut config, SocketAddrSpace::Unspecified);
  1513. let client = cluster
  1514. .build_validator_tpu_quic_client(cluster.entry_point_info.pubkey())
  1515. .unwrap();
  1516. loop {
  1517. let last_slot = client
  1518. .rpc_client()
  1519. .get_slot_with_commitment(CommitmentConfig::processed())
  1520. .expect("Couldn't get slot");
  1521. if last_slot > 4 * VOTE_THRESHOLD_DEPTH as u64 {
  1522. break;
  1523. }
  1524. sleep(Duration::from_secs(1));
  1525. }
  1526. cluster.close_preserve_ledgers();
  1527. let leader_pubkey = *cluster.entry_point_info.pubkey();
  1528. let ledger_path = cluster.validators[&leader_pubkey].info.ledger_path.clone();
  1529. let ledger = Blockstore::open(&ledger_path).unwrap();
  1530. for i in 0..2 * VOTE_THRESHOLD_DEPTH {
  1531. let meta = ledger.meta(i as u64).unwrap().unwrap();
  1532. let parent = meta.parent_slot;
  1533. let expected_parent = i.saturating_sub(1);
  1534. assert_eq!(parent, Some(expected_parent as u64));
  1535. }
  1536. }
  1537. #[test]
  1538. #[serial]
  1539. fn test_optimistic_confirmation_violation_detection() {
  1540. solana_logger::setup_with_default(RUST_LOG_FILTER);
  1541. // First set up the cluster with 2 nodes
  1542. let slots_per_epoch = 2048;
  1543. let node_stakes = vec![50 * DEFAULT_NODE_STAKE, 51 * DEFAULT_NODE_STAKE];
  1544. let validator_keys: Vec<_> = [
  1545. "4qhhXNTbKD1a5vxDDLZcHKj7ELNeiivtUBxn3wUK1F5VRsQVP89VUhfXqSfgiFB14GfuBgtrQ96n9NvWQADVkcCg",
  1546. "3kHBzVwie5vTEaY6nFCPeFT8qDpoXzn7dCEioGRNBTnUDpvwnG85w8Wq63gVWpVTP8k2a8cgcWRjSXyUkEygpXWS",
  1547. ]
  1548. .iter()
  1549. .map(|s| (Arc::new(Keypair::from_base58_string(s)), true))
  1550. .take(node_stakes.len())
  1551. .collect();
  1552. // Do not restart the validator which is the cluster entrypoint because its gossip port
  1553. // might be changed after restart resulting in the two nodes not being able to
  1554. // to form a cluster. The heavier validator is the second node.
  1555. let node_to_restart = validator_keys[1].0.pubkey();
  1556. let mut config = ClusterConfig {
  1557. mint_lamports: DEFAULT_MINT_LAMPORTS + node_stakes.iter().sum::<u64>(),
  1558. node_stakes: node_stakes.clone(),
  1559. validator_configs: make_identical_validator_configs(
  1560. &ValidatorConfig::default_for_test(),
  1561. node_stakes.len(),
  1562. ),
  1563. validator_keys: Some(validator_keys),
  1564. slots_per_epoch,
  1565. stakers_slot_offset: slots_per_epoch,
  1566. skip_warmup_slots: true,
  1567. ..ClusterConfig::default()
  1568. };
  1569. let mut cluster = LocalCluster::new(&mut config, SocketAddrSpace::Unspecified);
  1570. // Let the nodes run for a while. Wait for validators to vote on slot `S`
  1571. // so that the vote on `S-1` is definitely in gossip and optimistic confirmation is
  1572. // detected on slot `S-1` for sure, then stop the heavier of the two
  1573. // validators
  1574. let client = cluster
  1575. .build_validator_tpu_quic_client(&node_to_restart)
  1576. .unwrap();
  1577. let start = Instant::now();
  1578. let target_slot = 50;
  1579. let max_wait_time_seconds = 100;
  1580. let mut optimistically_confirmed_slot;
  1581. loop {
  1582. optimistically_confirmed_slot = client
  1583. .rpc_client()
  1584. .get_slot_with_commitment(CommitmentConfig::confirmed())
  1585. .unwrap();
  1586. if optimistically_confirmed_slot > target_slot {
  1587. break;
  1588. }
  1589. if start.elapsed() > Duration::from_secs(max_wait_time_seconds) {
  1590. cluster.exit();
  1591. panic!(
  1592. "Didn't get optimistcally confirmed slot > {target_slot} within \
  1593. {max_wait_time_seconds} seconds"
  1594. );
  1595. }
  1596. sleep(Duration::from_millis(100));
  1597. }
  1598. info!("exiting node");
  1599. drop(client);
  1600. let mut exited_validator_info = cluster.exit_node(&node_to_restart);
  1601. info!("exiting node success");
  1602. // Mark fork as dead on the heavier validator, this should make the fork effectively
  1603. // dead, even though it was optimistically confirmed. The smaller validator should
  1604. // create and jump over to a new fork
  1605. // Also, remove saved tower to intentionally make the restarted validator to violate the
  1606. // optimistic confirmation
  1607. let optimistically_confirmed_slot_parent = {
  1608. let tower = restore_tower(
  1609. &exited_validator_info.info.ledger_path,
  1610. &exited_validator_info.info.keypair.pubkey(),
  1611. )
  1612. .unwrap();
  1613. // Vote must exist since we waited for OC and so this node must have voted
  1614. let last_voted_slot = tower.last_voted_slot().expect("vote must exist");
  1615. let blockstore = open_blockstore(&exited_validator_info.info.ledger_path);
  1616. // The last vote must be descended from the OC slot
  1617. assert!(
  1618. AncestorIterator::new_inclusive(last_voted_slot, &blockstore)
  1619. .contains(&optimistically_confirmed_slot)
  1620. );
  1621. info!(
  1622. "Setting slot: {optimistically_confirmed_slot} on main fork as dead, should cause fork"
  1623. );
  1624. // Necessary otherwise tower will inform this validator that it's latest
  1625. // vote is on slot `optimistically_confirmed_slot`. This will then prevent this validator
  1626. // from resetting to the parent of `optimistically_confirmed_slot` to create an alternative fork because
  1627. // 1) Validator can't vote on earlier ancestor of last vote due to switch threshold (can't vote
  1628. // on ancestors of last vote)
  1629. // 2) Won't reset to this earlier ancestor because reset can only happen on same voted fork if
  1630. // it's for the last vote slot or later
  1631. remove_tower(&exited_validator_info.info.ledger_path, &node_to_restart);
  1632. blockstore
  1633. .set_dead_slot(optimistically_confirmed_slot)
  1634. .unwrap();
  1635. blockstore
  1636. .meta(optimistically_confirmed_slot)
  1637. .unwrap()
  1638. .unwrap()
  1639. .parent_slot
  1640. .unwrap()
  1641. };
  1642. {
  1643. // Buffer stderr to detect optimistic slot violation log
  1644. let buf = std::env::var("OPTIMISTIC_CONF_TEST_DUMP_LOG")
  1645. .err()
  1646. .map(|_| BufferRedirect::stderr().unwrap());
  1647. // In order to prevent the node from voting on a slot it's already voted on
  1648. // which can potentially cause a panic in gossip, start up the validator as a
  1649. // non voter and wait for it to make a new block
  1650. exited_validator_info.config.voting_disabled = true;
  1651. cluster.restart_node(
  1652. &node_to_restart,
  1653. exited_validator_info,
  1654. SocketAddrSpace::Unspecified,
  1655. );
  1656. // Wait for this node to make a fork that doesn't include the `optimistically_confirmed_slot``
  1657. info!(
  1658. "Looking for slot not equal to {optimistically_confirmed_slot} with parent \
  1659. {optimistically_confirmed_slot_parent}"
  1660. );
  1661. let start = Instant::now();
  1662. let new_fork_slot;
  1663. 'outer: loop {
  1664. sleep(Duration::from_millis(1000));
  1665. let ledger_path = cluster.ledger_path(&node_to_restart);
  1666. let blockstore = open_blockstore(&ledger_path);
  1667. let potential_new_forks = blockstore
  1668. .meta(optimistically_confirmed_slot_parent)
  1669. .unwrap()
  1670. .unwrap()
  1671. .next_slots;
  1672. for slot in potential_new_forks {
  1673. // Wait for a fork to be created that does not include the OC slot
  1674. // Now on restart the validator should only vote for this new`slot` which they have
  1675. // never voted on before and thus avoids the panic in gossip
  1676. if slot > optimistically_confirmed_slot && blockstore.is_full(slot) {
  1677. new_fork_slot = slot;
  1678. break 'outer;
  1679. }
  1680. }
  1681. if start.elapsed() > Duration::from_secs(max_wait_time_seconds) {
  1682. cluster.exit();
  1683. panic!("Didn't get new fork within {max_wait_time_seconds} seconds");
  1684. }
  1685. }
  1686. // Exit again, restart with voting enabled
  1687. let mut exited_validator_info = cluster.exit_node(&node_to_restart);
  1688. exited_validator_info.config.voting_disabled = false;
  1689. cluster.restart_node(
  1690. &node_to_restart,
  1691. exited_validator_info,
  1692. SocketAddrSpace::Unspecified,
  1693. );
  1694. // Wait for a root descended from `new_fork_slot` to be set.
  1695. let client = cluster
  1696. .build_validator_tpu_quic_client(&node_to_restart)
  1697. .unwrap();
  1698. info!("looking for root > {optimistically_confirmed_slot} on new fork {new_fork_slot}");
  1699. let start = Instant::now();
  1700. loop {
  1701. info!("Client connecting to: {}", client.rpc_client().url());
  1702. let last_root = client
  1703. .rpc_client()
  1704. .get_slot_with_commitment(CommitmentConfig::finalized())
  1705. .unwrap();
  1706. if last_root > new_fork_slot {
  1707. info!("Found root: {last_root} > {new_fork_slot}");
  1708. let ledger_path = cluster.ledger_path(&node_to_restart);
  1709. let blockstore = open_blockstore(&ledger_path);
  1710. if AncestorIterator::new_inclusive(last_root, &blockstore).contains(&new_fork_slot)
  1711. {
  1712. break;
  1713. }
  1714. }
  1715. if start.elapsed() > Duration::from_secs(max_wait_time_seconds) {
  1716. cluster.exit();
  1717. panic!("Didn't get root on new fork within {max_wait_time_seconds} seconds");
  1718. }
  1719. sleep(Duration::from_millis(100));
  1720. }
  1721. // Check to see that validator detected optimistic confirmation for
  1722. // `last_voted_slot` failed
  1723. let expected_log =
  1724. OptimisticConfirmationVerifier::format_optimistic_confirmed_slot_violation_log(
  1725. optimistically_confirmed_slot,
  1726. );
  1727. // Violation detection thread can be behind so poll logs up to 10 seconds
  1728. if let Some(mut buf) = buf {
  1729. let start = Instant::now();
  1730. let mut success = false;
  1731. let mut output = String::new();
  1732. while start.elapsed().as_secs() < 10 {
  1733. buf.read_to_string(&mut output).unwrap();
  1734. if output.contains(&expected_log) {
  1735. success = true;
  1736. break;
  1737. }
  1738. sleep(Duration::from_millis(10));
  1739. }
  1740. print!("{output}");
  1741. assert!(success);
  1742. } else {
  1743. panic!("dumped log and disabled testing");
  1744. }
  1745. }
  1746. // Make sure validator still makes progress
  1747. cluster_tests::check_for_new_roots(
  1748. 16,
  1749. &[cluster.get_contact_info(&node_to_restart).unwrap().clone()],
  1750. &cluster.connection_cache,
  1751. "test_optimistic_confirmation_violation",
  1752. );
  1753. }
  1754. #[test]
  1755. #[serial]
  1756. fn test_validator_saves_tower() {
  1757. solana_logger::setup_with_default(RUST_LOG_FILTER);
  1758. let validator_config = ValidatorConfig {
  1759. require_tower: true,
  1760. ..ValidatorConfig::default_for_test()
  1761. };
  1762. let validator_identity_keypair = Arc::new(Keypair::new());
  1763. let validator_id = validator_identity_keypair.pubkey();
  1764. let mut config = ClusterConfig {
  1765. node_stakes: vec![DEFAULT_NODE_STAKE],
  1766. validator_configs: vec![validator_config],
  1767. validator_keys: Some(vec![(validator_identity_keypair.clone(), true)]),
  1768. ..ClusterConfig::default()
  1769. };
  1770. let mut cluster = LocalCluster::new(&mut config, SocketAddrSpace::Unspecified);
  1771. let validator_client = cluster
  1772. .build_validator_tpu_quic_client(&validator_id)
  1773. .unwrap();
  1774. let ledger_path = cluster
  1775. .validators
  1776. .get(&validator_id)
  1777. .unwrap()
  1778. .info
  1779. .ledger_path
  1780. .clone();
  1781. let file_tower_storage = FileTowerStorage::new(ledger_path.clone());
  1782. // Wait for some votes to be generated
  1783. loop {
  1784. if let Ok(slot) = validator_client
  1785. .rpc_client()
  1786. .get_slot_with_commitment(CommitmentConfig::processed())
  1787. {
  1788. trace!("current slot: {slot}");
  1789. if slot > 2 {
  1790. break;
  1791. }
  1792. }
  1793. sleep(Duration::from_millis(10));
  1794. }
  1795. // Stop validator and check saved tower
  1796. let validator_info = cluster.exit_node(&validator_id);
  1797. let tower1 = Tower::restore(&file_tower_storage, &validator_id).unwrap();
  1798. trace!("tower1: {tower1:?}");
  1799. assert_eq!(tower1.root(), 0);
  1800. assert!(tower1.last_voted_slot().is_some());
  1801. // Restart the validator and wait for a new root
  1802. cluster.restart_node(&validator_id, validator_info, SocketAddrSpace::Unspecified);
  1803. let validator_client = cluster
  1804. .build_validator_tpu_quic_client(&validator_id)
  1805. .unwrap();
  1806. // Wait for the first new root
  1807. let last_replayed_root = loop {
  1808. if let Ok(root) = validator_client
  1809. .rpc_client()
  1810. .get_slot_with_commitment(CommitmentConfig::finalized())
  1811. {
  1812. trace!("current root: {root}");
  1813. if root > 0 {
  1814. break root;
  1815. }
  1816. }
  1817. sleep(Duration::from_millis(50));
  1818. };
  1819. // Stop validator, and check saved tower
  1820. let validator_info = cluster.exit_node(&validator_id);
  1821. let tower2 = Tower::restore(&file_tower_storage, &validator_id).unwrap();
  1822. trace!("tower2: {tower2:?}");
  1823. assert_eq!(tower2.root(), last_replayed_root);
  1824. // Rollback saved tower to `tower1` to simulate a validator starting from a newer snapshot
  1825. // without having to wait for that snapshot to be generated in this test
  1826. tower1
  1827. .save(&file_tower_storage, &validator_identity_keypair)
  1828. .unwrap();
  1829. cluster.restart_node(&validator_id, validator_info, SocketAddrSpace::Unspecified);
  1830. let validator_client = cluster
  1831. .build_validator_tpu_quic_client(&validator_id)
  1832. .unwrap();
  1833. // Wait for a new root, demonstrating the validator was able to make progress from the older `tower1`
  1834. let new_root = loop {
  1835. if let Ok(root) = validator_client
  1836. .rpc_client()
  1837. .get_slot_with_commitment(CommitmentConfig::finalized())
  1838. {
  1839. trace!("current root: {root}, last_replayed_root: {last_replayed_root}");
  1840. if root > last_replayed_root {
  1841. break root;
  1842. }
  1843. }
  1844. sleep(Duration::from_millis(50));
  1845. };
  1846. // Check the new root is reflected in the saved tower state
  1847. let mut validator_info = cluster.exit_node(&validator_id);
  1848. let tower3 = Tower::restore(&file_tower_storage, &validator_id).unwrap();
  1849. trace!("tower3: {tower3:?}");
  1850. let tower3_root = tower3.root();
  1851. assert!(tower3_root >= new_root);
  1852. // Remove the tower file entirely and allow the validator to start without a tower. It will
  1853. // rebuild tower from its vote account contents
  1854. remove_tower(&ledger_path, &validator_id);
  1855. validator_info.config.require_tower = false;
  1856. cluster.restart_node(&validator_id, validator_info, SocketAddrSpace::Unspecified);
  1857. let validator_client = cluster
  1858. .build_validator_tpu_quic_client(&validator_id)
  1859. .unwrap();
  1860. // Wait for another new root
  1861. let new_root = loop {
  1862. if let Ok(root) = validator_client
  1863. .rpc_client()
  1864. .get_slot_with_commitment(CommitmentConfig::finalized())
  1865. {
  1866. trace!("current root: {root}, last tower root: {tower3_root}");
  1867. if root > tower3_root {
  1868. break root;
  1869. }
  1870. }
  1871. sleep(Duration::from_millis(50));
  1872. };
  1873. cluster.close_preserve_ledgers();
  1874. let tower4 = Tower::restore(&file_tower_storage, &validator_id).unwrap();
  1875. trace!("tower4: {tower4:?}");
  1876. assert!(tower4.root() >= new_root);
  1877. }
  1878. fn root_in_tower(tower_path: &Path, node_pubkey: &Pubkey) -> Option<Slot> {
  1879. restore_tower(tower_path, node_pubkey).map(|tower| tower.root())
  1880. }
  1881. enum ClusterMode {
  1882. MasterOnly,
  1883. MasterSlave,
  1884. }
  1885. fn do_test_future_tower(cluster_mode: ClusterMode) {
  1886. solana_logger::setup_with_default(RUST_LOG_FILTER);
  1887. // First set up the cluster with 4 nodes
  1888. let slots_per_epoch = 2048;
  1889. let node_stakes = match cluster_mode {
  1890. ClusterMode::MasterOnly => vec![DEFAULT_NODE_STAKE],
  1891. ClusterMode::MasterSlave => vec![DEFAULT_NODE_STAKE * 100, DEFAULT_NODE_STAKE],
  1892. };
  1893. let validator_keys = [
  1894. "28bN3xyvrP4E8LwEgtLjhnkb7cY4amQb6DrYAbAYjgRV4GAGgkVM2K7wnxnAS7WDneuavza7x21MiafLu1HkwQt4",
  1895. "2saHBBoTkLMmttmPQP8KfBkcCw45S5cwtV3wTdGCscRC8uxdgvHxpHiWXKx4LvJjNJtnNcbSv5NdheokFFqnNDt8",
  1896. ]
  1897. .iter()
  1898. .map(|s| (Arc::new(Keypair::from_base58_string(s)), true))
  1899. .take(node_stakes.len())
  1900. .collect::<Vec<_>>();
  1901. let validators = validator_keys
  1902. .iter()
  1903. .map(|(kp, _)| kp.pubkey())
  1904. .collect::<Vec<_>>();
  1905. let validator_a_pubkey = match cluster_mode {
  1906. ClusterMode::MasterOnly => validators[0],
  1907. ClusterMode::MasterSlave => validators[1],
  1908. };
  1909. let mut config = ClusterConfig {
  1910. mint_lamports: DEFAULT_MINT_LAMPORTS + DEFAULT_NODE_STAKE * 100,
  1911. node_stakes: node_stakes.clone(),
  1912. validator_configs: make_identical_validator_configs(
  1913. &ValidatorConfig::default_for_test(),
  1914. node_stakes.len(),
  1915. ),
  1916. validator_keys: Some(validator_keys),
  1917. slots_per_epoch,
  1918. stakers_slot_offset: slots_per_epoch,
  1919. skip_warmup_slots: true,
  1920. ..ClusterConfig::default()
  1921. };
  1922. let mut cluster = LocalCluster::new(&mut config, SocketAddrSpace::Unspecified);
  1923. let val_a_ledger_path = cluster.ledger_path(&validator_a_pubkey);
  1924. loop {
  1925. sleep(Duration::from_millis(100));
  1926. if let Some(root) = root_in_tower(&val_a_ledger_path, &validator_a_pubkey) {
  1927. if root >= 15 {
  1928. break;
  1929. }
  1930. }
  1931. }
  1932. let purged_slot_before_restart = 10;
  1933. let validator_a_info = cluster.exit_node(&validator_a_pubkey);
  1934. {
  1935. // create a warped future tower without mangling the tower itself
  1936. info!(
  1937. "Revert blockstore before slot {purged_slot_before_restart} and effectively create a \
  1938. future tower",
  1939. );
  1940. let blockstore = open_blockstore(&val_a_ledger_path);
  1941. purge_slots_with_count(&blockstore, purged_slot_before_restart, 100);
  1942. }
  1943. cluster.restart_node(
  1944. &validator_a_pubkey,
  1945. validator_a_info,
  1946. SocketAddrSpace::Unspecified,
  1947. );
  1948. let mut newly_rooted = false;
  1949. let some_root_after_restart = purged_slot_before_restart + 25; // 25 is arbitrary; just wait a bit
  1950. for _ in 0..600 {
  1951. sleep(Duration::from_millis(100));
  1952. if let Some(root) = root_in_tower(&val_a_ledger_path, &validator_a_pubkey) {
  1953. if root >= some_root_after_restart {
  1954. newly_rooted = true;
  1955. break;
  1956. }
  1957. }
  1958. }
  1959. let _validator_a_info = cluster.exit_node(&validator_a_pubkey);
  1960. if newly_rooted {
  1961. // there should be no forks; i.e. monotonically increasing ancestor chain
  1962. let (last_vote, _) = last_vote_in_tower(&val_a_ledger_path, &validator_a_pubkey).unwrap();
  1963. let blockstore = open_blockstore(&val_a_ledger_path);
  1964. let actual_block_ancestors = AncestorIterator::new_inclusive(last_vote, &blockstore)
  1965. .take_while(|a| *a >= some_root_after_restart)
  1966. .collect::<Vec<_>>();
  1967. let expected_countinuous_no_fork_votes = (some_root_after_restart..=last_vote)
  1968. .rev()
  1969. .collect::<Vec<_>>();
  1970. assert_eq!(actual_block_ancestors, expected_countinuous_no_fork_votes);
  1971. assert!(actual_block_ancestors.len() > MAX_LOCKOUT_HISTORY);
  1972. info!("validator managed to handle future tower!");
  1973. } else {
  1974. panic!("no root detected");
  1975. }
  1976. }
  1977. #[test]
  1978. #[serial]
  1979. fn test_future_tower_master_only() {
  1980. do_test_future_tower(ClusterMode::MasterOnly);
  1981. }
  1982. #[test]
  1983. #[serial]
  1984. fn test_future_tower_master_slave() {
  1985. do_test_future_tower(ClusterMode::MasterSlave);
  1986. }
  1987. fn restart_whole_cluster_after_hard_fork(
  1988. cluster: &Arc<Mutex<LocalCluster>>,
  1989. validator_a_pubkey: Pubkey,
  1990. validator_b_pubkey: Pubkey,
  1991. mut validator_a_info: ClusterValidatorInfo,
  1992. validator_b_info: ClusterValidatorInfo,
  1993. ) {
  1994. // restart validator A first
  1995. let cluster_for_a = cluster.clone();
  1996. let val_a_ledger_path = validator_a_info.info.ledger_path.clone();
  1997. // Spawn a thread because wait_for_supermajority blocks in Validator::new()!
  1998. let thread = std::thread::spawn(move || {
  1999. let restart_context = cluster_for_a
  2000. .lock()
  2001. .unwrap()
  2002. .create_restart_context(&validator_a_pubkey, &mut validator_a_info);
  2003. let restarted_validator_info = LocalCluster::restart_node_with_context(
  2004. validator_a_info,
  2005. restart_context,
  2006. SocketAddrSpace::Unspecified,
  2007. );
  2008. cluster_for_a
  2009. .lock()
  2010. .unwrap()
  2011. .add_node(&validator_a_pubkey, restarted_validator_info);
  2012. });
  2013. // test validator A actually to wait for supermajority
  2014. let mut last_vote = None;
  2015. for _ in 0..10 {
  2016. sleep(Duration::from_millis(1000));
  2017. let (new_last_vote, _) =
  2018. last_vote_in_tower(&val_a_ledger_path, &validator_a_pubkey).unwrap();
  2019. if let Some(last_vote) = last_vote {
  2020. assert_eq!(last_vote, new_last_vote);
  2021. } else {
  2022. last_vote = Some(new_last_vote);
  2023. }
  2024. }
  2025. // restart validator B normally
  2026. cluster.lock().unwrap().restart_node(
  2027. &validator_b_pubkey,
  2028. validator_b_info,
  2029. SocketAddrSpace::Unspecified,
  2030. );
  2031. // validator A should now start so join its thread here
  2032. thread.join().unwrap();
  2033. }
  2034. #[test]
  2035. #[serial]
  2036. fn test_hard_fork_invalidates_tower() {
  2037. solana_logger::setup_with_default(RUST_LOG_FILTER);
  2038. // First set up the cluster with 2 nodes
  2039. let slots_per_epoch = 2048;
  2040. let node_stakes = vec![60 * DEFAULT_NODE_STAKE, 40 * DEFAULT_NODE_STAKE];
  2041. let validator_keys = [
  2042. "28bN3xyvrP4E8LwEgtLjhnkb7cY4amQb6DrYAbAYjgRV4GAGgkVM2K7wnxnAS7WDneuavza7x21MiafLu1HkwQt4",
  2043. "2saHBBoTkLMmttmPQP8KfBkcCw45S5cwtV3wTdGCscRC8uxdgvHxpHiWXKx4LvJjNJtnNcbSv5NdheokFFqnNDt8",
  2044. ]
  2045. .iter()
  2046. .map(|s| (Arc::new(Keypair::from_base58_string(s)), true))
  2047. .take(node_stakes.len())
  2048. .collect::<Vec<_>>();
  2049. let validators = validator_keys
  2050. .iter()
  2051. .map(|(kp, _)| kp.pubkey())
  2052. .collect::<Vec<_>>();
  2053. let validator_a_pubkey = validators[0];
  2054. let validator_b_pubkey = validators[1];
  2055. let mut config = ClusterConfig {
  2056. mint_lamports: DEFAULT_MINT_LAMPORTS + node_stakes.iter().sum::<u64>(),
  2057. node_stakes: node_stakes.clone(),
  2058. validator_configs: make_identical_validator_configs(
  2059. &ValidatorConfig::default_for_test(),
  2060. node_stakes.len(),
  2061. ),
  2062. validator_keys: Some(validator_keys),
  2063. slots_per_epoch,
  2064. stakers_slot_offset: slots_per_epoch,
  2065. skip_warmup_slots: true,
  2066. ..ClusterConfig::default()
  2067. };
  2068. let cluster = std::sync::Arc::new(std::sync::Mutex::new(LocalCluster::new(
  2069. &mut config,
  2070. SocketAddrSpace::Unspecified,
  2071. )));
  2072. let val_a_ledger_path = cluster.lock().unwrap().ledger_path(&validator_a_pubkey);
  2073. let min_root = 15;
  2074. loop {
  2075. sleep(Duration::from_millis(100));
  2076. if let Some(root) = root_in_tower(&val_a_ledger_path, &validator_a_pubkey) {
  2077. if root >= min_root {
  2078. break;
  2079. }
  2080. }
  2081. }
  2082. let mut validator_a_info = cluster.lock().unwrap().exit_node(&validator_a_pubkey);
  2083. let mut validator_b_info = cluster.lock().unwrap().exit_node(&validator_b_pubkey);
  2084. // setup hard fork at slot < a previously rooted slot!
  2085. // hard fork earlier than root is very unrealistic in the wild, but it's handy for
  2086. // persistent tower's lockout behavior...
  2087. let hard_fork_slot = min_root - 5;
  2088. let hard_fork_slots = Some(vec![hard_fork_slot]);
  2089. let mut hard_forks = solana_hard_forks::HardForks::default();
  2090. hard_forks.register(hard_fork_slot);
  2091. let expected_shred_version = solana_shred_version::compute_shred_version(
  2092. &cluster.lock().unwrap().genesis_config.hash(),
  2093. Some(&hard_forks),
  2094. );
  2095. cluster
  2096. .lock()
  2097. .unwrap()
  2098. .set_shred_version(expected_shred_version);
  2099. validator_a_info
  2100. .config
  2101. .new_hard_forks
  2102. .clone_from(&hard_fork_slots);
  2103. validator_a_info.config.wait_for_supermajority = Some(hard_fork_slot);
  2104. validator_a_info.config.expected_shred_version = Some(expected_shred_version);
  2105. validator_b_info.config.new_hard_forks = hard_fork_slots;
  2106. validator_b_info.config.wait_for_supermajority = Some(hard_fork_slot);
  2107. validator_b_info.config.expected_shred_version = Some(expected_shred_version);
  2108. // Clear ledger of all slots post hard fork
  2109. {
  2110. let blockstore_a = open_blockstore(&validator_a_info.info.ledger_path);
  2111. let blockstore_b = open_blockstore(&validator_b_info.info.ledger_path);
  2112. purge_slots_with_count(&blockstore_a, hard_fork_slot + 1, 100);
  2113. purge_slots_with_count(&blockstore_b, hard_fork_slot + 1, 100);
  2114. }
  2115. restart_whole_cluster_after_hard_fork(
  2116. &cluster,
  2117. validator_a_pubkey,
  2118. validator_b_pubkey,
  2119. validator_a_info,
  2120. validator_b_info,
  2121. );
  2122. // new slots should be rooted after hard-fork cluster relaunch
  2123. cluster
  2124. .lock()
  2125. .unwrap()
  2126. .check_for_new_roots(16, "hard fork", SocketAddrSpace::Unspecified);
  2127. }
  2128. #[test]
  2129. #[serial]
  2130. fn test_run_test_load_program_accounts_root() {
  2131. run_test_load_program_accounts(CommitmentConfig::finalized());
  2132. }
  2133. fn create_simple_snapshot_config(ledger_path: &Path) -> SnapshotConfig {
  2134. SnapshotConfig {
  2135. full_snapshot_archives_dir: ledger_path.to_path_buf(),
  2136. bank_snapshots_dir: ledger_path.join(BANK_SNAPSHOTS_DIR),
  2137. ..SnapshotConfig::default()
  2138. }
  2139. }
  2140. fn create_snapshot_to_hard_fork(
  2141. blockstore: &Blockstore,
  2142. snapshot_slot: Slot,
  2143. hard_forks: Vec<Slot>,
  2144. ) {
  2145. let process_options = ProcessOptions {
  2146. halt_at_slot: Some(snapshot_slot),
  2147. new_hard_forks: Some(hard_forks),
  2148. run_verification: false,
  2149. ..ProcessOptions::default()
  2150. };
  2151. let ledger_path = blockstore.ledger_path();
  2152. let genesis_config = open_genesis_config(ledger_path, u64::MAX).unwrap();
  2153. let snapshot_config = create_simple_snapshot_config(ledger_path);
  2154. let (bank_forks, ..) = bank_forks_utils::load(
  2155. &genesis_config,
  2156. blockstore,
  2157. vec![
  2158. create_accounts_run_and_snapshot_dirs(ledger_path.join("accounts"))
  2159. .unwrap()
  2160. .0,
  2161. ],
  2162. &snapshot_config,
  2163. process_options,
  2164. None,
  2165. None,
  2166. None,
  2167. Arc::default(),
  2168. )
  2169. .unwrap();
  2170. let bank = bank_forks.read().unwrap().get(snapshot_slot).unwrap();
  2171. let full_snapshot_archive_info = snapshot_bank_utils::bank_to_full_snapshot_archive(
  2172. ledger_path,
  2173. &bank,
  2174. Some(snapshot_config.snapshot_version),
  2175. ledger_path,
  2176. ledger_path,
  2177. snapshot_config.archive_format,
  2178. )
  2179. .unwrap();
  2180. info!(
  2181. "Successfully created snapshot for slot {}, hash {}: {}",
  2182. bank.slot(),
  2183. bank.hash(),
  2184. full_snapshot_archive_info.path().display(),
  2185. );
  2186. }
  2187. #[test]
  2188. #[ignore]
  2189. #[serial]
  2190. fn test_hard_fork_with_gap_in_roots() {
  2191. solana_logger::setup_with_default(RUST_LOG_FILTER);
  2192. // First set up the cluster with 2 nodes
  2193. let slots_per_epoch = 2048;
  2194. let node_stakes = vec![60, 40];
  2195. let validator_keys = [
  2196. "28bN3xyvrP4E8LwEgtLjhnkb7cY4amQb6DrYAbAYjgRV4GAGgkVM2K7wnxnAS7WDneuavza7x21MiafLu1HkwQt4",
  2197. "2saHBBoTkLMmttmPQP8KfBkcCw45S5cwtV3wTdGCscRC8uxdgvHxpHiWXKx4LvJjNJtnNcbSv5NdheokFFqnNDt8",
  2198. ]
  2199. .iter()
  2200. .map(|s| (Arc::new(Keypair::from_base58_string(s)), true))
  2201. .take(node_stakes.len())
  2202. .collect::<Vec<_>>();
  2203. let validators = validator_keys
  2204. .iter()
  2205. .map(|(kp, _)| kp.pubkey())
  2206. .collect::<Vec<_>>();
  2207. let validator_a_pubkey = validators[0];
  2208. let validator_b_pubkey = validators[1];
  2209. let validator_config = ValidatorConfig {
  2210. snapshot_config: LocalCluster::create_dummy_load_only_snapshot_config(),
  2211. ..ValidatorConfig::default_for_test()
  2212. };
  2213. let mut config = ClusterConfig {
  2214. mint_lamports: 100_000,
  2215. node_stakes: node_stakes.clone(),
  2216. validator_configs: make_identical_validator_configs(&validator_config, node_stakes.len()),
  2217. validator_keys: Some(validator_keys),
  2218. slots_per_epoch,
  2219. stakers_slot_offset: slots_per_epoch,
  2220. skip_warmup_slots: true,
  2221. ..ClusterConfig::default()
  2222. };
  2223. let cluster = std::sync::Arc::new(std::sync::Mutex::new(LocalCluster::new(
  2224. &mut config,
  2225. SocketAddrSpace::Unspecified,
  2226. )));
  2227. let val_a_ledger_path = cluster.lock().unwrap().ledger_path(&validator_a_pubkey);
  2228. let val_b_ledger_path = cluster.lock().unwrap().ledger_path(&validator_b_pubkey);
  2229. let min_last_vote = 45;
  2230. let min_root = 10;
  2231. loop {
  2232. sleep(Duration::from_millis(100));
  2233. if let Some((last_vote, _)) = last_vote_in_tower(&val_a_ledger_path, &validator_a_pubkey) {
  2234. if last_vote >= min_last_vote
  2235. && root_in_tower(&val_a_ledger_path, &validator_a_pubkey) > Some(min_root)
  2236. {
  2237. break;
  2238. }
  2239. }
  2240. }
  2241. // stop all nodes of the cluster
  2242. let mut validator_a_info = cluster.lock().unwrap().exit_node(&validator_a_pubkey);
  2243. let mut validator_b_info = cluster.lock().unwrap().exit_node(&validator_b_pubkey);
  2244. // hard fork slot is effectively a (possibly skipping) new root.
  2245. // assert that the precondition of validator a to test gap between
  2246. // blockstore and hard fork...
  2247. let hard_fork_slot = min_last_vote - 5;
  2248. assert!(hard_fork_slot > root_in_tower(&val_a_ledger_path, &validator_a_pubkey).unwrap());
  2249. let hard_fork_slots = Some(vec![hard_fork_slot]);
  2250. let mut hard_forks = HardForks::default();
  2251. hard_forks.register(hard_fork_slot);
  2252. let expected_shred_version = solana_shred_version::compute_shred_version(
  2253. &cluster.lock().unwrap().genesis_config.hash(),
  2254. Some(&hard_forks),
  2255. );
  2256. // create hard-forked snapshot only for validator a, emulating the manual cluster restart
  2257. // procedure with `agave-ledger-tool create-snapshot`
  2258. let genesis_slot = 0;
  2259. {
  2260. let blockstore_a = Blockstore::open(&val_a_ledger_path).unwrap();
  2261. create_snapshot_to_hard_fork(&blockstore_a, hard_fork_slot, vec![hard_fork_slot]);
  2262. // Intentionally make agave-validator unbootable by replaying blocks from the genesis to
  2263. // ensure the hard-forked snapshot is used always. Otherwise, we couldn't create a gap
  2264. // in the ledger roots column family reliably.
  2265. // There was a bug which caused the hard-forked snapshot at an unrooted slot to forget
  2266. // to root some slots (thus, creating a gap in roots, which shouldn't happen).
  2267. purge_slots_with_count(&blockstore_a, genesis_slot, 1);
  2268. let next_slot = genesis_slot + 1;
  2269. let mut meta = blockstore_a.meta(next_slot).unwrap().unwrap();
  2270. meta.unset_parent();
  2271. blockstore_a.put_meta(next_slot, &meta).unwrap();
  2272. }
  2273. // strictly speaking, new_hard_forks isn't needed for validator a.
  2274. // but when snapshot loading isn't working, you might see:
  2275. // shred version mismatch: expected NNNN found: MMMM
  2276. //validator_a_info.config.new_hard_forks = hard_fork_slots.clone();
  2277. // effectively pass the --hard-fork parameter to validator b
  2278. validator_b_info.config.new_hard_forks = hard_fork_slots;
  2279. validator_a_info.config.wait_for_supermajority = Some(hard_fork_slot);
  2280. validator_a_info.config.expected_shred_version = Some(expected_shred_version);
  2281. validator_b_info.config.wait_for_supermajority = Some(hard_fork_slot);
  2282. validator_b_info.config.expected_shred_version = Some(expected_shred_version);
  2283. restart_whole_cluster_after_hard_fork(
  2284. &cluster,
  2285. validator_a_pubkey,
  2286. validator_b_pubkey,
  2287. validator_a_info,
  2288. validator_b_info,
  2289. );
  2290. // new slots should be rooted after hard-fork cluster relaunch
  2291. cluster
  2292. .lock()
  2293. .unwrap()
  2294. .check_for_new_roots(16, "hard fork", SocketAddrSpace::Unspecified);
  2295. // drop everything to open blockstores below
  2296. drop(cluster);
  2297. let (common_last_vote, common_root) = {
  2298. let (last_vote_a, _) = last_vote_in_tower(&val_a_ledger_path, &validator_a_pubkey).unwrap();
  2299. let (last_vote_b, _) = last_vote_in_tower(&val_b_ledger_path, &validator_b_pubkey).unwrap();
  2300. let root_a = root_in_tower(&val_a_ledger_path, &validator_a_pubkey).unwrap();
  2301. let root_b = root_in_tower(&val_b_ledger_path, &validator_b_pubkey).unwrap();
  2302. (last_vote_a.min(last_vote_b), root_a.min(root_b))
  2303. };
  2304. let blockstore_a = Blockstore::open(&val_a_ledger_path).unwrap();
  2305. let blockstore_b = Blockstore::open(&val_b_ledger_path).unwrap();
  2306. // collect all slot/root parents
  2307. let mut slots_a = AncestorIterator::new(common_last_vote, &blockstore_a).collect::<Vec<_>>();
  2308. let mut roots_a = blockstore_a
  2309. .reversed_rooted_slot_iterator(common_root)
  2310. .unwrap()
  2311. .collect::<Vec<_>>();
  2312. // artificially restore the forcibly purged genesis only for the validator A just for the sake of
  2313. // the final assertions.
  2314. slots_a.push(genesis_slot);
  2315. roots_a.push(genesis_slot);
  2316. let slots_b = AncestorIterator::new(common_last_vote, &blockstore_b).collect::<Vec<_>>();
  2317. let roots_b = blockstore_b
  2318. .reversed_rooted_slot_iterator(common_root)
  2319. .unwrap()
  2320. .collect::<Vec<_>>();
  2321. // compare them all!
  2322. assert_eq!((&slots_a, &roots_a), (&slots_b, &roots_b));
  2323. assert_eq!(&slots_a[slots_a.len() - roots_a.len()..].to_vec(), &roots_a);
  2324. assert_eq!(&slots_b[slots_b.len() - roots_b.len()..].to_vec(), &roots_b);
  2325. }
  2326. #[test]
  2327. #[serial]
  2328. fn test_restart_tower_rollback() {
  2329. // Test node crashing and failing to save its tower before restart
  2330. // Cluster continues to make progress, this node is able to rejoin with
  2331. // outdated tower post restart.
  2332. solana_logger::setup_with_default(RUST_LOG_FILTER);
  2333. // First set up the cluster with 2 nodes
  2334. let slots_per_epoch = 2048;
  2335. let node_stakes = vec![DEFAULT_NODE_STAKE * 100, DEFAULT_NODE_STAKE];
  2336. let validator_strings = [
  2337. "28bN3xyvrP4E8LwEgtLjhnkb7cY4amQb6DrYAbAYjgRV4GAGgkVM2K7wnxnAS7WDneuavza7x21MiafLu1HkwQt4",
  2338. "2saHBBoTkLMmttmPQP8KfBkcCw45S5cwtV3wTdGCscRC8uxdgvHxpHiWXKx4LvJjNJtnNcbSv5NdheokFFqnNDt8",
  2339. ];
  2340. let validator_keys = validator_strings
  2341. .iter()
  2342. .map(|s| (Arc::new(Keypair::from_base58_string(s)), true))
  2343. .take(node_stakes.len())
  2344. .collect::<Vec<_>>();
  2345. let b_pubkey = validator_keys[1].0.pubkey();
  2346. let mut config = ClusterConfig {
  2347. mint_lamports: DEFAULT_MINT_LAMPORTS + DEFAULT_NODE_STAKE * 100,
  2348. node_stakes: node_stakes.clone(),
  2349. validator_configs: make_identical_validator_configs(
  2350. &ValidatorConfig::default_for_test(),
  2351. node_stakes.len(),
  2352. ),
  2353. validator_keys: Some(validator_keys),
  2354. slots_per_epoch,
  2355. stakers_slot_offset: slots_per_epoch,
  2356. skip_warmup_slots: true,
  2357. ..ClusterConfig::default()
  2358. };
  2359. let mut cluster = LocalCluster::new(&mut config, SocketAddrSpace::Unspecified);
  2360. let val_b_ledger_path = cluster.ledger_path(&b_pubkey);
  2361. let mut earlier_tower: Tower;
  2362. loop {
  2363. sleep(Duration::from_millis(1000));
  2364. // Grab the current saved tower
  2365. earlier_tower = restore_tower(&val_b_ledger_path, &b_pubkey).unwrap();
  2366. if earlier_tower.last_voted_slot().unwrap_or(0) > 1 {
  2367. break;
  2368. }
  2369. }
  2370. let mut exited_validator_info: ClusterValidatorInfo;
  2371. let last_voted_slot: Slot;
  2372. loop {
  2373. sleep(Duration::from_millis(1000));
  2374. // Wait for second, lesser staked validator to make a root past the earlier_tower's
  2375. // latest vote slot, then exit that validator
  2376. let tower = restore_tower(&val_b_ledger_path, &b_pubkey).unwrap();
  2377. if tower.root()
  2378. > earlier_tower
  2379. .last_voted_slot()
  2380. .expect("Earlier tower must have at least one vote")
  2381. {
  2382. exited_validator_info = cluster.exit_node(&b_pubkey);
  2383. last_voted_slot = tower.last_voted_slot().unwrap();
  2384. break;
  2385. }
  2386. }
  2387. // Now rewrite the tower with the *earlier_tower*. We disable voting until we reach
  2388. // a slot we did not previously vote for in order to avoid duplicate vote slashing
  2389. // issues.
  2390. save_tower(
  2391. &val_b_ledger_path,
  2392. &earlier_tower,
  2393. &exited_validator_info.info.keypair,
  2394. );
  2395. exited_validator_info.config.wait_to_vote_slot = Some(last_voted_slot + 10);
  2396. cluster.restart_node(
  2397. &b_pubkey,
  2398. exited_validator_info,
  2399. SocketAddrSpace::Unspecified,
  2400. );
  2401. // Check this node is making new roots
  2402. cluster.check_for_new_roots(
  2403. 20,
  2404. "test_restart_tower_rollback",
  2405. SocketAddrSpace::Unspecified,
  2406. );
  2407. }
  2408. #[test]
  2409. #[serial]
  2410. fn test_run_test_load_program_accounts_partition_root() {
  2411. run_test_load_program_accounts_partition(CommitmentConfig::finalized());
  2412. }
  2413. fn run_test_load_program_accounts_partition(scan_commitment: CommitmentConfig) {
  2414. let num_slots_per_validator = 8;
  2415. let partitions: [usize; 2] = [1, 1];
  2416. let (leader_schedule, validator_keys) = create_custom_leader_schedule_with_random_keys(&[
  2417. num_slots_per_validator,
  2418. num_slots_per_validator,
  2419. ]);
  2420. let (update_client_sender, update_client_receiver) = unbounded();
  2421. let (scan_client_sender, scan_client_receiver) = unbounded();
  2422. let exit = Arc::new(AtomicBool::new(false));
  2423. let (t_update, t_scan, additional_accounts) = setup_transfer_scan_threads(
  2424. 1000,
  2425. exit.clone(),
  2426. scan_commitment,
  2427. update_client_receiver,
  2428. scan_client_receiver,
  2429. );
  2430. let on_partition_start = |cluster: &mut LocalCluster, _: &mut ()| {
  2431. let update_client = cluster
  2432. .build_validator_tpu_quic_client(cluster.entry_point_info.pubkey())
  2433. .unwrap();
  2434. update_client_sender.send(update_client).unwrap();
  2435. let scan_client = cluster
  2436. .build_validator_tpu_quic_client(cluster.entry_point_info.pubkey())
  2437. .unwrap();
  2438. scan_client_sender.send(scan_client).unwrap();
  2439. };
  2440. let on_partition_before_resolved = |_: &mut LocalCluster, _: &mut ()| {};
  2441. let on_partition_resolved = |cluster: &mut LocalCluster, _: &mut ()| {
  2442. cluster.check_for_new_roots(
  2443. 20,
  2444. "run_test_load_program_accounts_partition",
  2445. SocketAddrSpace::Unspecified,
  2446. );
  2447. exit.store(true, Ordering::Relaxed);
  2448. t_update.join().unwrap();
  2449. t_scan.join().unwrap();
  2450. };
  2451. run_cluster_partition(
  2452. &partitions,
  2453. Some((leader_schedule, validator_keys)),
  2454. (),
  2455. on_partition_start,
  2456. on_partition_before_resolved,
  2457. on_partition_resolved,
  2458. None,
  2459. additional_accounts,
  2460. );
  2461. }
  2462. #[test]
  2463. #[serial]
  2464. fn test_rpc_block_subscribe() {
  2465. let leader_stake = 100 * DEFAULT_NODE_STAKE;
  2466. let rpc_stake = DEFAULT_NODE_STAKE;
  2467. let total_stake = leader_stake + rpc_stake;
  2468. let node_stakes = vec![leader_stake, rpc_stake];
  2469. let mut validator_config = ValidatorConfig::default_for_test();
  2470. validator_config.enable_default_rpc_block_subscribe();
  2471. let validator_keys = [
  2472. "28bN3xyvrP4E8LwEgtLjhnkb7cY4amQb6DrYAbAYjgRV4GAGgkVM2K7wnxnAS7WDneuavza7x21MiafLu1HkwQt4",
  2473. "2saHBBoTkLMmttmPQP8KfBkcCw45S5cwtV3wTdGCscRC8uxdgvHxpHiWXKx4LvJjNJtnNcbSv5NdheokFFqnNDt8",
  2474. ]
  2475. .iter()
  2476. .map(|s| (Arc::new(Keypair::from_base58_string(s)), true))
  2477. .take(node_stakes.len())
  2478. .collect::<Vec<_>>();
  2479. let rpc_node_pubkey = &validator_keys[1].0.pubkey();
  2480. let mut config = ClusterConfig {
  2481. mint_lamports: total_stake,
  2482. node_stakes,
  2483. validator_configs: make_identical_validator_configs(&validator_config, 2),
  2484. validator_keys: Some(validator_keys),
  2485. skip_warmup_slots: true,
  2486. ..ClusterConfig::default()
  2487. };
  2488. let cluster = LocalCluster::new(&mut config, SocketAddrSpace::Unspecified);
  2489. let rpc_node_contact_info = cluster.get_contact_info(rpc_node_pubkey).unwrap();
  2490. let (mut block_subscribe_client, receiver) = PubsubClient::block_subscribe(
  2491. &format!(
  2492. "ws://{}",
  2493. // It is important that we subscribe to a non leader node as there
  2494. // is a race condition which can cause leader nodes to not send
  2495. // BlockUpdate notifications properly. See https://github.com/solana-labs/solana/pull/34421
  2496. &rpc_node_contact_info.rpc_pubsub().unwrap().to_string()
  2497. ),
  2498. RpcBlockSubscribeFilter::All,
  2499. Some(RpcBlockSubscribeConfig {
  2500. commitment: Some(CommitmentConfig::confirmed()),
  2501. encoding: None,
  2502. transaction_details: None,
  2503. show_rewards: None,
  2504. max_supported_transaction_version: None,
  2505. }),
  2506. )
  2507. .unwrap();
  2508. let mut received_block = false;
  2509. let max_wait = 10_000;
  2510. let start = Instant::now();
  2511. while !received_block {
  2512. assert!(
  2513. start.elapsed() <= Duration::from_millis(max_wait),
  2514. "Went too long {max_wait} ms without receiving a confirmed block",
  2515. );
  2516. let responses: Vec<_> = receiver.try_iter().collect();
  2517. // Wait for a response
  2518. if !responses.is_empty() {
  2519. for response in responses {
  2520. assert!(response.value.err.is_none());
  2521. assert!(response.value.block.is_some());
  2522. if response.value.slot > 1 {
  2523. received_block = true;
  2524. }
  2525. }
  2526. }
  2527. sleep(Duration::from_millis(100));
  2528. }
  2529. // If we don't drop the cluster, the blocking web socket service
  2530. // won't return, and the `block_subscribe_client` won't shut down
  2531. drop(cluster);
  2532. block_subscribe_client.shutdown().unwrap();
  2533. }
  2534. #[test]
  2535. #[serial]
  2536. #[allow(unused_attributes)]
  2537. fn test_oc_bad_signatures() {
  2538. solana_logger::setup_with_default(RUST_LOG_FILTER);
  2539. let total_stake = 100 * DEFAULT_NODE_STAKE;
  2540. let leader_stake = (total_stake as f64 * VOTE_THRESHOLD_SIZE) as u64;
  2541. let our_node_stake = total_stake - leader_stake;
  2542. let node_stakes = vec![leader_stake, our_node_stake];
  2543. let mut validator_config = ValidatorConfig {
  2544. require_tower: true,
  2545. ..ValidatorConfig::default_for_test()
  2546. };
  2547. validator_config.enable_default_rpc_block_subscribe();
  2548. let validator_keys = [
  2549. "28bN3xyvrP4E8LwEgtLjhnkb7cY4amQb6DrYAbAYjgRV4GAGgkVM2K7wnxnAS7WDneuavza7x21MiafLu1HkwQt4",
  2550. "2saHBBoTkLMmttmPQP8KfBkcCw45S5cwtV3wTdGCscRC8uxdgvHxpHiWXKx4LvJjNJtnNcbSv5NdheokFFqnNDt8",
  2551. ]
  2552. .iter()
  2553. .map(|s| (Arc::new(Keypair::from_base58_string(s)), true))
  2554. .take(node_stakes.len())
  2555. .collect::<Vec<_>>();
  2556. let our_id = validator_keys.last().unwrap().0.pubkey();
  2557. let mut config = ClusterConfig {
  2558. mint_lamports: total_stake,
  2559. node_stakes,
  2560. validator_configs: make_identical_validator_configs(&validator_config, 2),
  2561. validator_keys: Some(validator_keys),
  2562. skip_warmup_slots: true,
  2563. ..ClusterConfig::default()
  2564. };
  2565. let mut cluster = LocalCluster::new(&mut config, SocketAddrSpace::Unspecified);
  2566. // 2) Kill our node and start up a thread to simulate votes to control our voting behavior
  2567. let our_info = cluster.exit_node(&our_id);
  2568. let node_keypair = our_info.info.keypair;
  2569. let vote_keypair = our_info.info.voting_keypair;
  2570. info!(
  2571. "our node id: {}, vote id: {}",
  2572. node_keypair.pubkey(),
  2573. vote_keypair.pubkey()
  2574. );
  2575. // 3) Start up a spy to listen for and push votes to leader TPU
  2576. let client = cluster
  2577. .build_validator_tpu_quic_client(cluster.entry_point_info.pubkey())
  2578. .unwrap();
  2579. let cluster_funding_keypair = cluster.funding_keypair.insecure_clone();
  2580. let voter_thread_sleep_ms: usize = 100;
  2581. let num_votes_simulated = Arc::new(AtomicUsize::new(0));
  2582. let gossip_voter = cluster_tests::start_gossip_voter(
  2583. &cluster.entry_point_info.gossip().unwrap(),
  2584. &node_keypair,
  2585. |(_label, leader_vote_tx)| {
  2586. let vote = vote_parser::parse_vote_transaction(&leader_vote_tx)
  2587. .map(|(_, vote, ..)| vote)
  2588. .unwrap();
  2589. // Filter out empty votes
  2590. if !vote.is_empty() {
  2591. Some((vote, leader_vote_tx))
  2592. } else {
  2593. None
  2594. }
  2595. },
  2596. {
  2597. let node_keypair = node_keypair.insecure_clone();
  2598. let vote_keypair = vote_keypair.insecure_clone();
  2599. let num_votes_simulated = num_votes_simulated.clone();
  2600. move |vote_slot, leader_vote_tx, parsed_vote, _cluster_info| {
  2601. info!("received vote for {vote_slot}");
  2602. let vote_hash = parsed_vote.hash();
  2603. info!("Simulating vote from our node on slot {vote_slot}, hash {vote_hash}");
  2604. // Add all recent vote slots on this fork to allow cluster to pass
  2605. // vote threshold checks in replay. Note this will instantly force a
  2606. // root by this validator.
  2607. let tower_sync = TowerSync::new_from_slots(vec![vote_slot], vote_hash, None);
  2608. let bad_authorized_signer_keypair = Keypair::new();
  2609. let mut vote_tx = vote_transaction::new_tower_sync_transaction(
  2610. tower_sync,
  2611. leader_vote_tx.message.recent_blockhash,
  2612. &node_keypair,
  2613. &vote_keypair,
  2614. // Make a bad signer
  2615. &bad_authorized_signer_keypair,
  2616. None,
  2617. );
  2618. LocalCluster::send_transaction_with_retries(
  2619. &client,
  2620. &[&cluster_funding_keypair, &bad_authorized_signer_keypair],
  2621. &mut vote_tx,
  2622. 5,
  2623. )
  2624. .unwrap();
  2625. num_votes_simulated.fetch_add(1, Ordering::Relaxed);
  2626. }
  2627. },
  2628. voter_thread_sleep_ms as u64,
  2629. cluster.validators.len().saturating_sub(1),
  2630. 0,
  2631. 0,
  2632. cluster.entry_point_info.shred_version(),
  2633. );
  2634. let (mut block_subscribe_client, receiver) = PubsubClient::block_subscribe(
  2635. &format!(
  2636. "ws://{}",
  2637. &cluster.entry_point_info.rpc_pubsub().unwrap().to_string()
  2638. ),
  2639. RpcBlockSubscribeFilter::All,
  2640. Some(RpcBlockSubscribeConfig {
  2641. commitment: Some(CommitmentConfig::confirmed()),
  2642. encoding: None,
  2643. transaction_details: None,
  2644. show_rewards: None,
  2645. max_supported_transaction_version: None,
  2646. }),
  2647. )
  2648. .unwrap();
  2649. const MAX_VOTES_TO_SIMULATE: usize = 10;
  2650. // Make sure test doesn't take too long
  2651. assert!(voter_thread_sleep_ms * MAX_VOTES_TO_SIMULATE <= 1000);
  2652. loop {
  2653. let responses: Vec<_> = receiver.try_iter().collect();
  2654. // Nothing should get optimistically confirmed or rooted
  2655. assert!(responses.is_empty());
  2656. // Wait for the voter thread to attempt sufficient number of votes to give
  2657. // a chance for the violation to occur
  2658. if num_votes_simulated.load(Ordering::Relaxed) > MAX_VOTES_TO_SIMULATE {
  2659. break;
  2660. }
  2661. sleep(Duration::from_millis(100));
  2662. }
  2663. // Clean up voter thread
  2664. gossip_voter.close();
  2665. // If we don't drop the cluster, the blocking web socket service
  2666. // won't return, and the `block_subscribe_client` won't shut down
  2667. drop(cluster);
  2668. block_subscribe_client.shutdown().unwrap();
  2669. }
  2670. #[test]
  2671. #[serial]
  2672. #[ignore]
  2673. fn test_votes_land_in_fork_during_long_partition() {
  2674. let total_stake = 3 * DEFAULT_NODE_STAKE;
  2675. // Make `lighter_stake` insufficient for switching threshold
  2676. let lighter_stake = (SWITCH_FORK_THRESHOLD * total_stake as f64) as u64;
  2677. let heavier_stake = lighter_stake + 1;
  2678. let failures_stake = total_stake - lighter_stake - heavier_stake;
  2679. // Give lighter stake 30 consecutive slots before
  2680. // the heavier stake gets a single slot
  2681. let partitions: &[(usize, usize)] =
  2682. &[(heavier_stake as usize, 1), (lighter_stake as usize, 30)];
  2683. #[derive(Default)]
  2684. struct PartitionContext {
  2685. heaviest_validator_key: Pubkey,
  2686. lighter_validator_key: Pubkey,
  2687. heavier_fork_slot: Slot,
  2688. }
  2689. let on_partition_start = |_cluster: &mut LocalCluster,
  2690. validator_keys: &[Pubkey],
  2691. _dead_validator_infos: Vec<ClusterValidatorInfo>,
  2692. context: &mut PartitionContext| {
  2693. // validator_keys[0] is the validator that will be killed, i.e. the validator with
  2694. // stake == `failures_stake`
  2695. context.heaviest_validator_key = validator_keys[1];
  2696. context.lighter_validator_key = validator_keys[2];
  2697. };
  2698. let on_before_partition_resolved =
  2699. |cluster: &mut LocalCluster, context: &mut PartitionContext| {
  2700. let lighter_validator_ledger_path = cluster.ledger_path(&context.lighter_validator_key);
  2701. let heavier_validator_ledger_path =
  2702. cluster.ledger_path(&context.heaviest_validator_key);
  2703. // Wait for each node to have created and voted on its own partition
  2704. loop {
  2705. let (heavier_validator_latest_vote_slot, _) = last_vote_in_tower(
  2706. &heavier_validator_ledger_path,
  2707. &context.heaviest_validator_key,
  2708. )
  2709. .unwrap();
  2710. info!(
  2711. "Checking heavier validator's last vote {heavier_validator_latest_vote_slot} \
  2712. is on a separate fork"
  2713. );
  2714. let lighter_validator_blockstore = open_blockstore(&lighter_validator_ledger_path);
  2715. if lighter_validator_blockstore
  2716. .meta(heavier_validator_latest_vote_slot)
  2717. .unwrap()
  2718. .is_none()
  2719. {
  2720. context.heavier_fork_slot = heavier_validator_latest_vote_slot;
  2721. return;
  2722. }
  2723. sleep(Duration::from_millis(100));
  2724. }
  2725. };
  2726. let on_partition_resolved = |cluster: &mut LocalCluster, context: &mut PartitionContext| {
  2727. let lighter_validator_ledger_path = cluster.ledger_path(&context.lighter_validator_key);
  2728. let start = Instant::now();
  2729. let max_wait = ms_for_n_slots(MAX_PROCESSING_AGE as u64, DEFAULT_TICKS_PER_SLOT);
  2730. // Wait for the lighter node to switch over and root the `context.heavier_fork_slot`
  2731. loop {
  2732. assert!(
  2733. // Should finish faster than if the cluster were relying on replay vote
  2734. // refreshing to refresh the vote on blockhash expiration for the vote
  2735. // transaction.
  2736. start.elapsed() <= Duration::from_millis(max_wait),
  2737. "Went too long {max_wait} ms without a root",
  2738. );
  2739. let lighter_validator_blockstore = open_blockstore(&lighter_validator_ledger_path);
  2740. if lighter_validator_blockstore.is_root(context.heavier_fork_slot) {
  2741. info!(
  2742. "Partition resolved, new root made in {}ms",
  2743. start.elapsed().as_millis()
  2744. );
  2745. return;
  2746. }
  2747. sleep(Duration::from_millis(100));
  2748. }
  2749. };
  2750. run_kill_partition_switch_threshold(
  2751. &[(failures_stake as usize, 0)],
  2752. partitions,
  2753. None,
  2754. PartitionContext::default(),
  2755. on_partition_start,
  2756. on_before_partition_resolved,
  2757. on_partition_resolved,
  2758. );
  2759. }
  2760. fn setup_transfer_scan_threads(
  2761. num_starting_accounts: usize,
  2762. exit: Arc<AtomicBool>,
  2763. scan_commitment: CommitmentConfig,
  2764. update_client_receiver: Receiver<QuicTpuClient>,
  2765. scan_client_receiver: Receiver<QuicTpuClient>,
  2766. ) -> (
  2767. JoinHandle<()>,
  2768. JoinHandle<()>,
  2769. Vec<(Pubkey, AccountSharedData)>,
  2770. ) {
  2771. let exit_ = exit.clone();
  2772. let starting_keypairs: Arc<Vec<Keypair>> = Arc::new(
  2773. iter::repeat_with(Keypair::new)
  2774. .take(num_starting_accounts)
  2775. .collect(),
  2776. );
  2777. let target_keypairs: Arc<Vec<Keypair>> = Arc::new(
  2778. iter::repeat_with(Keypair::new)
  2779. .take(num_starting_accounts)
  2780. .collect(),
  2781. );
  2782. let starting_accounts: Vec<(Pubkey, AccountSharedData)> = starting_keypairs
  2783. .iter()
  2784. .map(|k| {
  2785. (
  2786. k.pubkey(),
  2787. AccountSharedData::new(1, 0, &system_program::id()),
  2788. )
  2789. })
  2790. .collect();
  2791. let starting_keypairs_ = starting_keypairs.clone();
  2792. let target_keypairs_ = target_keypairs.clone();
  2793. let t_update = Builder::new()
  2794. .name("update".to_string())
  2795. .spawn(move || {
  2796. let client = update_client_receiver.recv().unwrap();
  2797. loop {
  2798. if exit_.load(Ordering::Relaxed) {
  2799. return;
  2800. }
  2801. let (blockhash, _) = client
  2802. .rpc_client()
  2803. .get_latest_blockhash_with_commitment(CommitmentConfig::processed())
  2804. .unwrap();
  2805. for i in 0..starting_keypairs_.len() {
  2806. let result = client.async_transfer(
  2807. 1,
  2808. &starting_keypairs_[i],
  2809. &target_keypairs_[i].pubkey(),
  2810. blockhash,
  2811. );
  2812. if result.is_err() {
  2813. debug!("Failed in transfer for starting keypair: {result:?}");
  2814. }
  2815. }
  2816. for i in 0..starting_keypairs_.len() {
  2817. let result = client.async_transfer(
  2818. 1,
  2819. &target_keypairs_[i],
  2820. &starting_keypairs_[i].pubkey(),
  2821. blockhash,
  2822. );
  2823. if result.is_err() {
  2824. debug!("Failed in transfer for starting keypair: {result:?}");
  2825. }
  2826. }
  2827. }
  2828. })
  2829. .unwrap();
  2830. // Scan, the total funds should add up to the original
  2831. let mut scan_commitment_config = RpcProgramAccountsConfig::default();
  2832. scan_commitment_config.account_config.commitment = Some(scan_commitment);
  2833. let tracked_pubkeys: HashSet<Pubkey> = starting_keypairs
  2834. .iter()
  2835. .chain(target_keypairs.iter())
  2836. .map(|k| k.pubkey())
  2837. .collect();
  2838. let expected_total_balance = num_starting_accounts as u64;
  2839. let t_scan = Builder::new()
  2840. .name("scan".to_string())
  2841. .spawn(move || {
  2842. let client = scan_client_receiver.recv().unwrap();
  2843. loop {
  2844. if exit.load(Ordering::Relaxed) {
  2845. return;
  2846. }
  2847. if let Some(total_scan_balance) = client
  2848. .rpc_client()
  2849. .get_program_accounts_with_config(
  2850. &system_program::id(),
  2851. scan_commitment_config.clone(),
  2852. )
  2853. .ok()
  2854. .map(|result| {
  2855. result
  2856. .into_iter()
  2857. .map(|(key, account)| {
  2858. if tracked_pubkeys.contains(&key) {
  2859. account.lamports
  2860. } else {
  2861. 0
  2862. }
  2863. })
  2864. .sum::<u64>()
  2865. })
  2866. {
  2867. assert_eq!(total_scan_balance, expected_total_balance);
  2868. }
  2869. }
  2870. })
  2871. .unwrap();
  2872. (t_update, t_scan, starting_accounts)
  2873. }
  2874. fn run_test_load_program_accounts(scan_commitment: CommitmentConfig) {
  2875. solana_logger::setup_with_default(RUST_LOG_FILTER);
  2876. // First set up the cluster with 2 nodes
  2877. let slots_per_epoch = 2048;
  2878. let node_stakes = vec![51 * DEFAULT_NODE_STAKE, 50 * DEFAULT_NODE_STAKE];
  2879. let validator_keys: Vec<_> = [
  2880. "4qhhXNTbKD1a5vxDDLZcHKj7ELNeiivtUBxn3wUK1F5VRsQVP89VUhfXqSfgiFB14GfuBgtrQ96n9NvWQADVkcCg",
  2881. "3kHBzVwie5vTEaY6nFCPeFT8qDpoXzn7dCEioGRNBTnUDpvwnG85w8Wq63gVWpVTP8k2a8cgcWRjSXyUkEygpXWS",
  2882. ]
  2883. .iter()
  2884. .map(|s| (Arc::new(Keypair::from_base58_string(s)), true))
  2885. .take(node_stakes.len())
  2886. .collect();
  2887. let num_starting_accounts = 1000;
  2888. let exit = Arc::new(AtomicBool::new(false));
  2889. let (update_client_sender, update_client_receiver) = unbounded();
  2890. let (scan_client_sender, scan_client_receiver) = unbounded();
  2891. // Setup the update/scan threads
  2892. let (t_update, t_scan, starting_accounts) = setup_transfer_scan_threads(
  2893. num_starting_accounts,
  2894. exit.clone(),
  2895. scan_commitment,
  2896. update_client_receiver,
  2897. scan_client_receiver,
  2898. );
  2899. let mut config = ClusterConfig {
  2900. mint_lamports: DEFAULT_MINT_LAMPORTS + node_stakes.iter().sum::<u64>(),
  2901. node_stakes: node_stakes.clone(),
  2902. validator_configs: make_identical_validator_configs(
  2903. &ValidatorConfig::default_for_test(),
  2904. node_stakes.len(),
  2905. ),
  2906. validator_keys: Some(validator_keys),
  2907. slots_per_epoch,
  2908. stakers_slot_offset: slots_per_epoch,
  2909. skip_warmup_slots: true,
  2910. additional_accounts: starting_accounts,
  2911. ..ClusterConfig::default()
  2912. };
  2913. let cluster = LocalCluster::new(&mut config, SocketAddrSpace::Unspecified);
  2914. // Give the threads a client to use for querying the cluster
  2915. let all_pubkeys = cluster.get_node_pubkeys();
  2916. let other_validator_id = all_pubkeys
  2917. .into_iter()
  2918. .find(|x| x != cluster.entry_point_info.pubkey())
  2919. .unwrap();
  2920. let client = cluster
  2921. .build_validator_tpu_quic_client(cluster.entry_point_info.pubkey())
  2922. .unwrap();
  2923. update_client_sender.send(client).unwrap();
  2924. let scan_client = cluster
  2925. .build_validator_tpu_quic_client(&other_validator_id)
  2926. .unwrap();
  2927. scan_client_sender.send(scan_client).unwrap();
  2928. // Wait for some roots to pass
  2929. cluster.check_for_new_roots(
  2930. 40,
  2931. "run_test_load_program_accounts",
  2932. SocketAddrSpace::Unspecified,
  2933. );
  2934. // Exit and ensure no violations of consistency were found
  2935. exit.store(true, Ordering::Relaxed);
  2936. t_update.join().unwrap();
  2937. t_scan.join().unwrap();
  2938. }
  2939. #[test]
  2940. #[serial]
  2941. fn test_no_lockout_violation_with_tower() {
  2942. do_test_lockout_violation_with_or_without_tower(true);
  2943. }
  2944. #[test]
  2945. #[serial]
  2946. fn test_lockout_violation_without_tower() {
  2947. do_test_lockout_violation_with_or_without_tower(false);
  2948. }
  2949. // A bit convoluted test case; but this roughly follows this test theoretical scenario:
  2950. // Validator A, B, C have 31, 36, 33 % of stake respectively. Leader schedule is split, first half
  2951. // of the test B is always leader, second half C is.
  2952. // We don't give validator A any slots because it's going to be deleting its ledger,
  2953. // so it may create different blocks for slots it's already created blocks for on a different fork
  2954. //
  2955. // Step 1: Kill C, only A and B should be running
  2956. //
  2957. // base_slot -> next_slot_on_a (Wait for A to vote)
  2958. //
  2959. // Step 2:
  2960. // Kill A and B once we verify that A has voted voted on some `next_slot_on_a` >= 1.
  2961. // Copy B's ledger to A and C but only up to slot `next_slot_on_a`.
  2962. //
  2963. // Step 3:
  2964. // Restart validator C to make it produce blocks on a fork from `base_slot`
  2965. // that doesn't include `next_slot_on_a`. Wait for it to vote on its own fork.
  2966. //
  2967. // base_slot -> next_slot_on_c
  2968. //
  2969. // Step 4: Restart `A` which had 31% of the stake, it's missing `next_slot_on_a` in
  2970. // its ledger since we copied the ledger from B excluding this slot, so it sees
  2971. //
  2972. // base_slot -> next_slot_on_c
  2973. //
  2974. // Step 5:
  2975. // Without the persisted tower:
  2976. // `A` would choose to vote on the new fork from C on `next_slot_on_c`
  2977. //
  2978. // With the persisted tower:
  2979. // `A` should not be able to generate a switching proof.
  2980. //
  2981. fn do_test_lockout_violation_with_or_without_tower(with_tower: bool) {
  2982. solana_logger::setup_with("info");
  2983. // First set up the cluster with 4 nodes
  2984. let slots_per_epoch = 2048;
  2985. let node_stakes = vec![
  2986. 31 * DEFAULT_NODE_STAKE,
  2987. 36 * DEFAULT_NODE_STAKE,
  2988. 33 * DEFAULT_NODE_STAKE,
  2989. ];
  2990. let validator_b_last_leader_slot: Slot = 8;
  2991. let truncated_slots: Slot = 100;
  2992. // Each pubkeys are prefixed with A, B, C
  2993. let validator_keys = [
  2994. "28bN3xyvrP4E8LwEgtLjhnkb7cY4amQb6DrYAbAYjgRV4GAGgkVM2K7wnxnAS7WDneuavza7x21MiafLu1HkwQt4",
  2995. "2saHBBoTkLMmttmPQP8KfBkcCw45S5cwtV3wTdGCscRC8uxdgvHxpHiWXKx4LvJjNJtnNcbSv5NdheokFFqnNDt8",
  2996. "4mx9yoFBeYasDKBGDWCTWGJdWuJCKbgqmuP8bN9umybCh5Jzngw7KQxe99Rf5uzfyzgba1i65rJW4Wqk7Ab5S8ye",
  2997. ]
  2998. .iter()
  2999. .map(|s| (Arc::new(Keypair::from_base58_string(s)), true))
  3000. .take(node_stakes.len())
  3001. .collect::<Vec<_>>();
  3002. let validators = validator_keys
  3003. .iter()
  3004. .map(|(kp, _)| kp.pubkey())
  3005. .collect::<Vec<_>>();
  3006. let (validator_a_pubkey, validator_b_pubkey, validator_c_pubkey) =
  3007. (validators[0], validators[1], validators[2]);
  3008. // Disable voting on all validators other than validator B
  3009. let mut default_config = ValidatorConfig::default_for_test();
  3010. // Ensure B can make leader blocks up till the fork slot, and give the remaining slots to C. This is
  3011. // also important so `C` doesn't run into NoPropagatedConfirmation errors on making its first forked
  3012. // slot.
  3013. //
  3014. // Don't give validator A any slots because it's going to be deleting its ledger, so it may create
  3015. // versions of slots it's already created, but on a different fork.
  3016. let validator_to_slots = vec![
  3017. (
  3018. validator_b_pubkey,
  3019. validator_b_last_leader_slot as usize + 1,
  3020. ),
  3021. (validator_c_pubkey, DEFAULT_SLOTS_PER_EPOCH as usize),
  3022. ];
  3023. // Trick C into not producing any blocks during this time, in case its leader slots come up before we can
  3024. // kill the validator. We don't want any forks during the time validator B is producing its initial blocks.
  3025. let c_validator_to_slots = vec![(validator_b_pubkey, DEFAULT_SLOTS_PER_EPOCH as usize)];
  3026. let c_leader_schedule = create_custom_leader_schedule(c_validator_to_slots.into_iter());
  3027. let leader_schedule = Arc::new(create_custom_leader_schedule(
  3028. validator_to_slots.into_iter(),
  3029. ));
  3030. for slot in 0..=validator_b_last_leader_slot {
  3031. assert_eq!(leader_schedule[slot], validator_b_pubkey);
  3032. }
  3033. default_config.fixed_leader_schedule = Some(FixedSchedule {
  3034. leader_schedule: leader_schedule.clone(),
  3035. });
  3036. let mut validator_configs =
  3037. make_identical_validator_configs(&default_config, node_stakes.len());
  3038. // Disable voting on validator C
  3039. validator_configs[2].voting_disabled = true;
  3040. // C should not produce any blocks at this time
  3041. validator_configs[2].fixed_leader_schedule = Some(FixedSchedule {
  3042. leader_schedule: Arc::new(c_leader_schedule),
  3043. });
  3044. let mut config = ClusterConfig {
  3045. mint_lamports: DEFAULT_MINT_LAMPORTS + node_stakes.iter().sum::<u64>(),
  3046. node_stakes,
  3047. validator_configs,
  3048. validator_keys: Some(validator_keys),
  3049. slots_per_epoch,
  3050. stakers_slot_offset: slots_per_epoch,
  3051. skip_warmup_slots: true,
  3052. ..ClusterConfig::default()
  3053. };
  3054. let mut cluster = LocalCluster::new(&mut config, SocketAddrSpace::Unspecified);
  3055. let val_a_ledger_path = cluster.ledger_path(&validator_a_pubkey);
  3056. let val_b_ledger_path = cluster.ledger_path(&validator_b_pubkey);
  3057. let val_c_ledger_path = cluster.ledger_path(&validator_c_pubkey);
  3058. info!("val_a {validator_a_pubkey} ledger path {val_a_ledger_path:?}");
  3059. info!("val_b {validator_b_pubkey} ledger path {val_b_ledger_path:?}");
  3060. info!("val_c {validator_c_pubkey} ledger path {val_c_ledger_path:?}");
  3061. info!("Exiting validator C");
  3062. let mut validator_c_info = cluster.exit_node(&validator_c_pubkey);
  3063. info!("Waiting on validator A to vote");
  3064. // Step 1: Wait for validator A to vote so the tower file exists, and so we can determine the
  3065. // `base_slot` and `next_slot_on_a`
  3066. loop {
  3067. if let Some((last_vote, _)) = last_vote_in_tower(&val_a_ledger_path, &validator_a_pubkey) {
  3068. if last_vote >= 1 {
  3069. break;
  3070. }
  3071. }
  3072. sleep(Duration::from_millis(100));
  3073. }
  3074. // kill A and B
  3075. info!("Exiting validators A and B");
  3076. let _validator_b_info = cluster.exit_node(&validator_b_pubkey);
  3077. let validator_a_info = cluster.exit_node(&validator_a_pubkey);
  3078. let next_slot_on_a = last_vote_in_tower(&val_a_ledger_path, &validator_a_pubkey)
  3079. .unwrap()
  3080. .0;
  3081. let base_slot = next_slot_on_a - 1;
  3082. info!("base slot: {base_slot}, next_slot_on_a: {next_slot_on_a}");
  3083. // Step 2:
  3084. // Truncate ledger, copy over B's ledger to C
  3085. info!("Create validator C's ledger");
  3086. {
  3087. // first copy from validator B's ledger
  3088. std::fs::remove_dir_all(&validator_c_info.info.ledger_path).unwrap();
  3089. let mut opt = fs_extra::dir::CopyOptions::new();
  3090. opt.copy_inside = true;
  3091. fs_extra::dir::copy(&val_b_ledger_path, &val_c_ledger_path, &opt).unwrap();
  3092. // Remove B's tower in C's new copied ledger
  3093. remove_tower(&val_c_ledger_path, &validator_b_pubkey);
  3094. let blockstore = open_blockstore(&val_c_ledger_path);
  3095. purge_slots_with_count(&blockstore, next_slot_on_a, truncated_slots);
  3096. }
  3097. info!("Create validator A's ledger");
  3098. {
  3099. // Now we copy these blocks to A
  3100. let b_blockstore = open_blockstore(&val_b_ledger_path);
  3101. let a_blockstore = open_blockstore(&val_a_ledger_path);
  3102. copy_blocks(next_slot_on_a, &b_blockstore, &a_blockstore, false);
  3103. // Purge unnecessary slots
  3104. purge_slots_with_count(&a_blockstore, next_slot_on_a + 1, truncated_slots);
  3105. }
  3106. {
  3107. let blockstore = open_blockstore(&val_a_ledger_path);
  3108. if !with_tower {
  3109. info!("Removing tower!");
  3110. remove_tower(&val_a_ledger_path, &validator_a_pubkey);
  3111. // Remove next_slot_on_a from ledger to force validator A to select
  3112. // votes_on_c_fork. Otherwise, in the test case without a tower,
  3113. // the validator A will immediately vote for 27 on restart, because it
  3114. // hasn't gotten the heavier fork from validator C yet.
  3115. // Then it will be stuck on 27 unable to switch because C doesn't
  3116. // have enough stake to generate a switching proof
  3117. purge_slots_with_count(&blockstore, next_slot_on_a, truncated_slots);
  3118. } else {
  3119. info!("Not removing tower!");
  3120. }
  3121. }
  3122. // Step 3:
  3123. // Run validator C only to make it produce and vote on its own fork.
  3124. info!("Restart validator C again!!!");
  3125. validator_c_info.config.voting_disabled = false;
  3126. // C should now produce blocks
  3127. validator_c_info.config.fixed_leader_schedule = Some(FixedSchedule { leader_schedule });
  3128. cluster.restart_node(
  3129. &validator_c_pubkey,
  3130. validator_c_info,
  3131. SocketAddrSpace::Unspecified,
  3132. );
  3133. let mut votes_on_c_fork = std::collections::BTreeSet::new();
  3134. let mut last_vote = 0;
  3135. let now = Instant::now();
  3136. loop {
  3137. let elapsed = now.elapsed();
  3138. assert!(
  3139. elapsed <= Duration::from_secs(30),
  3140. "C failed to create a fork past {base_slot} in {} seconds, last_vote {last_vote}, \
  3141. votes_on_c_fork: {votes_on_c_fork:?}",
  3142. elapsed.as_secs(),
  3143. );
  3144. sleep(Duration::from_millis(100));
  3145. if let Some((newest_vote, _)) = last_vote_in_tower(&val_c_ledger_path, &validator_c_pubkey)
  3146. {
  3147. last_vote = newest_vote;
  3148. if last_vote != base_slot {
  3149. votes_on_c_fork.insert(last_vote);
  3150. // Collect 4 votes
  3151. if votes_on_c_fork.len() >= 4 {
  3152. break;
  3153. }
  3154. }
  3155. }
  3156. }
  3157. assert!(!votes_on_c_fork.is_empty());
  3158. info!("Collected validator C's votes: {votes_on_c_fork:?}");
  3159. // Step 4:
  3160. // verify whether there was violation or not
  3161. info!("Restart validator A again!!!");
  3162. cluster.restart_node(
  3163. &validator_a_pubkey,
  3164. validator_a_info,
  3165. SocketAddrSpace::Unspecified,
  3166. );
  3167. // monitor for actual votes from validator A
  3168. let mut bad_vote_detected = false;
  3169. let mut a_votes = vec![];
  3170. for _ in 0..100 {
  3171. sleep(Duration::from_millis(100));
  3172. if let Some((last_vote, _)) = last_vote_in_tower(&val_a_ledger_path, &validator_a_pubkey) {
  3173. a_votes.push(last_vote);
  3174. let blockstore = open_blockstore(&val_a_ledger_path);
  3175. let mut ancestors = AncestorIterator::new(last_vote, &blockstore);
  3176. if ancestors.any(|a| votes_on_c_fork.contains(&a)) {
  3177. bad_vote_detected = true;
  3178. break;
  3179. }
  3180. }
  3181. }
  3182. info!("Observed A's votes on: {a_votes:?}");
  3183. // an elaborate way of assert!(with_tower && !bad_vote_detected || ...)
  3184. let expects_optimistic_confirmation_violation = !with_tower;
  3185. if bad_vote_detected != expects_optimistic_confirmation_violation {
  3186. if bad_vote_detected {
  3187. panic!("No violation expected because of persisted tower!");
  3188. } else {
  3189. panic!("Violation expected because of removed persisted tower!");
  3190. }
  3191. } else if bad_vote_detected {
  3192. info!(
  3193. "THIS TEST expected violations. And indeed, there was some, because of removed \
  3194. persisted tower."
  3195. );
  3196. } else {
  3197. info!(
  3198. "THIS TEST expected no violation. And indeed, there was none, thanks to persisted \
  3199. tower."
  3200. );
  3201. }
  3202. }
  3203. #[test]
  3204. #[serial]
  3205. // Steps in this test:
  3206. // We want to create a situation like:
  3207. /*
  3208. 1 (2%, killed and restarted) --- 200 (37%, lighter fork)
  3209. /
  3210. 0
  3211. \-------- 4 (38%, heavier fork)
  3212. */
  3213. // where the 2% that voted on slot 1 don't see their votes land in a block
  3214. // due to blockhash expiration, and thus without resigning their votes with
  3215. // a newer blockhash, will deem slot 4 the heavier fork and try to switch to
  3216. // slot 4, which doesn't pass the switch threshold. This stalls the network.
  3217. // We do this by:
  3218. // 1) Creating a partition so all three nodes don't see each other
  3219. // 2) Kill the validator with 2%
  3220. // 3) Wait for longer than blockhash expiration
  3221. // 4) Copy in the lighter fork's blocks up, *only* up to the first slot in the lighter fork
  3222. // (not all the blocks on the lighter fork!), call this slot `L`
  3223. // 5) Restart the validator with 2% so that he votes on `L`, but the vote doesn't land
  3224. // due to blockhash expiration
  3225. // 6) Resolve the partition so that the 2% repairs the other fork, and tries to switch,
  3226. // stalling the network.
  3227. fn test_fork_choice_refresh_old_votes() {
  3228. solana_logger::setup_with_default(RUST_LOG_FILTER);
  3229. let max_switch_threshold_failure_pct = 1.0 - 2.0 * SWITCH_FORK_THRESHOLD;
  3230. let total_stake = 100 * DEFAULT_NODE_STAKE;
  3231. let max_failures_stake = (max_switch_threshold_failure_pct * total_stake as f64) as u64;
  3232. // 1% less than the failure stake, where the 2% is allocated to a validator that
  3233. // has no leader slots and thus won't be able to vote on its own fork.
  3234. let failures_stake = max_failures_stake;
  3235. let total_alive_stake = total_stake - failures_stake;
  3236. let alive_stake_1 = total_alive_stake / 2 - 1;
  3237. let alive_stake_2 = total_alive_stake - alive_stake_1 - 1;
  3238. // Heavier fork still doesn't have enough stake to switch. Both branches need
  3239. // the vote to land from the validator with `alive_stake_3` to allow the other
  3240. // fork to switch.
  3241. let alive_stake_3 = 2 * DEFAULT_NODE_STAKE;
  3242. assert!(alive_stake_1 < alive_stake_2);
  3243. assert!(alive_stake_1 + alive_stake_3 > alive_stake_2);
  3244. let num_lighter_partition_slots_per_rotation = 8;
  3245. // ratio of total number of leader slots to the number of leader slots allocated
  3246. // to the lighter partition
  3247. let total_slots_to_lighter_partition_ratio = 2;
  3248. let partitions: &[(usize, usize)] = &[
  3249. (
  3250. alive_stake_1 as usize,
  3251. num_lighter_partition_slots_per_rotation,
  3252. ),
  3253. (
  3254. alive_stake_2 as usize,
  3255. (total_slots_to_lighter_partition_ratio - 1) * num_lighter_partition_slots_per_rotation,
  3256. ),
  3257. (alive_stake_3 as usize, 0),
  3258. ];
  3259. #[derive(Default)]
  3260. struct PartitionContext {
  3261. smallest_validator_info: Option<ClusterValidatorInfo>,
  3262. lighter_fork_validator_key: Pubkey,
  3263. heaviest_validator_key: Pubkey,
  3264. first_slot_in_lighter_partition: Slot,
  3265. }
  3266. let on_partition_start = |cluster: &mut LocalCluster,
  3267. validator_keys: &[Pubkey],
  3268. _: Vec<ClusterValidatorInfo>,
  3269. context: &mut PartitionContext| {
  3270. // Kill validator with alive_stake_3, second in `partitions` slice
  3271. let smallest_validator_key = &validator_keys[3];
  3272. let info = cluster.exit_node(smallest_validator_key);
  3273. context.smallest_validator_info = Some(info);
  3274. // validator_keys[0] is the validator that will be killed, i.e. the validator with
  3275. // stake == `failures_stake`
  3276. context.lighter_fork_validator_key = validator_keys[1];
  3277. // Third in `partitions` slice
  3278. context.heaviest_validator_key = validator_keys[2];
  3279. };
  3280. let ticks_per_slot = 32;
  3281. let on_before_partition_resolved =
  3282. |cluster: &mut LocalCluster, context: &mut PartitionContext| {
  3283. // Equal to ms_per_slot * MAX_PROCESSING_AGE, rounded up
  3284. let sleep_time_ms = ms_for_n_slots(
  3285. MAX_PROCESSING_AGE as u64 * total_slots_to_lighter_partition_ratio as u64,
  3286. ticks_per_slot,
  3287. );
  3288. info!("Wait for blockhashes to expire, {sleep_time_ms} ms");
  3289. // Wait for blockhashes to expire
  3290. sleep(Duration::from_millis(sleep_time_ms));
  3291. let smallest_validator_key = context
  3292. .smallest_validator_info
  3293. .as_ref()
  3294. .unwrap()
  3295. .info
  3296. .keypair
  3297. .pubkey();
  3298. let smallest_ledger_path = context
  3299. .smallest_validator_info
  3300. .as_ref()
  3301. .unwrap()
  3302. .info
  3303. .ledger_path
  3304. .clone();
  3305. info!(
  3306. "smallest validator key: {smallest_validator_key}, path: {smallest_ledger_path:?}"
  3307. );
  3308. let lighter_fork_ledger_path = cluster.ledger_path(&context.lighter_fork_validator_key);
  3309. let heaviest_ledger_path = cluster.ledger_path(&context.heaviest_validator_key);
  3310. // Wait for blockhashes to expire
  3311. let mut distance_from_tip: usize;
  3312. loop {
  3313. // Get latest votes. We make sure to wait until the vote has landed in
  3314. // blockstore. This is important because if we were the leader for the block there
  3315. // is a possibility of voting before broadcast has inserted in blockstore.
  3316. let lighter_fork_latest_vote = wait_for_last_vote_in_tower_to_land_in_ledger(
  3317. &lighter_fork_ledger_path,
  3318. &context.lighter_fork_validator_key,
  3319. )
  3320. .unwrap();
  3321. let heaviest_fork_latest_vote = wait_for_last_vote_in_tower_to_land_in_ledger(
  3322. &heaviest_ledger_path,
  3323. &context.heaviest_validator_key,
  3324. )
  3325. .unwrap();
  3326. // Check if sufficient blockhashes have expired on the smaller fork
  3327. {
  3328. let smallest_blockstore = open_blockstore(&smallest_ledger_path);
  3329. let lighter_fork_blockstore = open_blockstore(&lighter_fork_ledger_path);
  3330. let heaviest_blockstore = open_blockstore(&heaviest_ledger_path);
  3331. info!("Opened blockstores");
  3332. // Find the first slot on the smaller fork
  3333. let lighter_ancestors: BTreeSet<Slot> =
  3334. std::iter::once(lighter_fork_latest_vote)
  3335. .chain(AncestorIterator::new(
  3336. lighter_fork_latest_vote,
  3337. &lighter_fork_blockstore,
  3338. ))
  3339. .collect();
  3340. let heavier_ancestors: BTreeSet<Slot> =
  3341. std::iter::once(heaviest_fork_latest_vote)
  3342. .chain(AncestorIterator::new(
  3343. heaviest_fork_latest_vote,
  3344. &heaviest_blockstore,
  3345. ))
  3346. .collect();
  3347. let (different_ancestor_index, different_ancestor) = lighter_ancestors
  3348. .iter()
  3349. .enumerate()
  3350. .zip(heavier_ancestors.iter())
  3351. .find(|((_index, lighter_fork_ancestor), heavier_fork_ancestor)| {
  3352. lighter_fork_ancestor != heavier_fork_ancestor
  3353. })
  3354. .unwrap()
  3355. .0;
  3356. let last_common_ancestor_index = different_ancestor_index - 1;
  3357. // It's critical that the heavier fork has at least one vote on it.
  3358. // This is important because the smallest validator must see a vote on the heavier fork
  3359. // to avoid voting again on its own fork.
  3360. // Because we don't have a simple method of parsing blockstore for all votes, we proxy this check
  3361. // by ensuring the heavier fork was long enough to land a vote. The minimum length would be 4 more
  3362. // than the last common ancestor N, because the first vote would be made at least by N+3 (if threshold check failed on slot N+1),
  3363. // and then would land by slot N + 4.
  3364. assert!(heavier_ancestors.len() > last_common_ancestor_index + 4);
  3365. context.first_slot_in_lighter_partition = *different_ancestor;
  3366. distance_from_tip = lighter_ancestors.len() - different_ancestor_index - 1;
  3367. info!(
  3368. "Distance in number of blocks between earliest slot {} and latest slot {} \
  3369. on lighter partition is {}",
  3370. context.first_slot_in_lighter_partition,
  3371. lighter_fork_latest_vote,
  3372. distance_from_tip
  3373. );
  3374. if distance_from_tip > MAX_PROCESSING_AGE {
  3375. // Must have been updated in the above loop
  3376. assert!(context.first_slot_in_lighter_partition != 0);
  3377. info!(
  3378. "First slot in lighter partition is {}",
  3379. context.first_slot_in_lighter_partition
  3380. );
  3381. // Copy all the blocks from the smaller partition up to `first_slot_in_lighter_partition`
  3382. // into the smallest validator's blockstore so that it will attempt to refresh
  3383. copy_blocks(
  3384. lighter_fork_latest_vote,
  3385. &lighter_fork_blockstore,
  3386. &smallest_blockstore,
  3387. false,
  3388. );
  3389. // Also copy all the blocks from the heavier partition so the smallest validator will
  3390. // not vote again on its own fork
  3391. copy_blocks(
  3392. heaviest_fork_latest_vote,
  3393. &heaviest_blockstore,
  3394. &smallest_blockstore,
  3395. false,
  3396. );
  3397. // Simulate a vote for the `first_slot_in_lighter_partition`
  3398. let bank_hash = lighter_fork_blockstore
  3399. .get_bank_hash(context.first_slot_in_lighter_partition)
  3400. .unwrap();
  3401. cluster_tests::apply_votes_to_tower(
  3402. &context
  3403. .smallest_validator_info
  3404. .as_ref()
  3405. .unwrap()
  3406. .info
  3407. .keypair,
  3408. vec![(context.first_slot_in_lighter_partition, bank_hash)],
  3409. smallest_ledger_path,
  3410. );
  3411. drop(smallest_blockstore);
  3412. break;
  3413. }
  3414. }
  3415. sleep(Duration::from_millis(ms_for_n_slots(
  3416. ((MAX_PROCESSING_AGE - distance_from_tip)
  3417. * total_slots_to_lighter_partition_ratio) as u64,
  3418. ticks_per_slot,
  3419. )));
  3420. }
  3421. // Restart the smallest validator that we killed earlier in `on_partition_start()`
  3422. cluster.restart_node(
  3423. &smallest_validator_key,
  3424. context.smallest_validator_info.take().unwrap(),
  3425. SocketAddrSpace::Unspecified,
  3426. );
  3427. // Now resolve partition, allow validator to see the fork with the heavier validator,
  3428. // but the fork it's currently on is the heaviest, if only its own vote landed!
  3429. };
  3430. // Check that new roots were set after the partition resolves (gives time
  3431. // for lockouts built during partition to resolve and gives validators an opportunity
  3432. // to try and switch forks)
  3433. let on_partition_resolved = |cluster: &mut LocalCluster, context: &mut PartitionContext| {
  3434. // Wait until a root is made past the first slot on the correct fork
  3435. cluster.check_min_slot_is_rooted(
  3436. context.first_slot_in_lighter_partition,
  3437. "test_fork_choice_refresh_old_votes",
  3438. SocketAddrSpace::Unspecified,
  3439. );
  3440. // Check that the correct fork was rooted
  3441. let heaviest_ledger_path = cluster.ledger_path(&context.heaviest_validator_key);
  3442. let heaviest_blockstore = open_blockstore(&heaviest_ledger_path);
  3443. info!(
  3444. "checking that {} was rooted in {:?}",
  3445. context.first_slot_in_lighter_partition, heaviest_ledger_path
  3446. );
  3447. assert!(heaviest_blockstore.is_root(context.first_slot_in_lighter_partition));
  3448. };
  3449. run_kill_partition_switch_threshold(
  3450. &[(failures_stake as usize - 1, 0)],
  3451. partitions,
  3452. Some(ticks_per_slot),
  3453. PartitionContext::default(),
  3454. on_partition_start,
  3455. on_before_partition_resolved,
  3456. on_partition_resolved,
  3457. );
  3458. }
  3459. #[test]
  3460. #[serial]
  3461. fn test_kill_heaviest_partition() {
  3462. // This test:
  3463. // 1) Spins up four partitions, the heaviest being the first with more stake
  3464. // 2) Schedules the other validators for sufficient slots in the schedule
  3465. // so that they will still be locked out of voting for the major partition
  3466. // when the partition resolves
  3467. // 3) Kills the most staked partition. Validators are locked out, but should all
  3468. // eventually choose the major partition
  3469. // 4) Check for recovery
  3470. let num_slots_per_validator = 8;
  3471. let partitions: [usize; 4] = [
  3472. 11 * DEFAULT_NODE_STAKE as usize,
  3473. 10 * DEFAULT_NODE_STAKE as usize,
  3474. 10 * DEFAULT_NODE_STAKE as usize,
  3475. 10 * DEFAULT_NODE_STAKE as usize,
  3476. ];
  3477. let (leader_schedule, validator_keys) = create_custom_leader_schedule_with_random_keys(&[
  3478. num_slots_per_validator * (partitions.len() - 1),
  3479. num_slots_per_validator,
  3480. num_slots_per_validator,
  3481. num_slots_per_validator,
  3482. ]);
  3483. let empty = |_: &mut LocalCluster, _: &mut ()| {};
  3484. let validator_to_kill = validator_keys[0].pubkey();
  3485. let on_partition_resolved = |cluster: &mut LocalCluster, _: &mut ()| {
  3486. info!("Killing validator with id: {validator_to_kill}");
  3487. cluster.exit_node(&validator_to_kill);
  3488. cluster.check_for_new_roots(16, "PARTITION_TEST", SocketAddrSpace::Unspecified);
  3489. };
  3490. run_cluster_partition(
  3491. &partitions,
  3492. Some((leader_schedule, validator_keys)),
  3493. (),
  3494. empty,
  3495. empty,
  3496. on_partition_resolved,
  3497. None,
  3498. vec![],
  3499. )
  3500. }
  3501. #[test]
  3502. #[serial]
  3503. fn test_kill_partition_switch_threshold_no_progress() {
  3504. let max_switch_threshold_failure_pct = 1.0 - 2.0 * SWITCH_FORK_THRESHOLD;
  3505. let total_stake = 10_000 * DEFAULT_NODE_STAKE;
  3506. let max_failures_stake = (max_switch_threshold_failure_pct * total_stake as f64) as u64;
  3507. let failures_stake = max_failures_stake;
  3508. let total_alive_stake = total_stake - failures_stake;
  3509. let alive_stake_1 = total_alive_stake / 2;
  3510. let alive_stake_2 = total_alive_stake - alive_stake_1;
  3511. // Check that no new roots were set 400 slots after partition resolves (gives time
  3512. // for lockouts built during partition to resolve and gives validators an opportunity
  3513. // to try and switch forks)
  3514. let on_partition_start =
  3515. |_: &mut LocalCluster, _: &[Pubkey], _: Vec<ClusterValidatorInfo>, _: &mut ()| {};
  3516. let on_before_partition_resolved = |_: &mut LocalCluster, _: &mut ()| {};
  3517. let on_partition_resolved = |cluster: &mut LocalCluster, _: &mut ()| {
  3518. cluster.check_no_new_roots(400, "PARTITION_TEST", SocketAddrSpace::Unspecified);
  3519. };
  3520. // This kills `max_failures_stake`, so no progress should be made
  3521. run_kill_partition_switch_threshold(
  3522. &[(failures_stake as usize, 16)],
  3523. &[(alive_stake_1 as usize, 8), (alive_stake_2 as usize, 8)],
  3524. None,
  3525. (),
  3526. on_partition_start,
  3527. on_before_partition_resolved,
  3528. on_partition_resolved,
  3529. );
  3530. }
  3531. #[test]
  3532. #[serial]
  3533. fn test_kill_partition_switch_threshold_progress() {
  3534. let max_switch_threshold_failure_pct = 1.0 - 2.0 * SWITCH_FORK_THRESHOLD;
  3535. let total_stake = 10_000 * DEFAULT_NODE_STAKE;
  3536. // Kill `< max_failures_stake` of the validators
  3537. let max_failures_stake = (max_switch_threshold_failure_pct * total_stake as f64) as u64;
  3538. let failures_stake = max_failures_stake - 1;
  3539. let total_alive_stake = total_stake - failures_stake;
  3540. // Partition the remaining alive validators, should still make progress
  3541. // once the partition resolves
  3542. let alive_stake_1 = total_alive_stake / 2;
  3543. let alive_stake_2 = total_alive_stake - alive_stake_1;
  3544. let bigger = std::cmp::max(alive_stake_1, alive_stake_2);
  3545. let smaller = std::cmp::min(alive_stake_1, alive_stake_2);
  3546. // At least one of the forks must have > SWITCH_FORK_THRESHOLD in order
  3547. // to guarantee switching proofs can be created. Make sure the other fork
  3548. // is <= SWITCH_FORK_THRESHOLD to make sure progress can be made. Caches
  3549. // bugs such as liveness issues bank-weighted fork choice, which may stall
  3550. // because the fork with less stake could have more weight, but other fork would:
  3551. // 1) Not be able to generate a switching proof
  3552. // 2) Other more staked fork stops voting, so doesn't catch up in bank weight.
  3553. assert!(
  3554. bigger as f64 / total_stake as f64 > SWITCH_FORK_THRESHOLD
  3555. && smaller as f64 / total_stake as f64 <= SWITCH_FORK_THRESHOLD
  3556. );
  3557. let on_partition_start =
  3558. |_: &mut LocalCluster, _: &[Pubkey], _: Vec<ClusterValidatorInfo>, _: &mut ()| {};
  3559. let on_before_partition_resolved = |_: &mut LocalCluster, _: &mut ()| {};
  3560. let on_partition_resolved = |cluster: &mut LocalCluster, _: &mut ()| {
  3561. cluster.check_for_new_roots(16, "PARTITION_TEST", SocketAddrSpace::Unspecified);
  3562. };
  3563. run_kill_partition_switch_threshold(
  3564. &[(failures_stake as usize, 16)],
  3565. &[(alive_stake_1 as usize, 8), (alive_stake_2 as usize, 8)],
  3566. None,
  3567. (),
  3568. on_partition_start,
  3569. on_before_partition_resolved,
  3570. on_partition_resolved,
  3571. );
  3572. }
  3573. #[test]
  3574. #[serial]
  3575. #[allow(unused_attributes)]
  3576. fn test_duplicate_shreds_broadcast_leader() {
  3577. run_duplicate_shreds_broadcast_leader(true);
  3578. }
  3579. #[test]
  3580. #[serial]
  3581. #[ignore]
  3582. #[allow(unused_attributes)]
  3583. fn test_duplicate_shreds_broadcast_leader_ancestor_hashes() {
  3584. run_duplicate_shreds_broadcast_leader(false);
  3585. }
  3586. fn run_duplicate_shreds_broadcast_leader(vote_on_duplicate: bool) {
  3587. solana_logger::setup_with_default(RUST_LOG_FILTER);
  3588. // Create 4 nodes:
  3589. // 1) Bad leader sending different versions of shreds to both of the other nodes
  3590. // 2) 1 node who's voting behavior in gossip
  3591. // 3) 1 validator gets the same version as the leader, will see duplicate confirmation
  3592. // 4) 1 validator will not get the same version as the leader. For each of these
  3593. // duplicate slots `S` either:
  3594. // a) The leader's version of `S` gets > DUPLICATE_THRESHOLD of votes in gossip and so this
  3595. // node will repair that correct version
  3596. // b) A descendant `D` of some version of `S` gets > DUPLICATE_THRESHOLD votes in gossip,
  3597. // but no version of `S` does. Then the node will not know to repair the right version
  3598. // by just looking at gossip, but will instead have to use EpochSlots repair after
  3599. // detecting that a descendant does not chain to its version of `S`, and marks that descendant
  3600. // dead.
  3601. // Scenarios a) or b) are triggered by our node in 2) who's voting behavior we control.
  3602. // Critical that bad_leader_stake + good_node_stake < DUPLICATE_THRESHOLD and that
  3603. // bad_leader_stake + good_node_stake + our_node_stake > DUPLICATE_THRESHOLD so that
  3604. // our vote is the determining factor.
  3605. //
  3606. // Also critical that bad_leader_stake > 1 - DUPLICATE_THRESHOLD, so that the leader
  3607. // doesn't try and dump his own block, which will happen if:
  3608. // 1. A version is duplicate confirmed
  3609. // 2. The version they played/stored into blockstore isn't the one that is duplicated
  3610. // confirmed.
  3611. let bad_leader_stake = 10_000_000 * DEFAULT_NODE_STAKE;
  3612. // Ensure that the good_node_stake is always on the critical path, and the partition node
  3613. // should never be on the critical path. This way, none of the bad shreds sent to the partition
  3614. // node corrupt the good node.
  3615. let good_node_stake = 500 * DEFAULT_NODE_STAKE;
  3616. let our_node_stake = 10_000_000 * DEFAULT_NODE_STAKE;
  3617. let partition_node_stake = DEFAULT_NODE_STAKE;
  3618. let node_stakes = vec![
  3619. bad_leader_stake,
  3620. partition_node_stake,
  3621. good_node_stake,
  3622. // Needs to be last in the vector, so that we can
  3623. // find the id of this node. See call to `test_faulty_node`
  3624. // below for more details.
  3625. our_node_stake,
  3626. ];
  3627. assert_eq!(*node_stakes.last().unwrap(), our_node_stake);
  3628. let total_stake: u64 = node_stakes.iter().sum();
  3629. assert!(
  3630. ((bad_leader_stake + good_node_stake) as f64 / total_stake as f64) < DUPLICATE_THRESHOLD
  3631. );
  3632. assert!(
  3633. (bad_leader_stake + good_node_stake + our_node_stake) as f64 / total_stake as f64
  3634. > DUPLICATE_THRESHOLD
  3635. );
  3636. assert!((bad_leader_stake as f64 / total_stake as f64) >= 1.0 - DUPLICATE_THRESHOLD);
  3637. // Important that the partition node stake is the smallest so that it gets selected
  3638. // for the partition.
  3639. assert!(partition_node_stake < our_node_stake && partition_node_stake < good_node_stake);
  3640. let (duplicate_slot_sender, duplicate_slot_receiver) = unbounded();
  3641. // 1) Set up the cluster
  3642. let (mut cluster, validator_keys) = test_faulty_node(
  3643. BroadcastStageType::BroadcastDuplicates(BroadcastDuplicatesConfig {
  3644. partition: ClusterPartition::Stake(partition_node_stake),
  3645. duplicate_slot_sender: Some(duplicate_slot_sender),
  3646. }),
  3647. node_stakes,
  3648. None,
  3649. None,
  3650. );
  3651. // This is why it's important our node was last in `node_stakes`
  3652. let our_id = validator_keys.last().unwrap().pubkey();
  3653. // 2) Kill our node and start up a thread to simulate votes to control our voting behavior
  3654. let our_info = cluster.exit_node(&our_id);
  3655. let node_keypair = our_info.info.keypair;
  3656. let vote_keypair = our_info.info.voting_keypair;
  3657. let bad_leader_id = *cluster.entry_point_info.pubkey();
  3658. let bad_leader_ledger_path = cluster.validators[&bad_leader_id].info.ledger_path.clone();
  3659. info!("our node id: {}", node_keypair.pubkey());
  3660. // 3) Start up a gossip instance to listen for and push votes
  3661. let voter_thread_sleep_ms = 100;
  3662. let gossip_voter = cluster_tests::start_gossip_voter(
  3663. &cluster.entry_point_info.gossip().unwrap(),
  3664. &node_keypair,
  3665. move |(label, leader_vote_tx)| {
  3666. // Filter out votes not from the bad leader
  3667. if label.pubkey() == bad_leader_id {
  3668. let vote = vote_parser::parse_vote_transaction(&leader_vote_tx)
  3669. .map(|(_, vote, ..)| vote)
  3670. .unwrap();
  3671. // Filter out empty votes
  3672. if !vote.is_empty() {
  3673. Some((vote, leader_vote_tx))
  3674. } else {
  3675. None
  3676. }
  3677. } else {
  3678. None
  3679. }
  3680. },
  3681. {
  3682. let node_keypair = node_keypair.insecure_clone();
  3683. let vote_keypair = vote_keypair.insecure_clone();
  3684. let mut gossip_vote_index = 0;
  3685. let mut duplicate_slots = vec![];
  3686. move |latest_vote_slot, leader_vote_tx, parsed_vote, cluster_info| {
  3687. info!("received vote for {latest_vote_slot}");
  3688. // Add to EpochSlots. Mark all slots frozen between slot..=max_vote_slot.
  3689. let new_epoch_slots: Vec<Slot> = (0..latest_vote_slot + 1).collect();
  3690. info!("Simulating epoch slots from our node: {new_epoch_slots:?}");
  3691. cluster_info.push_epoch_slots(&new_epoch_slots);
  3692. for slot in duplicate_slot_receiver.try_iter() {
  3693. duplicate_slots.push(slot);
  3694. }
  3695. let vote_hash = parsed_vote.hash();
  3696. if vote_on_duplicate || !duplicate_slots.contains(&latest_vote_slot) {
  3697. info!(
  3698. "Simulating vote from our node on slot {latest_vote_slot}, hash \
  3699. {vote_hash}"
  3700. );
  3701. // Add all recent vote slots on this fork to allow cluster to pass
  3702. // vote threshold checks in replay. Note this will instantly force a
  3703. // root by this validator, but we're not concerned with lockout violations
  3704. // by this validator so it's fine.
  3705. let leader_blockstore = open_blockstore(&bad_leader_ledger_path);
  3706. let mut vote_slots: Vec<(Slot, u32)> =
  3707. AncestorIterator::new_inclusive(latest_vote_slot, &leader_blockstore)
  3708. .take(MAX_LOCKOUT_HISTORY)
  3709. .zip(1..)
  3710. .collect();
  3711. vote_slots.reverse();
  3712. let mut vote = TowerSync::from(vote_slots);
  3713. let root =
  3714. AncestorIterator::new_inclusive(latest_vote_slot, &leader_blockstore)
  3715. .nth(MAX_LOCKOUT_HISTORY);
  3716. vote.root = root;
  3717. vote.hash = vote_hash;
  3718. let vote_tx = vote_transaction::new_tower_sync_transaction(
  3719. vote,
  3720. leader_vote_tx.message.recent_blockhash,
  3721. &node_keypair,
  3722. &vote_keypair,
  3723. &vote_keypair,
  3724. None,
  3725. );
  3726. gossip_vote_index += 1;
  3727. gossip_vote_index %= MAX_VOTES;
  3728. cluster_info.push_vote_at_index(vote_tx, gossip_vote_index);
  3729. }
  3730. }
  3731. },
  3732. voter_thread_sleep_ms as u64,
  3733. cluster.validators.len().saturating_sub(1),
  3734. 5000, // Refresh if 5 seconds of inactivity
  3735. 5, // Refresh the past 5 votes
  3736. cluster.entry_point_info.shred_version(),
  3737. );
  3738. // 4) Check that the cluster is making progress
  3739. cluster.check_for_new_roots(
  3740. 16,
  3741. "test_duplicate_shreds_broadcast_leader",
  3742. SocketAddrSpace::Unspecified,
  3743. );
  3744. // Clean up threads
  3745. gossip_voter.close();
  3746. }
  3747. #[test]
  3748. #[serial]
  3749. #[ignore]
  3750. fn test_switch_threshold_uses_gossip_votes() {
  3751. solana_logger::setup_with_default(RUST_LOG_FILTER);
  3752. let total_stake = 100 * DEFAULT_NODE_STAKE;
  3753. // Minimum stake needed to generate a switching proof
  3754. let minimum_switch_stake = (SWITCH_FORK_THRESHOLD * total_stake as f64) as u64;
  3755. // Make the heavier stake insufficient for switching so tha the lighter validator
  3756. // cannot switch without seeing a vote from the dead/failure_stake validator.
  3757. let heavier_stake = minimum_switch_stake;
  3758. let lighter_stake = heavier_stake - 1;
  3759. let failures_stake = total_stake - heavier_stake - lighter_stake;
  3760. let partitions: &[(usize, usize)] = &[(heavier_stake as usize, 8), (lighter_stake as usize, 8)];
  3761. #[derive(Default)]
  3762. struct PartitionContext {
  3763. heaviest_validator_key: Pubkey,
  3764. lighter_validator_key: Pubkey,
  3765. dead_validator_info: Option<ClusterValidatorInfo>,
  3766. }
  3767. let on_partition_start = |_cluster: &mut LocalCluster,
  3768. validator_keys: &[Pubkey],
  3769. mut dead_validator_infos: Vec<ClusterValidatorInfo>,
  3770. context: &mut PartitionContext| {
  3771. assert_eq!(dead_validator_infos.len(), 1);
  3772. context.dead_validator_info = Some(dead_validator_infos.pop().unwrap());
  3773. // validator_keys[0] is the validator that will be killed, i.e. the validator with
  3774. // stake == `failures_stake`
  3775. context.heaviest_validator_key = validator_keys[1];
  3776. context.lighter_validator_key = validator_keys[2];
  3777. };
  3778. let on_before_partition_resolved = |_: &mut LocalCluster, _: &mut PartitionContext| {};
  3779. // Check that new roots were set after the partition resolves (gives time
  3780. // for lockouts built during partition to resolve and gives validators an opportunity
  3781. // to try and switch forks)
  3782. let on_partition_resolved = |cluster: &mut LocalCluster, context: &mut PartitionContext| {
  3783. let lighter_validator_ledger_path = cluster.ledger_path(&context.lighter_validator_key);
  3784. let heavier_validator_ledger_path = cluster.ledger_path(&context.heaviest_validator_key);
  3785. let (lighter_validator_latest_vote, _) = last_vote_in_tower(
  3786. &lighter_validator_ledger_path,
  3787. &context.lighter_validator_key,
  3788. )
  3789. .unwrap();
  3790. info!("Lighter validator's latest vote is for slot {lighter_validator_latest_vote}");
  3791. // Lighter partition should stop voting after detecting the heavier partition and try
  3792. // to switch. Loop until we see a greater vote by the heavier validator than the last
  3793. // vote made by the lighter validator on the lighter fork.
  3794. let mut heavier_validator_latest_vote;
  3795. let mut heavier_validator_latest_vote_hash;
  3796. let heavier_blockstore = open_blockstore(&heavier_validator_ledger_path);
  3797. loop {
  3798. let (sanity_check_lighter_validator_latest_vote, _) = last_vote_in_tower(
  3799. &lighter_validator_ledger_path,
  3800. &context.lighter_validator_key,
  3801. )
  3802. .unwrap();
  3803. // Lighter validator should stop voting, because `on_partition_resolved` is only
  3804. // called after a propagation time where blocks from the other fork should have
  3805. // finished propagating
  3806. assert_eq!(
  3807. sanity_check_lighter_validator_latest_vote,
  3808. lighter_validator_latest_vote
  3809. );
  3810. let (new_heavier_validator_latest_vote, new_heavier_validator_latest_vote_hash) =
  3811. last_vote_in_tower(
  3812. &heavier_validator_ledger_path,
  3813. &context.heaviest_validator_key,
  3814. )
  3815. .unwrap();
  3816. heavier_validator_latest_vote = new_heavier_validator_latest_vote;
  3817. heavier_validator_latest_vote_hash = new_heavier_validator_latest_vote_hash;
  3818. // Latest vote for each validator should be on different forks
  3819. assert_ne!(lighter_validator_latest_vote, heavier_validator_latest_vote);
  3820. if heavier_validator_latest_vote > lighter_validator_latest_vote {
  3821. let heavier_ancestors: HashSet<Slot> =
  3822. AncestorIterator::new(heavier_validator_latest_vote, &heavier_blockstore)
  3823. .collect();
  3824. assert!(!heavier_ancestors.contains(&lighter_validator_latest_vote));
  3825. break;
  3826. }
  3827. }
  3828. info!("Checking to make sure lighter validator doesn't switch");
  3829. let mut latest_slot = lighter_validator_latest_vote;
  3830. // Number of chances the validator had to switch votes but didn't
  3831. let mut total_voting_opportunities = 0;
  3832. while total_voting_opportunities <= 5 {
  3833. let (new_latest_slot, latest_slot_ancestors) =
  3834. find_latest_replayed_slot_from_ledger(&lighter_validator_ledger_path, latest_slot);
  3835. latest_slot = new_latest_slot;
  3836. // Ensure `latest_slot` is on the other fork
  3837. if latest_slot_ancestors.contains(&heavier_validator_latest_vote) {
  3838. let tower = restore_tower(
  3839. &lighter_validator_ledger_path,
  3840. &context.lighter_validator_key,
  3841. )
  3842. .unwrap();
  3843. // Check that there was an opportunity to vote
  3844. if !tower.is_locked_out(latest_slot, &latest_slot_ancestors) {
  3845. // Ensure the lighter blockstore has not voted again
  3846. let new_lighter_validator_latest_vote = tower.last_voted_slot().unwrap();
  3847. assert_eq!(
  3848. new_lighter_validator_latest_vote,
  3849. lighter_validator_latest_vote
  3850. );
  3851. info!("Incrementing voting opportunities: {total_voting_opportunities}");
  3852. total_voting_opportunities += 1;
  3853. } else {
  3854. info!("Tower still locked out, can't vote for slot: {latest_slot}");
  3855. }
  3856. } else if latest_slot > heavier_validator_latest_vote {
  3857. warn!(
  3858. "validator is still generating blocks on its own fork, last processed slot: \
  3859. {latest_slot}"
  3860. );
  3861. }
  3862. sleep(Duration::from_millis(50));
  3863. }
  3864. // Make a vote from the killed validator for slot `heavier_validator_latest_vote` in gossip
  3865. info!("Simulate vote for slot: {heavier_validator_latest_vote} from dead validator");
  3866. let vote_keypair = &context
  3867. .dead_validator_info
  3868. .as_ref()
  3869. .unwrap()
  3870. .info
  3871. .voting_keypair
  3872. .clone();
  3873. let node_keypair = &context
  3874. .dead_validator_info
  3875. .as_ref()
  3876. .unwrap()
  3877. .info
  3878. .keypair
  3879. .clone();
  3880. cluster_tests::submit_vote_to_cluster_gossip(
  3881. node_keypair,
  3882. vote_keypair,
  3883. heavier_validator_latest_vote,
  3884. heavier_validator_latest_vote_hash,
  3885. // Make the vote transaction with a random blockhash. Thus, the vote only lives in gossip but
  3886. // never makes it into a block
  3887. Hash::new_unique(),
  3888. cluster
  3889. .get_contact_info(&context.heaviest_validator_key)
  3890. .unwrap()
  3891. .gossip()
  3892. .unwrap(),
  3893. &SocketAddrSpace::Unspecified,
  3894. )
  3895. .unwrap();
  3896. loop {
  3897. // Wait for the lighter validator to switch to the heavier fork
  3898. let (new_lighter_validator_latest_vote, _) = last_vote_in_tower(
  3899. &lighter_validator_ledger_path,
  3900. &context.lighter_validator_key,
  3901. )
  3902. .unwrap();
  3903. if new_lighter_validator_latest_vote != lighter_validator_latest_vote {
  3904. info!(
  3905. "Lighter validator switched forks at slot: {new_lighter_validator_latest_vote}"
  3906. );
  3907. let (heavier_validator_latest_vote, _) = last_vote_in_tower(
  3908. &heavier_validator_ledger_path,
  3909. &context.heaviest_validator_key,
  3910. )
  3911. .unwrap();
  3912. let (smaller, larger) =
  3913. if new_lighter_validator_latest_vote > heavier_validator_latest_vote {
  3914. (
  3915. heavier_validator_latest_vote,
  3916. new_lighter_validator_latest_vote,
  3917. )
  3918. } else {
  3919. (
  3920. new_lighter_validator_latest_vote,
  3921. heavier_validator_latest_vote,
  3922. )
  3923. };
  3924. // Check the new vote is on the same fork as the heaviest fork
  3925. let heavier_blockstore = open_blockstore(&heavier_validator_ledger_path);
  3926. let larger_slot_ancestors: HashSet<Slot> =
  3927. AncestorIterator::new(larger, &heavier_blockstore)
  3928. .chain(std::iter::once(larger))
  3929. .collect();
  3930. assert!(larger_slot_ancestors.contains(&smaller));
  3931. break;
  3932. } else {
  3933. sleep(Duration::from_millis(50));
  3934. }
  3935. }
  3936. };
  3937. let ticks_per_slot = 8;
  3938. run_kill_partition_switch_threshold(
  3939. &[(failures_stake as usize, 0)],
  3940. partitions,
  3941. Some(ticks_per_slot),
  3942. PartitionContext::default(),
  3943. on_partition_start,
  3944. on_before_partition_resolved,
  3945. on_partition_resolved,
  3946. );
  3947. }
  3948. #[test]
  3949. #[serial]
  3950. fn test_listener_startup() {
  3951. let mut config = ClusterConfig {
  3952. node_stakes: vec![DEFAULT_NODE_STAKE],
  3953. num_listeners: 3,
  3954. validator_configs: make_identical_validator_configs(
  3955. &ValidatorConfig::default_for_test(),
  3956. 1,
  3957. ),
  3958. ..ClusterConfig::default()
  3959. };
  3960. let cluster = LocalCluster::new(&mut config, SocketAddrSpace::Unspecified);
  3961. let cluster_nodes = discover_validators(
  3962. &cluster.entry_point_info.gossip().unwrap(),
  3963. 4,
  3964. cluster.entry_point_info.shred_version(),
  3965. SocketAddrSpace::Unspecified,
  3966. )
  3967. .unwrap();
  3968. assert_eq!(cluster_nodes.len(), 4);
  3969. }
  3970. fn find_latest_replayed_slot_from_ledger(
  3971. ledger_path: &Path,
  3972. mut latest_slot: Slot,
  3973. ) -> (Slot, HashSet<Slot>) {
  3974. loop {
  3975. let mut blockstore = open_blockstore(ledger_path);
  3976. // This is kind of a hack because we can't query for new frozen blocks over RPC
  3977. // since the validator is not voting.
  3978. let new_latest_slots: Vec<Slot> = blockstore
  3979. .slot_meta_iterator(latest_slot)
  3980. .unwrap()
  3981. .filter_map(|(s, _)| if s > latest_slot { Some(s) } else { None })
  3982. .collect();
  3983. if let Some(new_latest_slot) = new_latest_slots.first() {
  3984. latest_slot = *new_latest_slot;
  3985. info!("Checking latest_slot {latest_slot}");
  3986. // Wait for the slot to be fully received by the validator
  3987. loop {
  3988. info!("Waiting for slot {latest_slot} to be full");
  3989. if blockstore.is_full(latest_slot) {
  3990. break;
  3991. } else {
  3992. sleep(Duration::from_millis(50));
  3993. blockstore = open_blockstore(ledger_path);
  3994. }
  3995. }
  3996. // Wait for the slot to be replayed
  3997. loop {
  3998. info!("Waiting for slot {latest_slot} to be replayed");
  3999. if blockstore.get_bank_hash(latest_slot).is_some() {
  4000. return (
  4001. latest_slot,
  4002. AncestorIterator::new(latest_slot, &blockstore).collect(),
  4003. );
  4004. } else {
  4005. sleep(Duration::from_millis(50));
  4006. blockstore = open_blockstore(ledger_path);
  4007. }
  4008. }
  4009. }
  4010. sleep(Duration::from_millis(50));
  4011. }
  4012. }
  4013. #[test]
  4014. #[serial]
  4015. fn test_cluster_partition_1_1() {
  4016. let empty = |_: &mut LocalCluster, _: &mut ()| {};
  4017. let on_partition_resolved = |cluster: &mut LocalCluster, _: &mut ()| {
  4018. cluster.check_for_new_roots(16, "PARTITION_TEST", SocketAddrSpace::Unspecified);
  4019. };
  4020. run_cluster_partition(
  4021. &[1, 1],
  4022. None,
  4023. (),
  4024. empty,
  4025. empty,
  4026. on_partition_resolved,
  4027. None,
  4028. vec![],
  4029. )
  4030. }
  4031. #[test]
  4032. #[serial]
  4033. fn test_cluster_partition_1_1_1() {
  4034. let empty = |_: &mut LocalCluster, _: &mut ()| {};
  4035. let on_partition_resolved = |cluster: &mut LocalCluster, _: &mut ()| {
  4036. cluster.check_for_new_roots(16, "PARTITION_TEST", SocketAddrSpace::Unspecified);
  4037. };
  4038. run_cluster_partition(
  4039. &[1, 1, 1],
  4040. None,
  4041. (),
  4042. empty,
  4043. empty,
  4044. on_partition_resolved,
  4045. None,
  4046. vec![],
  4047. )
  4048. }
  4049. #[test]
  4050. #[serial]
  4051. fn test_leader_failure_4() {
  4052. solana_logger::setup_with_default(RUST_LOG_FILTER);
  4053. error!("test_leader_failure_4");
  4054. // Cluster needs a supermajority to remain even after taking 1 node offline,
  4055. // so the minimum number of nodes for this test is 4.
  4056. let num_nodes = 4;
  4057. let validator_config = ValidatorConfig::default_for_test();
  4058. // Embed vote and stake account in genesis to avoid waiting for stake
  4059. // activation and race conditions around accepting gossip votes, repairing
  4060. // blocks, etc. before we advance through too many epochs.
  4061. let validator_keys: Option<Vec<(Arc<Keypair>, bool)>> = Some(
  4062. (0..num_nodes)
  4063. .map(|_| (Arc::new(Keypair::new()), true))
  4064. .collect(),
  4065. );
  4066. // Skip the warmup slots because these short epochs can cause problems when
  4067. // bringing multiple fresh validators online that are pre-staked in genesis.
  4068. // The problems arise because we skip their leader slots while they're still
  4069. // starting up, experience partitioning, and can fail to generate leader
  4070. // schedules in time because the short epochs have the same slots per epoch
  4071. // as the total tower height, so any skipped slots can lead to not rooting,
  4072. // not generating leader schedule, and stalling the cluster.
  4073. let skip_warmup_slots = true;
  4074. let mut config = ClusterConfig {
  4075. node_stakes: vec![DEFAULT_NODE_STAKE; num_nodes],
  4076. validator_configs: make_identical_validator_configs(&validator_config, num_nodes),
  4077. validator_keys,
  4078. skip_warmup_slots,
  4079. ..ClusterConfig::default()
  4080. };
  4081. let local = LocalCluster::new(&mut config, SocketAddrSpace::Unspecified);
  4082. cluster_tests::kill_entry_and_spend_and_verify_rest(
  4083. &local.entry_point_info,
  4084. &local
  4085. .validators
  4086. .get(local.entry_point_info.pubkey())
  4087. .unwrap()
  4088. .config
  4089. .validator_exit,
  4090. &local.funding_keypair,
  4091. &local.connection_cache,
  4092. num_nodes,
  4093. config.ticks_per_slot * config.poh_config.target_tick_duration.as_millis() as u64,
  4094. SocketAddrSpace::Unspecified,
  4095. );
  4096. }
  4097. // This test verifies that even if votes from a validator end up taking too long to land, and thus
  4098. // some of the referenced slots are slots are no longer present in the slot hashes sysvar,
  4099. // consensus can still be attained.
  4100. //
  4101. // Validator A (60%)
  4102. // Validator B (40%)
  4103. // / --- 10 --- [..] --- 16 (B is voting, due to network issues is initially not able to see the other fork at all)
  4104. // /
  4105. // 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 (A votes 1 - 9 votes are landing normally. B does the same however votes are not landing)
  4106. // \
  4107. // \--[..]-- 73 (majority fork)
  4108. // A is voting on the majority fork and B wants to switch to this fork however in this majority fork
  4109. // the earlier votes for B (1 - 9) never landed so when B eventually goes to vote on 73, slots in
  4110. // its local vote state are no longer present in slot hashes.
  4111. //
  4112. // 1. Wait for B's tower to see local vote state was updated to new fork
  4113. // 2. Wait X blocks, check B's vote state on chain has been properly updated
  4114. //
  4115. // NOTE: it is not reliable for B to organically have 1 to reach 2^16 lockout, so we simulate the 6
  4116. // consecutive votes on the minor fork by manually incrementing the confirmation levels for the
  4117. // common ancestor votes in tower.
  4118. // To allow this test to run in a reasonable time we change the
  4119. // slot_hash expiry to 64 slots.
  4120. #[test]
  4121. #[serial]
  4122. fn test_slot_hash_expiry() {
  4123. solana_logger::setup_with_default(RUST_LOG_FILTER);
  4124. solana_slot_hashes::set_entries_for_tests_only(64);
  4125. let slots_per_epoch = 2048;
  4126. let node_stakes = vec![60 * DEFAULT_NODE_STAKE, 40 * DEFAULT_NODE_STAKE];
  4127. let validator_keys = [
  4128. "28bN3xyvrP4E8LwEgtLjhnkb7cY4amQb6DrYAbAYjgRV4GAGgkVM2K7wnxnAS7WDneuavza7x21MiafLu1HkwQt4",
  4129. "2saHBBoTkLMmttmPQP8KfBkcCw45S5cwtV3wTdGCscRC8uxdgvHxpHiWXKx4LvJjNJtnNcbSv5NdheokFFqnNDt8",
  4130. ]
  4131. .iter()
  4132. .map(|s| (Arc::new(Keypair::from_base58_string(s)), true))
  4133. .collect::<Vec<_>>();
  4134. let node_vote_keys = [
  4135. "3NDQ3ud86RTVg8hTy2dDWnS4P8NfjhZ2gDgQAJbr3heaKaUVS1FW3sTLKA1GmDrY9aySzsa4QxpDkbLv47yHxzr3",
  4136. "46ZHpHE6PEvXYPu3hf9iQqjBk2ZNDaJ9ejqKWHEjxaQjpAGasKaWKbKHbP3646oZhfgDRzx95DH9PCBKKsoCVngk",
  4137. ]
  4138. .iter()
  4139. .map(|s| Arc::new(Keypair::from_base58_string(s)))
  4140. .collect::<Vec<_>>();
  4141. let vs = validator_keys
  4142. .iter()
  4143. .map(|(kp, _)| kp.pubkey())
  4144. .collect::<Vec<_>>();
  4145. let (a_pubkey, b_pubkey) = (vs[0], vs[1]);
  4146. // We want B to not vote (we are trying to simulate its votes not landing until it gets to the
  4147. // minority fork)
  4148. let mut validator_configs =
  4149. make_identical_validator_configs(&ValidatorConfig::default_for_test(), node_stakes.len());
  4150. validator_configs[1].voting_disabled = true;
  4151. let mut config = ClusterConfig {
  4152. mint_lamports: DEFAULT_MINT_LAMPORTS + node_stakes.iter().sum::<u64>(),
  4153. node_stakes,
  4154. validator_configs,
  4155. validator_keys: Some(validator_keys),
  4156. node_vote_keys: Some(node_vote_keys),
  4157. slots_per_epoch,
  4158. stakers_slot_offset: slots_per_epoch,
  4159. skip_warmup_slots: true,
  4160. ..ClusterConfig::default()
  4161. };
  4162. let mut cluster = LocalCluster::new(&mut config, SocketAddrSpace::Unspecified);
  4163. let mut common_ancestor_slot = 8;
  4164. let a_ledger_path = cluster.ledger_path(&a_pubkey);
  4165. let b_ledger_path = cluster.ledger_path(&b_pubkey);
  4166. // Immediately kill B (we just needed it for the initial stake distribution)
  4167. info!("Killing B");
  4168. let mut b_info = cluster.exit_node(&b_pubkey);
  4169. // Let A run for a while until we get to the common ancestor
  4170. info!("Letting A run until common_ancestor_slot");
  4171. loop {
  4172. if let Some((last_vote, _)) = last_vote_in_tower(&a_ledger_path, &a_pubkey) {
  4173. if last_vote >= common_ancestor_slot {
  4174. break;
  4175. }
  4176. }
  4177. sleep(Duration::from_millis(100));
  4178. }
  4179. // Keep A running, but setup B so that it thinks it has voted up until common ancestor (but
  4180. // doesn't know anything past that)
  4181. {
  4182. info!("Copying A's ledger to B");
  4183. std::fs::remove_dir_all(&b_info.info.ledger_path).unwrap();
  4184. let mut opt = fs_extra::dir::CopyOptions::new();
  4185. opt.copy_inside = true;
  4186. fs_extra::dir::copy(&a_ledger_path, &b_ledger_path, &opt).unwrap();
  4187. // remove A's tower in B's new copied ledger
  4188. info!("Removing A's tower in B's ledger dir");
  4189. remove_tower(&b_ledger_path, &a_pubkey);
  4190. // load A's tower and save it as B's tower
  4191. info!("Loading A's tower");
  4192. if let Some(mut a_tower) = restore_tower(&a_ledger_path, &a_pubkey) {
  4193. a_tower.node_pubkey = b_pubkey;
  4194. // Update common_ancestor_slot because A is still running
  4195. if let Some(s) = a_tower.last_voted_slot() {
  4196. common_ancestor_slot = s;
  4197. info!("New common_ancestor_slot {common_ancestor_slot}");
  4198. } else {
  4199. panic!("A's tower has no votes");
  4200. }
  4201. info!("Increase lockout by 6 confirmation levels and save as B's tower");
  4202. a_tower.increase_lockout(6);
  4203. save_tower(&b_ledger_path, &a_tower, &b_info.info.keypair);
  4204. info!("B's new tower: {:?}", a_tower.tower_slots());
  4205. } else {
  4206. panic!("A's tower is missing");
  4207. }
  4208. // Get rid of any slots past common_ancestor_slot
  4209. info!("Removing extra slots from B's blockstore");
  4210. let blockstore = open_blockstore(&b_ledger_path);
  4211. purge_slots_with_count(&blockstore, common_ancestor_slot + 1, 100);
  4212. }
  4213. info!(
  4214. "Run A on majority fork until it reaches slot hash expiry {}",
  4215. solana_slot_hashes::get_entries()
  4216. );
  4217. let mut last_vote_on_a;
  4218. // Keep A running for a while longer so the majority fork has some decent size
  4219. loop {
  4220. last_vote_on_a =
  4221. wait_for_last_vote_in_tower_to_land_in_ledger(&a_ledger_path, &a_pubkey).unwrap();
  4222. if last_vote_on_a >= common_ancestor_slot + 2 * (solana_slot_hashes::get_entries() as u64) {
  4223. let blockstore = open_blockstore(&a_ledger_path);
  4224. info!(
  4225. "A majority fork: {:?}",
  4226. AncestorIterator::new(last_vote_on_a, &blockstore).collect::<Vec<Slot>>()
  4227. );
  4228. break;
  4229. }
  4230. sleep(Duration::from_millis(100));
  4231. }
  4232. // Kill A and restart B with voting. B should now fork off
  4233. info!("Killing A");
  4234. let a_info = cluster.exit_node(&a_pubkey);
  4235. info!("Restarting B");
  4236. b_info.config.voting_disabled = false;
  4237. cluster.restart_node(&b_pubkey, b_info, SocketAddrSpace::Unspecified);
  4238. // B will fork off and accumulate enough lockout
  4239. info!("Allowing B to fork");
  4240. loop {
  4241. let blockstore = open_blockstore(&b_ledger_path);
  4242. let last_vote =
  4243. wait_for_last_vote_in_tower_to_land_in_ledger(&b_ledger_path, &b_pubkey).unwrap();
  4244. let mut ancestors = AncestorIterator::new(last_vote, &blockstore);
  4245. if let Some(index) = ancestors.position(|x| x == common_ancestor_slot) {
  4246. if index > 7 {
  4247. info!(
  4248. "B has forked for enough lockout: {:?}",
  4249. AncestorIterator::new(last_vote, &blockstore).collect::<Vec<Slot>>()
  4250. );
  4251. break;
  4252. }
  4253. }
  4254. sleep(Duration::from_millis(1000));
  4255. }
  4256. info!("Kill B");
  4257. b_info = cluster.exit_node(&b_pubkey);
  4258. info!("Resolve the partition");
  4259. {
  4260. // Here we let B know about the missing blocks that A had produced on its partition
  4261. let a_blockstore = open_blockstore(&a_ledger_path);
  4262. let b_blockstore = open_blockstore(&b_ledger_path);
  4263. copy_blocks(last_vote_on_a, &a_blockstore, &b_blockstore, false);
  4264. }
  4265. // Now restart A and B and see if B is able to eventually switch onto the majority fork
  4266. info!("Restarting A & B");
  4267. cluster.restart_node(&a_pubkey, a_info, SocketAddrSpace::Unspecified);
  4268. cluster.restart_node(&b_pubkey, b_info, SocketAddrSpace::Unspecified);
  4269. info!("Waiting for B to switch to majority fork and make a root");
  4270. cluster_tests::check_for_new_roots(
  4271. 16,
  4272. &[cluster.get_contact_info(&a_pubkey).unwrap().clone()],
  4273. &cluster.connection_cache,
  4274. "test_slot_hashes_expiry",
  4275. );
  4276. }
  4277. // This test simulates a case where a leader sends a duplicate block with different ancestry. One
  4278. // version builds off of the rooted path, however the other version builds off a pruned branch. The
  4279. // validators that receive the pruned version will need to repair in order to continue, which
  4280. // requires an ancestor hashes repair.
  4281. //
  4282. // We setup 3 validators:
  4283. // - majority, will produce the rooted path
  4284. // - minority, will produce the pruned path
  4285. // - our_node, will be fed the pruned version of the duplicate block and need to repair
  4286. //
  4287. // Additionally we setup 3 observer nodes to propagate votes and participate in the ancestor hashes
  4288. // sample.
  4289. //
  4290. // Fork structure:
  4291. //
  4292. // 0 - 1 - ... - 10 (fork slot) - 30 - ... - 61 (rooted path) - ...
  4293. // |
  4294. // |- 11 - ... - 29 (pruned path) - 81'
  4295. //
  4296. //
  4297. // Steps:
  4298. // 1) Different leader schedule, minority thinks it produces 0-29 and majority rest, majority
  4299. // thinks minority produces all blocks. This is to avoid majority accidentally producing blocks
  4300. // before it shuts down.
  4301. // 2) Start cluster, kill our_node.
  4302. // 3) Kill majority cluster after it votes for any slot > fork slot (guarantees that the fork slot is
  4303. // reached as minority cannot pass threshold otherwise).
  4304. // 4) Let minority produce forks on pruned forks until out of leader slots then kill.
  4305. // 5) Truncate majority ledger past fork slot so it starts building off of fork slot.
  4306. // 6) Restart majority and wait until it starts producing blocks on main fork and roots something
  4307. // past the fork slot.
  4308. // 7) Construct our ledger by copying majority ledger and copying blocks from minority for the pruned path.
  4309. // 8) In our node's ledger, change the parent of the latest slot in majority fork to be the latest
  4310. // slot in the minority fork (simulates duplicate built off of pruned block)
  4311. // 9) Start our node which will pruned the minority fork on ledger replay and verify that we can make roots.
  4312. //
  4313. #[test]
  4314. #[serial]
  4315. #[ignore]
  4316. fn test_duplicate_with_pruned_ancestor() {
  4317. solana_logger::setup_with("info,solana_metrics=off");
  4318. solana_core::repair::duplicate_repair_status::set_ancestor_hash_repair_sample_size_for_tests_only(3);
  4319. let majority_leader_stake = 10_000_000 * DEFAULT_NODE_STAKE;
  4320. let minority_leader_stake = 2_000_000 * DEFAULT_NODE_STAKE;
  4321. let our_node = DEFAULT_NODE_STAKE;
  4322. let observer_stake = DEFAULT_NODE_STAKE;
  4323. let slots_per_epoch = 2048;
  4324. let fork_slot: u64 = 10;
  4325. let fork_length: u64 = 20;
  4326. let majority_fork_buffer = 5;
  4327. let mut node_stakes = vec![majority_leader_stake, minority_leader_stake, our_node];
  4328. // We need enough observers to reach `ANCESTOR_HASH_REPAIR_SAMPLE_SIZE`
  4329. node_stakes.append(&mut vec![observer_stake; 3]);
  4330. let num_nodes = node_stakes.len();
  4331. let validator_keys = [
  4332. "28bN3xyvrP4E8LwEgtLjhnkb7cY4amQb6DrYAbAYjgRV4GAGgkVM2K7wnxnAS7WDneuavza7x21MiafLu1HkwQt4",
  4333. "2saHBBoTkLMmttmPQP8KfBkcCw45S5cwtV3wTdGCscRC8uxdgvHxpHiWXKx4LvJjNJtnNcbSv5NdheokFFqnNDt8",
  4334. "4mx9yoFBeYasDKBGDWCTWGJdWuJCKbgqmuP8bN9umybCh5Jzngw7KQxe99Rf5uzfyzgba1i65rJW4Wqk7Ab5S8ye",
  4335. ]
  4336. .iter()
  4337. .map(|s| (Arc::new(Keypair::from_base58_string(s)), true))
  4338. .chain(std::iter::repeat_with(|| (Arc::new(Keypair::new()), true)))
  4339. .take(node_stakes.len())
  4340. .collect::<Vec<_>>();
  4341. let validators = validator_keys
  4342. .iter()
  4343. .map(|(kp, _)| kp.pubkey())
  4344. .collect::<Vec<_>>();
  4345. let (majority_pubkey, minority_pubkey, our_node_pubkey) =
  4346. (validators[0], validators[1], validators[2]);
  4347. let mut default_config = ValidatorConfig::default_for_test();
  4348. // Minority fork is leader long enough to create pruned fork
  4349. let validator_to_slots = vec![
  4350. (minority_pubkey, (fork_slot + fork_length) as usize),
  4351. (majority_pubkey, slots_per_epoch as usize),
  4352. ];
  4353. let leader_schedule = create_custom_leader_schedule(validator_to_slots.into_iter());
  4354. default_config.fixed_leader_schedule = Some(FixedSchedule {
  4355. leader_schedule: Arc::new(leader_schedule),
  4356. });
  4357. let mut validator_configs = make_identical_validator_configs(&default_config, num_nodes);
  4358. // Don't let majority produce anything past the fork by tricking its leader schedule
  4359. validator_configs[0].fixed_leader_schedule = Some(FixedSchedule {
  4360. leader_schedule: Arc::new(create_custom_leader_schedule(
  4361. [(minority_pubkey, slots_per_epoch as usize)].into_iter(),
  4362. )),
  4363. });
  4364. let mut config = ClusterConfig {
  4365. mint_lamports: DEFAULT_MINT_LAMPORTS + node_stakes.iter().sum::<u64>(),
  4366. node_stakes,
  4367. validator_configs,
  4368. validator_keys: Some(validator_keys),
  4369. slots_per_epoch,
  4370. stakers_slot_offset: slots_per_epoch,
  4371. skip_warmup_slots: true,
  4372. ..ClusterConfig::default()
  4373. };
  4374. let mut cluster = LocalCluster::new(&mut config, SocketAddrSpace::Unspecified);
  4375. let majority_ledger_path = cluster.ledger_path(&majority_pubkey);
  4376. let minority_ledger_path = cluster.ledger_path(&minority_pubkey);
  4377. let our_node_ledger_path = cluster.ledger_path(&our_node_pubkey);
  4378. info!("majority {majority_pubkey} ledger path {majority_ledger_path:?}");
  4379. info!("minority {minority_pubkey} ledger path {minority_ledger_path:?}");
  4380. info!("our_node {our_node_pubkey} ledger path {our_node_ledger_path:?}");
  4381. info!("Killing our node");
  4382. let our_node_info = cluster.exit_node(&our_node_pubkey);
  4383. info!("Waiting on majority validator to vote on at least {fork_slot}");
  4384. let now = Instant::now();
  4385. let mut last_majority_vote = 0;
  4386. loop {
  4387. let elapsed = now.elapsed();
  4388. assert!(
  4389. elapsed <= Duration::from_secs(30),
  4390. "Majority validator failed to vote on a slot >= {fork_slot} in {} secs, majority \
  4391. validator last vote: {last_majority_vote}",
  4392. elapsed.as_secs(),
  4393. );
  4394. sleep(Duration::from_millis(100));
  4395. if let Some((last_vote, _)) = last_vote_in_tower(&majority_ledger_path, &majority_pubkey) {
  4396. last_majority_vote = last_vote;
  4397. if last_vote >= fork_slot {
  4398. break;
  4399. }
  4400. }
  4401. }
  4402. info!("Killing majority validator, waiting for minority fork to reach a depth of at least 15");
  4403. let mut majority_validator_info = cluster.exit_node(&majority_pubkey);
  4404. let now = Instant::now();
  4405. let mut last_minority_vote = 0;
  4406. while last_minority_vote < fork_slot + 15 {
  4407. let elapsed = now.elapsed();
  4408. assert!(
  4409. elapsed <= Duration::from_secs(30),
  4410. "Minority validator failed to create a fork of depth >= {} in 15 secs, \
  4411. last_minority_vote: {last_minority_vote}",
  4412. elapsed.as_secs(),
  4413. );
  4414. if let Some((last_vote, _)) = last_vote_in_tower(&minority_ledger_path, &minority_pubkey) {
  4415. last_minority_vote = last_vote;
  4416. }
  4417. }
  4418. info!("Killing minority validator, fork created successfully: {last_minority_vote:?}");
  4419. let last_minority_vote =
  4420. wait_for_last_vote_in_tower_to_land_in_ledger(&minority_ledger_path, &minority_pubkey)
  4421. .unwrap();
  4422. let minority_validator_info = cluster.exit_node(&minority_pubkey);
  4423. info!("Truncating majority validator ledger to {fork_slot}");
  4424. {
  4425. remove_tower(&majority_ledger_path, &majority_pubkey);
  4426. let blockstore = open_blockstore(&majority_ledger_path);
  4427. purge_slots_with_count(&blockstore, fork_slot + 1, 100);
  4428. }
  4429. info!("Restarting majority validator");
  4430. // Make sure we don't send duplicate votes
  4431. majority_validator_info.config.wait_to_vote_slot = Some(fork_slot + fork_length);
  4432. // Fix the leader schedule so we can produce blocks
  4433. majority_validator_info
  4434. .config
  4435. .fixed_leader_schedule
  4436. .clone_from(&minority_validator_info.config.fixed_leader_schedule);
  4437. cluster.restart_node(
  4438. &majority_pubkey,
  4439. majority_validator_info,
  4440. SocketAddrSpace::Unspecified,
  4441. );
  4442. let mut last_majority_root = 0;
  4443. let now = Instant::now();
  4444. info!(
  4445. "Waiting for majority validator to root something past {}",
  4446. fork_slot + fork_length + majority_fork_buffer
  4447. );
  4448. while last_majority_root <= fork_slot + fork_length + majority_fork_buffer {
  4449. let elapsed = now.elapsed();
  4450. assert!(
  4451. elapsed <= Duration::from_secs(60),
  4452. "Majority validator failed to root something > {} in {} secs, last majority validator \
  4453. vote: {last_majority_vote}",
  4454. fork_slot + fork_length + majority_fork_buffer,
  4455. elapsed.as_secs(),
  4456. );
  4457. sleep(Duration::from_millis(100));
  4458. if let Some(last_root) = last_root_in_tower(&majority_ledger_path, &majority_pubkey) {
  4459. last_majority_root = last_root;
  4460. }
  4461. }
  4462. let last_majority_vote =
  4463. wait_for_last_vote_in_tower_to_land_in_ledger(&majority_ledger_path, &majority_pubkey)
  4464. .unwrap();
  4465. info!(
  4466. "Creating duplicate block built off of pruned branch for our node. Last majority vote \
  4467. {last_majority_vote}, Last minority vote {last_minority_vote}"
  4468. );
  4469. {
  4470. {
  4471. // Copy majority fork
  4472. std::fs::remove_dir_all(&our_node_info.info.ledger_path).unwrap();
  4473. let mut opt = fs_extra::dir::CopyOptions::new();
  4474. opt.copy_inside = true;
  4475. fs_extra::dir::copy(&majority_ledger_path, &our_node_ledger_path, &opt).unwrap();
  4476. remove_tower(&our_node_ledger_path, &majority_pubkey);
  4477. }
  4478. // Copy minority fork to our blockstore
  4479. // Set trusted=true in blockstore copy to skip the parent slot >= latest root check;
  4480. // this check would otherwise prevent the pruned fork from being inserted
  4481. let minority_blockstore = open_blockstore(&minority_validator_info.info.ledger_path);
  4482. let our_blockstore = open_blockstore(&our_node_info.info.ledger_path);
  4483. copy_blocks(
  4484. last_minority_vote,
  4485. &minority_blockstore,
  4486. &our_blockstore,
  4487. true,
  4488. );
  4489. // Change last block parent to chain off of (purged) minority fork
  4490. info!("For our node, changing parent of {last_majority_vote} to {last_minority_vote}");
  4491. our_blockstore.clear_unconfirmed_slot(last_majority_vote);
  4492. let entries = create_ticks(
  4493. 64 * (std::cmp::max(1, last_majority_vote - last_minority_vote)),
  4494. 0,
  4495. Hash::default(),
  4496. );
  4497. let shreds =
  4498. entries_to_test_shreds(&entries, last_majority_vote, last_minority_vote, true, 0);
  4499. our_blockstore.insert_shreds(shreds, None, false).unwrap();
  4500. }
  4501. // Actual test, `our_node` will replay the minority fork, then the majority fork which will
  4502. // prune the minority fork. Then finally the problematic block will be skipped (not replayed)
  4503. // because its parent has been pruned from bank forks. Meanwhile the majority validator has
  4504. // continued making blocks and voting, duplicate confirming everything. This will cause the
  4505. // pruned fork to become popular triggering an ancestor hashes repair, eventually allowing our
  4506. // node to dump & repair & continue making roots.
  4507. info!("Restarting our node, verifying that our node is making roots past the duplicate block");
  4508. cluster.restart_node(
  4509. &our_node_pubkey,
  4510. our_node_info,
  4511. SocketAddrSpace::Unspecified,
  4512. );
  4513. cluster_tests::check_for_new_roots(
  4514. 16,
  4515. &[cluster.get_contact_info(&our_node_pubkey).unwrap().clone()],
  4516. &cluster.connection_cache,
  4517. "test_duplicate_with_pruned_ancestor",
  4518. );
  4519. }
  4520. /// Test fastboot to ensure a node can boot from local state and still produce correct snapshots
  4521. ///
  4522. /// 1. Start node 1 and wait for it to take snapshots
  4523. /// 2. Start node 2 with the snapshots from (1)
  4524. /// 3. Wait for node 2 to take a bank snapshot
  4525. /// 4. Restart node 2 with the local state from (3)
  4526. /// 5. Wait for node 2 to take new snapshots
  4527. /// 6. Start node 3 with the snapshots from (5)
  4528. /// 7. Wait for node 3 to take new snapshots
  4529. /// 8. Ensure the snapshots from (7) match node's 1 and 2
  4530. #[test]
  4531. #[serial]
  4532. fn test_boot_from_local_state() {
  4533. solana_logger::setup_with_default("error,local_cluster=info");
  4534. const FULL_SNAPSHOT_INTERVAL: SnapshotInterval =
  4535. SnapshotInterval::Slots(NonZeroU64::new(100).unwrap());
  4536. const INCREMENTAL_SNAPSHOT_INTERVAL: SnapshotInterval =
  4537. SnapshotInterval::Slots(NonZeroU64::new(10).unwrap());
  4538. let validator1_config =
  4539. SnapshotValidatorConfig::new(FULL_SNAPSHOT_INTERVAL, INCREMENTAL_SNAPSHOT_INTERVAL, 2);
  4540. let validator2_config =
  4541. SnapshotValidatorConfig::new(FULL_SNAPSHOT_INTERVAL, INCREMENTAL_SNAPSHOT_INTERVAL, 4);
  4542. let validator3_config =
  4543. SnapshotValidatorConfig::new(FULL_SNAPSHOT_INTERVAL, INCREMENTAL_SNAPSHOT_INTERVAL, 3);
  4544. let mut cluster_config = ClusterConfig {
  4545. node_stakes: vec![100 * DEFAULT_NODE_STAKE],
  4546. validator_configs: make_identical_validator_configs(&validator1_config.validator_config, 1),
  4547. ..ClusterConfig::default()
  4548. };
  4549. let mut cluster = LocalCluster::new(&mut cluster_config, SocketAddrSpace::Unspecified);
  4550. // in order to boot from local state, need to first have snapshot archives
  4551. info!("Waiting for validator1 to create snapshots...");
  4552. let (incremental_snapshot_archive, full_snapshot_archive) =
  4553. LocalCluster::wait_for_next_incremental_snapshot(
  4554. &cluster,
  4555. &validator1_config.full_snapshot_archives_dir,
  4556. &validator1_config.incremental_snapshot_archives_dir,
  4557. Some(Duration::from_secs(5 * 60)),
  4558. );
  4559. debug!(
  4560. "snapshot archives:\n\tfull: {full_snapshot_archive:?}\n\tincr: \
  4561. {incremental_snapshot_archive:?}"
  4562. );
  4563. info!("Waiting for validator1 to create snapshots... DONE");
  4564. info!("Copying snapshots to validator2...");
  4565. std::fs::copy(
  4566. full_snapshot_archive.path(),
  4567. validator2_config
  4568. .full_snapshot_archives_dir
  4569. .path()
  4570. .join(full_snapshot_archive.path().file_name().unwrap()),
  4571. )
  4572. .unwrap();
  4573. std::fs::copy(
  4574. incremental_snapshot_archive.path(),
  4575. validator2_config
  4576. .incremental_snapshot_archives_dir
  4577. .path()
  4578. .join(incremental_snapshot_archive.path().file_name().unwrap()),
  4579. )
  4580. .unwrap();
  4581. info!("Copying snapshots to validator2... DONE");
  4582. info!("Starting validator2...");
  4583. let validator2_identity = Arc::new(Keypair::new());
  4584. cluster.add_validator(
  4585. &validator2_config.validator_config,
  4586. DEFAULT_NODE_STAKE,
  4587. validator2_identity.clone(),
  4588. None,
  4589. SocketAddrSpace::Unspecified,
  4590. );
  4591. info!("Starting validator2... DONE");
  4592. // wait for a new bank snapshot to fastboot from that is newer than its snapshot archives
  4593. info!("Waiting for validator2 to create a new bank snapshot...");
  4594. let timer = Instant::now();
  4595. let bank_snapshot = loop {
  4596. if let Some(bank_snapshot) =
  4597. snapshot_utils::get_highest_bank_snapshot_post(&validator2_config.bank_snapshots_dir)
  4598. {
  4599. if bank_snapshot.slot > incremental_snapshot_archive.slot() {
  4600. break bank_snapshot;
  4601. }
  4602. }
  4603. assert!(
  4604. timer.elapsed() < Duration::from_secs(30),
  4605. "It should not take longer than 30 seconds to create a new bank snapshot"
  4606. );
  4607. std::thread::yield_now();
  4608. };
  4609. debug!("bank snapshot: {bank_snapshot:?}");
  4610. info!("Waiting for validator2 to create a new bank snapshot... DONE");
  4611. // restart WITH fastboot
  4612. info!("Restarting validator2 from local state...");
  4613. let mut validator2_info = cluster.exit_node(&validator2_identity.pubkey());
  4614. validator2_info.config.use_snapshot_archives_at_startup = UseSnapshotArchivesAtStartup::Never;
  4615. cluster.restart_node(
  4616. &validator2_identity.pubkey(),
  4617. validator2_info,
  4618. SocketAddrSpace::Unspecified,
  4619. );
  4620. info!("Restarting validator2 from local state... DONE");
  4621. info!("Waiting for validator2 to create snapshots...");
  4622. let (incremental_snapshot_archive, full_snapshot_archive) =
  4623. LocalCluster::wait_for_next_incremental_snapshot(
  4624. &cluster,
  4625. &validator2_config.full_snapshot_archives_dir,
  4626. &validator2_config.incremental_snapshot_archives_dir,
  4627. Some(Duration::from_secs(5 * 60)),
  4628. );
  4629. debug!(
  4630. "snapshot archives:\n\tfull: {full_snapshot_archive:?}\n\tincr: \
  4631. {incremental_snapshot_archive:?}"
  4632. );
  4633. info!("Waiting for validator2 to create snapshots... DONE");
  4634. info!("Copying snapshots to validator3...");
  4635. std::fs::copy(
  4636. full_snapshot_archive.path(),
  4637. validator3_config
  4638. .full_snapshot_archives_dir
  4639. .path()
  4640. .join(full_snapshot_archive.path().file_name().unwrap()),
  4641. )
  4642. .unwrap();
  4643. std::fs::copy(
  4644. incremental_snapshot_archive.path(),
  4645. validator3_config
  4646. .incremental_snapshot_archives_dir
  4647. .path()
  4648. .join(incremental_snapshot_archive.path().file_name().unwrap()),
  4649. )
  4650. .unwrap();
  4651. info!("Copying snapshots to validator3... DONE");
  4652. info!("Starting validator3...");
  4653. let validator3_identity = Arc::new(Keypair::new());
  4654. cluster.add_validator(
  4655. &validator3_config.validator_config,
  4656. DEFAULT_NODE_STAKE,
  4657. validator3_identity,
  4658. None,
  4659. SocketAddrSpace::Unspecified,
  4660. );
  4661. info!("Starting validator3... DONE");
  4662. // wait for a new snapshot to ensure the validator is making roots
  4663. info!("Waiting for validator3 to create snapshots...");
  4664. let (incremental_snapshot_archive, full_snapshot_archive) =
  4665. LocalCluster::wait_for_next_incremental_snapshot(
  4666. &cluster,
  4667. &validator3_config.full_snapshot_archives_dir,
  4668. &validator3_config.incremental_snapshot_archives_dir,
  4669. Some(Duration::from_secs(5 * 60)),
  4670. );
  4671. debug!(
  4672. "snapshot archives:\n\tfull: {full_snapshot_archive:?}\n\tincr: \
  4673. {incremental_snapshot_archive:?}"
  4674. );
  4675. info!("Waiting for validator3 to create snapshots... DONE");
  4676. // Ensure that all validators have the correct state by comparing snapshots.
  4677. // Since validator1 has been running the longest, if may be ahead of the others,
  4678. // so use it as the comparison for others.
  4679. // - wait for validator1 to take new snapshots
  4680. // - wait for the other validators to have high enough snapshots
  4681. // - ensure the other validators' snapshots match validator1's
  4682. //
  4683. // NOTE: There's a chance validator 2 or 3 has crossed the next full snapshot past what
  4684. // validator 1 has. If that happens, validator 2 or 3 may have purged the snapshots needed
  4685. // to compare with validator 1, and thus assert. If that happens, the full snapshot interval
  4686. // may need to be adjusted larger.
  4687. info!("Waiting for validator1 to create snapshots...");
  4688. let (incremental_snapshot_archive, full_snapshot_archive) =
  4689. LocalCluster::wait_for_next_incremental_snapshot(
  4690. &cluster,
  4691. &validator1_config.full_snapshot_archives_dir,
  4692. &validator1_config.incremental_snapshot_archives_dir,
  4693. Some(Duration::from_secs(5 * 60)),
  4694. );
  4695. debug!(
  4696. "snapshot archives:\n\tfull: {full_snapshot_archive:?}\n\tincr: \
  4697. {incremental_snapshot_archive:?}"
  4698. );
  4699. info!("Waiting for validator1 to create snapshots... DONE");
  4700. // These structs are used to provide better error logs if the asserts below are violated.
  4701. // The `allow(dead_code)` annotation is to appease clippy, which thinks the field is unused...
  4702. #[allow(dead_code)]
  4703. #[derive(Debug)]
  4704. struct SnapshotSlot(Slot);
  4705. #[allow(dead_code)]
  4706. #[derive(Debug)]
  4707. struct BaseSlot(Slot);
  4708. for (i, other_validator_config) in [(2, &validator2_config), (3, &validator3_config)] {
  4709. info!("Checking if validator{i} has the same snapshots as validator1...");
  4710. let timer = Instant::now();
  4711. loop {
  4712. if let Some(other_full_snapshot_slot) =
  4713. snapshot_utils::get_highest_full_snapshot_archive_slot(
  4714. &other_validator_config.full_snapshot_archives_dir,
  4715. )
  4716. {
  4717. let other_incremental_snapshot_slot =
  4718. snapshot_utils::get_highest_incremental_snapshot_archive_slot(
  4719. &other_validator_config.incremental_snapshot_archives_dir,
  4720. other_full_snapshot_slot,
  4721. );
  4722. if other_full_snapshot_slot >= full_snapshot_archive.slot()
  4723. && other_incremental_snapshot_slot >= Some(incremental_snapshot_archive.slot())
  4724. {
  4725. break;
  4726. }
  4727. }
  4728. assert!(
  4729. timer.elapsed() < Duration::from_secs(60),
  4730. "It should not take longer than 60 seconds to take snapshots",
  4731. );
  4732. std::thread::yield_now();
  4733. }
  4734. let other_full_snapshot_archives = snapshot_utils::get_full_snapshot_archives(
  4735. &other_validator_config.full_snapshot_archives_dir,
  4736. );
  4737. debug!("validator{i} full snapshot archives: {other_full_snapshot_archives:?}");
  4738. assert!(
  4739. other_full_snapshot_archives
  4740. .iter()
  4741. .any(
  4742. |other_full_snapshot_archive| other_full_snapshot_archive.slot()
  4743. == full_snapshot_archive.slot()
  4744. && other_full_snapshot_archive.hash() == full_snapshot_archive.hash()
  4745. ),
  4746. "full snapshot archive does not match!\n validator1: {:?}\n validator{i}: {:?}",
  4747. (
  4748. SnapshotSlot(full_snapshot_archive.slot()),
  4749. full_snapshot_archive.hash(),
  4750. ),
  4751. other_full_snapshot_archives
  4752. .iter()
  4753. .sorted_unstable()
  4754. .rev()
  4755. .map(|snap| (SnapshotSlot(snap.slot()), snap.hash()))
  4756. .collect::<Vec<_>>(),
  4757. );
  4758. let other_incremental_snapshot_archives = snapshot_utils::get_incremental_snapshot_archives(
  4759. &other_validator_config.incremental_snapshot_archives_dir,
  4760. );
  4761. debug!(
  4762. "validator{i} incremental snapshot archives: {other_incremental_snapshot_archives:?}"
  4763. );
  4764. assert!(
  4765. other_incremental_snapshot_archives
  4766. .iter()
  4767. .any(
  4768. |other_incremental_snapshot_archive| other_incremental_snapshot_archive
  4769. .base_slot()
  4770. == incremental_snapshot_archive.base_slot()
  4771. && other_incremental_snapshot_archive.slot()
  4772. == incremental_snapshot_archive.slot()
  4773. && other_incremental_snapshot_archive.hash()
  4774. == incremental_snapshot_archive.hash()
  4775. ),
  4776. "incremental snapshot archive does not match!\n validator1: {:?}\n validator{i}: \
  4777. {:?}",
  4778. (
  4779. BaseSlot(incremental_snapshot_archive.base_slot()),
  4780. SnapshotSlot(incremental_snapshot_archive.slot()),
  4781. incremental_snapshot_archive.hash(),
  4782. ),
  4783. other_incremental_snapshot_archives
  4784. .iter()
  4785. .sorted_unstable()
  4786. .rev()
  4787. .map(|snap| (
  4788. BaseSlot(snap.base_slot()),
  4789. SnapshotSlot(snap.slot()),
  4790. snap.hash(),
  4791. ))
  4792. .collect::<Vec<_>>(),
  4793. );
  4794. info!("Checking if validator{i} has the same snapshots as validator1... DONE");
  4795. }
  4796. }
  4797. /// Test fastboot to ensure a node can boot in case it crashed while archiving a full snapshot
  4798. ///
  4799. /// 1. Start a node and wait for it to take at least two full snapshots and one more
  4800. /// bank snapshot POST afterwards (for simplicity, wait for 2 full and 1 incremental).
  4801. /// 2. To simulate a node crashing while archiving a full snapshot, stop the node and
  4802. /// then delete the latest full snapshot archive.
  4803. /// 3. Restart the node. This should succeed, and boot from the older full snapshot archive,
  4804. /// *not* the latest bank snapshot POST.
  4805. /// 4. Take another incremental snapshot. This ensures the correct snapshot was loaded,
  4806. /// AND ensures the correct accounts hashes are present (which are needed when making
  4807. /// the bank snapshot POST for the new incremental snapshot).
  4808. #[test]
  4809. #[serial]
  4810. fn test_boot_from_local_state_missing_archive() {
  4811. solana_logger::setup_with_default(RUST_LOG_FILTER);
  4812. const FULL_SNAPSHOT_INTERVAL: SnapshotInterval =
  4813. SnapshotInterval::Slots(NonZeroU64::new(20).unwrap());
  4814. const INCREMENTAL_SNAPSHOT_INTERVAL: SnapshotInterval =
  4815. SnapshotInterval::Slots(NonZeroU64::new(10).unwrap());
  4816. let validator_config =
  4817. SnapshotValidatorConfig::new(FULL_SNAPSHOT_INTERVAL, INCREMENTAL_SNAPSHOT_INTERVAL, 7);
  4818. let mut cluster_config = ClusterConfig {
  4819. node_stakes: vec![100 * DEFAULT_NODE_STAKE],
  4820. validator_configs: make_identical_validator_configs(&validator_config.validator_config, 1),
  4821. ..ClusterConfig::default()
  4822. };
  4823. let mut cluster = LocalCluster::new(&mut cluster_config, SocketAddrSpace::Unspecified);
  4824. // we need two full snapshots and an incremental snapshot for this test
  4825. info!("Waiting for validator to create snapshots...");
  4826. LocalCluster::wait_for_next_full_snapshot(
  4827. &cluster,
  4828. &validator_config.full_snapshot_archives_dir,
  4829. Some(Duration::from_secs(5 * 60)),
  4830. );
  4831. LocalCluster::wait_for_next_full_snapshot(
  4832. &cluster,
  4833. &validator_config.full_snapshot_archives_dir,
  4834. Some(Duration::from_secs(5 * 60)),
  4835. );
  4836. LocalCluster::wait_for_next_incremental_snapshot(
  4837. &cluster,
  4838. &validator_config.full_snapshot_archives_dir,
  4839. &validator_config.incremental_snapshot_archives_dir,
  4840. Some(Duration::from_secs(5 * 60)),
  4841. );
  4842. debug!(
  4843. "snapshot archives:\n\tfull: {:?}\n\tincr: {:?}",
  4844. snapshot_utils::get_full_snapshot_archives(
  4845. validator_config.full_snapshot_archives_dir.path()
  4846. ),
  4847. snapshot_utils::get_incremental_snapshot_archives(
  4848. validator_config.incremental_snapshot_archives_dir.path()
  4849. ),
  4850. );
  4851. info!("Waiting for validator to create snapshots... DONE");
  4852. // now delete the latest full snapshot archive and restart, to simulate a crash while archiving
  4853. // a full snapshot package
  4854. info!("Stopping validator...");
  4855. let validator_pubkey = cluster.get_node_pubkeys()[0];
  4856. let mut validator_info = cluster.exit_node(&validator_pubkey);
  4857. info!("Stopping validator... DONE");
  4858. info!("Deleting latest full snapshot archive...");
  4859. let highest_full_snapshot = snapshot_utils::get_highest_full_snapshot_archive_info(
  4860. validator_config.full_snapshot_archives_dir.path(),
  4861. )
  4862. .unwrap();
  4863. fs::remove_file(highest_full_snapshot.path()).unwrap();
  4864. info!("Deleting latest full snapshot archive... DONE");
  4865. info!("Restarting validator...");
  4866. // if we set this to `Never`, the validator should not boot
  4867. validator_info.config.use_snapshot_archives_at_startup =
  4868. UseSnapshotArchivesAtStartup::WhenNewest;
  4869. cluster.restart_node(
  4870. &validator_pubkey,
  4871. validator_info,
  4872. SocketAddrSpace::Unspecified,
  4873. );
  4874. info!("Restarting validator... DONE");
  4875. // ensure we can create new incremental snapshots, since that is what used to fail
  4876. info!("Waiting for validator to create snapshots...");
  4877. LocalCluster::wait_for_next_incremental_snapshot(
  4878. &cluster,
  4879. &validator_config.full_snapshot_archives_dir,
  4880. &validator_config.incremental_snapshot_archives_dir,
  4881. Some(Duration::from_secs(5 * 60)),
  4882. );
  4883. info!("Waiting for validator to create snapshots... DONE");
  4884. }
  4885. // We want to simulate the following:
  4886. // /--- 1 --- 3 (duplicate block)
  4887. // 0
  4888. // \--- 2
  4889. //
  4890. // 1. > DUPLICATE_THRESHOLD of the nodes vote on some version of the duplicate block 3,
  4891. // but don't immediately duplicate confirm so they remove 3 from fork choice and reset PoH back to 1.
  4892. // 2. All the votes on 3 don't land because there are no further blocks building off 3.
  4893. // 3. Some < SWITCHING_THRESHOLD of nodes vote on 2, making it the heaviest fork because no votes on 3 landed
  4894. // 4. Nodes then see duplicate confirmation on 3.
  4895. // 5. Unless somebody builds off of 3 to include the duplicate confirmed votes, 2 will still be the heaviest.
  4896. // However, because 2 has < SWITCHING_THRESHOLD of the votes, people who voted on 3 can't switch, leading to a
  4897. // stall
  4898. #[test]
  4899. #[serial]
  4900. #[allow(unused_attributes)]
  4901. #[ignore]
  4902. fn test_duplicate_shreds_switch_failure() {
  4903. fn wait_for_duplicate_fork_frozen(ledger_path: &Path, dup_slot: Slot) -> Hash {
  4904. // Ensure all the slots <= dup_slot are also full so we know we can replay up to dup_slot
  4905. // on restart
  4906. info!("Waiting to receive and replay entire duplicate fork with tip {dup_slot}");
  4907. loop {
  4908. let duplicate_fork_validator_blockstore = open_blockstore(ledger_path);
  4909. if let Some(frozen_hash) = duplicate_fork_validator_blockstore.get_bank_hash(dup_slot) {
  4910. return frozen_hash;
  4911. }
  4912. sleep(Duration::from_millis(1000));
  4913. }
  4914. }
  4915. fn clear_ledger_and_tower(ledger_path: &Path, pubkey: &Pubkey, start_slot: Slot) {
  4916. remove_tower_if_exists(ledger_path, pubkey);
  4917. let blockstore = open_blockstore(ledger_path);
  4918. purge_slots_with_count(&blockstore, start_slot, 1000);
  4919. {
  4920. // Remove all duplicate proofs so that this dup_slot will vote on the `dup_slot`.
  4921. while let Some((proof_slot, _)) = blockstore.get_first_duplicate_proof() {
  4922. blockstore.remove_slot_duplicate_proof(proof_slot).unwrap();
  4923. }
  4924. }
  4925. }
  4926. fn restart_dup_validator(
  4927. cluster: &mut LocalCluster,
  4928. mut duplicate_fork_validator_info: ClusterValidatorInfo,
  4929. pubkey: &Pubkey,
  4930. dup_slot: Slot,
  4931. dup_shred1: &Shred,
  4932. dup_shred2: &Shred,
  4933. ) {
  4934. let disable_turbine = Arc::new(AtomicBool::new(true));
  4935. duplicate_fork_validator_info.config.voting_disabled = false;
  4936. duplicate_fork_validator_info.config.turbine_disabled = disable_turbine.clone();
  4937. info!("Restarting node: {pubkey}");
  4938. cluster.restart_node(
  4939. pubkey,
  4940. duplicate_fork_validator_info,
  4941. SocketAddrSpace::Unspecified,
  4942. );
  4943. let ledger_path = cluster.ledger_path(pubkey);
  4944. // Lift the partition after `pubkey` votes on the `dup_slot`
  4945. info!("Waiting on duplicate fork to vote on duplicate slot: {dup_slot}");
  4946. loop {
  4947. let last_vote = last_vote_in_tower(&ledger_path, pubkey);
  4948. if let Some((latest_vote_slot, _hash)) = last_vote {
  4949. info!("latest vote: {latest_vote_slot}");
  4950. if latest_vote_slot == dup_slot {
  4951. break;
  4952. }
  4953. }
  4954. sleep(Duration::from_millis(1000));
  4955. }
  4956. disable_turbine.store(false, Ordering::Relaxed);
  4957. // Send the validator the other version of the shred so they realize it's duplicate
  4958. info!("Resending duplicate shreds to duplicate fork validator");
  4959. cluster.send_shreds_to_validator(vec![dup_shred1, dup_shred2], pubkey);
  4960. // Check the validator detected a duplicate proof
  4961. info!("Waiting on duplicate fork validator to see duplicate shreds and make a proof",);
  4962. loop {
  4963. let duplicate_fork_validator_blockstore = open_blockstore(&ledger_path);
  4964. if let Some(dup_proof) = duplicate_fork_validator_blockstore.get_first_duplicate_proof()
  4965. {
  4966. assert_eq!(dup_proof.0, dup_slot);
  4967. break;
  4968. }
  4969. sleep(Duration::from_millis(1000));
  4970. }
  4971. }
  4972. solana_logger::setup_with_default(RUST_LOG_FILTER);
  4973. let validator_keypairs = [
  4974. "28bN3xyvrP4E8LwEgtLjhnkb7cY4amQb6DrYAbAYjgRV4GAGgkVM2K7wnxnAS7WDneuavza7x21MiafLu1HkwQt4",
  4975. "2saHBBoTkLMmttmPQP8KfBkcCw45S5cwtV3wTdGCscRC8uxdgvHxpHiWXKx4LvJjNJtnNcbSv5NdheokFFqnNDt8",
  4976. "4mx9yoFBeYasDKBGDWCTWGJdWuJCKbgqmuP8bN9umybCh5Jzngw7KQxe99Rf5uzfyzgba1i65rJW4Wqk7Ab5S8ye",
  4977. "2XFPyuzPuXMsPnkH98UNcQpfA7M4b2TUhRxcWEoWjy4M6ojQ7HGJSvotktEVbaq49Qxt16wUjdqvSJc6ecbFfZwj",
  4978. ]
  4979. .iter()
  4980. .map(|s| (Arc::new(Keypair::from_base58_string(s)), true))
  4981. .collect::<Vec<_>>();
  4982. let validators = validator_keypairs
  4983. .iter()
  4984. .map(|(kp, _)| kp.pubkey())
  4985. .collect::<Vec<_>>();
  4986. // Create 4 nodes:
  4987. // 1) Two nodes that sum to > DUPLICATE_THRESHOLD but < 2/3+ supermajority. It's important both
  4988. // of them individually have <= DUPLICATE_THRESHOLD to avoid duplicate confirming their own blocks
  4989. // immediately upon voting
  4990. // 2) One with <= SWITCHING_THRESHOLD so that validator from 1) can't switch to it
  4991. // 3) One bad leader to make duplicate slots
  4992. let total_stake = 100 * DEFAULT_NODE_STAKE;
  4993. let target_switch_fork_stake = (total_stake as f64 * SWITCH_FORK_THRESHOLD) as u64;
  4994. // duplicate_fork_node1_stake + duplicate_fork_node2_stake > DUPLICATE_THRESHOLD. Don't want
  4995. // one node with > DUPLICATE_THRESHOLD, otherwise they will automatically duplicate confirm a
  4996. // slot when they vote, which will prevent them from resetting to an earlier ancestor when they
  4997. // later discover that slot as duplicate.
  4998. let duplicate_fork_node1_stake = (total_stake as f64 * DUPLICATE_THRESHOLD) as u64;
  4999. let duplicate_fork_node2_stake = 1;
  5000. let duplicate_leader_stake = total_stake
  5001. - target_switch_fork_stake
  5002. - duplicate_fork_node1_stake
  5003. - duplicate_fork_node2_stake;
  5004. assert!(
  5005. duplicate_fork_node1_stake + duplicate_fork_node2_stake
  5006. > (total_stake as f64 * DUPLICATE_THRESHOLD) as u64
  5007. );
  5008. assert!(duplicate_fork_node1_stake <= (total_stake as f64 * DUPLICATE_THRESHOLD) as u64);
  5009. assert!(duplicate_fork_node2_stake <= (total_stake as f64 * DUPLICATE_THRESHOLD) as u64);
  5010. let node_stakes = vec![
  5011. duplicate_leader_stake,
  5012. target_switch_fork_stake,
  5013. duplicate_fork_node1_stake,
  5014. duplicate_fork_node2_stake,
  5015. ];
  5016. let (
  5017. // Has to be first in order to be picked as the duplicate leader
  5018. duplicate_leader_validator_pubkey,
  5019. target_switch_fork_validator_pubkey,
  5020. duplicate_fork_validator1_pubkey,
  5021. duplicate_fork_validator2_pubkey,
  5022. ) = (validators[0], validators[1], validators[2], validators[3]);
  5023. info!(
  5024. "duplicate_fork_validator1_pubkey: {duplicate_fork_validator1_pubkey}, \
  5025. duplicate_fork_validator2_pubkey: {duplicate_fork_validator2_pubkey}, \
  5026. target_switch_fork_validator_pubkey: {target_switch_fork_validator_pubkey}, \
  5027. duplicate_leader_validator_pubkey: {duplicate_leader_validator_pubkey}",
  5028. );
  5029. let validator_to_slots = vec![
  5030. (duplicate_leader_validator_pubkey, 50),
  5031. (target_switch_fork_validator_pubkey, 5),
  5032. // The ideal sequence of events for the `duplicate_fork_validator1_pubkey` validator would go:
  5033. // 1. Vote for duplicate block `D`
  5034. // 2. See `D` is duplicate, remove from fork choice and reset to ancestor `A`, potentially generating a fork off that ancestor
  5035. // 3. See `D` is duplicate confirmed, but because of the bug fixed by https://github.com/solana-labs/solana/pull/28172
  5036. // where we disallow resetting to a slot which matches the last vote slot, we still don't build off `D`,
  5037. // and continue building on `A`.
  5038. //
  5039. // The `target_switch_fork_validator_pubkey` fork is necessary in 2. to force the validator stall trying to switch
  5040. // vote on that other fork and prevent the validator from making a freebie vote from `A` and allowing consensus to continue.
  5041. // It's important we don't give the `duplicate_fork_validator1_pubkey` leader slots until a certain number
  5042. // of slots have elapsed to ensure:
  5043. // 1. We have ample time to ensure he doesn't have a chance to make a block until after 2 when they see the block is duplicate.
  5044. // Otherwise, they'll build the block on top of the duplicate block, which will possibly include a vote for the duplicate block.
  5045. // We want to avoid this because this will make fork choice pick the duplicate block.
  5046. // 2. Ensure the `duplicate_fork_validator1_pubkey` sees the target switch fork before it can make another vote
  5047. // on any forks he himself generates from A. Otherwise, he will make a freebie vote on his own fork from `A` and
  5048. // consensus will continue on that fork.
  5049. // Give the duplicate fork validator plenty of leader slots after the initial delay to prevent
  5050. // 1. Switch fork from getting locked out for too long
  5051. // 2. A lot of consecutive slots in which to build up lockout in tower and make new roots
  5052. // to resolve the partition
  5053. (duplicate_fork_validator1_pubkey, 500),
  5054. ];
  5055. let leader_schedule = create_custom_leader_schedule(validator_to_slots.into_iter());
  5056. // 1) Set up the cluster
  5057. let (duplicate_slot_sender, duplicate_slot_receiver) = unbounded();
  5058. let validator_configs = validator_keypairs
  5059. .into_iter()
  5060. .map(|(validator_keypair, in_genesis)| {
  5061. let pubkey = validator_keypair.pubkey();
  5062. // Only allow the leader to vote so that no version gets duplicate confirmed.
  5063. // This is to avoid the leader dumping his own block.
  5064. let voting_disabled = { pubkey != duplicate_leader_validator_pubkey };
  5065. ValidatorTestConfig {
  5066. validator_keypair,
  5067. validator_config: ValidatorConfig {
  5068. voting_disabled,
  5069. ..ValidatorConfig::default_for_test()
  5070. },
  5071. in_genesis,
  5072. }
  5073. })
  5074. .collect();
  5075. let (mut cluster, _validator_keypairs) = test_faulty_node(
  5076. BroadcastStageType::BroadcastDuplicates(BroadcastDuplicatesConfig {
  5077. partition: ClusterPartition::Pubkey(vec![
  5078. // Don't include the other dup validator here, otherwise
  5079. // this dup version will have enough to be duplicate confirmed and
  5080. // will cause the dup leader to try and dump its own slot,
  5081. // crashing before it can signal the duplicate slot via the
  5082. // `duplicate_slot_receiver` below
  5083. duplicate_fork_validator1_pubkey,
  5084. ]),
  5085. duplicate_slot_sender: Some(duplicate_slot_sender),
  5086. }),
  5087. node_stakes,
  5088. Some(validator_configs),
  5089. Some(FixedSchedule {
  5090. leader_schedule: Arc::new(leader_schedule),
  5091. }),
  5092. );
  5093. // Kill two validators that might duplicate confirm the duplicate block
  5094. info!("Killing unnecessary validators");
  5095. let duplicate_fork_validator2_ledger_path =
  5096. cluster.ledger_path(&duplicate_fork_validator2_pubkey);
  5097. let duplicate_fork_validator2_info = cluster.exit_node(&duplicate_fork_validator2_pubkey);
  5098. let target_switch_fork_validator_ledger_path =
  5099. cluster.ledger_path(&target_switch_fork_validator_pubkey);
  5100. let mut target_switch_fork_validator_info =
  5101. cluster.exit_node(&target_switch_fork_validator_pubkey);
  5102. // 2) Wait for a duplicate slot to land on both validators and for the target switch
  5103. // fork validator to get another version of the slot. Also ensure all versions of
  5104. // the block are playable
  5105. let dup_slot = duplicate_slot_receiver
  5106. .recv_timeout(Duration::from_millis(30_000))
  5107. .expect("Duplicate leader failed to make a duplicate slot in allotted time");
  5108. // Make sure both validators received and replay the complete blocks
  5109. let dup_frozen_hash = wait_for_duplicate_fork_frozen(
  5110. &cluster.ledger_path(&duplicate_fork_validator1_pubkey),
  5111. dup_slot,
  5112. );
  5113. let original_frozen_hash = wait_for_duplicate_fork_frozen(
  5114. &cluster.ledger_path(&duplicate_leader_validator_pubkey),
  5115. dup_slot,
  5116. );
  5117. assert_ne!(
  5118. original_frozen_hash, dup_frozen_hash,
  5119. "Duplicate leader and partition target got same hash: {original_frozen_hash}",
  5120. );
  5121. // 3) Force `duplicate_fork_validator1_pubkey` to see a duplicate proof
  5122. info!("Waiting for duplicate proof for slot: {dup_slot}");
  5123. let duplicate_proof = {
  5124. // Grab the other version of the slot from the `duplicate_leader_validator_pubkey`
  5125. // which we confirmed to have a different version of the frozen hash in the loop
  5126. // above
  5127. let ledger_path = cluster.ledger_path(&duplicate_leader_validator_pubkey);
  5128. let blockstore = open_blockstore(&ledger_path);
  5129. let dup_shred = blockstore
  5130. .get_data_shreds_for_slot(dup_slot, 0)
  5131. .unwrap()
  5132. .pop()
  5133. .unwrap();
  5134. info!(
  5135. "Sending duplicate shred: {:?} to {:?}",
  5136. dup_shred.signature(),
  5137. duplicate_fork_validator1_pubkey
  5138. );
  5139. cluster.send_shreds_to_validator(vec![&dup_shred], &duplicate_fork_validator1_pubkey);
  5140. wait_for_duplicate_proof(
  5141. &cluster.ledger_path(&duplicate_fork_validator1_pubkey),
  5142. dup_slot,
  5143. )
  5144. .unwrap_or_else(|| panic!("Duplicate proof for slot {dup_slot} not found"))
  5145. };
  5146. // 3) Kill all the validators
  5147. info!("Killing remaining validators");
  5148. let duplicate_fork_validator1_ledger_path =
  5149. cluster.ledger_path(&duplicate_fork_validator1_pubkey);
  5150. let duplicate_fork_validator1_info = cluster.exit_node(&duplicate_fork_validator1_pubkey);
  5151. let duplicate_leader_ledger_path = cluster.ledger_path(&duplicate_leader_validator_pubkey);
  5152. cluster.exit_node(&duplicate_leader_validator_pubkey);
  5153. let dup_shred1 = Shred::new_from_serialized_shred(duplicate_proof.shred1.clone()).unwrap();
  5154. let dup_shred2 = Shred::new_from_serialized_shred(duplicate_proof.shred2).unwrap();
  5155. assert_eq!(dup_shred1.slot(), dup_shred2.slot());
  5156. assert_eq!(dup_shred1.slot(), dup_slot);
  5157. // Purge everything including the `dup_slot` from the `target_switch_fork_validator_pubkey`
  5158. info!("Purging towers and ledgers for: {duplicate_leader_validator_pubkey:?}");
  5159. Blockstore::destroy(&target_switch_fork_validator_ledger_path).unwrap();
  5160. {
  5161. let blockstore1 = open_blockstore(&duplicate_leader_ledger_path);
  5162. let blockstore2 = open_blockstore(&target_switch_fork_validator_ledger_path);
  5163. copy_blocks(dup_slot, &blockstore1, &blockstore2, false);
  5164. }
  5165. clear_ledger_and_tower(
  5166. &target_switch_fork_validator_ledger_path,
  5167. &target_switch_fork_validator_pubkey,
  5168. dup_slot,
  5169. );
  5170. info!("Purging towers and ledgers for: {duplicate_fork_validator1_pubkey:?}");
  5171. clear_ledger_and_tower(
  5172. &duplicate_fork_validator1_ledger_path,
  5173. &duplicate_fork_validator1_pubkey,
  5174. dup_slot + 1,
  5175. );
  5176. info!("Purging towers and ledgers for: {duplicate_fork_validator2_pubkey:?}");
  5177. // Copy validator 1's ledger to validator 2 so that they have the same version
  5178. // of the duplicate slot
  5179. clear_ledger_and_tower(
  5180. &duplicate_fork_validator2_ledger_path,
  5181. &duplicate_fork_validator2_pubkey,
  5182. dup_slot,
  5183. );
  5184. Blockstore::destroy(&duplicate_fork_validator2_ledger_path).unwrap();
  5185. {
  5186. let blockstore1 = open_blockstore(&duplicate_fork_validator1_ledger_path);
  5187. let blockstore2 = open_blockstore(&duplicate_fork_validator2_ledger_path);
  5188. copy_blocks(dup_slot, &blockstore1, &blockstore2, false);
  5189. }
  5190. // Set entrypoint to `target_switch_fork_validator_pubkey` so we can run discovery in gossip even without the
  5191. // bad leader
  5192. cluster.set_entry_point(target_switch_fork_validator_info.info.contact_info.clone());
  5193. // 4) Restart `target_switch_fork_validator_pubkey`, and ensure they vote on their own leader slot
  5194. // that's not descended from the duplicate slot
  5195. info!("Restarting switch fork node");
  5196. target_switch_fork_validator_info.config.voting_disabled = false;
  5197. cluster.restart_node(
  5198. &target_switch_fork_validator_pubkey,
  5199. target_switch_fork_validator_info,
  5200. SocketAddrSpace::Unspecified,
  5201. );
  5202. let target_switch_fork_validator_ledger_path =
  5203. cluster.ledger_path(&target_switch_fork_validator_pubkey);
  5204. info!("Waiting for switch fork to make block past duplicate fork");
  5205. loop {
  5206. let last_vote = wait_for_last_vote_in_tower_to_land_in_ledger(
  5207. &target_switch_fork_validator_ledger_path,
  5208. &target_switch_fork_validator_pubkey,
  5209. );
  5210. if let Some(latest_vote_slot) = last_vote {
  5211. if latest_vote_slot > dup_slot {
  5212. let blockstore = open_blockstore(&target_switch_fork_validator_ledger_path);
  5213. let ancestor_slots: HashSet<Slot> =
  5214. AncestorIterator::new_inclusive(latest_vote_slot, &blockstore).collect();
  5215. assert!(ancestor_slots.contains(&latest_vote_slot));
  5216. assert!(ancestor_slots.contains(&0));
  5217. assert!(!ancestor_slots.contains(&dup_slot));
  5218. break;
  5219. }
  5220. }
  5221. sleep(Duration::from_millis(1000));
  5222. }
  5223. // Now restart the duplicate validators
  5224. // Start the node with partition enabled so they don't see the `target_switch_fork_validator_pubkey`
  5225. // before voting on the duplicate block
  5226. info!("Restarting duplicate fork node");
  5227. // Ensure `duplicate_fork_validator1_pubkey` votes before starting up `duplicate_fork_validator2_pubkey`
  5228. // to prevent them seeing `dup_slot` as duplicate confirmed before voting.
  5229. restart_dup_validator(
  5230. &mut cluster,
  5231. duplicate_fork_validator1_info,
  5232. &duplicate_fork_validator1_pubkey,
  5233. dup_slot,
  5234. &dup_shred1,
  5235. &dup_shred2,
  5236. );
  5237. restart_dup_validator(
  5238. &mut cluster,
  5239. duplicate_fork_validator2_info,
  5240. &duplicate_fork_validator2_pubkey,
  5241. dup_slot,
  5242. &dup_shred1,
  5243. &dup_shred2,
  5244. );
  5245. // Wait for the `duplicate_fork_validator1_pubkey` to make another leader block on top
  5246. // of the duplicate fork which includes their own vote for `dup_block`. This
  5247. // should make the duplicate fork the heaviest
  5248. info!("Waiting on duplicate fork validator to generate block on top of duplicate fork",);
  5249. loop {
  5250. let duplicate_fork_validator_blockstore =
  5251. open_blockstore(&cluster.ledger_path(&duplicate_fork_validator1_pubkey));
  5252. let meta = duplicate_fork_validator_blockstore
  5253. .meta(dup_slot)
  5254. .unwrap()
  5255. .unwrap();
  5256. if !meta.next_slots.is_empty() {
  5257. info!(
  5258. "duplicate fork validator saw new slots: {:?} on top of duplicate slot",
  5259. meta.next_slots
  5260. );
  5261. break;
  5262. }
  5263. sleep(Duration::from_millis(1000));
  5264. }
  5265. // Check that the cluster is making progress
  5266. cluster.check_for_new_roots(
  5267. 16,
  5268. "test_duplicate_shreds_switch_failure",
  5269. SocketAddrSpace::Unspecified,
  5270. );
  5271. }
  5272. #[test]
  5273. #[serial]
  5274. fn test_randomly_mixed_block_verification_methods_between_bootstrap_and_not() {
  5275. // tailored logging just to see two block verification methods are working correctly
  5276. solana_logger::setup_with_default(
  5277. "solana_metrics::metrics=warn,solana_core=warn,\
  5278. solana_runtime::installed_scheduler_pool=trace,solana_ledger::blockstore_processor=debug,\
  5279. info",
  5280. );
  5281. let num_nodes = BlockVerificationMethod::COUNT;
  5282. let mut config =
  5283. ClusterConfig::new_with_equal_stakes(num_nodes, DEFAULT_MINT_LAMPORTS, DEFAULT_NODE_STAKE);
  5284. // Overwrite block_verification_method with shuffled variants
  5285. let mut methods = BlockVerificationMethod::iter().collect::<Vec<_>>();
  5286. methods.shuffle(&mut rand::thread_rng());
  5287. for (validator_config, method) in config.validator_configs.iter_mut().zip_eq(methods) {
  5288. validator_config.block_verification_method = method;
  5289. }
  5290. let local = LocalCluster::new(&mut config, SocketAddrSpace::Unspecified);
  5291. cluster_tests::spend_and_verify_all_nodes(
  5292. &local.entry_point_info,
  5293. &local.funding_keypair,
  5294. num_nodes,
  5295. HashSet::new(),
  5296. SocketAddrSpace::Unspecified,
  5297. &local.connection_cache,
  5298. );
  5299. }
  5300. /// Forks previous marked invalid should be marked as such in fork choice on restart
  5301. #[test]
  5302. #[ignore]
  5303. #[serial]
  5304. fn test_invalid_forks_persisted_on_restart() {
  5305. solana_logger::setup_with("info,solana_metrics=off,solana_ledger=off");
  5306. let dup_slot = 10;
  5307. let validator_keypairs = [
  5308. "28bN3xyvrP4E8LwEgtLjhnkb7cY4amQb6DrYAbAYjgRV4GAGgkVM2K7wnxnAS7WDneuavza7x21MiafLu1HkwQt4",
  5309. "2saHBBoTkLMmttmPQP8KfBkcCw45S5cwtV3wTdGCscRC8uxdgvHxpHiWXKx4LvJjNJtnNcbSv5NdheokFFqnNDt8",
  5310. ]
  5311. .iter()
  5312. .map(|s| (Arc::new(Keypair::from_base58_string(s)), true))
  5313. .collect::<Vec<_>>();
  5314. let majority_keypair = validator_keypairs[1].0.clone();
  5315. let validators = validator_keypairs
  5316. .iter()
  5317. .map(|(kp, _)| kp.pubkey())
  5318. .collect::<Vec<_>>();
  5319. let node_stakes = vec![DEFAULT_NODE_STAKE, 100 * DEFAULT_NODE_STAKE];
  5320. let (target_pubkey, majority_pubkey) = (validators[0], validators[1]);
  5321. // Need majority validator to make the dup_slot
  5322. let validator_to_slots = vec![
  5323. (majority_pubkey, dup_slot as usize + 5),
  5324. (target_pubkey, DEFAULT_SLOTS_PER_EPOCH as usize),
  5325. ];
  5326. let leader_schedule = create_custom_leader_schedule(validator_to_slots.into_iter());
  5327. let mut default_config = ValidatorConfig::default_for_test();
  5328. default_config.fixed_leader_schedule = Some(FixedSchedule {
  5329. leader_schedule: Arc::new(leader_schedule),
  5330. });
  5331. let mut validator_configs = make_identical_validator_configs(&default_config, 2);
  5332. // Majority shouldn't duplicate confirm anything
  5333. validator_configs[1].voting_disabled = true;
  5334. let mut cluster = LocalCluster::new(
  5335. &mut ClusterConfig {
  5336. mint_lamports: DEFAULT_MINT_LAMPORTS + node_stakes.iter().sum::<u64>(),
  5337. validator_configs,
  5338. node_stakes,
  5339. validator_keys: Some(validator_keypairs),
  5340. skip_warmup_slots: true,
  5341. ..ClusterConfig::default()
  5342. },
  5343. SocketAddrSpace::Unspecified,
  5344. );
  5345. let target_ledger_path = cluster.ledger_path(&target_pubkey);
  5346. // Wait for us to vote past duplicate slot
  5347. let timer = Instant::now();
  5348. loop {
  5349. if let Some(slot) =
  5350. wait_for_last_vote_in_tower_to_land_in_ledger(&target_ledger_path, &target_pubkey)
  5351. {
  5352. if slot > dup_slot {
  5353. break;
  5354. }
  5355. }
  5356. assert!(
  5357. timer.elapsed() < Duration::from_secs(30),
  5358. "Did not make more than 10 blocks in 30 seconds"
  5359. );
  5360. sleep(Duration::from_millis(100));
  5361. }
  5362. // Send duplicate
  5363. let parent = {
  5364. let blockstore = open_blockstore(&target_ledger_path);
  5365. let parent = blockstore
  5366. .meta(dup_slot)
  5367. .unwrap()
  5368. .unwrap()
  5369. .parent_slot
  5370. .unwrap();
  5371. let entries = create_ticks(
  5372. 64 * (std::cmp::max(1, dup_slot - parent)),
  5373. 0,
  5374. cluster.genesis_config.hash(),
  5375. );
  5376. let last_hash = entries.last().unwrap().hash;
  5377. let version = solana_shred_version::version_from_hash(&last_hash);
  5378. let dup_shreds = Shredder::new(dup_slot, parent, 0, version)
  5379. .unwrap()
  5380. .entries_to_merkle_shreds_for_tests(
  5381. &majority_keypair,
  5382. &entries,
  5383. true, // is_full_slot
  5384. None, // chained_merkle_root
  5385. 0, // next_shred_index,
  5386. 0, // next_code_index
  5387. &ReedSolomonCache::default(),
  5388. &mut ProcessShredsStats::default(),
  5389. )
  5390. .0;
  5391. info!("Sending duplicate shreds for {dup_slot}");
  5392. cluster.send_shreds_to_validator(dup_shreds.iter().collect(), &target_pubkey);
  5393. wait_for_duplicate_proof(&target_ledger_path, dup_slot)
  5394. .expect("Duplicate proof for {dup_slot} not found");
  5395. parent
  5396. };
  5397. info!("Duplicate proof for {dup_slot} has landed, restarting node");
  5398. let info = cluster.exit_node(&target_pubkey);
  5399. {
  5400. let blockstore = open_blockstore(&target_ledger_path);
  5401. purge_slots_with_count(&blockstore, dup_slot + 5, 100);
  5402. }
  5403. // Restart, should create an entirely new fork
  5404. cluster.restart_node(&target_pubkey, info, SocketAddrSpace::Unspecified);
  5405. info!("Waiting for fork built off {parent}");
  5406. let timer = Instant::now();
  5407. let mut checked_children: HashSet<Slot> = HashSet::default();
  5408. let mut done = false;
  5409. while !done {
  5410. let blockstore = open_blockstore(&target_ledger_path);
  5411. let parent_meta = blockstore.meta(parent).unwrap().expect("Meta must exist");
  5412. for child in parent_meta.next_slots {
  5413. if checked_children.contains(&child) {
  5414. continue;
  5415. }
  5416. if blockstore.is_full(child) {
  5417. let shreds = blockstore
  5418. .get_data_shreds_for_slot(child, 0)
  5419. .expect("Child is full");
  5420. let mut is_our_block = true;
  5421. for shred in shreds {
  5422. is_our_block &= shred.verify(&target_pubkey);
  5423. }
  5424. if is_our_block {
  5425. done = true;
  5426. }
  5427. checked_children.insert(child);
  5428. }
  5429. }
  5430. assert!(
  5431. timer.elapsed() < Duration::from_secs(30),
  5432. "Did not create a new fork off parent {parent} in 30 seconds after restart"
  5433. );
  5434. sleep(Duration::from_millis(100));
  5435. }
  5436. }