edo1z blog

プログラミングなどに関するブログです

Go言語によるビットコインのフルノード実装btcdを調べる(1)

btcsuite/btcdを調べてみます。Goで書かれたビットコインのフルノード実装です。ウォレット機能はありません。コマンドラインのオプションの説明はここです。ドキュメントはここです。今使っているのは、btcd version 0.12.0-betaです。

設定ファイルなど

$HOME/.btcdに各種設定ファイルやブロックデータ、接続先peer情報等が保存されます。設定ファイルは、.btcd/btcd.confです。このファイルで、testnet=1とするとテストネットを利用できます。接続先peer情報は、.btcd/data/mainnet/peers.jsonにあります。下記のような形式で格納されていました。testnetの場合は、mainnetがtestnetになります。

{
    "Addr":"133.33.333.33:8333",
    "Src":"114.44.444.44:8333",
    "Attempts":0,
    "TimeStamp":1497783231,
    "LastAttempt":-62135596800,
    "LastSuccess":-62135596800
}

データベースは、LevelDBというのが使われていますが、メタデータはLevelDBで、ブロックデータは、フラットファイル形式でffldbとかいう独自?の形式を使っているみたいです。よくわからないので後で調べます。データの場所は、.btcd/data/mainnet/blocks_ffldbにあります。ブロックデータ?は、000000149.fdbといったファイルです。metadataは、.btcd/data/mainnet/blocks_ffldb/metadataにあり、859650.ldbといったファイルになっています。それぞれどんなデータが入っているのかわかっていませんので後で調べます。

btcdを実行してみる

インストールしてbtcdコマンドを実行すると、既存の他ノードを検索・接続し、ブロックのダウンロードが始まります。最初は既存のノードとつながったことがないので、peers.jsonは空(多分)なはずで、perrs.json以外から接続先を発見することになりますが、DNSシードというノードのIP一覧を保有するDNSサーバに問い合わせをする形でIPを取得するそうです。ソースコード内のDNSseedを検索してみました。下記6つがDNSseedなのかなと思いました。一つfalseになってるけど。

DNSSeeds: []DNSSeed{
    {"seed.bitcoin.sipa.be", true},
    {"dnsseed.bluematt.me", true},
    {"dnsseed.bitcoin.dashjr.org", false},
    {"seed.bitcoinstats.com", true},
    {"seed.bitnodes.io", false},
    {"seed.bitcoin.jonasschnelli.ch", true},
},

ノード同士の接続の流れ

DNSシードへの問い合わせ等でノードを発見したら接続します。通常8333ポートにTCP接続して、versionメッセージを送信することで、handshake(握手)を始めます。このあたりの処理はbtcd/peerに入っているようです。peerのドキュメントやサンプルはここにあります。

次はpeerを調べてみます。