diff --git a/antchain-bridge-plugin-test/.gitignore b/antchain-bridge-plugin-test/.gitignore
new file mode 100644
index 00000000..5ff6309b
--- /dev/null
+++ b/antchain-bridge-plugin-test/.gitignore
@@ -0,0 +1,38 @@
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### IntelliJ IDEA ###
+.idea/modules.xml
+.idea/jarRepositories.xml
+.idea/compiler.xml
+.idea/libraries/
+*.iws
+*.iml
+*.ipr
+
+### Eclipse ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
+
+### Mac OS ###
+.DS_Store
\ No newline at end of file
diff --git a/antchain-bridge-plugin-test/dependency-reduced-pom.xml b/antchain-bridge-plugin-test/dependency-reduced-pom.xml
new file mode 100644
index 00000000..b398c49a
--- /dev/null
+++ b/antchain-bridge-plugin-test/dependency-reduced-pom.xml
@@ -0,0 +1,103 @@
+
+
+ 4.0.0
+ com.ali.antchain
+ antchain-bridge-plugin-tester
+ PlugsTest
+ 0.1.0
+ http://maven.apache.org
+
+
+
+ maven-shade-plugin
+ 3.2.4
+
+
+ package
+
+ shade
+
+
+
+
+ com.slc.antchain.PluginsTest
+
+
+
+
+
+ *:*
+
+ META-INF/*.SF
+ META-INF/*.DSA
+ META-INF/*.RSA
+
+
+
+
+
+
+
+
+ maven-compiler-plugin
+
+ 8
+ 8
+
+
+
+
+
+
+ org.web3j
+ core
+ 4.9.8
+ provided
+
+
+ slf4j-api
+ org.slf4j
+
+
+
+
+ org.slf4j
+ slf4j-api
+ 1.7.28
+ provided
+
+
+ ch.qos.logback
+ logback-classic
+ 1.2.11
+ test
+
+
+ logback-core
+ ch.qos.logback
+
+
+
+
+ junit
+ junit
+ 4.13.2
+ test
+
+
+ hamcrest-core
+ org.hamcrest
+
+
+
+
+ com.alipay.antchain.bridge
+ simple-ethereum-bbc
+ 0.2.0
+ test
+
+
+
+ UTF-8
+
+
diff --git a/antchain-bridge-plugin-test/pom.xml b/antchain-bridge-plugin-test/pom.xml
new file mode 100644
index 00000000..965988a3
--- /dev/null
+++ b/antchain-bridge-plugin-test/pom.xml
@@ -0,0 +1,117 @@
+
+ 4.0.0
+
+
+ com.ali.antchain
+ antchain-bridge-plugin-tester
+ 0.1.0
+ jar
+
+ PlugsTest
+ http://maven.apache.org
+
+
+ UTF-8
+
+
+
+
+ com.alipay.antchain.bridge
+ antchain-bridge-plugin-lib
+ 0.2.3
+
+
+ com.alipay.antchain.bridge
+ antchain-bridge-spi
+ 0.2.3
+
+
+ org.web3j
+ core
+ 4.9.8
+ provided
+
+
+ org.slf4j
+ slf4j-api
+
+
+
+
+ org.projectlombok
+ lombok
+ 1.18.24
+ compile
+
+
+ org.slf4j
+ slf4j-api
+ 1.7.28
+ provided
+
+
+ ch.qos.logback
+ logback-classic
+ 1.2.11
+ test
+
+
+ junit
+ junit
+ 4.13.2
+ test
+
+
+ com.alipay.antchain.bridge
+ simple-ethereum-bbc
+ 0.2.0
+ test
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+ 3.2.4
+
+
+ package
+
+ shade
+
+
+
+
+ com.slc.antchain.PluginsTest
+
+
+
+
+
+ *:*
+
+ META-INF/*.SF
+ META-INF/*.DSA
+ META-INF/*.RSA
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 8
+ 8
+
+
+
+
+
+
diff --git a/antchain-bridge-plugin-test/src/main/java/com/ali/antchain/EthPluginTestTool.java b/antchain-bridge-plugin-test/src/main/java/com/ali/antchain/EthPluginTestTool.java
new file mode 100644
index 00000000..39e2d35d
--- /dev/null
+++ b/antchain-bridge-plugin-test/src/main/java/com/ali/antchain/EthPluginTestTool.java
@@ -0,0 +1,80 @@
+package com.ali.antchain;
+
+import com.ali.antchain.abstarct.IPluginTestTool;
+import com.ali.antchain.core.*;
+import com.ali.antchain.testers.EthTester;
+import com.alipay.antchain.bridge.commons.bbc.AbstractBBCContext;
+import com.alipay.antchain.bridge.plugins.spi.bbc.AbstractBBCService;
+
+public class EthPluginTestTool implements IPluginTestTool {
+
+ AbstractBBCContext inContext;
+ AbstractBBCService bbcService;
+
+ public EthPluginTestTool(AbstractBBCContext _context, AbstractBBCService _service) {
+ inContext = _context;
+ bbcService = _service;
+ }
+
+ @Override
+ public void startupTest() {
+ StartUpTest.run(inContext, bbcService);
+ }
+
+ @Override
+ public void shutdownTest() {
+ ShutDownTest.run(inContext, bbcService);
+ }
+
+ @Override
+ public void getcontextTest(){
+ GetContextTest.run(inContext, bbcService);
+ }
+
+ @Override
+ public void setupamcontractTest(){
+ SetupAuthMessageContractTest.run(inContext, bbcService);
+ }
+
+ @Override
+ public void setupsdpcontractTest(){
+ SetupSDPMessageContractTest.run(inContext, bbcService);
+ }
+
+ @Override
+ public void setprotocolTest() throws Exception {
+ StartUpTest.runBefore(inContext, bbcService);
+ SetProtocolTest.run(bbcService, new EthTester(bbcService));
+ }
+
+ @Override
+ public void querysdpmessageseqTest() {
+ StartUpTest.runBefore(inContext, bbcService);
+ QuerySDPMessageSeqTest.run(bbcService);
+ }
+
+ @Override
+ public void setamcontractandlocaldomainTest() {
+ StartUpTest.runBefore(inContext, bbcService);
+ SetAMContractAndLocaldomainTest.run(bbcService);
+ }
+
+ @Override
+ public void readcrosschainmessagereceiptTest() {
+ StartUpTest.runBefore(inContext, bbcService);
+ ReadCrossChainMessageReceiptTest.run(bbcService, new EthTester(bbcService));
+ }
+
+ @Override
+ public void readcrosschainmessagebyheightTest() {
+ StartUpTest.runBefore(inContext, bbcService);
+ ReadCrossChainMessageByHeightTest.run(bbcService, new EthTester(bbcService));
+ }
+
+ @Override
+ public void relayauthmessageTest() {
+ StartUpTest.runBefore(inContext, bbcService);
+ RelayAuthMessageTest.run(bbcService, new EthTester(bbcService));
+ }
+
+}
diff --git a/antchain-bridge-plugin-test/src/main/java/com/ali/antchain/abstarct/AbstractTester.java b/antchain-bridge-plugin-test/src/main/java/com/ali/antchain/abstarct/AbstractTester.java
new file mode 100644
index 00000000..30bb2c0c
--- /dev/null
+++ b/antchain-bridge-plugin-test/src/main/java/com/ali/antchain/abstarct/AbstractTester.java
@@ -0,0 +1,22 @@
+package com.ali.antchain.abstarct;
+
+import com.alipay.antchain.bridge.commons.bbc.AbstractBBCContext;
+import com.alipay.antchain.bridge.plugins.spi.bbc.AbstractBBCService;
+import lombok.Getter;
+import lombok.Setter;
+import org.slf4j.Logger;
+import org.slf4j.helpers.NOPLogger;
+
+/**
+ * 插件测试工具需要实现的定制化操作
+ * todo: 这里的方法肯定不能抛出异常啊!有异常的在接口里面处理妥当!
+ */
+@Getter
+@Setter
+public abstract class AbstractTester implements ITester {
+
+ private Logger bbcLogger;
+ public AbstractTester() {
+ bbcLogger = NOPLogger.NOP_LOGGER;
+ }
+}
diff --git a/antchain-bridge-plugin-test/src/main/java/com/ali/antchain/abstarct/IPluginTestTool.java b/antchain-bridge-plugin-test/src/main/java/com/ali/antchain/abstarct/IPluginTestTool.java
new file mode 100644
index 00000000..aa5f4ef0
--- /dev/null
+++ b/antchain-bridge-plugin-test/src/main/java/com/ali/antchain/abstarct/IPluginTestTool.java
@@ -0,0 +1,43 @@
+package com.ali.antchain.abstarct;
+
+// 和插件测试框架约定的接口
+public interface IPluginTestTool {
+
+ public void startupTest();
+
+ public void shutdownTest();
+
+ public void getcontextTest();
+
+ public void setupamcontractTest();
+
+ public void setupsdpcontractTest();
+
+ public void setprotocolTest() throws Exception;
+
+ public void querysdpmessageseqTest();
+
+ public void setamcontractandlocaldomainTest();
+
+// public void relayamprepare() throws Exception {
+// RelayAmPrepare.run(context, service);
+// }
+
+ public void readcrosschainmessagereceiptTest();
+
+ public void relayauthmessageTest();
+
+ public void readcrosschainmessagebyheightTest();
+
+// public static void main(String[] args) throws Exception{
+// String url = "http://127.0.0.1:7545";
+// String key = "0x45cfa3b6addf98274bfd9e3482a695406c7dcc99e1588bd6e0127b8fc06ae916";
+// long gasPrice = 2300000000L;
+// long gasLimit = 3000000;
+// PlugsTest test = new PlugsTest(url,key,gasPrice,gasLimit);
+//// test.ethinit.init();
+// test.startup();
+// }
+
+
+}
diff --git a/antchain-bridge-plugin-test/src/main/java/com/ali/antchain/abstarct/ITester.java b/antchain-bridge-plugin-test/src/main/java/com/ali/antchain/abstarct/ITester.java
new file mode 100644
index 00000000..b4bcffae
--- /dev/null
+++ b/antchain-bridge-plugin-test/src/main/java/com/ali/antchain/abstarct/ITester.java
@@ -0,0 +1,38 @@
+package com.ali.antchain.abstarct;
+
+import com.alipay.antchain.bridge.plugins.spi.bbc.AbstractBBCService;
+
+// 需要不同测试工具实现的定制化测试操作
+public interface ITester {
+
+ /**
+ * 根据am合约地址调用链上am合约的getProtocol方法,返回protocol合约地址,用于验证setProtocol方法是否正确执行
+ *
+ * @param amContractAddr
+ * @return
+ */
+ public String getProtocol(String amContractAddr);
+
+ /**
+ * 向链上部署app合约,并设置app合约中的protocol合约地址,返回app合约地址
+ * @param protocolAddr
+ * @return
+ */
+ public byte[] deployApp(String protocolAddr);
+
+ /**
+ * 查询链上txHash的交易是否已上链,会重试一定次数直至已上链
+ * @param txhash
+ */
+ public void waitForTxConfirmed(String txhash);
+
+ public String sendMsg(AbstractBBCService service);
+
+// public String create();
+//
+// public void preExecute(String encodefunc, AbstractBBCService service);
+//
+// public void sendTx(AbstractBBCService service,String encodefunc);
+
+
+}
diff --git a/antchain-bridge-plugin-test/src/main/java/com/ali/antchain/core/GetContextTest.java b/antchain-bridge-plugin-test/src/main/java/com/ali/antchain/core/GetContextTest.java
new file mode 100644
index 00000000..1410eefa
--- /dev/null
+++ b/antchain-bridge-plugin-test/src/main/java/com/ali/antchain/core/GetContextTest.java
@@ -0,0 +1,98 @@
+package com.ali.antchain.core;
+
+import com.alipay.antchain.bridge.commons.bbc.AbstractBBCContext;
+import com.alipay.antchain.bridge.commons.bbc.syscontract.AuthMessageContract;
+import com.alipay.antchain.bridge.commons.bbc.syscontract.SDPContract;
+import com.alipay.antchain.bridge.plugins.spi.bbc.AbstractBBCService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class GetContextTest {
+
+ private static final Logger log = LoggerFactory.getLogger(GetContextTest.class);
+ AbstractBBCService service;
+
+ public GetContextTest(AbstractBBCService service) {
+ this.service = service;
+ }
+ public static void run(AbstractBBCContext context, AbstractBBCService service){
+ GetContextTest getctx = new GetContextTest(service);
+ getctx.getcontext(context);
+ }
+ public void getcontext(AbstractBBCContext context){
+ if (service == null) {
+ throw new IllegalStateException("Service is not initialized.");
+ }
+ try {
+ // 启动服务
+ service.startup(context);
+ // 获取上下文
+ AbstractBBCContext ctx = service.getContext();
+ // 检查上下文是否为空
+ if (ctx != null) {
+ log.info( "Context: {}", ctx);
+
+ // 打印 AM 合约
+ processAuthMessageContract(ctx);
+
+ // 打印 SDP 合约
+ processSDPContract(ctx);
+
+ } else {
+ log.warn( "Context is null.");
+ }
+ } catch (Exception e) {
+ // 处理异常
+ log.error("An error occurred: ", e);
+ }
+ }
+ private void processAuthMessageContract(AbstractBBCContext ctx) {
+ AuthMessageContract authMessageContract = ctx.getAuthMessageContract();
+ if (authMessageContract != null) {
+ log.info("Auth Message Contract: {}", authMessageContract);
+ }
+ }
+
+ private void processSDPContract(AbstractBBCContext ctx) {
+ SDPContract sdpContract = ctx.getSdpContract();
+ if (sdpContract != null) {
+ log.info("SDP Contract: {}", sdpContract);
+ }
+ }
+}
+
+//public class GetContextTest {
+//
+// private static final Logger log = LoggerFactory.getLogger(GetContextTest.class);
+//
+// private AbstractBBCService service;
+//
+// public GetContextTest(AbstractBBCService service) {
+// this.service = service;
+// }
+//
+// public static void run(AbstractBBCContext context){
+// getcontext(context);
+// }
+//
+// public void getcontext(AbstractBBCContext context){
+// if (service == null) {
+// throw new IllegalStateException("Service is not initialized.");
+// }
+// try {
+// service.startup(context);
+// AbstractBBCContext ctx = service.getContext();
+// if (ctx != null) {
+// log.info("Context: {}", ctx);
+// processAuthMessageContract(ctx);
+// processSDPContract(ctx);
+// } else {
+// log.warn("Context is null.");
+// }
+// } catch (Exception e) {
+// log.error("An unexpected error occurred: ", e);
+// }
+// }
+//
+//
+//}
diff --git a/antchain-bridge-plugin-test/src/main/java/com/ali/antchain/core/QuerySDPMessageSeqTest.java b/antchain-bridge-plugin-test/src/main/java/com/ali/antchain/core/QuerySDPMessageSeqTest.java
new file mode 100644
index 00000000..2f12c40d
--- /dev/null
+++ b/antchain-bridge-plugin-test/src/main/java/com/ali/antchain/core/QuerySDPMessageSeqTest.java
@@ -0,0 +1,59 @@
+package com.ali.antchain.core;
+
+import cn.hutool.crypto.digest.DigestUtil;
+import com.alipay.antchain.bridge.commons.bbc.AbstractBBCContext;
+import com.alipay.antchain.bridge.plugins.spi.bbc.AbstractBBCService;
+
+public class QuerySDPMessageSeqTest {
+
+ AbstractBBCService bbcService;
+
+ public QuerySDPMessageSeqTest(AbstractBBCService _bbcService) {
+ this.bbcService = _bbcService;
+ }
+
+
+ public static void run(AbstractBBCService _bbcService) {
+ QuerySDPMessageSeqTest querySDPMessageSeqTest = new QuerySDPMessageSeqTest(_bbcService);
+
+ querySDPMessageSeqTest.querysdpmessageseq_success();
+ }
+
+ public void querysdpmessageseq_success() {
+ // 部署AM、SDP合约
+ prepare();
+
+ // query seq
+ long seq = bbcService.querySDPMessageSeq(
+ "senderDomain",
+ DigestUtil.sha256Hex("senderID"),
+ "receiverDomain",
+ DigestUtil.sha256Hex("receiverID")
+ );
+ }
+
+
+ private void prepare() {
+ // set up am
+ bbcService.setupAuthMessageContract();
+
+ // set up sdp
+ bbcService.setupSDPMessageContract();
+
+ AbstractBBCContext curCtx = bbcService.getContext();
+
+ // set protocol to am (sdp type: 0)
+ bbcService.setProtocol(curCtx.getSdpContract().getContractAddress(), "0");
+
+ // set am to sdp
+ bbcService.setAmContract(curCtx.getAuthMessageContract().getContractAddress());
+
+ // set local domain to sdp
+ bbcService.setLocalDomain("receiverDomain");
+
+ // check contract ready
+ curCtx = bbcService.getContext();
+
+ }
+
+}
diff --git a/antchain-bridge-plugin-test/src/main/java/com/ali/antchain/core/ReadCrossChainMessageByHeightTest.java b/antchain-bridge-plugin-test/src/main/java/com/ali/antchain/core/ReadCrossChainMessageByHeightTest.java
new file mode 100644
index 00000000..bfbb7e58
--- /dev/null
+++ b/antchain-bridge-plugin-test/src/main/java/com/ali/antchain/core/ReadCrossChainMessageByHeightTest.java
@@ -0,0 +1,54 @@
+package com.ali.antchain.core;
+
+import com.ali.antchain.abstarct.AbstractTester;
+import com.alipay.antchain.bridge.commons.bbc.AbstractBBCContext;
+import com.alipay.antchain.bridge.plugins.spi.bbc.AbstractBBCService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ReadCrossChainMessageByHeightTest {
+ private static final Logger log = LoggerFactory.getLogger(ReadCrossChainMessageReceiptTest.class);
+
+ AbstractTester tester;
+ AbstractBBCService service;
+
+ public ReadCrossChainMessageByHeightTest(AbstractBBCService service, AbstractTester tester) {
+ this.service = service;
+ this.tester = tester;
+ }
+
+ public static void run(AbstractBBCService service, AbstractTester tester) {
+ ReadCrossChainMessageByHeightTest test = new ReadCrossChainMessageByHeightTest(service, tester);
+ test.readCrossChainMessageByHeight_success();
+ }
+
+ private void readCrossChainMessageByHeight_success() {
+ // 对应 relayAmPrepare
+ prepare();
+
+ tester.sendMsg(service);
+ }
+
+
+
+ private void prepare() {
+ // set up am
+ service.setupAuthMessageContract();
+
+ // set up sdp
+ service.setupSDPMessageContract();
+
+ AbstractBBCContext curCtx = service.getContext();
+
+ // set protocol to am (sdp type: 0)
+ service.setProtocol(curCtx.getSdpContract().getContractAddress(), "0");
+
+ // set am to sdp
+ service.setAmContract(curCtx.getAuthMessageContract().getContractAddress());
+
+ // set local domain to sdp
+ service.setLocalDomain("receiverDomain");
+
+ }
+
+}
diff --git a/antchain-bridge-plugin-test/src/main/java/com/ali/antchain/core/ReadCrossChainMessageReceiptTest.java b/antchain-bridge-plugin-test/src/main/java/com/ali/antchain/core/ReadCrossChainMessageReceiptTest.java
new file mode 100644
index 00000000..a13d3ddc
--- /dev/null
+++ b/antchain-bridge-plugin-test/src/main/java/com/ali/antchain/core/ReadCrossChainMessageReceiptTest.java
@@ -0,0 +1,293 @@
+//package com.ali.antchain.core;
+//
+//import cn.hutool.core.util.HexUtil;
+//import cn.hutool.core.util.StrUtil;
+//import cn.hutool.crypto.digest.DigestUtil;
+//import com.ali.antchain.Test.RelayAmPrepare;
+//import com.ali.antchain.abi.AppContract;
+//import com.alipay.antchain.bridge.commons.bbc.AbstractBBCContext;
+//import com.alipay.antchain.bridge.commons.core.am.AuthMessageFactory;
+//import com.alipay.antchain.bridge.commons.core.am.IAuthMessage;
+//import com.alipay.antchain.bridge.commons.core.base.CrossChainMessageReceipt;
+//import com.alipay.antchain.bridge.commons.core.sdp.ISDPMessage;
+//import com.alipay.antchain.bridge.commons.core.sdp.SDPMessageFactory;
+//import com.alipay.antchain.bridge.commons.utils.codec.tlv.TLVTypeEnum;
+//import com.alipay.antchain.bridge.commons.utils.codec.tlv.TLVUtils;
+//import com.alipay.antchain.bridge.commons.utils.codec.tlv.annotation.TLVField;
+//import com.alipay.antchain.bridge.plugins.spi.bbc.AbstractBBCService;
+//import lombok.Getter;
+//import lombok.Setter;
+//import org.slf4j.Logger;
+//import org.slf4j.LoggerFactory;
+//
+//import java.io.ByteArrayOutputStream;
+//import java.io.IOException;
+//import java.util.Objects;
+//
+//public class ReadCrossChainMessageReceiptTest {
+//
+// private static final Logger log = LoggerFactory.getLogger(ReadCrossChainMessageReceiptTest.class);
+// AbstractBBCService service;
+// AppContract appContract;
+//
+// public ReadCrossChainMessageReceiptTest(AbstractBBCService service) {
+// this.service = service;
+// }
+// public static void run(AbstractBBCContext context, AbstractBBCService service){
+// RelayAmPrepare relayam = new RelayAmPrepare(service);
+// relayam.relayamprepare(context);
+// }
+//
+// public void readcrosschainmessagereceipt(AbstractBBCContext context) throws IOException {
+// RelayAmPrepare.run(context,service);
+// CrossChainMessageReceipt crossChainMessageReceipt = service.relayAuthMessage(getRawMsgFromRelayer());
+//
+//// waitForTxConfirmed(crossChainMessageReceipt.getTxhash(), ethereumBBCService.getWeb3j());
+//
+// // read receipt by txHash
+// CrossChainMessageReceipt crossChainMessageReceipt1 = service.readCrossChainMessageReceipt(crossChainMessageReceipt.getTxhash());
+// if (!crossChainMessageReceipt1.isConfirmed()) {
+// // 记录调试信息
+// log.warn("Transaction is not confirmed: " + crossChainMessageReceipt1.getTxhash());
+// }
+// if (!Objects.equals(crossChainMessageReceipt.isSuccessful(), crossChainMessageReceipt1.isSuccessful())) {
+// // 记录调试信息
+// log.warn("Success status mismatch: " + crossChainMessageReceipt.getTxhash());
+// }
+// }
+//
+// private byte[] getRawMsgFromRelayer() throws IOException {
+// ISDPMessage sdpMessage = SDPMessageFactory.createSDPMessage(
+// 1,
+// new byte[32],
+// "receiverDomain",
+// HexUtil.decodeHex(
+// String.format("000000000000000000000000%s", StrUtil.removePrefix(appContract.getContractAddress(), "0x"))
+// ),
+// -1,
+// "awesome antchain-bridge".getBytes()
+// );
+//
+// IAuthMessage am = AuthMessageFactory.createAuthMessage(
+// 1,
+// DigestUtil.sha256("senderID"),
+// 0,
+// sdpMessage.encode()
+// );
+//
+// MockResp resp = new MockResp();
+// resp.setRawResponse(am.encode());
+//
+// MockProof proof = new MockProof();
+// proof.setResp(resp);
+// proof.setDomain("senderDomain");
+//
+// byte[] rawProof = TLVUtils.encode(proof);
+//
+// ByteArrayOutputStream stream = new ByteArrayOutputStream();
+// stream.write(new byte[]{0, 0, 0, 0});
+//
+// int len = rawProof.length;
+// stream.write((len >>> 24) & 0xFF);
+// stream.write((len >>> 16) & 0xFF);
+// stream.write((len >>> 8) & 0xFF);
+// stream.write((len) & 0xFF);
+//
+// stream.write(rawProof);
+//
+// return stream.toByteArray();
+// }
+//
+// @Getter
+// @Setter
+// public static class MockResp {
+//
+// @TLVField(tag = 0, type = TLVTypeEnum.BYTES)
+// private byte[] rawResponse;
+// }
+//
+// @Getter
+// @Setter
+// public static class MockProof {
+//
+// @TLVField(tag = 5, type = TLVTypeEnum.BYTES)
+// private MockResp resp;
+//
+// @TLVField(tag = 9, type = TLVTypeEnum.STRING)
+// private String domain;
+// }
+//}
+package com.ali.antchain.core;
+
+import cn.hutool.crypto.digest.DigestUtil;
+import com.ali.antchain.abstarct.AbstractTester;
+import com.alipay.antchain.bridge.commons.bbc.AbstractBBCContext;
+import com.alipay.antchain.bridge.commons.bbc.syscontract.ContractStatusEnum;
+import com.alipay.antchain.bridge.commons.core.am.AuthMessageFactory;
+import com.alipay.antchain.bridge.commons.core.am.IAuthMessage;
+import com.alipay.antchain.bridge.commons.core.base.CrossChainMessageReceipt;
+import com.alipay.antchain.bridge.commons.core.sdp.ISDPMessage;
+import com.alipay.antchain.bridge.commons.core.sdp.SDPMessageFactory;
+import com.alipay.antchain.bridge.commons.utils.codec.tlv.TLVTypeEnum;
+import com.alipay.antchain.bridge.commons.utils.codec.tlv.TLVUtils;
+import com.alipay.antchain.bridge.commons.utils.codec.tlv.annotation.TLVField;
+import com.alipay.antchain.bridge.plugins.spi.bbc.AbstractBBCService;
+import lombok.Getter;
+import lombok.Setter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Arrays;
+
+public class ReadCrossChainMessageReceiptTest {
+
+ private static final Logger log = LoggerFactory.getLogger(ReadCrossChainMessageReceiptTest.class);
+
+ AbstractTester tester;
+ AbstractBBCService service;
+
+ public ReadCrossChainMessageReceiptTest(AbstractBBCService service, AbstractTester tester) {
+ this.service = service;
+ this.tester = tester;
+ }
+
+ public static void run(AbstractBBCService service, AbstractTester tester) {
+ ReadCrossChainMessageReceiptTest test = new ReadCrossChainMessageReceiptTest(service, tester);
+ test.relayauthmessagereciept_success();
+ }
+
+ public void relayauthmessagereciept_success() {
+
+ log.info("Start preparing for relay auth message receipt");
+ // 部署AM、SDP合约
+ prepare();
+ log.info("Preparation for relay auth message receipt completed");
+
+ try {
+ // relay am msg
+ AbstractBBCContext curCtx = service.getContext();
+
+ log.info("sdpContract: {}", curCtx.getSdpContract().getContractAddress());
+
+ byte[] targetIdentity = tester.deployApp(curCtx.getSdpContract().getContractAddress());
+
+ log.info("Deployed app with identity: " + Arrays.toString(targetIdentity));
+
+ CrossChainMessageReceipt receipt = service.relayAuthMessage(getRawMsgFromRelayer(targetIdentity));
+ tester.waitForTxConfirmed(receipt.getTxhash());
+
+ // read receipt by txHash
+ CrossChainMessageReceipt receipt1 = service.readCrossChainMessageReceipt(receipt.getTxhash());
+
+ log.info("Read receipt with txhash: " + receipt.getTxhash());
+
+ System.out.println("============================================");
+ System.out.println(receipt1.isConfirmed());
+ System.out.println("============================================");
+// Assert.assertTrue(receipt1.isConfirmed());
+ } catch (Exception e) {
+ // 异常处理
+ log.error("Error occurred during relay auth message receipt", e);
+ throw new RuntimeException("Error occurred during relay auth message receipt", e);
+ }
+ }
+
+
+ private void prepare() {
+ // set up am
+ service.setupAuthMessageContract();
+
+ // set up sdp
+ service.setupSDPMessageContract();
+
+ AbstractBBCContext curCtx = service.getContext();
+
+ // set protocol to am (sdp type: 0)
+ service.setProtocol(curCtx.getSdpContract().getContractAddress(), "0");
+
+ // set am to sdp
+ service.setAmContract(curCtx.getAuthMessageContract().getContractAddress());
+
+ // set local domain to sdp
+ service.setLocalDomain("receiverDomain");
+
+ // check contract ready
+ curCtx = service.getContext();
+
+ }
+
+ /**
+ * 伪造中继上的跨链消息
+ *
+ * @param targetIdentity
+ * @return
+ * @throws IOException
+ */
+ private byte[] getRawMsgFromRelayer(byte[] targetIdentity) {
+ try {
+ ISDPMessage sdpMessage = SDPMessageFactory.createSDPMessage(
+ 1,
+ new byte[32],
+ "receiverDomain",
+ targetIdentity,
+ -1,
+ "awesome antchain-bridge".getBytes()
+ );
+
+ IAuthMessage am = AuthMessageFactory.createAuthMessage(
+ 1,
+ DigestUtil.sha256("senderID"),
+ 0,
+ sdpMessage.encode()
+ );
+
+ MockResp resp = new MockResp();
+ resp.setRawResponse(am.encode());
+
+ MockProof proof = new MockProof();
+ proof.setResp(resp);
+ proof.setDomain("senderDomain");
+
+ byte[] rawProof = TLVUtils.encode(proof);
+
+ ByteArrayOutputStream stream = new ByteArrayOutputStream();
+ stream.write(new byte[]{0, 0, 0, 0});
+
+ int len = rawProof.length;
+ stream.write((len >>> 24) & 0xFF);
+ stream.write((len >>> 16) & 0xFF);
+ stream.write((len >>> 8) & 0xFF);
+ stream.write((len) & 0xFF);
+
+ stream.write(rawProof);
+
+ return stream.toByteArray();
+ } catch (Exception e) {
+ log.error("", e);
+ }
+
+ return new byte[0];
+ }
+
+
+ @Getter
+ @Setter
+ public static class MockProof {
+
+ @TLVField(tag = 5, type = TLVTypeEnum.BYTES)
+ private MockResp resp;
+
+ @TLVField(tag = 9, type = TLVTypeEnum.STRING)
+ private String domain;
+ }
+
+ @Getter
+ @Setter
+ public static class MockResp {
+
+ @TLVField(tag = 0, type = TLVTypeEnum.BYTES)
+ private byte[] rawResponse;
+ }
+}
diff --git a/antchain-bridge-plugin-test/src/main/java/com/ali/antchain/core/RelayAuthMessageTest.java b/antchain-bridge-plugin-test/src/main/java/com/ali/antchain/core/RelayAuthMessageTest.java
new file mode 100644
index 00000000..1baeec94
--- /dev/null
+++ b/antchain-bridge-plugin-test/src/main/java/com/ali/antchain/core/RelayAuthMessageTest.java
@@ -0,0 +1,157 @@
+package com.ali.antchain.core;
+
+import cn.hutool.crypto.digest.DigestUtil;
+import com.ali.antchain.abstarct.AbstractTester;
+import com.alipay.antchain.bridge.commons.bbc.AbstractBBCContext;
+import com.alipay.antchain.bridge.commons.bbc.syscontract.ContractStatusEnum;
+import com.alipay.antchain.bridge.commons.core.am.AuthMessageFactory;
+import com.alipay.antchain.bridge.commons.core.am.IAuthMessage;
+import com.alipay.antchain.bridge.commons.core.base.CrossChainMessageReceipt;
+import com.alipay.antchain.bridge.commons.core.sdp.ISDPMessage;
+import com.alipay.antchain.bridge.commons.core.sdp.SDPMessageFactory;
+import com.alipay.antchain.bridge.commons.utils.codec.tlv.TLVTypeEnum;
+import com.alipay.antchain.bridge.commons.utils.codec.tlv.TLVUtils;
+import com.alipay.antchain.bridge.commons.utils.codec.tlv.annotation.TLVField;
+import com.alipay.antchain.bridge.plugins.spi.bbc.AbstractBBCService;
+import lombok.Getter;
+import lombok.Setter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+public class RelayAuthMessageTest {
+
+ private static final Logger log = LoggerFactory.getLogger(RelayAuthMessageTest.class);
+
+ AbstractTester tester;
+ AbstractBBCService service;
+
+ public RelayAuthMessageTest(AbstractBBCService service, AbstractTester tester) {
+ this.service = service;
+ this.tester = tester;
+ }
+
+ public static void run(AbstractBBCService service, AbstractTester tester) {
+ RelayAuthMessageTest relayAuthMessageTest = new RelayAuthMessageTest(service, tester);
+ relayAuthMessageTest.relayauthmessage_success();
+ }
+
+ public void relayauthmessage_success() {
+ // 部署AM、SDP合约
+ prepare();
+
+ // 部署APP合约
+ AbstractBBCContext curCtx = service.getContext();
+
+
+
+ byte[] targetIdentity = tester.deployApp(curCtx.getSdpContract().getContractAddress());
+
+ CrossChainMessageReceipt receipt = service.relayAuthMessage(getRawMsgFromRelayer(targetIdentity));
+
+ System.out.println("======================================");
+ System.out.println(receipt.isSuccessful());
+
+
+ tester.waitForTxConfirmed(receipt.getTxhash());
+ }
+
+
+ private void prepare() {
+ // set up am
+ service.setupAuthMessageContract();
+
+ // set up sdp
+ service.setupSDPMessageContract();
+
+ AbstractBBCContext curCtx = service.getContext();
+
+ // set protocol to am (sdp type: 0)
+ service.setProtocol(curCtx.getSdpContract().getContractAddress(), "0");
+
+ // set am to sdp
+ service.setAmContract(curCtx.getAuthMessageContract().getContractAddress());
+
+ // set local domain to sdp
+ service.setLocalDomain("receiverDomain");
+
+ // check contract ready
+ curCtx = service.getContext();
+
+ }
+
+ /**
+ * 伪造中继上的跨链消息
+ *
+ * @param targetIdentity
+ * @return
+ * @throws IOException
+ */
+ private byte[] getRawMsgFromRelayer(byte[] targetIdentity) {
+ try {
+ ISDPMessage sdpMessage = SDPMessageFactory.createSDPMessage(
+ 1,
+ new byte[32],
+ "receiverDomain",
+ targetIdentity,
+ -1,
+ "awesome antchain-bridge".getBytes()
+ );
+
+ IAuthMessage am = AuthMessageFactory.createAuthMessage(
+ 1,
+ DigestUtil.sha256("senderID"),
+ 0,
+ sdpMessage.encode()
+ );
+
+ MockResp resp = new MockResp();
+ resp.setRawResponse(am.encode());
+
+ MockProof proof = new MockProof();
+ proof.setResp(resp);
+ proof.setDomain("senderDomain");
+
+ byte[] rawProof = TLVUtils.encode(proof);
+
+ ByteArrayOutputStream stream = new ByteArrayOutputStream();
+ stream.write(new byte[]{0, 0, 0, 0});
+
+ int len = rawProof.length;
+ stream.write((len >>> 24) & 0xFF);
+ stream.write((len >>> 16) & 0xFF);
+ stream.write((len >>> 8) & 0xFF);
+ stream.write((len) & 0xFF);
+
+ stream.write(rawProof);
+
+ return stream.toByteArray();
+ } catch (Exception e) {
+ log.error("", e);
+ }
+
+ return new byte[0];
+ }
+
+
+ @Getter
+ @Setter
+ public static class MockProof {
+
+ @TLVField(tag = 5, type = TLVTypeEnum.BYTES)
+ private MockResp resp;
+
+ @TLVField(tag = 9, type = TLVTypeEnum.STRING)
+ private String domain;
+ }
+
+ @Getter
+ @Setter
+ public static class MockResp {
+
+ @TLVField(tag = 0, type = TLVTypeEnum.BYTES)
+ private byte[] rawResponse;
+ }
+}
diff --git a/antchain-bridge-plugin-test/src/main/java/com/ali/antchain/core/SetAMContractAndLocaldomainTest.java b/antchain-bridge-plugin-test/src/main/java/com/ali/antchain/core/SetAMContractAndLocaldomainTest.java
new file mode 100644
index 00000000..18290b30
--- /dev/null
+++ b/antchain-bridge-plugin-test/src/main/java/com/ali/antchain/core/SetAMContractAndLocaldomainTest.java
@@ -0,0 +1,38 @@
+package com.ali.antchain.core;
+
+import com.ali.antchain.abstarct.AbstractTester;
+import com.alipay.antchain.bridge.commons.bbc.AbstractBBCContext;
+import com.alipay.antchain.bridge.commons.bbc.syscontract.ContractStatusEnum;
+import com.alipay.antchain.bridge.plugins.spi.bbc.AbstractBBCService;
+
+public class SetAMContractAndLocaldomainTest {
+
+ AbstractBBCService bbcService;
+
+ public SetAMContractAndLocaldomainTest(AbstractBBCService _bbcService) {
+ bbcService = _bbcService;
+ }
+
+ public static void run(AbstractBBCService _bbcService) {
+ SetAMContractAndLocaldomainTest setAMContractAndLocaldomainTest = new SetAMContractAndLocaldomainTest(_bbcService);
+
+ setAMContractAndLocaldomainTest.setAMContractAndLocaldomain_success();
+ }
+
+ public void setAMContractAndLocaldomain_success() {
+ // before
+ bbcService.setupAuthMessageContract();
+ bbcService.setupSDPMessageContract();
+ AbstractBBCContext curCtx = bbcService.getContext();
+
+ // set am to sdp
+ bbcService.setAmContract(curCtx.getAuthMessageContract().getContractAddress());
+
+ // set local domain to sdp
+ bbcService.setLocalDomain("receiverDomain");
+
+ // check after
+ curCtx = bbcService.getContext();
+ }
+
+}
diff --git a/antchain-bridge-plugin-test/src/main/java/com/ali/antchain/core/SetProtocolTest.java b/antchain-bridge-plugin-test/src/main/java/com/ali/antchain/core/SetProtocolTest.java
new file mode 100644
index 00000000..20177b8c
--- /dev/null
+++ b/antchain-bridge-plugin-test/src/main/java/com/ali/antchain/core/SetProtocolTest.java
@@ -0,0 +1,122 @@
+package com.ali.antchain.core;
+
+import com.ali.antchain.abstarct.AbstractTester;
+import com.alipay.antchain.bridge.commons.bbc.AbstractBBCContext;
+import com.alipay.antchain.bridge.commons.bbc.syscontract.ContractStatusEnum;
+import com.alipay.antchain.bridge.plugins.spi.bbc.AbstractBBCService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Stack;
+
+public class SetProtocolTest {
+
+ AbstractTester tester;
+ AbstractBBCService bbcService;
+
+ public SetProtocolTest(AbstractBBCService _bbcService, AbstractTester _tester) {
+ bbcService = _bbcService;
+ tester = _tester;
+ }
+
+ public static void run(AbstractBBCService _bbcService, AbstractTester _tester) throws Exception {
+ SetProtocolTest setProtocolTest = new SetProtocolTest(_bbcService, _tester);
+ setProtocolTest.setprotocol_success();
+ }
+
+// public void setprotocol_success() {
+// tester.getBbcLogger().info("start setprotocol_success test ...");
+//
+// // 1. prepare
+//// bbcService.startup(inContext);
+// bbcService.setupAuthMessageContract();
+// bbcService.setupSDPMessageContract();
+//
+// // 2. before set protocol
+// AbstractBBCContext curCtx = bbcService.getContext();
+// tester.getBbcLogger().info("before set_protocol, ctx: {}", curCtx);
+// Assert.assertNotNull(curCtx.getAuthMessageContract());
+// Assert.assertNotNull(curCtx.getAuthMessageContract().getContractAddress());
+// Assert.assertEquals(ContractStatusEnum.CONTRACT_DEPLOYED, curCtx.getAuthMessageContract().getStatus());
+//
+// // 3. execute set_protocol
+// bbcService.setProtocol(curCtx.getSdpContract().getContractAddress(),"0");
+//
+// // 4. after set protocol
+// // 4.1 Check whether the protocol address is correct.
+// String protocolAddr = tester.getProtocol(curCtx.getAuthMessageContract().getContractAddress());
+// Assert.assertEquals(curCtx.getSdpContract().getContractAddress(), protocolAddr);
+//
+// // 4.2 Check whether the contract status in the context is ready
+// curCtx = bbcService.getContext();
+// Assert.assertEquals(ContractStatusEnum.CONTRACT_READY, curCtx.getAuthMessageContract().getStatus());
+// }
+ public void setprotocol_success() throws Exception {
+ tester.getBbcLogger().info("start setprotocol_success test ...");
+
+ // 1. prepare
+// try {
+// bbcService.startup(inContext);
+// tester.getBbcLogger().info("After startup, ctx: {}", bbcService.getContext());
+// } catch (Exception e) {
+// tester.getBbcLogger().error("Failed to start up service", e);
+// throw e;
+// }
+
+ setupContracts();
+
+ // 2. before set protocol
+ AbstractBBCContext curCtx = bbcService.getContext();
+ logContextInfo(curCtx);
+ checkContractStatus(curCtx);
+
+ // 3. execute set_protocol
+ try {
+ bbcService.setProtocol(curCtx.getSdpContract().getContractAddress(), "0");
+ } catch (Exception e) {
+ tester.getBbcLogger().error("Failed to set protocol", e);
+ throw e;
+ }
+
+ // 4. after set protocol
+ // 4.1 Check whether the protocol address is correct.
+ try {
+ String protocolAddr = tester.getProtocol(curCtx.getAuthMessageContract().getContractAddress());
+ } catch (Exception e) {
+ tester.getBbcLogger().error("Failed to get protocol address", e);
+ throw e;
+ }
+
+ // 4.2 Check whether the contract status in the context is ready
+ try {
+ curCtx = bbcService.getContext();
+ } catch (Exception e) {
+ tester.getBbcLogger().error("Failed to check contract status", e);
+ throw e;
+ }
+ }
+
+ private void setupContracts() {
+ try {
+ bbcService.setupAuthMessageContract();
+ bbcService.setupSDPMessageContract();
+ tester.getBbcLogger().info("Contracts setup completed.");
+ } catch (Exception e) {
+ tester.getBbcLogger().error("Failed to setup contracts", e);
+ throw e;
+ }
+ }
+
+ private void logContextInfo(AbstractBBCContext ctx) {
+ tester.getBbcLogger().info("Current context: {}", ctx);
+ }
+
+ private void checkContractStatus(AbstractBBCContext ctx) {
+ try {
+ } catch (AssertionError e) {
+ tester.getBbcLogger().error("Contract status assertion failed", e);
+ throw e;
+ }
+ }
+
+}
diff --git a/antchain-bridge-plugin-test/src/main/java/com/ali/antchain/core/SetupAuthMessageContractTest.java b/antchain-bridge-plugin-test/src/main/java/com/ali/antchain/core/SetupAuthMessageContractTest.java
new file mode 100644
index 00000000..0bc9ca39
--- /dev/null
+++ b/antchain-bridge-plugin-test/src/main/java/com/ali/antchain/core/SetupAuthMessageContractTest.java
@@ -0,0 +1,57 @@
+package com.ali.antchain.core;
+
+import com.alipay.antchain.bridge.commons.bbc.syscontract.ContractStatusEnum;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import com.alipay.antchain.bridge.commons.bbc.AbstractBBCContext;
+import com.alipay.antchain.bridge.plugins.spi.bbc.AbstractBBCService;
+
+
+
+public class SetupAuthMessageContractTest {
+
+ private static final Logger log = LoggerFactory.getLogger(SetupAuthMessageContractTest.class);
+ AbstractBBCService service;
+
+ public SetupAuthMessageContractTest(AbstractBBCService service) {
+ this.service = service;
+ }
+
+ public static void run(AbstractBBCContext context, AbstractBBCService service){
+ SetupAuthMessageContractTest SetupAm = new SetupAuthMessageContractTest(service);
+ SetupAm.setupamcontract_success(context);
+ }
+
+ public void setupamcontract_success(AbstractBBCContext context) {
+ try {
+ service.startup(context);
+
+ // 部署AM合约前,上下文中合约状态为空
+ AbstractBBCContext curCtx = service.getContext();
+ log.info("before setup am contract, ctx: {}", curCtx);
+// Assert.assertNull(curCtx.getAuthMessageContract());
+ if (curCtx.getAuthMessageContract() != null) {
+ throw new IllegalStateException("Expected AuthMessageContract to be null before setup.");
+ }
+ service.setupAuthMessageContract();
+
+ // 部署AM合约后,上下文中合约状态为`CONTRACT_DEPLOYED`
+ curCtx = service.getContext();
+ log.info("after setup am contract, ctx: {}", curCtx);
+// Assert.assertNotNull(curCtx.getAuthMessageContract());
+// Assert.assertNotNull(curCtx.getAuthMessageContract().getContractAddress());
+// Assert.assertEquals(ContractStatusEnum.CONTRACT_DEPLOYED, curCtx.getAuthMessageContract().getStatus());
+ if (curCtx.getAuthMessageContract() == null) {
+ throw new IllegalStateException("AuthMessageContract should not be null after setup.");
+ }
+ if (curCtx.getAuthMessageContract().getContractAddress() == null) {
+ throw new IllegalStateException("Contract address should not be null after setup.");
+ }
+ if (!ContractStatusEnum.CONTRACT_DEPLOYED.equals(curCtx.getAuthMessageContract().getStatus())) {
+ throw new IllegalStateException("Contract status should be CONTRACT_DEPLOYED after setup.");
+ }
+ } catch (Exception e) {
+ log.error("Failed to setup authentication message contract", e);
+ }
+ }
+}
diff --git a/antchain-bridge-plugin-test/src/main/java/com/ali/antchain/core/SetupSDPMessageContractTest.java b/antchain-bridge-plugin-test/src/main/java/com/ali/antchain/core/SetupSDPMessageContractTest.java
new file mode 100644
index 00000000..d78a4a28
--- /dev/null
+++ b/antchain-bridge-plugin-test/src/main/java/com/ali/antchain/core/SetupSDPMessageContractTest.java
@@ -0,0 +1,43 @@
+package com.ali.antchain.core;
+
+import com.alipay.antchain.bridge.commons.bbc.AbstractBBCContext;
+import com.alipay.antchain.bridge.plugins.spi.bbc.AbstractBBCService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SetupSDPMessageContractTest {
+
+ private static final Logger log = LoggerFactory.getLogger(SetupAuthMessageContractTest.class);
+ AbstractBBCService service;
+
+ public SetupSDPMessageContractTest(AbstractBBCService service) {
+ this.service = service;
+ }
+
+ public static void run(AbstractBBCContext context, AbstractBBCService service){
+ SetupSDPMessageContractTest SetupSDP = new SetupSDPMessageContractTest(service);
+ SetupSDP.setupsdpcontract_success(context);
+ }
+
+ public void setupsdpcontract_success(AbstractBBCContext context) {
+ if (service == null) {
+ throw new IllegalStateException("Service is not initialized.");
+ }
+ try {
+ service.startup(context);
+
+ // set up am
+ service.setupAuthMessageContract();
+
+ // set up sdp
+ service.setupSDPMessageContract();
+
+ // get context
+ AbstractBBCContext ctx = service.getContext();
+
+ log.info("SDP contract status: {}", ctx.getSdpContract().getStatus());
+ } catch (Exception e) {
+ log.error("Error setting up SDP contract", e);
+ }
+ }
+}
diff --git a/antchain-bridge-plugin-test/src/main/java/com/ali/antchain/core/ShutDownTest.java b/antchain-bridge-plugin-test/src/main/java/com/ali/antchain/core/ShutDownTest.java
new file mode 100644
index 00000000..d5e649c3
--- /dev/null
+++ b/antchain-bridge-plugin-test/src/main/java/com/ali/antchain/core/ShutDownTest.java
@@ -0,0 +1,37 @@
+package com.ali.antchain.core;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import com.alipay.antchain.bridge.commons.bbc.AbstractBBCContext;
+import com.alipay.antchain.bridge.plugins.spi.bbc.AbstractBBCService;
+
+public class ShutDownTest {
+
+ private static final Logger log = LoggerFactory.getLogger(ShutDownTest.class);
+ AbstractBBCService service;
+
+ public ShutDownTest(AbstractBBCService service) {
+ this.service = service;
+ }
+
+ public static void run(AbstractBBCContext context, AbstractBBCService service){
+ ShutDownTest shutdown = new ShutDownTest(service);
+ shutdown.shutdown_success(context);
+ shutdown.shutdown_fail(context);
+ }
+
+ public void shutdown_success(AbstractBBCContext context){
+ try {
+ // 调用 shutdown关闭服务
+ service.startup(context);
+ service.shutdown();
+ } catch (Exception e) {
+ log.error("Failed to setup authentication message contract", e);
+ }
+ }
+
+ public void shutdown_fail(AbstractBBCContext context){
+ //TODO
+ System.out.println("shutdown fail...");
+ }
+}
diff --git a/antchain-bridge-plugin-test/src/main/java/com/ali/antchain/core/StartUpTest.java b/antchain-bridge-plugin-test/src/main/java/com/ali/antchain/core/StartUpTest.java
new file mode 100644
index 00000000..804f62ae
--- /dev/null
+++ b/antchain-bridge-plugin-test/src/main/java/com/ali/antchain/core/StartUpTest.java
@@ -0,0 +1,44 @@
+package com.ali.antchain.core;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import com.alipay.antchain.bridge.commons.bbc.AbstractBBCContext;
+import com.alipay.antchain.bridge.plugins.spi.bbc.AbstractBBCService;
+
+public class StartUpTest {
+
+ private static final Logger log = LoggerFactory.getLogger(StartUpTest.class);
+ AbstractBBCService service;
+
+ public StartUpTest(AbstractBBCService service) {
+ this.service = service;
+ }
+
+ public static void runBefore(AbstractBBCContext context, AbstractBBCService service){
+ StartUpTest startUpTest = new StartUpTest(service);
+ startUpTest.startup_success(context);
+ startUpTest.startup_fail(context);
+ }
+
+ public static void run(AbstractBBCContext context, AbstractBBCService service){
+ StartUpTest startUpTest = new StartUpTest(service);
+
+ startUpTest.startup_success(context);
+ }
+
+ public void startup_success(AbstractBBCContext context) {
+ try {
+ service.startup(context);
+ // 使用日志框架记录信息
+ log.info("Context: {}", service.getContext());
+ log.info("AuthMessageContract: {}", service.getContext().getAuthMessageContract());
+ log.info("SdpContract: {}", service.getContext().getSdpContract());
+ } catch (Exception e) {
+ // 异常处理
+ log.error("Error during startup test", e);
+ }
+ }
+ public void startup_fail(AbstractBBCContext context) {
+ //TODO
+ System.out.println("startup fail...");
+ }
+}
diff --git a/antchain-bridge-plugin-test/src/main/java/com/ali/antchain/testers/EthTester.java b/antchain-bridge-plugin-test/src/main/java/com/ali/antchain/testers/EthTester.java
new file mode 100644
index 00000000..f9495700
--- /dev/null
+++ b/antchain-bridge-plugin-test/src/main/java/com/ali/antchain/testers/EthTester.java
@@ -0,0 +1,285 @@
+package com.ali.antchain.testers;
+
+import cn.hutool.core.collection.ListUtil;
+import cn.hutool.core.util.HexUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.crypto.digest.DigestUtil;
+import com.ali.antchain.abi.AppContract;
+import com.ali.antchain.abi.AuthMsg;
+import com.ali.antchain.abstarct.AbstractTester;
+
+import com.alipay.antchain.bridge.commons.bbc.AbstractBBCContext;
+import com.alipay.antchain.bridge.commons.core.base.CrossChainMessage;
+import com.alipay.antchain.bridge.plugins.spi.bbc.AbstractBBCService;
+import lombok.Getter;
+import org.apache.commons.codec.binary.Hex;
+import org.web3j.abi.FunctionEncoder;
+import org.web3j.abi.datatypes.DynamicBytes;
+import org.web3j.abi.datatypes.Function;
+import org.web3j.abi.datatypes.Type;
+import org.web3j.abi.datatypes.Utf8String;
+import org.web3j.abi.datatypes.generated.Bytes32;
+import org.web3j.crypto.Credentials;
+import org.web3j.protocol.Web3j;
+import org.web3j.protocol.core.DefaultBlockParameterName;
+import org.web3j.protocol.core.methods.request.Transaction;
+import org.web3j.protocol.core.methods.response.EthCall;
+import org.web3j.protocol.core.methods.response.EthGetTransactionReceipt;
+import org.web3j.protocol.core.methods.response.EthSendTransaction;
+import org.web3j.protocol.core.methods.response.TransactionReceipt;
+import org.web3j.tx.RawTransactionManager;
+import org.web3j.tx.TransactionManager;
+import org.web3j.tx.gas.DefaultGasProvider;
+
+import java.lang.reflect.Field;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+
+public class EthTester extends AbstractTester {
+
+ private static final String WEB3J = "web3j";
+ private static final String CREDENTIALS = "credentials";
+ private static final String TRANSACTIONMANAGER = "rawTransactionManager";
+
+ private String remote_app_contract;
+
+ private static final int MAX_TX_RESULT_QUERY_TIME = 100;
+
+ @Getter
+ Web3j web3jClient;
+
+ AppContract appContract;
+
+ Credentials credentials;
+
+ RawTransactionManager rawTransactionManager;
+
+ // bbcService 启动后传入才是有意义的
+ public EthTester(AbstractBBCService started_service) {
+
+ try {
+ Class> serviceClazz = started_service.getClass();
+
+ // 1. 从 service 中获取 web3j 客户端
+ Field web3jField = serviceClazz.getDeclaredField(WEB3J);
+ // 允许访问私有字段
+ web3jField.setAccessible(true);
+ Object web3jObj = web3jField.get(started_service);
+ if (web3jObj instanceof Web3j) {
+ web3jClient = (Web3j) web3jObj;
+ }
+
+ // 2. 从 service 中获取 credentials
+ Field credentialsField = serviceClazz.getDeclaredField(CREDENTIALS);
+ credentialsField.setAccessible(true);
+ Object credentialsObj = credentialsField.get(started_service);
+ if (credentialsObj instanceof Credentials) {
+ credentials = (Credentials) credentialsObj;
+ }
+
+ // 3. 从 service 中获取 rawTransactionManager
+ Field rawTransactionManagerField = serviceClazz.getDeclaredField(TRANSACTIONMANAGER);
+ rawTransactionManagerField.setAccessible(true);
+ Object rawTransactionManagerObj = rawTransactionManagerField.get(started_service);
+ if (rawTransactionManagerObj instanceof TransactionManager) {
+ rawTransactionManager = (RawTransactionManager) rawTransactionManagerObj;
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+
+ @Override
+ public String getProtocol(String amContractAddr) {
+ try {
+ return AuthMsg.load(
+ amContractAddr,
+ web3jClient,
+ credentials,
+ new DefaultGasProvider())
+ .getProtocol(BigInteger.ZERO)
+ .send();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public byte[] deployApp(String protocolAddr) {
+ try {
+ // 1. 部署合约
+ appContract = AppContract.deploy(
+ web3jClient,
+ rawTransactionManager,
+ new DefaultGasProvider()
+ ).send();
+
+ System.out.println("address: "+appContract.getContractAddress());
+
+ this.remote_app_contract = appContract.getContractAddress();
+
+ byte[] appContractAddr = HexUtil.decodeHex(String.format("000000000000000000000000%s", StrUtil.removePrefix(appContract.getContractAddress(), "0x")));
+
+ // 2. 设置app合约中的protocol合约地址
+ TransactionReceipt receipt = appContract.setProtocol(protocolAddr).send();
+ if (receipt.isStatusOK()) {
+ getBbcLogger().info("set protocol({}) to app contract({})",
+ appContract.getContractAddress(),
+ protocolAddr);
+ } else {
+ throw new Exception(String.format("failed to set protocol(%s) to app contract(%s)",
+ appContract.getContractAddress(),
+ protocolAddr));
+ }
+
+ return appContractAddr;
+ } catch (Exception e) {
+ System.out.println("err: "+e.getMessage());
+ // 递归输出 e 的 cause
+ Throwable cause = e.getCause();
+ while (cause != null) {
+ System.out.println("cause: "+cause.getMessage());
+ cause = cause.getCause();
+ }
+ getBbcLogger().error("", e);
+ }
+
+ return null;
+ }
+
+
+ @Override
+ public String sendMsg(AbstractBBCService service) {
+
+ String txhash = "";
+ // 3. query latest height
+ long height1 = service.queryLatestHeight();
+
+ try {
+ // 部署APP合约
+ AbstractBBCContext curCtx = service.getContext();
+ deployApp(curCtx.getSdpContract().getContractAddress());
+
+ // 1. create function
+ List inputParameters = new ArrayList<>();
+ inputParameters.add(new Utf8String("remoteDomain"));
+ inputParameters.add(new Bytes32(DigestUtil.sha256(remote_app_contract)));
+ inputParameters.add(new DynamicBytes("UnorderedCrossChainMessage".getBytes()));
+ Function function = new Function(
+ AppContract.FUNC_SENDUNORDEREDMESSAGE, // function name
+ inputParameters, // inputs
+ Collections.emptyList() // outputs
+ );
+ String encodedFunc = FunctionEncoder.encode(function);
+
+ // 获取service的class
+ Class> serviceClazz = service.getClass();
+
+ // 2.1 从 service 中获取 web3j
+ Field web3jField = null;
+ web3jField = serviceClazz.getDeclaredField(WEB3J);
+
+ // 允许访问私有字段
+ web3jField.setAccessible(true);
+ Object web3jObj = null;
+ web3jObj = web3jField.get(service);
+ if (web3jObj instanceof Web3j) {
+ web3jClient = (Web3j) web3jObj;
+ }
+
+ // 2.2 从 service 中获取 credentials
+ Field credentialsField = serviceClazz.getDeclaredField(CREDENTIALS);
+ credentialsField.setAccessible(true);
+ Object credentialsObj = credentialsField.get(service);
+
+ if (credentialsObj instanceof Credentials) {
+ credentials = (Credentials) credentialsObj;
+ }
+
+
+ // 2.4 调用ethcall
+ EthCall call = web3jClient.ethCall(
+ Transaction.createEthCallTransaction(
+ credentials.getAddress(),
+ appContract.getContractAddress(),
+ encodedFunc
+ ),
+ DefaultBlockParameterName.LATEST
+ ).send();
+
+ // 2.5 获取rawTransactionManager
+ Field rawTransactionManagerField = serviceClazz.getDeclaredField(TRANSACTIONMANAGER);
+ rawTransactionManagerField.setAccessible(true);
+ Object rawTransactionManagerObj = rawTransactionManagerField.get(service);
+ if (rawTransactionManagerObj instanceof TransactionManager) {
+ rawTransactionManager = (RawTransactionManager) rawTransactionManagerObj;
+ }
+
+ // 2.6 发送交易
+ EthSendTransaction ethSendTransaction = rawTransactionManager.sendTransaction(
+ BigInteger.valueOf(4100000000L),
+ BigInteger.valueOf(10000000L),
+ appContract.getContractAddress(),
+ encodedFunc,
+ BigInteger.ZERO
+ );
+ txhash = ethSendTransaction.getTransactionHash();
+ getBbcLogger().info("send unordered msg tx {}", ethSendTransaction.getTransactionHash());
+
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ waitForTxConfirmed(txhash);
+
+ long height2 = service.queryLatestHeight();
+
+
+ // 4. read cc msg
+ List messageList = ListUtil.toList();
+ for (long i = height1; i <= height2; i++) {
+ messageList.addAll(service.readCrossChainMessagesByHeight(i));
+ }
+// System.out.println("height1: "+height1);
+// System.out.println("height2: "+height2);
+// System.out.println("size of messageList: "+messageList.size());
+
+// Assert.assertEquals(1, messageList.size());
+// Assert.assertEquals(CrossChainMessage.CrossChainMessageType.AUTH_MSG, messageList.get(0).getType());
+ if (messageList.size() != 1 || messageList.get(0).getType() != CrossChainMessage.CrossChainMessageType.AUTH_MSG) {
+ throw new RuntimeException("failed to send msg");
+ }
+
+ System.out.println("txHash: "+txhash);
+ return txhash;
+
+ }
+
+ @Override
+ public void waitForTxConfirmed(String txhash) {
+ try {
+ for (int i = 0; i < MAX_TX_RESULT_QUERY_TIME; i++) {
+ Optional receiptOptional = web3jClient.ethGetTransactionReceipt(txhash).send().getTransactionReceipt();
+ if (receiptOptional.isPresent() && receiptOptional.get().getBlockNumber().longValue() > 0L) {
+ if (receiptOptional.get().getStatus().equals("0x1")) {
+ getBbcLogger().info("tx {} has been confirmed as success", txhash);
+ } else {
+ getBbcLogger().error("tx {} has been confirmed as failed", txhash);
+ }
+ break;
+ }
+ Thread.sleep(1_000);
+ }
+
+ EthGetTransactionReceipt ethGetTransactionReceipt = web3jClient.ethGetTransactionReceipt(txhash).send();
+ TransactionReceipt transactionReceipt = ethGetTransactionReceipt.getTransactionReceipt().get();
+ } catch (Exception e) {
+ getBbcLogger().error("", e);
+ }
+
+ }
+}
diff --git a/antchain-bridge-plugin-test/src/test/java/com/ali/antchain/EthPluginTestToolTest.java b/antchain-bridge-plugin-test/src/test/java/com/ali/antchain/EthPluginTestToolTest.java
new file mode 100644
index 00000000..d77bdc75
--- /dev/null
+++ b/antchain-bridge-plugin-test/src/test/java/com/ali/antchain/EthPluginTestToolTest.java
@@ -0,0 +1,82 @@
+package com.ali.antchain;
+
+
+import com.alipay.antchain.bridge.commons.bbc.AbstractBBCContext;
+import com.alipay.antchain.bridge.commons.bbc.DefaultBBCContext;
+
+import com.alipay.antchain.bridge.plugins.ethereum.EthereumBBCService;
+import com.alipay.antchain.bridge.plugins.spi.bbc.AbstractBBCService;
+import junit.framework.TestCase;
+import org.junit.Before;
+import org.junit.Test;
+
+public class EthPluginTestToolTest extends TestCase {
+
+ // 测试入参
+ AbstractBBCContext inContext;
+ AbstractBBCService bbcService;
+
+ // 测试主体结构
+ EthPluginTestTool ethTestTool;
+ String product;
+ String url = "http://127.0.0.1:8545";
+ String key = "0xef56b373888bae5e370852bfc8a0e7b98bc4a75d32f7428eca76c2bd7e8a2a56";
+ long gasPrice = 2300000000L;
+ long gasLimit = 3000000;
+
+ String testConfig = "{\"gasLimit\":"+gasLimit+",\"gasPrice\":"+gasPrice+",\"privateKey\":\""+key+"\",\"url\":\""+url+"\"}";
+
+ @Before
+ public void setUp() throws Exception {
+ inContext = new DefaultBBCContext();
+ inContext.setConfForBlockchainClient(testConfig.getBytes());
+ bbcService = new EthereumBBCService();
+
+ ethTestTool = new EthPluginTestTool(inContext, bbcService);
+ }
+
+ public void testStartupTest() {
+ ethTestTool.startupTest();
+ }
+
+ public void testShutdownTest() {
+ ethTestTool.shutdownTest();
+ }
+
+ public void testGetcontextTest() {
+ ethTestTool.getcontextTest();
+ }
+
+ public void testSetupamcontractTest() {
+ ethTestTool.setupamcontractTest();
+ }
+
+ public void testSetupsdpcontractTest() {
+ ethTestTool.setupsdpcontractTest();
+ }
+
+ @Test
+ public void testSetprotocolTest() throws Exception {
+ ethTestTool.setprotocolTest();
+ }
+@Test
+ public void testQuerysdpmessageseqTest() {
+ ethTestTool.querysdpmessageseqTest();
+ }
+
+ public void testSetamcontractandlocaldomainTest() {
+ ethTestTool.setamcontractandlocaldomainTest();
+ }
+
+ public void testReadcrosschainmessagereceiptTest() {
+ ethTestTool.readcrosschainmessagereceiptTest();
+ }
+
+ public void testReadcrosschainmessagebyheightTest() {
+ ethTestTool.readcrosschainmessagebyheightTest();
+ }
+
+ public void testRelayauthmessageTest() {
+ ethTestTool.relayauthmessageTest();
+ }
+}
\ No newline at end of file
diff --git a/antchain-bridge-plugin-test/src/test/java/com/ali/antchain/EthTest.java b/antchain-bridge-plugin-test/src/test/java/com/ali/antchain/EthTest.java
new file mode 100644
index 00000000..27c3c4b8
--- /dev/null
+++ b/antchain-bridge-plugin-test/src/test/java/com/ali/antchain/EthTest.java
@@ -0,0 +1,72 @@
+//package com.ali.antchain;
+//
+//import com.ali.antchain.EthPluginTestTool;
+//import com.ali.antchain.lib.service.EthereumBBCService;
+//import com.alipay.antchain.bridge.commons.bbc.AbstractBBCContext;
+//import com.alipay.antchain.bridge.commons.bbc.DefaultBBCContext;
+//import com.alipay.antchain.bridge.plugins.spi.bbc.AbstractBBCService;
+//import junit.framework.TestCase;
+//import org.junit.Before;
+//import org.junit.Test;
+//
+//public class EthTest extends TestCase {
+// EthPluginTestTool ethtest;
+// AbstractBBCService service;
+// AbstractBBCContext context;
+// String product;
+// String url = "http://127.0.0.1:7545";
+// String key = "0xc52e50920ed5e3548e22152fb0e5d5fd13d49ab5bad98212a73027d6e1f1e7ef";
+// long gasPrice = 2300000000L;
+// long gasLimit = 3000000;
+// @Before
+// public void setUp() throws Exception {
+// service = new EthereumBBCService();
+// context = new DefaultBBCContext();
+// product = "simple-ethereum";
+// ethtest = new EthPluginTestTool(context,service,product);
+// ethtest.EthConfigInit(url,key,gasPrice,gasLimit);
+// }
+// @Test
+// public void testStartup() throws Exception {
+// ethtest.startup();
+// }
+//
+// public void testShutdown() throws Exception {
+// ethtest.shutdown();
+// }
+//
+// public void testGetcontext() throws Exception {
+// ethtest.getcontext();
+// }
+//
+// public void testSetupAmContract() throws Exception {
+// ethtest.setupamcontract();
+// }
+//
+// public void testSetupSDPContract() throws Exception {
+// ethtest.setupsdpcontract();
+// }
+//
+// public void testQuerySDPMessageSeq() throws Exception {
+// ethtest.querysdpmessageseq();
+// }
+//
+// public void testSetAmContractAndLocalDomain() throws Exception {
+// ethtest.setamcontractandlocaldomain();
+// }
+//
+// public void testSetProtocol() throws Exception {
+// ethtest.setamcontractandlocaldomain();
+// }
+//
+// public void testRelayamprepare() throws Exception {
+// ethtest.relayamprepare();
+// }
+// public void testReadcrosschainmessagereceipt() throws Exception {
+// ethtest.readcrosschainmessagereceipt();
+// }
+//
+// public void testSetprotocol() throws Exception {
+// ethtest.setprotocol();
+// }
+//}
\ No newline at end of file
diff --git a/antchain-bridge-plugin-test/src/test/java/com/ali/antchain/TestPlugs.java b/antchain-bridge-plugin-test/src/test/java/com/ali/antchain/TestPlugs.java
new file mode 100644
index 00000000..49928b9e
--- /dev/null
+++ b/antchain-bridge-plugin-test/src/test/java/com/ali/antchain/TestPlugs.java
@@ -0,0 +1,50 @@
+//package com.ali.antchain;
+//
+//import com.ali.antchain.abstarct.IPluginTestTool;
+//import com.alipay.antchain.bridge.commons.bbc.AbstractBBCContext;
+//import com.alipay.antchain.bridge.plugins.spi.bbc.AbstractBBCService;
+//import junit.framework.TestCase;
+//
+//public class TestPlugs extends TestCase {
+//
+// String product = "simple-ethereum";
+// String url = "http://127.0.0.1:7545";
+// String key = "0x45cfa3b6addf98274bfd9e3482a695406c7dcc99e1588bd6e0127b8fc06ae916";
+// long gasPrice = 2300000000L;
+// long gasLimit = 3000000;
+// AbstractBBCContext context;
+// AbstractBBCService service;
+//
+// IPluginTestTool plugsTest = new IPluginTestTool(context,service,product);
+//
+// public void testStartup() throws Exception {
+// plugsTest.startup();
+// }
+//
+// public void testShutdown() throws Exception {
+// plugsTest.shutdown();
+// }
+//
+// public void testGetcontext() throws Exception {
+// plugsTest.getcontext();
+// }
+//
+// public void testSetupamcontract() throws Exception {
+// plugsTest.setupamcontract();
+// }
+//
+// public void testQuerysdpmessageseq() throws Exception {
+// plugsTest.querysdpmessageseq();
+// }
+//
+// public void testSetprotocol() throws Exception {
+// plugsTest.setprotocol();
+// }
+//
+//
+// public void testSetamcontractandlocaldomain() throws Exception {
+// plugsTest.setamcontractandlocaldomain();
+// }
+//
+//
+//}
\ No newline at end of file
diff --git a/pluginset/chainmaker/offchain-plugin/src/main/java/com/alipay/antchain/bridge/plugins/chainmaker/ChainMakerBBCService.java b/pluginset/chainmaker/offchain-plugin/src/main/java/com/alipay/antchain/bridge/plugins/chainmaker/ChainMakerBBCService.java
index d1276c03..b6247b2c 100755
--- a/pluginset/chainmaker/offchain-plugin/src/main/java/com/alipay/antchain/bridge/plugins/chainmaker/ChainMakerBBCService.java
+++ b/pluginset/chainmaker/offchain-plugin/src/main/java/com/alipay/antchain/bridge/plugins/chainmaker/ChainMakerBBCService.java
@@ -35,12 +35,10 @@
import org.chainmaker.pb.common.*;
import org.chainmaker.pb.config.ChainConfigOuterClass;
import org.chainmaker.sdk.*;
-import org.chainmaker.sdk.config.SdkConfig;
+import org.chainmaker.sdk.config.*;
import org.chainmaker.sdk.crypto.ChainMakerCryptoSuiteException;
-import org.chainmaker.sdk.utils.CryptoUtils;
-import org.chainmaker.sdk.utils.SdkUtils;
+import org.chainmaker.sdk.utils.*;
import org.chainmaker.sdk.utils.Utils;
-import org.chainmaker.sdk.utils.UtilsException;
import org.web3j.abi.*;
import org.web3j.abi.datatypes.*;
import org.web3j.abi.datatypes.generated.Bytes32;
@@ -48,6 +46,7 @@
import org.web3j.protocol.core.methods.response.Log;
import java.io.IOException;
+import java.lang.reflect.Field;
import java.math.BigInteger;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
@@ -124,36 +123,41 @@ public void startup(AbstractBBCContext abstractBBCContext) {
getBBCLogger().info("[startup] ChainMaker startup with context: {}",
new String(abstractBBCContext.getConfForBlockchainClient()));
- if (ObjectUtil.isNull(abstractBBCContext)) {
- throw new RuntimeException("null bbc context");
- }
- if (ObjectUtil.isEmpty(abstractBBCContext.getConfForBlockchainClient())) {
- throw new RuntimeException("empty blockchain client conf");
- }
-
- // 1. Obtain the configuration information
try {
- config = ChainMakerConfig.fromJsonString(new String(abstractBBCContext.getConfForBlockchainClient()));
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- if (StrUtil.isEmpty(config.getSdkConfig())) {
- throw new RuntimeException("SdkConfig is empty");
- }
- if (config.getAdminTlsKeyPaths().isEmpty()) {
- throw new RuntimeException("AdminTlsKeyPath is empty");
- }
- if (config.getAdminTlsKeyPaths().size() != config.getAdminTlsCertPaths().size()) {
- throw new RuntimeException("AdminTlsCertPaths size not match");
- }
- if (config.getAdminKeyPaths().isEmpty()) {
- throw new RuntimeException("AdminKeyPath is empty");
- }
- if (config.getAdminKeyPaths().size() != config.getAdminKeyPaths().size()) {
- throw new RuntimeException("AdminKeyPaths size not match");
- }
- if (config.getOrgIds().isEmpty()) {
- throw new RuntimeException("OrgId is empty");
+ if (ObjectUtil.isNull(abstractBBCContext)) {
+ throw new RuntimeException("null bbc context");
+ }
+ if (ObjectUtil.isEmpty(abstractBBCContext.getConfForBlockchainClient())) {
+ throw new RuntimeException("empty blockchain client conf");
+ }
+
+ // 1. Obtain the configuration information
+ try {
+ config = ChainMakerConfig.fromJsonString(new String(abstractBBCContext.getConfForBlockchainClient()));
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ if (StrUtil.isEmpty(config.getSdkConfig())) {
+ throw new RuntimeException("SdkConfig is empty");
+ }
+ if (config.getAdminTlsKeyPaths().isEmpty()) {
+ throw new RuntimeException("AdminTlsKeyPath is empty");
+ }
+ if (config.getAdminTlsKeyPaths().size() != config.getAdminTlsCertPaths().size()) {
+ throw new RuntimeException("AdminTlsCertPaths size not match");
+ }
+ if (config.getAdminKeyPaths().isEmpty()) {
+ throw new RuntimeException("AdminKeyPath is empty");
+ }
+ if (config.getAdminKeyPaths().size() != config.getAdminKeyPaths().size()) {
+ throw new RuntimeException("AdminKeyPaths size not match");
+ }
+ if (config.getOrgIds().isEmpty()) {
+ throw new RuntimeException("OrgId is empty");
+ }
+ } catch (Exception e) {
+ getBBCLogger().error("[startup] Obtain the configuration information exception", e);
+ throw e;
}
// 2. Connect to the chainmaker network
@@ -161,13 +165,24 @@ public void startup(AbstractBBCContext abstractBBCContext) {
SdkConfig sdkConfig = gson.fromJson(config.getSdkConfig(), SdkConfig.class);
try {
chainManager = ChainManager.getInstance();
- chainClient = chainManager.getChainClient(sdkConfig.getChainClient().getChainId());
- if (chainClient == null) {
- chainClient = chainManager.createChainClient(sdkConfig);
+
+ // 移除chainManager中缓存的链sdk
+ for (Field field : ChainManager.class.getDeclaredFields()) {
+ if (StrUtil.equals(field.getName(), "chains")) {
+ field.setAccessible(true);
+ Map map = (Map) field.get(chainManager);
+ map.remove(sdkConfig.getChainClient().getChainId());
+ getBBCLogger().info("[startup] chainManager remove chain, id: {}",
+ sdkConfig.getChainClient().getChainId());
+ break;
+ }
}
- } catch (ChainClientException | RpcServiceClientException | UtilsException |
- ChainMakerCryptoSuiteException ex) {
- throw new RuntimeException(ex);
+
+ chainClient = chainManager.createChainClient(sdkConfig);
+ } catch (ChainClientException | RpcServiceClientException | UtilsException | ChainMakerCryptoSuiteException |
+ IllegalAccessException e) {
+ getBBCLogger().error("[startup] Connect to the chainmaker network exception", e);
+ throw new RuntimeException(e);
}
// 3. get client address of chainClient
@@ -176,6 +191,7 @@ public void startup(AbstractBBCContext abstractBBCContext) {
chainClient.getClientUser().getCertificate(),
ChainConfigOuterClass.AddrType.ETHEREUM);
} catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
+ getBBCLogger().error("[startup] fail to get client address", e);
throw new RuntimeException("fail to get client address", e);
}
@@ -191,6 +207,7 @@ public void startup(AbstractBBCContext abstractBBCContext) {
config.getAdminTlsKeyPaths().get(i),
config.getAdminTlsCertPaths().get(i)));
} catch (ChainMakerCryptoSuiteException e) {
+ getBBCLogger().error("[startup] fail to create admin user for endorsement", e);
throw new RuntimeException("fail to create admin user for endorsement", e);
}
}
@@ -198,6 +215,9 @@ public void startup(AbstractBBCContext abstractBBCContext) {
// 3. set context
this.bbcContext = new ChainMakerContext(abstractBBCContext);
+ this.bbcContext.setAmContractName(this.config.getAmContractName());
+ this.bbcContext.setSdpContractName(this.config.getSdpContractName());
+
// 4. set the pre-deployed contracts into context
if (ObjectUtil.isNull(abstractBBCContext.getAuthMessageContract())
&& StrUtil.isNotEmpty(this.config.getAmContractAddressDeployed())) {
@@ -215,7 +235,17 @@ public void startup(AbstractBBCContext abstractBBCContext) {
this.bbcContext.setSdpContract(sdpContract);
}
- getBBCLogger().info("ChainMaker startup success");
+ getBBCLogger().info("ChainMaker startup success, (" +
+ "amAddr: {}, amStatus: {}, " +
+ "sdpAddr: {}, sdpStatus: {}," +
+ "amName: {}, sdpName: {})",
+ this.bbcContext.getAuthMessageContract() != null ? this.bbcContext.getAuthMessageContract().getContractAddress() : "",
+ this.bbcContext.getAuthMessageContract() != null ? this.bbcContext.getAuthMessageContract().getStatus() : "",
+ this.bbcContext.getSdpContract() != null ? this.bbcContext.getSdpContract().getContractAddress() : "",
+ this.bbcContext.getSdpContract() != null ? this.bbcContext.getSdpContract().getStatus() : "",
+ this.bbcContext.getAmContractName() != null ? this.bbcContext.getAmContractName() : "",
+ this.bbcContext.getSdpContractName() != null ? this.bbcContext.getSdpContractName() : ""
+ );
}
@Override
@@ -282,6 +312,8 @@ public void setupAuthMessageContract() {
authMessageContract.setStatus(ContractStatusEnum.CONTRACT_DEPLOYED);
bbcContext.setAuthMessageContract(authMessageContract);
bbcContext.setAmContractName(contract.getName());
+ config.setAmContractName(contract.getName());
+ bbcContext.setConfForBlockchainClient(config.toJsonString().getBytes());
getBBCLogger().info("setup am contract successful: {}-{}",
contract.getName(),
contract.getAddress());
@@ -312,6 +344,8 @@ public void setupSDPMessageContract() {
sdpContract.setStatus(ContractStatusEnum.CONTRACT_DEPLOYED);
bbcContext.setSdpContract(sdpContract);
bbcContext.setSdpContractName(contract.getName());
+ config.setSdpContractName(contract.getName());
+ bbcContext.setConfForBlockchainClient(config.toJsonString().getBytes());
getBBCLogger().info("setup sdp contract successful: {}-{}",
contract.getName(),
contract.getAddress());