blockchainのpeerとlightningのpeer

当然役割が異なる。1st layerでは、peer -> pool > nodeとなっていくけれど、lightningでは、仕組みが異なってくる。

lightningの場合はもう少し単純で、peerと、serverだけで、少なくともlndの場合は動いている。

Peer to Peer(ピア・トゥ・ピア または ピア・ツー・ピア)とは、複数の端末間で通信を行う際のアーキテクチャのひとつで、対等の者(Peer、ピア)同士が通信をすることを特徴とする通信方式、通信モデル、あるいは通信技術の一分野を指す。P2Pと略記することが多く、以下本記事においてもP2Pとする。

この場合のpeerと、実装におけるpeerっていうのは、意味が異なっている。 ピアが「対等」な関係にあるものということを強調したいときに使われるのに対して、ノードはネットワークの幾何学的な形(トポロジー)が意識されている場合に使われる、なんて言うこともあるけど、実装だと特別な意味を持つ。

実装におけるイメージは、下記にまとめられると思う。node、またはserverが上記におけるpeerだ。

  1. peer
    他のnodeの持つ一つのpeerとconnectionを暗号化して確立する。lightning networkの場合はnoise protocolになる。

  2. pool
    peerをコントロールする。txの同期とかの際に、どこに接続するのかとかを探す。この機能はlightningにはない。だけど、multihopとかするならあってもいいような気もするけど、どうなんだろうか。open tx しないといけないから、つないでいても意味が無いからか。

  3. node
    これは、いわゆるspvとかfullとかという形で現れる。poolや、chain、mempoolをコントロールする。もちろんlightningには存在しない。

っていう感じかな。だからもちろんpeer自体の実装自体も異なってくるはずか。

lnd のpeerは、net.connをオーバーライドして、brontide形式で暗号化して送信する際に意識を不要にしている。すごい。こういう実装を自然にできるようにならないと。

// WriteMessage writes the next message p to the passed io.Writer. The
// ciphertext of the message is prepended with an encrypt+auth'd length which
// must be used as the AD to the AEAD construction when being decrypted by the
// other side.
func (b *Machine) WriteMessage(w io.Writer, p []byte) error {  
    // The total length of each message payload including the MAC size
    // payload exceed the largest number encodable within a 16-bit unsigned
    // integer.
    if len(p) > math.MaxUint16 {
        return ErrMaxMessageLengthExceeded
    }

    // The full length of the packet is only the packet length, and does
    // NOT include the MAC.
    fullLength := uint16(len(p))

    var pktLen [2]byte
    binary.BigEndian.PutUint16(pktLen[:], fullLength)

    // First, write out the encrypted+MAC'd length prefix for the packet.
    cipherLen := b.sendCipher.Encrypt(nil, nil, pktLen[:])
    if _, err := w.Write(cipherLen); err != nil {
        return err
    }

    // Finally, write out the encrypted packet itself. We only write out a
    // single packet, as any fragmentation should have taken place at a
    // higher level.
    cipherText := b.sendCipher.Encrypt(nil, nil, p)
    _, err := w.Write(cipherText)
    return err
}