lit メモ
litのコードから、SPV nodeの立ち上げプロセスを理解しようと思う。
読むソースは、最新のものではなく、initial commitとしている。最初のcommitに注目するやり方は、仕組みを汲み取るという理由では、結構役に立つ方法だ。 各機能のminimum実装をやってみようとも思っている。
USPV
litはmicro-SPV libraryであるuspvを使っている。
standard portである8333に接続し、ブロックヘッダーを取得して、 bloom filterを使って自分に関係するブロックとtxをダウンロードして送受金を実行できる。
Step 1: ECPriv
// read key file (generate if not found)
rootPriv, err := uspv.ReadKeyFileToECPriv(keyFileName, Params)
ECPriv(Elliptical curve private key)を生成している。これはHD Key(hierarchical deterministic)のMaster Keyで、bitcoinの秘密鍵管理の標準である。
ちなみに、seedはrand関数を使って生成されているが、これは疑似乱数ジェネレータであり、人がランダムに設定した方がより安全と思われる。
btcutil/hdkeychain/extendedkey.go#L564
_, err := rand.Read(buf)
Step 2: NewTxStore
上記で生成したKeyとbtcdで定義されているテストネットパラメータを元に、SPV nodeのtransaction storeを生成する。
// setup TxStore first (before spvcon)
Store := uspv.NewTxStore(rootPriv, Params)
Storeの中身は下記の通り。
StateDB *bolt.DB // place to write all this down
pureなGo key/value storeであり、walletのDBとなる。
FreezeSet map[wire.OutPoint]*FrozenTx
wire.OutPointは、txをhashとindexで特定するための定義で、それをキーとして確定すみtxを格納する。
FreezeMutex sync.Mutex
排他ロック用
OPEventChan chan lnutil.OutPointEvent
confirmationか、spentの状況の確認をする
Param *chaincfg.Params // network parameters (testnet3, segnet, etc)
rootPrivKey *hdkeychain.ExtendedKey
実はuspvは独立したLibraryではなく、litのpackage(lnutil)に依存していることがわかる。
Step 3: OpenSPV
いよいよSPVnodeを開く。
Lit web UI
litには、web ui(electron)が準備されている。
web uiディレクトリ配下にソースコードが配置されていないため戸惑うと思うが、これはissue #281にて議論されており、makefileでbinary fuleを準備するように変更されているためだ。
実際のソースコードは、削除直前のcommitで見れるが、コードをpullrequest等する場合にどうしたらいいかまだわからない。
web技術でデスクトップアプリを作成することを可能にする、electronをreact + ELECTRONのbootstrapで立ち上げており、しかもredux等(UIのstate(状態)を管理をするためのフレームワーク)は使っておらず、非常にシンプルな構成になっている。
websockets RPCでport 8001に直接つなぎに行っており、それ以外のportでlitを走らせていても接続させることができない。