[bitcoin] headerssync-paramsって何?

Readmeを読むと以下のように書いている
A script to generate optimal parameters for the headerssync module (src/headerssync.cpp). It takes no command-line
options, as all its configuration is set at the top of the file. It runs many times faster inside PyPy. Invocation:
つまり、node間でのヘッダー情報のやり取りのことだ。c++ファイルのヘッダではない。stateで、 PRESYNC、REDOWNLOAD、FINALとある。

src/headerssync.h, src/headerssync.cpp を見てみる。
### headerssync.h
A compressed CBlockHeader, which leaves out the prevhash
HeadersSyncState
We wish to download a peer’s headers chain in a DoS-resistant way.
* – In the first download phase, called pre-synchronization, we can calculate
* the work on the chain as we go (just by checking the nBits value on each
* header, and validating the proof-of-work).
In phase 1 (presync)
In phase 2 (redownload)

#### headerssync.cpp
// The two constants below are computed using the simulation script in
// contrib/devtools/headerssync-params.py.
m_max_commitments = 6*(Ticks(NodeClock::now() – NodeSeconds{std::chrono::seconds{chain_start->GetMedianTimePast()}}) + MAX_FUTURE_BLOCK_TIME) / HEADER_COMMITMENT_PERIOD;

downloadはこれでやってる?

    if (m_current_chain_work >= m_minimum_required_work) {
        m_redownloaded_headers.clear();
        m_redownload_buffer_last_height = m_chain_start->nHeight;
        m_redownload_buffer_first_prev_hash = m_chain_start->GetBlockHash();
        m_redownload_buffer_last_hash = m_chain_start->GetBlockHash();
        m_redownload_chain_work = m_chain_start->nChainWork;
        m_download_state = State::REDOWNLOAD;
        LogPrint(BCLog::NET, "Initial headers sync transition with peer=%d: reached sufficient work at height=%i, redownloading from height=%i\n", m_id, m_current_height, m_redownload_buffer_last_height);
    }

downloadのstatusに応じて処理しているのはわかるが、getHashの処理とかはheaderssync.cppの中には書いてないように見えるがどこでやってるんだろうか?

あと、基本的に、HeadersSyncState::${処理}と書かれていますね。
なんか凄いな…

bitcoin.confの構成

mainnet=1               # mainnetを利用する
txindex=1               # indexを作成して全てのトランザクションIDを参照可能にする
server=1                # JSON RPCサーバとしてコマンドを受け付ける
rest=1                  # REST インターフェースを有効にする
rpcuser= "Username"     # JSON RPCのためのユーザ名
rpcpassword= "Password" # JSON RPCのためのパスワード
rpcport=8332            # JSON RPC用ポート番号

gen-bitcoin-conf.sh

export LC_ALL=C
TOPDIR=${TOPDIR:-$(git rev-parse --show-toplevel)}
BUILDDIR=${BUILDDIR:-$TOPDIR}
BINDIR=${BINDIR:-$BUILDDIR/src}
BITCOIND=${BITCOIND:-$BINDIR/bitcoind}
SHARE_EXAMPLES_DIR=${SHARE_EXAMPLES_DIR:-$TOPDIR/share/examples}
EXAMPLE_CONF_FILE=${EXAMPLE_CONF_FILE:-$SHARE_EXAMPLES_DIR/bitcoin.conf}

[ ! -x "$BITCOIND" ] && echo "$BITCOIND not found or not executable." && exit 1

DIRTY=""
VERSION_OUTPUT=$($BITCOIND --version)
if [[ $VERSION_OUTPUT == *"dirty"* ]]; then
  DIRTY="${DIRTY}${BITCOIND}\n"
fi

if [ -n "$DIRTY" ]
then
  echo -e "WARNING: $BITCOIND was built from a dirty tree.\n"
  echo -e "To safely generate a bitcoin.conf file, please commit your changes to $BITCOIND, rebuild, then run this script again.\n"
fi

echo 'Generating example bitcoin.conf file in share/examples/'

# create the directory, if it doesn't exist
mkdir -p "${SHARE_EXAMPLES_DIR}"

