建無分叉線性區(qū)塊鏈快照(bootstrap.dat)完整指南)
區(qū)塊鏈【免費下載鏈接】dogecoinvery currency項目地址https://gitcode.com/gh_mirrors/do/dogecoin點擊查看免費下載導(dǎo)讀contrib/linearize目錄下提供了一對 Python 腳本——linearize-hashes.py與linearize-data.py用于把 Dogecoin 節(jié)點本地存儲的blocks/blkNNNNN.dat區(qū)塊數(shù)據(jù)重排為一條線性、無分叉、可復(fù)現(xiàn)的最佳版本區(qū)塊鏈典型產(chǎn)物即用于快速同步的bootstrap.dat。本文以 contrib/linearize/README.md 為主體骨架完整講解兩階段操作流程、全部配置項及其默認(rèn)值并結(jié)合 linearize-hashes.py、linearize-data.py 的源碼與 chainparams.cpp 等鏈參數(shù)定義深入說明腳本背后的原理與各參數(shù)的實際影響。讀完本文你將能獨立配置并運行完整的區(qū)塊數(shù)據(jù)線性化流程生成可在其他節(jié)點上直接使用的 bootstrap 數(shù)據(jù)。一、linearize 工具是什么在 Dogecoin 這類基于工作量證明PoW的區(qū)塊鏈中節(jié)點在運行過程中可能因為分叉、重組或同步中斷把多條鏈上的區(qū)塊寫入本地的blkNNNNN.dat文件中。這些文件里的區(qū)塊順序是磁盤寫入順序而不是鏈上高度順序其中夾雜著后來被丟棄的孤塊。linearize工具的作用正是解決這個問題linearize-hashes.py通過 JSON-RPC 調(diào)用getblockhash按高度從min_height到max_height逐塊取得一條主鏈上的區(qū)塊哈希清單hashlistlinearize-data.py以該哈希清單為準(zhǔn)繩掃描本地blocks/目錄中的原始blkNNNNN.dat把屬于主鏈的區(qū)塊按高度順序重寫為單一文件如bootstrap.dat或blocks/blkNNNNN.dat形式的目錄輸出。兩個腳本運行于 Python 3同時保持與 Python 2 的兼容腳本頭部均聲明#!/usr/bin/env python3且通過from __future__ import print_function兼容舊版本。腳本版權(quán)頭同時標(biāo)注了 Bitcoin Core 與 Dogecoin Core 開發(fā)者說明該工具是 Dogecoin 從 Bitcoin Core 繼承并持續(xù)維護(hù)的實用工具。一個典型的應(yīng)用場景你希望把本機已同步完成的完整區(qū)塊鏈導(dǎo)出用于其他機器的離線快速同步或者你需要一份干凈的、只包含主鏈區(qū)塊的數(shù)據(jù)集進(jìn)行分析。linearize 就是為這類構(gòu)建 bootstrap 數(shù)據(jù)的需求而設(shè)計的。二、完整工作流程概覽整個流程分為兩步先跑哈希腳本再跑數(shù)據(jù)腳本# 第 1 步從運行中的節(jié)點獲取主鏈哈希清單 $ ./linearize-hashes.py linearize.cfg hashlist.txt # 第 2 步依據(jù)哈希清單把本地 blk*.dat 重排為線性區(qū)塊鏈 $ ./linearize-data.py linearize.cfg兩個腳本都只接受一個命令行參數(shù)配置文件路徑。若參數(shù)數(shù)量不對腳本會打印用法并退出見兩個腳本主入口處的Usage:提示。配置文件的解析規(guī)則也很簡單逐行讀取#開頭的行為注釋被跳過其余按key value形式解析對應(yīng)源碼中re.search(^(\w)\s*\s*(\S.*)$, line)的正則邏輯未識別的行直接忽略。一個值得注意的先后依賴linearize-data.py默認(rèn)讀取名為hashlist.txt的哈希清單文件可通過配置項hashlist修改所以第 1 步的重定向輸出文件名需要與第 2 步配置中的hashlist保持一致。三、第 1 步下載哈希清單linearize-hashes.py3.1 前置條件linearize-hashes.py需要一個可用的 JSON-RPC 服務(wù)端點本地或遠(yuǎn)程均可。只需運行dogecoind或帶-server參數(shù)的dogecoin-qt即可滿足# 啟動帶 RPC 服務(wù)的節(jié)點 $ dogecoind -server -daemon # 或 $ dogecoin-qt -server從源碼看腳本通過BitcoinRPC類linearize-hashes.py基于標(biāo)準(zhǔn)庫http.client/httplib實現(xiàn) HTTP JSON-RPC 調(diào)用請求頭使用 HTTP Basic 認(rèn)證Authorization: Basic base64(user:pass)每次最多批量請求 10000 個區(qū)塊哈希max_blocks_per_call10000參數(shù)逐批推進(jìn)高度直到max_height。3.2 必需配置項配置項說明rpcuserRPC 用戶名與節(jié)點配置中的rpcuser一致rpcpasswordRPC 密碼與節(jié)點配置中的rpcpassword一致若配置文件中缺失rpcuser或rpcpassword腳本會直接報錯退出源碼中Missing username and/or password in cfg file分支。3.3 可選配置項配置項默認(rèn)值說明host127.0.0.1JSON-RPC 服務(wù)地址port22555JSON-RPC 服務(wù)端口。主網(wǎng) RPC 端口為 22555與 chainparamsbase.cpp 中nRPCPort 22555一致測試網(wǎng)為 44555見同文件第 48 行min_height0起始高度含max_height313000結(jié)束高度含。注意示例配置中的 313000 是一個較舊的鏈高上限實際使用時應(yīng)設(shè)置為不低于當(dāng)前鏈高的值rev_hash_bytesfalse若為true輸出的區(qū)塊哈希將做字節(jié)反轉(zhuǎn)即對getblockhash返回的哈希做字節(jié)序翻轉(zhuǎn)。默認(rèn)關(guān)閉設(shè)計初衷是生成獨立哈希清單但配合linearize-data.py使用也安全——數(shù)據(jù)腳本輸出結(jié)果與字節(jié)格式無關(guān)3.4 字節(jié)反轉(zhuǎn)原理rev_hash_bytes的實現(xiàn)對應(yīng)源碼中的hex_switchEndian函數(shù)把哈希十六進(jìn)制字符串按每兩個字符一個字節(jié)切分后逆序拼接。getblockhash返回的是內(nèi)部存儲順序的哈希而區(qū)塊頭中hashPrevBlock等字段以相反字節(jié)序?qū)懭氪疟P某些下游工具需要磁盤序此時可打開該開關(guān)。3.5 常見錯誤排查RPC 連接被拒絕腳本捕獲ConnectionRefusedError并輸出 RPC connection refused. Check RPC settings and the server status.請檢查host/port是否指向正在運行的節(jié)點、節(jié)點是否開啟了server1某高度返回錯誤腳本對每個響應(yīng)檢查error字段出錯時打印JSON-RPC: error at height h并以狀態(tài)碼 1 退出響應(yīng)亂序源碼通過assert(resp_obj[id] x)斷言響應(yīng)與請求同序。四、第 2 步重排本地區(qū)塊數(shù)據(jù)linearize-data.py4.1 必需配置項二選一配置項說明output_file最終區(qū)塊鏈寫入的單個文件路徑如bootstrap.datoutput輸出目錄啟用后腳本會按blk%05d.dat命名規(guī)則寫出多個文件如blk00000.dat此時output_file被忽略若兩者都未配置腳本打印 Missing output file / directory 并退出。源碼中通過self.fileOutput False區(qū)分兩種模式linearize-data.py。4.2 可選配置項配置項默認(rèn)值說明debug_outputfalse設(shè)為true時打印額外調(diào)試信息例如掃描到哈希清單中不存在的未知區(qū)塊時輸出 Skipping unknown block file_timestamp0關(guān)閉設(shè)為非 0 時在關(guān)閉每個輸出文件時通過os.utime將文件訪問/修改時間分別設(shè)為當(dāng)前時間與寫入該文件的最新區(qū)塊的時間戳genesis主網(wǎng)創(chuàng)世塊哈希1a91e3dace36e2be3bf030a65679fe821aa1d6ef92e7c9902eb318182c355691用于校驗哈希清單完整性若哈希清單中不包含該創(chuàng)世塊哈希腳本輸出 Genesis block not found in hashlist 且不執(zhí)行復(fù)制。該默認(rèn)值在 chainparams.cpp 的hashGenesisBlock斷言中可交叉驗證inputinput相對目錄本地dogecoind的blocks/目錄內(nèi)含blkNNNNN.dat。主網(wǎng)默認(rèn)數(shù)據(jù)目錄下通常為~/.dogecoin/blocks測試網(wǎng)為~/.dogecoin/testnet3/blockshashlisthashlist.txt由linearize-hashes.py生成的哈希清單文本文件路徑max_out_sz1000*1000*1000字節(jié)約 1 GB單文件模式下輸出文件達(dá)到該大小后自動滾動到下一個文件。注意在目錄輸出模式下該限制同樣生效滾動時文件名序號遞增netmagicc0c0c0c0網(wǎng)絡(luò)魔法數(shù)。主網(wǎng)c0c0c0c0與 chainparams.cpp 中主網(wǎng)pchMessageStart一致測試網(wǎng)對應(yīng)值在 chainparams.cpp 中為fcc1b7dc示例配置中給出的測試網(wǎng)0b110907為較早時期的值實際配置請以源碼鏈參數(shù)為準(zhǔn)。腳本會用它校驗blk*.dat中每個區(qū)塊的頭部魔法數(shù)字不匹配即停止并輸出 Invalid magicout_of_order_cache_sz100*1000*1000字節(jié)約 100 MB亂序區(qū)塊的內(nèi)存緩存上限。自 Bitcoin Core 0.10 起區(qū)塊可能亂序?qū)懭氪疟P遇到尚未輪到輸出的區(qū)塊時若緩存未滿則直接讀入內(nèi)存暫存否則跳過磁盤偏移f.seek待輪到該高度時再從磁盤按記錄的偏移量BlockExtent重新讀取rev_hash_bytesfalse若為true讀取哈希清單時對每個哈希做字節(jié)反轉(zhuǎn)以匹配linearize-hashes.py生成時的設(shè)置get_block_hashes中的hex_switchEndian調(diào)用split_timestamp0關(guān)閉設(shè)為非 0 時除了max_out_sz限制外每當(dāng)輸出遇到新的月份按區(qū)塊頭中的時間戳判斷源碼通過struct.unpack(I, blk_hdr[68:72])取nTime即滾動到新文件4.3 腳本的核心處理邏輯linearize-data.py的主流程BlockDataCopier.run見 linearize-data.py可以概括為建立高度索引mkblockmap把哈希清單構(gòu)造成{hash: height}映射順序掃描輸入文件按blk%05d.dat編號逐個打開輸入文件每個區(qū)塊由 8 字節(jié)文件頭4 字節(jié)netmagic 4 字節(jié)小端長度與 80 字節(jié)區(qū)塊頭組成inLen為文件頭聲明長度減去 80 字節(jié)頭部后的載荷長度哈希校驗對每個區(qū)塊頭做雙重 SHA-256calc_hdr_hash再經(jīng)bufreverse/wordreverse字節(jié)整理得到規(guī)范哈希字符串與blkmap比對順序?qū)懭肴舢?dāng)前區(qū)塊高度恰好等于已輸出計數(shù)blkCountOut直接復(fù)制否則記錄其BlockExtent文件號、偏移、頭部、大小暫存視緩存空間決定讀入內(nèi)存還是留待回讀進(jìn)度反饋每寫滿 1000 個區(qū)塊打印一次進(jìn)度%i blocks scanned, %i blocks written (of %i, %.1f%% complete)全部完成后輸出Done (%i blocks written)。這個亂序緩存 回讀設(shè)計保證了即使磁盤上的區(qū)塊順序雜亂輸出結(jié)果依然是嚴(yán)格按高度遞增的線性鏈。五、參考配置example-linearize.cfg 逐項解讀倉庫在 example-linearize.cfg 中給出了完整的示例配置按模塊拆分如下# dogecoind RPC 設(shè)置linearize-hashes 使用 rpcusersomeuser rpcpasswordsomepassword host127.0.0.1 port22555 #port44555 # 測試網(wǎng) RPC 端口 # 哈希清單設(shè)置linearize-hashes 使用 max_height313000 # 輸入 / 輸出設(shè)置linearize-data 使用 # 主網(wǎng) netmagicc0c0c0c0 genesis1a91e3dace36e2be3bf030a65679fe821aa1d6ef92e7c9902eb318182c355691 input/home/example/.dogecoin/blocks # 測試網(wǎng)示例配置中的舊值實際鏈參數(shù)請以 src/chainparams.cpp 為準(zhǔn) #netmagic0b110907 #genesisbb0a78264637406b6360aad926284d544d7049f45189db5664f3c4d07350559e #input/home/example/.dogecoin/testnet3/blocks # output 選項啟用后區(qū)塊鏈寫入指定目錄此時忽略 output_file。 # 若未使用 output則使用 output_file。 # output/home/example/blockchain_directory output_file/home/example/Downloads/bootstrap.dat hashlisthashlist.txt # 亂序區(qū)塊內(nèi)存緩存上限字節(jié) out_of_order_cache_sz 100000000 # 是否反轉(zhuǎn) getblockhash 返回的哈希字節(jié)序 rev_hash_bytes False # 新月份時是否設(shè)置新區(qū)塊鏈文件的訪問/修改時間 file_timestamp 0 # 是否按新月份或特定高度拆分區(qū)塊鏈文件 split_timestamp 0 # 是否打印調(diào)試輸出 debug_output False其中g(shù)enesis的測試網(wǎng)取值bb0a78264637406b6360aad926284d544d7049f45189db5664f3c4d07350559e與 chainparams.cpp 中的測試網(wǎng)hashGenesisBlock斷言完全一致可作為交叉驗證依據(jù)。提示rpcuser/rpcpassword必須與節(jié)點實際啟動參數(shù)或節(jié)點配置一致。節(jié)點側(cè) RPC 憑據(jù)可通過啟動參數(shù)-rpcuseruser -rpcpasswordpass或配置文件中的同名選項指定參見倉庫根目錄的 share/dogecoin.conf 模板。六、運行完整流程的實操步驟步驟 A準(zhǔn)備節(jié)點與配置文件確保節(jié)點已同步到目標(biāo)高度并開啟 RPCdogecoind -server -daemon -rpcuseruser -rpcpasswordpass復(fù)制 example-linearize.cfg 為你的配置文件如linearize.cfg修改rpcuser、rpcpassword、input、output_file與max_height設(shè)為當(dāng)前鏈高可通過 RPCgetblockcount查詢確認(rèn)input指向的blocks/目錄真實存在且包含blkNNNNN.dat文件。步驟 B生成哈希清單$ ./linearize-hashes.py linearize.cfg hashlist.txt執(zhí)行后檢查hashlist.txt第一行應(yīng)為主網(wǎng)創(chuàng)世塊哈希1a91e3dace36e2be3bf030a65679fe821aa1d6ef92e7c9902eb318182c355691主網(wǎng)場景總行數(shù)應(yīng)等于max_height - min_height 1。步驟 C生成線性化區(qū)塊鏈$ ./linearize-data.py linearize.cfg觀察輸出腳本先打印Read N hashes隨后逐個打開輸入文件Input file path/blk00000.dat遇到亂序區(qū)塊會按緩存策略處理遇到未知區(qū)塊孤塊在debug_outputtrue時打印跳過信息結(jié)束時打印Done (N blocks written)其中 N 應(yīng)等于哈希清單中的區(qū)塊數(shù)。產(chǎn)物即為你配置的output_file如bootstrap.dat或output目錄下的blkNNNNN.dat系列文件可以直接拷貝到其他節(jié)點的數(shù)據(jù)目錄用于離線快速同步。七、參數(shù)選擇與調(diào)優(yōu)建議場景建議只想導(dǎo)出一個大文件使用output_file保持默認(rèn)max_out_sz1 GB即可超限會自動分卷也可調(diào)大該值減少分卷數(shù)需要按月份歸檔打開split_timestamp 1配合output目錄模式產(chǎn)出按自然月拆分的區(qū)塊文件磁盤上亂序區(qū)塊很多、內(nèi)存充足適當(dāng)調(diào)大out_of_order_cache_sz減少重復(fù)磁盤尋址回讀加快處理速度內(nèi)存緊張則保持默認(rèn) 100 MB處理中途排查問題打開debug_output true可看到被跳過的未知區(qū)塊哈希便于判斷輸入數(shù)據(jù)是否混雜了分叉塊不確定鏈參數(shù)嚴(yán)格對照 chainparams.cpp 中的pchMessageStart與hashGenesisBlock取值填寫netmagic與genesismax_out_sz與out_of_order_cache_sz的默認(rèn)值均為 10 億字節(jié)量級1000*1000*1000與100*1000*1000在 linearize-data.py 中可確認(rèn)。兩者的權(quán)衡本質(zhì)是磁盤 I/O 與內(nèi)存占用的互換緩存越大越少回讀磁盤但占用內(nèi)存越多。八、總結(jié)contrib/linearize提供了從運行中的 Dogecoin 節(jié)點到干凈、線性、無分叉的區(qū)塊鏈快照的完整工具鏈linearize-hashes.py負(fù)責(zé)按高度拉取主鏈哈希權(quán)威清單linearize-data.py負(fù)責(zé)以該清單為準(zhǔn)對本地blkNNNNN.dat進(jìn)行重排、校驗與輸出。本文覆蓋了兩步流程的全部命令、必需/可選配置項及其默認(rèn)值與源碼出處、示例配置的逐項解讀以及亂序區(qū)塊緩存、月份拆分、字節(jié)序反轉(zhuǎn)等底層實現(xiàn)原理。結(jié)合 example-linearize.cfg、linearize-hashes.py、linearize-data.py 與鏈參數(shù)定義文件 chainparams.cpp、chainparamsbase.cpp你可以直接照此流程生成屬于自己的bootstrap.dat離線同步數(shù)據(jù)。贊分享區(qū)塊鏈【免費下載鏈接】dogecoinvery currency項目地址https://gitcode.com/gh_mirrors/do/dogecoin點擊查看免費下載相關(guān)推薦Bitcoin Core linearize 腳本實戰(zhàn)構(gòu)建線性無分叉的 Bootstrap 區(qū)塊鏈Bitcoin Core linearize 腳本實戰(zhàn)構(gòu)建線性無分叉的 Bootstrap 區(qū)塊鏈 本篇圍繞 contrib/linearize/README區(qū)塊鏈金融科技網(wǎng)絡(luò)密碼學(xué)Zcash contrib/linearize 詳解從本地區(qū)塊數(shù)據(jù)構(gòu)建線性 bootstrap.datZcash contrib/linearize 詳解從本地區(qū)塊數(shù)據(jù)構(gòu)建線性 bootstrap.dat 本文圍繞 contrib/linearize/READ區(qū)塊鏈金融科技密碼學(xué)后端Dogecoin Core 倉庫 contrib 目錄全指南開發(fā)、構(gòu)建與驗證工具鏈詳解Dogecoin Core 倉庫 contrib 目錄全指南開發(fā)、構(gòu)建與驗證工具鏈詳解 導(dǎo)讀 本篇文章以 Dogecoin Core 源碼倉庫中的 contr區(qū)塊鏈創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考