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());