L6

Erlang 节点源码导读

深入 Aeternity 节点的 Erlang/OTP 实现

为什么选择 Erlang?

Aeternity 节点完全使用 Erlang/OTP 编写,这不是偶然的选择。Erlang 诞生于爱立信电信系统,天生为高可用、高并发场景设计。

Actor 模型

轻量级进程(Process),进程间通过消息传递通信,无共享内存

容错设计

"Let it crash" 哲学,Supervisor Tree 自动恢复故障进程

热代码更新

无需停机即可升级代码,适合长期运行的区块链节点

趣闻:Erlang 曾支撑 WhatsApp 用仅 50 个工程师服务 10 亿用户,其高并发能力在区块链 P2P 网络中同样适用。
Erlang 核心概念
OTP Application

Erlang 代码按 Application 组织,每个 Application 是一个独立的功能单元,有自己的 Supervisor Tree。

% 启动 Application
application:start(aecore).
% 停止
application:stop(aecore).
Supervisor Tree

监督树定义了进程之间的父子关系,父进程负责监控子进程,子进程崩溃时自动重启。

% Supervisor 策略
{one_for_one, 5, 10}  % 1个崩5次/10秒
{one_for_all, ...}    % 1崩全重启
{rest_for_one, ...}   % 后续都重启
GenServer

通用服务器行为模式,封装了消息循环、状态管理、同步/异步调用。

% 同步调用
gen_server:call(Pid, Request).
% 异步调用
gen_server:cast(Pid, Message).
消息传递

进程间通过 ! 发送消息,通过 receive 接收,天然支持分布式。

% 发送消息
Pid ! {hello, "world"}.
% 接收消息
receive
    {hello, Msg} -> io:format("~p~n", [Msg])
end.
项目结构 (Umbrella 风格)

Aeternity 采用典型的 Erlang umbrella 项目结构,apps/* 下每个子目录是一个独立的 OTP Application。

aeternity/
├── apps/
│   ├── aecore/        # 区块链核心:链状态、区块、共识、交易池、P2P
│   ├── aehttp/        # HTTP API / WebSocket / Rosetta
│   ├── aecontract/    # 合约交易、状态树、Sophia 工具
│   ├── aefate/        # FATE VM (主要执行引擎)
│   ├── aevm/          # AEVM (类 EVM)
│   ├── aechannel/     # 状态通道 FSM
│   ├── aens/          # 命名系统 (AENS)
│   ├── aeoracle/      # Oracle 模块
│   ├── aega/          # Generalized Accounts
│   └── aestratum/     # Stratum 挖矿服务
├── config/
│   └── sys.config     # 系统配置
├── rebar.config       # 构建配置
└── Makefile           # 编译入口
核心 Applications 一览
Application职责
aecore区块链核心:链状态、区块插入、共识/出块、交易池、P2P、DB
aehttpHTTP API / WebSocket / Rosetta,对外提供节点能力
aecontract合约相关交易、合约状态树、Sophia 代码与类型工具
aefateFATE VM - Sophia 合约主要执行环境
aechannel状态通道:FSM、Noise 会话、通道交易
aens命名系统:name hash、pointers、解析/查询
aeoracleOracle:对象/交易/状态树与序列化
共识机制:Bitcoin-NG

Aeternity 实现了 Bitcoin-NG 共识,将区块分为两类:

Key Block
  • 通过 PoW 挖矿产生
  • 选举 Leader(Beneficiary)
  • 不包含交易,只有元数据
  • 验证 Nonce + PoW Evidence
Micro Block
  • 由当前 Leader 快速生成
  • 承载实际交易
  • 签名验证(无需 PoW)
  • 支持 PoF(Proof of Fraud)
核心模块
  • aec_conductor - 出块/插入区块的中枢,区分 local_powstratumpos 三种模式
  • aec_consensus_bitcoin_ng - Bitcoin-NG 共识实现
  • aec_block_generator - Micro Block 组装
链核心与状态管理
aec_chain

链对象查询:top block/header/hash、按 hash/height 查询

aec_tx_pool

交易池(mempool),管理未上链交易,区分本地/网络来源

aec_block_insertion

区块插入封装为事务化 state transition

交易生命周期
aehttp (收 tx) aec_tx_pool (入池) aec_block_generator (组块) aec_conductor (签名/插入)
FATE VM - 智能合约引擎

FATE(Fast Aeternity Transaction Engine)是 Aeternity 特色的高层虚拟机,直接执行接近 Sophia 源码的高级指令。

类型安全

执行前检查操作数类型

Gas 模型

基于操作复杂度和数据大小

链交互

通过 aefa_chain_api 交互

独立运行

aefate:main/1 单机执行
内置高级指令示例
oracle_register    % Oracle 注册
aens_transfer      % AENS 转让
str_length         % 字符串长度
map_lookup         % Map 查找
...
状态通道 (State Channels)

状态通道实现位于 apps/aechannel,围绕 aesc_fsm(有限状态机)组织。

状态流转
阶段流程
Open CH_OPEN → CH_ACCEPT → FND_CREATED → FND_SIGNED → FND_LOCKED → open
Update UPDATE → UPDATE_ACK (链下更新状态,无需上链)
Close SHUTDOWN → SHUTDOWN_ACK → mutual_closing → mutual_closed
Dispute deposit / withdraw / force_progress / slash (链上争议)
推荐阅读路线

如果你想深入"啃下"这个仓库,推荐按以下顺序建立心智模型:

  1. 启动与模式
    aecore_appaecore_sup (主监督树)
  2. 链与落盘
    aec_chainaec_chain_stateaec_block_insertionaec_db
  3. 交易生命周期
    aehttp (收 tx) → aec_tx_pool (入池) → aec_block_generator (组块) → aec_conductor (插入)
  4. 共识切换
    aec_conductor:get_active_consensus_module/0 + aec_consensus_*
  5. 合约执行
    aect_* (交易/对象/树) → aefateaevm (执行)
  6. 扩展系统
    aechannel / aens / aeoracle / aega
  7. 对外接口
    aehttp_app (listener) → aehttp_api_router (路由) → aehttp_logic (调用链核心)
默认端口与配置
默认端口
HTTP External3013
HTTP Internal3113
Channel WebSocket3014
P2P Sync3015
Rosetta3213
关键配置文件
  • config/sys.config - 系统配置
  • config/vm.args - VM 参数
  • aeternity_config_schema.json - 配置 Schema
存储后端

默认使用 Mnesia + RocksDB,通过 persist: true 开启 RocksDB。

工程挑战
多版本演进

代码中大量以 protocol version / hard fork 为条件分支,合约、交易、共识都随硬分叉演进

并发 + 一致性

Erlang actor 模型适合高并发,但区块插入/状态迁移要求严格一致性(mnesia 事务、缓存一致性)

链上 + 链下

状态通道、oracle、命名系统、GA 都深入交易类型/状态树/VM 的协同设计

导航
Erlang (当前)