比特币闪电网络代码解析
Posted mutourend
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了比特币闪电网络代码解析相关的知识,希望对你有一定的参考价值。
1. 引言
本文关注的代码库为:
总体架构设计为:
-----------------
| KeysInterface | --------------
----------------- | UserConfig |
-------------------- ^ --------------
------| MessageSendEvent | | ^ ----------------
/ -------------------- | | | FeeEstimator | <-----------------------
| (as MessageSendEventsProvider) | | ---------------- \\
| ^ | | ^ ------------------------ |
| \\ | | / ---------> | BroadcasterInterface | |
| \\ | | / / ------------------------ |
| \\ | | / / ^ |
| (as ------------------ ---------------- | |
| ChannelMessageHandler)-> | ChannelManager | ----> | chain::Watch | | |
v / ------------------ ---------------- | |
--------------- / (as EventsProvider) ^ | |
| PeerManager |- \\ | | |
--------------- \\ | (is-a) | |
| ----------------- \\ _---------------- / /
| | chain::Access | \\ / | ChainMonitor |---------------
| ----------------- \\ / ----------------
| ^ \\ / |
(as RoutingMessageHandler) | v v
\\ ---------------------- --------- -----------------
-----------------> | NetGraphMsgHandler | | Event | | chain::Filter |
---------------------- --------- -----------------
核心组成主要有:
- ChannelManager:用于维护多个通道,路由支付,提供发起支付和接收支付的API接口。
- ChannelMonitor:监督通道的链上状态,惩罚错误操作的交易方,当有即将过期的unresolved HTLCs时强制关闭通道。
- NetGraphMsgHandler:处理receiving channel和node announcements,可通过
get_route
计算路由路径。 - PeerManager:处理认证和加密通讯协议,监督节点的活跃状态,与ChannelManager和NetGraphMsgHandler进行消息交互。
2. lightning模块
- src/util/message_signing.rs:为闪电网络中消息的签名和验签机制。
- src/util/zbase32.rs:为对human-oriented base-32 encoding 的实现。最终的消息签名经过了base32编码:
signature = zbase32(SigRec(sha256d(("Lightning Signed Message:" + msg)))
。 - src/util/byte_utils.rs:实现了big-endian、little-endian 与array、slice之间的转换。
- src/util/chacha20.rs、chacha20poly1305rfc.rs、poly1305.rs:ChaCha20-Poly1305是由ChaCha20流密码和Poly1305消息认证码(MAC)结合的一种应用在互联网安全协议中的认证加密算法。
- src/util/config.rs:包含了通道握手、通道配置、用户通道配置信息。
- src/util/enforcing_trait_impls:可强制进行某种策略验证的强化签名。提供了sign_counterparty_commitment、sign_holder_commitment_and_htlcs等签名接口。
pub struct EnforcingSigner {
pub inner: InMemorySigner,
/// The last counterparty commitment number we signed, backwards counting
pub last_commitment_number: Arc<Mutex<Option<u64>>>,
/// The last holder commitment number we revoked, backwards counting
pub revoked_commitment: Arc<Mutex<u64>>,
pub disable_revocation_policy_check: bool,
}
- src/util/errors.rs:定义了客户端常用错误码及描述。
- src/util/events.rs:定义了Event(如FundingGenerationReady、PaymentReceived、PaymentSent、PaymentFailed、PendingHTLCsForwardable、SpendableOutputs),以及MessageSendEvent(由ChannelManager生成,有SendAcceptChannel、SendOpenChannel等等)
- src/util/fuzz_wrappers.rs:定义了hash_to_message 宏。
- src/util/logger.rs:实现了日志接口。
- src/util/macro_logger.rs:定义了一些自定义结构体的日志打印规则。
- src/util/scid_utils.rs:定义了short_channel_id 与 block、tx_index、vout_index之间的一些转换规则。
- src/util/ser_macros.rs:定义了tlv、tlv_stream的一些编码解码宏。
- src/util/ser.rs:定义一些结构体的read、write及序列化接口。
- src/util/test_utils.rs:定义了一些chain、channel等接口。
- src/util/transaction_utils.rs:定义了交易output相关接口。有一些SegWit Transaction input/output weight测试用例。
- src/routing/network_graph.rs:维护通道和节点信息,可用于计算路由路径。
- src/routing/router.rs:基于NetworkGraph和RoutingFees等计算路由路径,提供了
get_route
API。 - src/chain/chaininterface.rs:定义了闪电网络与链的交互接口。
- src/chain/chainmonitor.rs:用于连接链下通道和监控链上交易。
- src/chain/channelmonitor.rs:用于监控链上交易并创建相应声明。
- src/chain/keysinterface.rs:提供闪电网络中所需keys。
- src/chain/onchaintx.rs:用于构建声明,并bump in-flight transactions until confirmations。
- src/chain/package.rs:用于assemble claimable outpoints in package of one or more transactions。
- src/chain/transaction.rs:定义闪电网络中交易的output。注意比特币上的OutPoint的index为u32,而闪电网络中交易OutPoint的index限定为u16。
- src/ln/chan_utils.rs:构建scripts和派生与通道相关的keys。
3. TLV (Type-Length-Value Format)中的BigSize编解码
uint8(x) if x < 0xfd
0xfd + be16(uint16(x)) if x < 0x10000
0xfe + be32(uint32(x)) if x < 0x100000000
0xff + be64(x) otherwise.
对应的代码实现为:
/// Lightning TLV uses a custom variable-length integer called BigSize. It is similar to Bitcoin's
/// variable-length integers except that it is serialized in big-endian instead of little-endian.
///
/// Like Bitcoin's variable-length integer, it exhibits ambiguity in that certain values can be
/// encoded in several different ways, which we must check for at deserialization-time. Thus, if
/// you're looking for an example of a variable-length integer to use for your own project, move
/// along, this is a rather poor design.
pub(crate) struct BigSize(pub u64);
impl Writeable for BigSize {
#[inline]
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ::std::io::Error> {
match self.0 {
0...0xFC => {
(self.0 as u8).write(writer)
},
0xFD...0xFFFF => {
0xFDu8.write(writer)?;
(self.0 as u16).write(writer)
},
0x10000...0xFFFFFFFF => {
0xFEu8.write(writer)?;
(self.0 as u32).write(writer)
},
_ => {
0xFFu8.write(writer)?;
(self.0 as u64).write(writer)
},
}
}
}
impl Readable for BigSize {
#[inline]
fn read<R: Read>(reader: &mut R) -> Result<BigSize, DecodeError> {
let n: u8 = Readable::read(reader)?;
match n {
0xFF => {
let x: u64 = Readable::read(reader)?;
if x < 0x100000000 {
Err(DecodeError::InvalidValue)
} else {
Ok(BigSize(x))
}
}
0xFE => {
let x: u32 = Readable::read(reader)?;
if x < 0x10000 {
Err(DecodeError::InvalidValue)
} else {
Ok(BigSize(x as u64))
}
}
0xFD => {
let x: u16 = Readable::read(reader)?;
if x < 0xFD {
Err(DecodeError::InvalidValue)
} else {
Ok(BigSize(x as u64))
}
}
n => Ok(BigSize(n as u64))
}
}
}
以上是关于比特币闪电网络代码解析的主要内容,如果未能解决你的问题,请参考以下文章
比特币闪电网络(Lightning Network)及其工作原理