# create the header text
cat > "${EXAMPLE_CONF_FILE}" << 'EOF'
##
## bitcoin.conf configuration file.
## Generated by contrib/devtools/gen-bitcoin-conf.sh.
##
## Lines beginning with # are comments.
## All possible configuration options are provided. To use, copy this file
## to your data directory (default or specified by -datadir), uncomment
## options you would like to change, and save the file.
##


### Options
EOF

# parse the output from bitcoind --help
# adding newlines is a bit funky to ensure portability for BSD
# see here for more details: https://stackoverflow.com/a/24575385
${BITCOIND} --help \
    | sed '1,/Print this help message and exit/d' \
    | sed -E 's/^[[:space:]]{2}\-/#/' \
    | sed -E 's/^[[:space:]]{7}/# /' \
    | sed -E '/[=[:space:]]/!s/#.*$/&=1/' \
    | awk '/^#[a-z]/{x=$0;next}{if (NF==0) print x"\n",x="";else print}' \
    | sed 's,\(^[[:upper:]].*\)\:$,\
### \1,' \
    | sed 's/[[:space:]]*$//' >> "${EXAMPLE_CONF_FILE}"

# create the footer text
cat >> "${EXAMPLE_CONF_FILE}" << 'EOF'

# [Sections]
# Most options will apply to all networks. To confine an option to a specific
# network, add it under the relevant section below.
#
# Note: If not specified under a network section, the options addnode, connect,
# port, bind, rpcport, rpcbind, and wallet will only apply to mainnet.

# Options for mainnet
[main]

# Options for testnet
[test]

# Options for signet
[signet]

# Options for regtest
[regtest]
EOF

sedの使い方

1.rakus rakus
2.rakus

$ sed -e ‘s/rakus/RAKUS/g’ sample.tx
1.RAKUS RAKUS
2.RAKUS

-Eのところは複数指定にしている?

${BITCOIND} --help \
    | sed '1,/Print this help message and exit/d' \
    | sed -E 's/^[[:space:]]{2}\-/#/' \
    | sed -E 's/^[[:space:]]{7}/# /' \
    | sed -E '/[=[:space:]]/!s/#.*$/&=1/' \
    | awk '/^#[a-z]/{x=$0;next}{if (NF==0) print x"\n",x="";else print}' \
    | sed 's,\(^[[:upper:]].*\)\:$,\
### \1,' \
    | sed 's/[[:space:]]*$//' >> "${EXAMPLE_CONF_FILE}"

circular-dependencies : 循環参照

あるファイルを require したときにその結果が空のオブジェクトとして返される問題
module.exports first, lazy require, dependency injectionなどの解決方法がある

import sys
import re

MAPPING = {
    'core_read.cpp': 'core_io.cpp',
    'core_write.cpp': 'core_io.cpp',
}

# Directories with header-based modules, where the assumption that .cpp files
# define functions and variables declared in corresponding .h files is
# incorrect.
HEADER_MODULE_PATHS = [
    'interfaces/'
]

def module_name(path):
    if path in MAPPING:
        path = MAPPING[path]
    if any(path.startswith(dirpath) for dirpath in HEADER_MODULE_PATHS):
        return path
    if path.endswith(".h"):
        return path[:-2]
    if path.endswith(".c"):
        return path[:-2]
    if path.endswith(".cpp"):
        return path[:-4]
    return None

files = dict()
deps: dict[str, set[str]] = dict()

RE = re.compile("^#include <(.*)>")

# Iterate over files, and create list of modules
for arg in sys.argv[1:]:
    module = module_name(arg)
    if module is None:
        print("Ignoring file %s (does not constitute module)\n" % arg)
    else:
        files[arg] = module
        deps[module] = set()

# Iterate again, and build list of direct dependencies for each module
# TODO: implement support for multiple include directories
for arg in sorted(files.keys()):
    module = files[arg]
    with open(arg, 'r', encoding="utf8") as f:
        for line in f:
            match = RE.match(line)
            if match:
                include = match.group(1)
                included_module = module_name(include)
                if included_module is not None and included_module in deps and included_module != module:
                    deps[module].add(included_module)

