-
Notifications
You must be signed in to change notification settings - Fork 19
异构链数据验证服务开发手册
异构链数据验证服务(Hetero-Chain Data Verifier Service, HCDVS)提供了异构链数据在跨链过程中的验证能力,比如验证共识状态(区块头的抽象)、跨链消息的正确性、合法性,PTC会使用HCDVS完成背书功能,PTC通过调用HCDVS来确认Relayer发送过来的共识状态、跨链消息等数据的正确性,从而判断是否可以对其背书。
目前HCDVS是以Java插件的形式实现并提供服务。HCDVS需要和BBC插件配套使用,因为HCDVS的很多输入参数,是从同类型(product)BBC返回的,在插件之外以bytes传播。
要实现HCDVS插件,方法和BBC插件类似,只需要_实现特定的接口,并在实现类打上特定的注解即可_。
下面是一个简单的HCDVS实现。可以看到,目前仅需要实现下面四个接口即可,后面会详细解释每个接口的含义,下面需要先准备好开发环境。
package com.alipay.antchain.bridge.plugins.demo.testchain;
import com.alipay.antchain.bridge.commons.core.base.ConsensusState;
import com.alipay.antchain.bridge.commons.core.base.CrossChainMessage;
import com.alipay.antchain.bridge.commons.core.bta.IBlockchainTrustAnchor;
import com.alipay.antchain.bridge.plugins.lib.HeteroChainDataVerifierService;
import com.alipay.antchain.bridge.plugins.spi.ptc.AbstractHCDVSService;
import com.alipay.antchain.bridge.plugins.spi.ptc.core.VerifyResult;
/**
* This {@code TestChainHCDVSService} is a demo implementation of {@link HeteroChainDataVerifierService}.
* <p>
* It's a <b>{@code Blockchain Bridge Component}</b> plugin for the heterogeneous blockchain <b>testchain</b>
* in this demo.
* </p>
*/
@HeteroChainDataVerifierService(products = "testchain", pluginId = "testchain_hcdvsservice")
public class TestChainHCDVSService extends AbstractHCDVSService {
private TestChainSDK sdk;
private AbstractHCDVSService hcdvsContext;
@Override
public VerifyResult verifyAnchorConsensusState(IBlockchainTrustAnchor bta, ConsensusState anchorState) {
return VerifyResult.builder()
.success(true).build();
}
@Override
public VerifyResult verifyConsensusState(ConsensusState stateToVerify, ConsensusState anchorState) {
return VerifyResult.builder()
.success(true).build();
}
@Override
public VerifyResult verifyCrossChainMessage(CrossChainMessage message, ConsensusState anchorState) {
return VerifyResult.builder()
.success(true).build();
}
@Override
public byte[] parseMessageFromLedgerData(byte[] ledgerData) {
return new byte[0];
}
}
要开发HCDVS插件,需要下面两个依赖。
<dependency>
<groupId>com.alipay.antchain.bridge</groupId>
<artifactId>antchain-bridge-plugin-lib</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.alipay.antchain.bridge</groupId>
<artifactId>antchain-bridge-spi</artifactId>
<version>1.0.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
找到ACB SDK的代码,注意版本,然后在项目目录下执行:
mvn clean install -Dmaven.test.skip=true
Tip
如果编译bcdns相关模块有问题,可以在项目的pom.xml的modules
标签下找到bcdns-services/embedded-bcdns/embedded-bcdns-core
和antchain-bridge-bcdns-factory
先注释掉。
首先你需要新建一个类文件,比如上面的TestChainHCDVSService
。
在你的实现类加上注解@HeteroChainDataVerifierService
,类似@BBCService
,通过products
设置当前HCDVS支持的链类型,通过pluginId
设置插件ID:
/**
* The annotation to mark PTC plugin implementation.
*/
@Retention(RUNTIME)
@Target(TYPE)
@Inherited
@Documented
public @interface HeteroChainDataVerifierService {
/**
* the blockchain product name like {@code Ethereum} etc.
*
* @return {@link String[]}
*/
String[] products() default {};
/**
* the unique identity of the plugin
*
* @return {@link String[]}
*/
String[] pluginId() default {};
}
然后你需要继承AbstractHCDVSService,它实现了接口IHeteroChainDataVerifierService,并提供了getHCDVSLogger
方法,可以通过这个获取一个运行环境的logger对象,打印日志:
public abstract class AbstractHCDVSService implements IHeteroChainDataVerifierService {
private Logger hcdvsLogger = NOPLogger.NOP_LOGGER;
private void setLogger(Logger hcdvsLogger) {
this.hcdvsLogger = hcdvsLogger;
}
public final Logger getHCDVSLogger() {
return hcdvsLogger;
}
}
接口IHeteroChainDataVerifierService
如下:
包含接口:
- VerifyResult verifyAnchorConsensusState(IBlockchainTrustAnchor bta, ConsensusState anchorState);
验证最初的锚定共识状态的正确性,比如检查下BTA中共识节点信息是否可以验证anchorState的共识证明等。
- VerifyResult verifyConsensusState(ConsensusState stateToVerify, ConsensusState parentState);
使用parentState去验证stateToVerify,通常是用高度N的区块头中的共识公钥集合,去验证N+1高度的区块头的正确性。
- VerifyResult verifyCrossChainMessage(CrossChainMessage message, ConsensusState currState);
使用当前消息对应高度的共识状态来验证跨链消息的正确性,比如,使用跨链事件所在高度的区块头来验证跨链消息MerkleProof的正确性。
- byte[] parseMessageFromLedgerData(byte[] ledgerData);
从CrossChainMessage.ProvableLedgerData#ledgerData
中解析出AM消息原文,这个字段通常存放包含AM消息原文的账本数据,比如以太坊包含SendAuthMessage事件的收据,可以从中解析出AM原文。
下面详细介绍如何实现每个接口。
验证最初的锚定共识状态的正确性,PTC会调用这个接口来验证第一个共识状态的正确性,并作为后续的锚定共识状态。
- 入参中,
IBlockchainTrustAnchor bta
是用来验证区块的工具,包含了一些能代表区块链的数据,比如最初的共识公钥集合,能用来验证anchorState的正确性。 -
anchorState
是最开始锚定的共识状态,也就是一个区块头。
首先需要了解一下ConsensusState这个类
- csVersion:代表这个结构的版本号,目前仅有v1
- domain:为这个共识状态来自哪个域名
- height:这个共识状态的区块高度是多少
- hash:这个共识状态的区块hash是多少
- parentHash:这个共识状态的父区块hash是多少
- stateTimestamp:这个共识状态的区块时间戳是多少(如果有的话)
- stateData:共识状态的主要内容,这个由和HCDVS配套的BBC插件的
readConsensusState
确定,往往是包含整个区块头 - consensusNodeInfo:共识节点的信息内容,往往是共识节点的公钥集合,或者其他内容,用于验证共识对于这个高度的证明
- endorsements:共识对于这个高度的背书证明内容,往往是共识节点的签名集合
然后认识一下接口IBlockchainTrustAnchor
,这里比较关键的是getSubjectIdentity
方法,BTA里面存储了序列化的链关键信息,并且这个信息是被域名持有者放在subjectIdentity
字段并签名过的,因此通过从BTA获取subjectIdentity,并于区块头中的consensusNodeInfo进行对比,可以知道这部分共识相关内容是否正确。
最后认识一下返回类型VerifyResult
,它只包含两个字段,用来返回验证的结果:
- success:是否验证通过
- errorMsg:验证不通过的原因
- 从BTA获取subjectIdentity,这里按照插件本身逻辑,从bytes反序列化比如某个类(这需要插件开发者自己定制),可以从中获取到共识节点集合;
- 从anchorState获取共识节点集合,和从BTA中获取的进行对比,不相同则返回VerifyResult为false;
- 使用共识节点集合,验证anchorState中的endorsements的正确性;
- 从anchorState的stateData中解析出链的区块头,检查hash和高度等字段和共识状态中相同;
- 所有验证都正确则返回VerifyResult为true;
使用parentState去验证stateToVerify,通常是用高度N的区块头中的共识公钥集合,去验证N+1高度的区块头的正确性。
- parentState是经过PTC验证的可靠的父状态,从parentState获取共识节点集合
- 从stateToVerify中获取endorsements,并用上面的共识节点集合验证
- 从stateToVerify的stateData中解析出链的区块头,检查hash和高度等字段和共识状态中相同;
使用当前消息对应高度的共识状态来验证跨链消息的正确性,比如,使用跨链事件所在高度的区块头来验证跨链消息MerkleProof的正确性。
首先看下入参类型CrossChainMessage
,它来自BBC插件的readCrossChainMessagesByHeight
接口,可以参考.
CrossChainMessage
包含三个字段:
- message:序列化好的消息内容,比如AM消息
- type:跨链消息类型,比如AM(目前只有AM类型)
- provableData:跨链消息相关的可证明数据
ProvableLedgerData包含下面字段:
- height:该消息所在的区块高度
- txHash:发出该消息的交易hash
- blockHash:该消息所在的区块hash
- timestamp:该消息产生的时间戳
- ledgerData:异构链插件放入的包含跨链消息的账本数据,用于执行账本数据存在性验证
- proof:异构链插件放入的账本数据存在性证明,比如Merkle Proof
- currState是PTC已经验证过的共识状态,使用该共识状态作为验证锚点
- 从跨链消息的provableData中拿到ledgerData,比如包含以太坊SendAuthMessage事件的Receipt
- 从跨链消息的provableData中拿到proof,假设是Merkle Proof,这里解析并验证上面ledgerData符合证明,
- 获得receipt root后,从currState中解析出区块头,对比区块头中receipt root和merkle proof计算出来的相同,则证明验证通过
从CrossChainMessage.ProvableLedgerData#ledgerData
中解析出AM消息原文,这个字段通常存放包含AM消息原文的账本数据,比如以太坊包含SendAuthMessage事件的收据,可以从中解析出AM原文。
- 从bytes中解析出比如包含以太坊SendAuthMessage事件的Receipt
- 从Receipt中获取SendAuthMessage的data字段,并返回