lit メモ

litのコードから、SPV nodeの立ち上げプロセスを理解しようと思う。

読むソースは、最新のものではなく、initial commitとしている。最初のcommitに注目するやり方は、仕組みを汲み取るという理由では、結構役に立つ方法だ。 各機能のminimum実装をやってみようとも思っている。

USPV

litはmicro-SPV libraryであるuspvを使っている。
standard portである8333に接続し、ブロックヘッダーを取得して、 bloom filterを使って自分に関係するブロックとtxをダウンロードして送受金を実行できる。

Step 1: ECPriv

lit.go#L41

// 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の中身は下記の通り。

uspv/txstore.go#L22

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を走らせていても接続させることができない。