# Loop to find the shortest (remaining) circular dependency
have_cycle: bool = False
while True:
    shortest_cycle = None
    for module in sorted(deps.keys()):
        # Build the transitive closure of dependencies of module
        closure: dict[str, list[str]] = dict()
        for dep in deps[module]:
            closure[dep] = []
        while True:
            old_size = len(closure)
            old_closure_keys = sorted(closure.keys())
            for src in old_closure_keys:
                for dep in deps[src]:
                    if dep not in closure:
                        closure[dep] = closure[src] + [src]
            if len(closure) == old_size:
                break
        # If module is in its own transitive closure, it's a circular dependency; check if it is the shortest
        if module in closure and (shortest_cycle is None or len(closure[module]) + 1 < len(shortest_cycle)):
            shortest_cycle = [module] + closure[module]
    if shortest_cycle is None:
        break
    # We have the shortest circular dependency; report it
    module = shortest_cycle[0]
    print("Circular dependency: %s" % (" -> ".join(shortest_cycle + [module])))
    # And then break the dependency to avoid repeating in other cycles
    deps[shortest_cycle[-1]] = deps[shortest_cycle[-1]] - set([module])
    have_cycle = True

sys.exit(1 if have_cycle else 0)

[bitcoin] bitcoincoreのファイル構造 [その1]

まずGithubから bitcoincore のソースコードを clone してきます。
github上で見てもいいんですが、なんとなくローカルに落としたいですよね。。

$ git clone https://github.com/bitcoin/bitcoin.git
$ $ tree -L 3 -d
.
└── bitcoin
├── build-aux
│ └── m4
├── build_msvc
│ ├── bench_bitcoin
│ ├── bitcoin-cli
│ ├── bitcoind
│ ├── bitcoin-qt
│ ├── bitcoin-tx
│ ├── bitcoin-util
│ ├── bitcoin-wallet
│ ├── libbitcoin_cli
│ ├── libbitcoin_common
│ ├── libbitcoin_consensus
│ ├── libbitcoin_crypto
│ ├── libbitcoin_node
│ ├── libbitcoin_qt
│ ├── libbitcoin_util
│ ├── libbitcoin_wallet
│ ├── libbitcoin_wallet_tool
│ ├── libbitcoin_zmq
│ ├── libleveldb
│ ├── libminisketch
│ ├── libsecp256k1
│ ├── libtest_util
│ ├── libunivalue
│ ├── msbuild
│ ├── test_bitcoin
│ └── test_bitcoin-qt
├── ci
│ ├── lint
│ ├── retry
│ └── test
├── contrib
│ ├── completions
│ ├── debian
│ ├── devtools
│ ├── guix
│ ├── init
│ ├── linearize
│ ├── macdeploy
│ ├── message-capture
│ ├── qos
│ ├── seeds
│ ├── shell
│ ├── signet
│ ├── testgen
│ ├── tracing
│ ├── verify-binaries
│ ├── verify-commits
│ ├── windeploy
│ └── zmq
├── depends
│ ├── builders
│ ├── hosts
│ ├── packages
│ └── patches
├── doc
│ ├── design
│ ├── man
│ ├── policy
│ └── release-notes
├── share
│ ├── examples
│ ├── pixmaps
│ ├── qt
│ └── rpcauth
├── src
│ ├── bench
│ ├── common
│ ├── compat
│ ├── config
│ ├── consensus
│ ├── crc32c
│ ├── crypto
│ ├── index
│ ├── init
│ ├── interfaces
│ ├── ipc
│ ├── kernel
│ ├── leveldb
│ ├── logging
│ ├── minisketch
│ ├── node
│ ├── policy
│ ├── primitives
│ ├── qt
│ ├── rpc
│ ├── script
│ ├── secp256k1
│ ├── support
│ ├── test
│ ├── univalue
│ ├── util
│ ├── wallet
│ └── zmq
└── test
├── functional
├── fuzz
├── lint
├── sanitizer_suppressions
└── util

各ディレクトリ、各機能ごとの役割を細く見て行くことが必要ですね。

[bitcoin] ASICとは?

ASICとは
L 半導体集積回路の一つで、ある特定の機器や用途のために、必要な機能を組み合わせて設計、製造されるもの。
L フルカスタムICとセミカスタムICがある

[LightningNetwork] pathfinding

