Erlang 节点源码导读
深入 Aeternity 节点的 Erlang/OTP 实现
Aeternity 节点完全使用 Erlang/OTP 编写,这不是偶然的选择。Erlang 诞生于爱立信电信系统,天生为高可用、高并发场景设计。
Actor 模型
轻量级进程(Process),进程间通过消息传递通信,无共享内存
容错设计
"Let it crash" 哲学,Supervisor Tree 自动恢复故障进程
热代码更新
无需停机即可升级代码,适合长期运行的区块链节点
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.
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 |
aehttp | HTTP API / WebSocket / Rosetta,对外提供节点能力 |
aecontract | 合约相关交易、合约状态树、Sophia 代码与类型工具 |
aefate | FATE VM - Sophia 合约主要执行环境 |
aechannel | 状态通道:FSM、Noise 会话、通道交易 |
aens | 命名系统:name hash、pointers、解析/查询 |
aeoracle | Oracle:对象/交易/状态树与序列化 |
Aeternity 实现了 Bitcoin-NG 共识,将区块分为两类:
Key Block
- 通过 PoW 挖矿产生
- 选举 Leader(Beneficiary)
- 不包含交易,只有元数据
- 验证 Nonce + PoW Evidence
Micro Block
- 由当前 Leader 快速生成
- 承载实际交易
- 签名验证(无需 PoW)
- 支持 PoF(Proof of Fraud)
核心模块
aec_conductor- 出块/插入区块的中枢,区分local_pow、stratum、pos三种模式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
交易生命周期
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 查找
...
状态通道实现位于 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 (链上争议) |
如果你想深入"啃下"这个仓库,推荐按以下顺序建立心智模型:
-
启动与模式
aecore_app→aecore_sup(主监督树) -
链与落盘
aec_chain→aec_chain_state→aec_block_insertion→aec_db -
交易生命周期
aehttp(收 tx) →aec_tx_pool(入池) →aec_block_generator(组块) →aec_conductor(插入) -
共识切换
aec_conductor:get_active_consensus_module/0+aec_consensus_* -
合约执行
aect_*(交易/对象/树) →aefate或aevm(执行) -
扩展系统
aechannel/aens/aeoracle/aega -
对外接口
aehttp_app(listener) →aehttp_api_router(路由) →aehttp_logic(调用链核心)
默认端口
| HTTP External | 3013 |
| HTTP Internal | 3113 |
| Channel WebSocket | 3014 |
| P2P Sync | 3015 |
| Rosetta | 3213 |
关键配置文件
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 的协同设计