Kim S, Hwang S. EtherDiffer: Differential Testing on RPC Services of Ethereum Nodes[C]//Proceedings of the 31st ACM Joint European Software Engineering Conference and Symposium on the Foundations of Software Engineering. 2023: 1333-1344.
Abstract
区块链上的DApp一般由链下的前端和链上的后端组成,以太坊节点对前端实现了RPC并提供了一系列接口
然而RPC的spec存在不足
- 缺少对非确定性event的处理
- 缺少对无效参数的规定
本工作对4种节点实现的RPC服务进行差分测试,首先通过多并发交易和传播延迟生成非确定性交易,采用基于属性的生成和类型保持的变异生成语义有效和无效的测试用例。
不一致性包括:异常处理和返回值
Introduction
挑战
- 测试用例生成(基于属性的生成和类型保留的变异),定义DSL
- 语义有效的测试用例
- 语义无效但是可执行的测试用例:变异生成
- 执行交易前的初始状态一致:也作为了challenge,可以是手动构造操作码的原因
测试对象是4个客户端的RPC服务,意图是根据已有的SPEC规范来生成测试用例,实际贡献非常solid
项目开源:https://github.com/JosephK95/EtherDiffer-public
数据集:https://solidity-by-example.org/hello-world/
https://dl.acm.org/do/10.6084/m9.figshare.23913096.v1/full/
PPT和视频资料:
- https://2023.esec-fse.org/details/fse-2023-research-papers/10/EtherDiffer-Differential-Testing-on-RPC-Services-of-Ethereum-Nodes
- https://slideslive.com/39014005
Background
以太坊主网节点个数:https://ethernodes.org/
Methodolody
Overview
针对4个客户端geth Nethermind Erigon Besu,本地部署一个网络,每4个节点组成一个私链,共识用的是PoW
测试用例生成依赖web3.js
定义了DSL,用于捕捉函数参数的语法和语义要求,并将库规范转换为$spec_{DSL}$。EtherDiffer首先从specDSL中选择一个方法,然后Generator生成符合语义要求的模板代码,其中所有参数都满足其要求。此外,Mutator以随机方式将其中一个参数更改为语义无效的值,同时保持其类型。最后,Test Case Converter通过将模板代码与每个目标节点绑定来实例化一组四个测试用例。一旦执行完成,Error Checker报告只有一部分节点引发错误,而其他节点返回值,并且Value Checker报告返回值是否彼此不一致。
测试用例使用try-catch语句包装,以正确识别错误,同时保持EtherDiffer的执行
非确定性链的生成
考虑到多交易的并发和交易的传播时延
使用了Solidity by Example的简单程序生成了109个交易
DSL
目的:理解函数参数的类型和
测试用例生成
基于web3.js
为了自动化处理库规范,定义了一个领域特定语言,用于捕捉函数参数的类型和语义要求。规范s包括 类型定义、子类型关系、属性定义和方法声明。
类型t可以是基本类型t_p,对象类型,数组类型或两个类型的并集。对象类型是一组键-类型对的集合,其中一些可以是可选的。