支払い人から受取人へのパスを見つけることをpathfindingと呼ぶ
PathfindingはBOLTでは定義されておらず、さまざまなアルゴリズムを選択できる
平均チャネル数は8.8で上位のノードは2000のチャネル数もある
pathfindingはグラフトラバーサルに分類される
MCFPと呼ばれるコストを最小にしながら特定のフローを実現

パス候補のリストを作成し、何らかの関数でフィルタリングしてソートする。続いて、送信できるパスが見つかるまで、パスのプロービングを行う
チャネルグラフの構築で、node_announcementでIP情報が含まれているため、地図を作成できる
マルチパートペイメントでpathを柔軟化できる

[LightningNetwork] オニオンルーティング

オニオンルーティングはTorで使われている暗号化通信の手法
メッセージの送信者が入れ子になった暗号化の層を作成
origin nodeとfinal nodeがある

共通シークレット、セッションの秘密鍵、公開鍵からECDHアルゴリズムにより、rho, mu, um, padの鍵を生成する
オニオンをラッピングする

### ゴシッププロトコル(共有)
LNのイニシャルピアディスカバリはDNSに基づく
チャネルを、チェーン内の位置に基づいて参照する

[LightningNetwork] ルーティング

パス上の中間ノードをルーティングノードという
ライトニングネットワークはHash Time-Locked Contractを採用している
経路探索はチャネルグラフを調べる
ルーティングは経路探索によって事前に選択されたパスを使って、AからBにペイメントを転送しようとするネットワーク経由の一連のやり取り

エスクロー契約にして、ペイメントハッシュでやり取りを行う
契約には期限を設定する
ノードが預託を行うに十分な資金を持っている必要がある
PTLC(Point Time-Locked Contract)はSchnorr signature
インボイスをAliceからDinaにリクエストし、発行する

### HTLC(Hash Time-Lock Contract)
インボイスに暗号学的ハッシュ関数が入っている
H = Sha256(R)
OP_HASH160 OP_EQUALVERIFY
ペイメントプリイメージとの比較
受取人とマッチする公開鍵とその署名をスクリプトに入れる
OP_SHA256 OP_EQUALVERIFY OP_ChECKSIG

[LightningNetwork] ペイメントの送信

### ペイメントの送信
AliceとBobでコミットメントトランザクションを作成する
ブロードキャストするとファンディングアウトプットが消費される

### ライトニングプロトコルの失効とペナルティのメカニズム
– 非対称コミットメントトランザクション
L self, remotoとする
L 資金を取り戻す時間が与えられる
– 遅延支払い
– 失効鍵
L ペナルティトランザクションを作成することでチャネルの資金を独り占めできる

### チャネルの状態遷移
commitment_signedとrevoke_and_ackの2つのメッセージを交換する

commitment_signed: channel_id, signature, num_htlcs, htlc_signature
revoke_and_ack: channel_id, per_commitment_secret, next_per_commitment_point

[LightningNetwork] payment channel

2of2マルチシグのトランザクションを保管していて、そのトランザクションを独占的に使う手段となり得たら、そのビットコインを事実上所有していることになる。
ペイメントチャネルは2人のチャネルパートナーが2of2マルチシグアドレスにファンディングを行うことによって確立される
ライトニングノードはノードの公開鍵によって識別
ネットワークアドレスはTCP/IPもしくはTCP/Tor

識別子は ノードID@address:port
2つのノード間の通信をLightning Peer Protocol for Channel Managementと呼ぶ
チャネルはメッセージの交換で確立される
open_channel, accept_channel, funding_created, funding_signed, channel_ready, channel_readyの6つの時系列
トランザクションが十分な数の承認を得た時点で、channel_readyメッセージを交換し、チャネルは通常の実行モードを開始

### マルチシグアドレス
2 2 CHCKMULTISIG
=> p2wshのアドレスとしてエンコードされる
トランザクションを作成し、署名するがブロードキャストしない
払い戻しトランザクションを作成する…ファンディングトランザクションのインプットを計算する

### funding_created
funding_txid
funding_output_index

### funding_signed
channel idはfunding transaction idとoutput indexのビットごとのxor

### funding_transactionをブロードキャスト
ブロックチェーンでの承認数がminimum_depthになるのを待つ。その後channel_readyメッセージで相手に送信