diff --git a/.gitignore b/.gitignore
index f02a524..c0b16a4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -24,3 +24,4 @@ hs_err_pid*
replay_pid*
/.idea/
logs
+/r-facade/target/
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index a8cfefc..3143d0a 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -2,19 +2,18 @@
## Branch Strategy
-We recommend that developers following the rules [here](https://jeffkreeftmeijer.com/git-flow/git-flow.png).
+We recommend that developers following the `Trunk-based development` rules [here](https://trunkbaseddevelopment.com/).
-- Branch `main` with stable code and tags on it.
-- Branch `develop` for "next release" development.
+- Trunk branch `main` with stable code.
- Feature branches start with prefix `feat/`
- Release branches start with prefix `release/`
-- Hotfix branches start with prefix `hotfix/`
+- Hotfix branches start with prefix `hotfix/` or `fix/`
## Contributing
- Fork the repository or create branches.
- Checkout your branch like a feature or bugfix.
-- Make a pull request to the `develop` branch of this repository.
+- Make a pull request to the `main` branch of this repository.
- Wait for review and PR merged.
---
diff --git a/README.md b/README.md
index 7b88a7a..711f470 100644
--- a/README.md
+++ b/README.md
@@ -33,6 +33,10 @@ AntChain Bridge Relayer将功能实现分为两部分,分别为通信和可信
**确保安装了AntChain Bridge Plugin SDK,详情请[见](https://github.com/AntChainOpenLabs/AntChainBridgePluginSDK?tab=readme-ov-file#%E6%9E%84%E5%BB%BA)*
+> [!IMPORTANT]
+>
+> 注意当前Relayer要求SDK版本为0.3.0
+
### 编译
在项目根目录运行maven命令即可:
@@ -80,7 +84,7 @@ wget -qO- https://get.docker.com/ | bash
然后下载MySQL镜像并启动容器,注意这里指定了时区为`+08:00`,请修改为您的时区。
```
-docker run -itd --name mysql-test -p 3306:3306 -e MYSQL_ROOT_PASSWORD='YOUR_PWD' mysql --default-authentication-plugin=mysql_native_password --default_time_zone +08:00
+docker run -itd --name mysql-test -p 3306:3306 -e MYSQL_ROOT_PASSWORD='YOUR_PWD' mysql:8 --mysql-native-password=ON --default_time_zone +08:00
```
然后下载Redis镜像并启动容器:
@@ -333,7 +337,37 @@ relayer:
{"destDomain":{"domain":"domain.web3.net","domainSpace":false},"destRelayer":{"netAddressList":["https://localhost:8082"],"relayerCert":{"credentialSubject":"AADVAAAAAAAD...hNDRjY2UifV19","credentialSubjectInstance":{"applicant":{"rawId":"ZGlkOmJpZDplZmJ...1b1FHWDZMVUd3Zw==","type":"BID"},"name":"relay","rawSubjectPublicKey":"r2Ze5VBjX...yWnSkTM4=","subject":"eyJwdWJsaWNLZXkiO...jZSJ9XX0=","subjectInfo":"eyJwd...J9XX0=","subjectPublicKey":{"algorithm":"Ed25519","encoded":"MCowBQYDK2V...qJKDyWnSkTM4=","format":"X.509","pointEncoding":"r2Ze5V...ifV19","expirationDate":1733811853,"id":"did:bid:efGeAv4Jr7V2FSyun77m4xTFmTDfG8nh","issuanceDate":1702275853,"issuer":{"rawId":"ZGlkOmJpZDpl...NTdtRENwQw==","type":"BID"},"proof":{"certHash":"Gaw4gcwXzn2i...K6HaPWBxXM=","hashAlgo":"SM3","rawProof":"kMZ/tvT19Tk...TQ4IVYlXkYjSBw==","sigAlgo":"Ed25519"},"type":"RELAYER_CERTIFICATE","version":"1"},"relayerCertId":"did:bid:efGeAv4Jr7V2FSyun77m4xTFmTDfG8nh"}}
```
-
+
+### 启动Embedded BCDNS
+
+> [!IMPORTANT]
+> Relayer从0.3.0版本开始支持启动内嵌的BCDNS服务,注意Relayer使用的Embedded BCDNS相关依赖的版本。
+
+Embedded BCDNS是内嵌在服务内部的BCDNS,提供中心化的权威服务,会使用一把私钥为跨链网络提供认证、准入等功能,按照服务端要求可以通过简单配置接入BCDNS,具体内容可以参考[这里](https://github.com/AntChainOpenLabs/AntChainBridgePluginSDK/tree/main/bcdns-services/embedded-bcdns/README.md)。
+
+通过在中继的配置增加下面一项,重启即可启动Embedded BCDNS,详细的配置可以参考AntChain Bridge SDK关于如何使用Embedded的[README](https://github.com/AntChainOpenLabs/AntChainBridgePluginSDK/tree/main/bcdns-services/embedded-bcdns/README.md)。
+
+```yaml
+acb:
+ bcdns:
+ embedded:
+ server-on: true
+ root-private-key-file: file:/path/to/embedded-bcdns-root-private-key.key
+ root-cert-file: file:/path/to/embedded-bcdns-root.crt
+```
+
+上面配置中的`root-private-key-file`和`root-cert-file`,可以通过CLI命令`generate-bcdns-root-cert`来生成,详细用法参考[这里](r-cli/README.md#5.5 生成BCDNS根证书)。
+
+需要在DB额外创建一些Embedded BCDNS的表,通过这里的SQL[脚本](https://github.com/AntChainOpenLabs/AntChainBridgePluginSDK/tree/main/bcdns-services/embedded-bcdns/embedded-bcdns-state-jdbc-spring-boot-starter/src/main/resources/ddl/mysql/ddl.sql)
+
+重新启动Relayer,启动日志中会看到:
+
+```
+INFO 63164 --- [ main] .EmbeddedBcdnsJdbcStateAutoConfiguration : start jdbc bcdns state
+INFO 63164 --- [ main] b.b.e.s.a.EmbeddedBcdnsAutoConfiguration : start embedded bcdns server on 0.0.0.0:8090
+```
+
+
## 社区治理
diff --git a/pom.xml b/pom.xml
index 5efba75..685ebfe 100644
--- a/pom.xml
+++ b/pom.xml
@@ -13,7 +13,7 @@
com.alipay.antchain.bridge
antchain-bridge-relayer
- 0.2.0
+ 0.3.0
pom
r-bootstrap
@@ -36,7 +36,8 @@
3.23.5
2.7.16
8.0.33
- 0.2.3
+ 0.3.0
+ 0.1.0
5.8.22
4.13.2
2.2.224
@@ -116,9 +117,19 @@
com.alipay.antchain.bridge
- antchain-bridge-bcdns
+ antchain-bridge-bcdns-factory
${acb-sdk.version}
+
+ com.alipay.antchain.bridge
+ embedded-bcdns-state-jdbc-spring-boot-starter
+ ${acb-embedded-bcdns.version}
+
+
+ com.alipay.antchain.bridge
+ embedded-bcdns-spring-boot-starter
+ ${acb-embedded-bcdns.version}
+
junit
junit
@@ -198,7 +209,7 @@
com.alipay.antchain.bridge
r-facade
- ${project.version}
+ 0.2.0
org.projectlombok
diff --git a/r-bootstrap/pom.xml b/r-bootstrap/pom.xml
index eb9302f..2eedbe1 100644
--- a/r-bootstrap/pom.xml
+++ b/r-bootstrap/pom.xml
@@ -6,7 +6,7 @@
com.alipay.antchain.bridge
antchain-bridge-relayer
- 0.2.0
+ 0.3.0
r-bootstrap
@@ -52,7 +52,7 @@
com.h2database
h2
- test
+
com.baomidou
@@ -86,6 +86,14 @@
com.github.ulisesbocchio
jasypt-spring-boot-starter
+
+ com.alipay.antchain.bridge
+ embedded-bcdns-state-jdbc-spring-boot-starter
+
+
+ com.alipay.antchain.bridge
+ embedded-bcdns-spring-boot-starter
+
diff --git a/r-bootstrap/src/main/java/com/alipay/antchain/bridge/relayer/bootstrap/config/RelayerCoreConfig.java b/r-bootstrap/src/main/java/com/alipay/antchain/bridge/relayer/bootstrap/config/RelayerCoreConfig.java
index 4c4dadd..15c50c2 100644
--- a/r-bootstrap/src/main/java/com/alipay/antchain/bridge/relayer/bootstrap/config/RelayerCoreConfig.java
+++ b/r-bootstrap/src/main/java/com/alipay/antchain/bridge/relayer/bootstrap/config/RelayerCoreConfig.java
@@ -25,6 +25,7 @@
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.PemUtil;
import com.alipay.antchain.bridge.commons.bcdns.AbstractCrossChainCertificate;
import com.alipay.antchain.bridge.commons.bcdns.CrossChainCertificateFactory;
@@ -44,6 +45,7 @@
import com.alipay.antchain.bridge.relayer.server.network.WSRelayerServer;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.BeanInitializationException;
@@ -55,6 +57,7 @@
import org.springframework.core.io.Resource;
import org.springframework.transaction.support.TransactionTemplate;
+@Slf4j
@Configuration
public class RelayerCoreConfig {
@@ -98,7 +101,15 @@ public class RelayerCoreConfig {
private boolean isDiscoveryService;
public AbstractCrossChainCertificate getLocalRelayerCrossChainCertificate() {
- AbstractCrossChainCertificate relayerCertificate = null;
+ if (StrUtil.equals("null", relayerCrossChainCert.getFilename())) {
+ log.warn("your relayer crosschain certificate is not set");
+ return null;
+ }
+ if (!relayerCrossChainCert.exists()) {
+ log.error("your relayer crosschain certificate {} not exist", relayerCrossChainCert.getFilename());
+ return null;
+ }
+ AbstractCrossChainCertificate relayerCertificate;
try {
relayerCertificate = CrossChainCertificateFactory.createCrossChainCertificateFromPem(
FileUtil.readBytes(relayerCrossChainCert.getFile())
@@ -111,7 +122,8 @@ public AbstractCrossChainCertificate getLocalRelayerCrossChainCertificate() {
}
public RelayerCredentialSubject getLocalRelayerCredentialSubject() {
- return RelayerCredentialSubject.decode(getLocalRelayerCrossChainCertificate().getCredentialSubject());
+ return ObjectUtil.isNull(getLocalRelayerCrossChainCertificate()) ?
+ null : RelayerCredentialSubject.decode(getLocalRelayerCrossChainCertificate().getCredentialSubject());
}
public String getLocalRelayerIssuerDomainSpace() {
@@ -136,7 +148,8 @@ public PrivateKey getLocalPrivateKey() {
}
public String getLocalRelayerNodeId() {
- return RelayerNodeInfo.calculateNodeId(getLocalRelayerCrossChainCertificate());
+ return ObjectUtil.isNull(getLocalRelayerCrossChainCertificate()) ?
+ null : RelayerNodeInfo.calculateNodeId(getLocalRelayerCrossChainCertificate());
}
@Bean
diff --git a/r-bootstrap/src/main/resources/logback-spring.xml b/r-bootstrap/src/main/resources/logback-spring.xml
index 8b0ac18..7d21183 100755
--- a/r-bootstrap/src/main/resources/logback-spring.xml
+++ b/r-bootstrap/src/main/resources/logback-spring.xml
@@ -62,6 +62,27 @@
ACCEPT
+
+ ${logging.path}/${APP_NAME}/embedded-bcdns.log
+
+ %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} -
+ %msg%n
+
+ UTF-8
+
+
+ ${logging.path}/${APP_NAME}/embedded-bcdns.log.%d{yyyy-MM-dd}.%i
+ 7
+ 50MB
+ 2GB
+ true
+
+
+ INFO
+ ACCEPT
+ ACCEPT
+
+
0
@@ -85,6 +106,10 @@
+
+
+
+
diff --git a/r-bootstrap/src/test/java/com/alipay/antchain/bridge/relayer/bootstrap/manager/BCDNSManagerTest.java b/r-bootstrap/src/test/java/com/alipay/antchain/bridge/relayer/bootstrap/manager/BCDNSManagerTest.java
index 8f7328c..e400348 100644
--- a/r-bootstrap/src/test/java/com/alipay/antchain/bridge/relayer/bootstrap/manager/BCDNSManagerTest.java
+++ b/r-bootstrap/src/test/java/com/alipay/antchain/bridge/relayer/bootstrap/manager/BCDNSManagerTest.java
@@ -21,7 +21,7 @@
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.map.MapUtil;
-import com.alipay.antchain.bridge.bcdns.impl.BlockChainDomainNameServiceFactory;
+import com.alipay.antchain.bridge.bcdns.factory.BlockChainDomainNameServiceFactory;
import com.alipay.antchain.bridge.bcdns.service.BCDNSTypeEnum;
import com.alipay.antchain.bridge.bcdns.service.IBlockChainDomainNameService;
import com.alipay.antchain.bridge.bcdns.types.base.DomainRouter;
diff --git a/r-cli/README.md b/r-cli/README.md
index 2ef2d79..516bd07 100644
--- a/r-cli/README.md
+++ b/r-cli/README.md
@@ -960,9 +960,9 @@ relayer:> query-curr-active-nodes
[
{
"last_active_time":1704366281000,
- "node_ip":"30.75.64.168",
+ "node_ip":"192.168.0.1",
"active":true,
- "node_id":"30.75.64.168"
+ "node_id":"192.168.0.1"
}
]
```
@@ -1080,3 +1080,137 @@ relayer:> convert-cross-chain-cert-to-pem --base64Input AAAIAgAAAAABAAAAMQEAKAAA
certificate in pem saved here: /path/to/output_1704359604268.crt
```
+### 5.5 生成BCDNS根证书
+
+> [!IMPORTANT]
+> 本功能要求CLI版本大于等于0.3.0
+
+在启动BCDNS时,需要提前准备好BCDNS私钥和自签名的根证书,这里提供一个工具🔧,帮助生成它们,尤其是在Relayer启动Embedded BCDNS的时候,可以用到这个功能。
+
+命令:`generate-bcdns-root-cert`,执行命令之后会生成一个BCDNS的PEM格式的根证书,并保存到本地,如果没有指定私钥、公钥,会顺便生成公私钥并保存在本地。
+
+参数:
+
+- `--certVersion`:证书格式版本,默认为1;
+- `--certId`:证书的ID,默认为“mybcdns”;
+- `--credSubjectName`:跨链证书的凭证主体名称 [可选,默认值 = mybcdns]
+- `--hashAlgo` HashAlgoEnum:要生成的 bcdns 根跨链证书的发行证明哈希算法,[可选,默认值 = `KECCAK_256`],支持`SHA2_256`, `KECCAK_256`, `SHA3_256`, `SM3`;
+- `--signAlgo` SignAlgoEnum:要生成的跨链证书的签名算法,[可选,默认值 = `KECCAK256_WITH_SECP256K1`],支持`ED25519`, `SHA256_WITH_RSA`, `SHA256_WITH_ECDSA`, `KECCAK256_WITH_SECP256K1`, `SM3_WITH_SM2`
+- `--oidType` ObjectIdentityType:拥有跨链证书的对象身份类型,[可选,默认值 = X509_PUBLIC_KEY_INFO],还支持BID,并会保存生成的BID Document
+- `--pubkeyFile` String:嵌入式 BCDNS 的根公钥路径,默认生成文件名为“embedded-bcdns-root-pubkey.key”的新公钥 [可选]
+- `--privateKeyFile` String:嵌入式 BCDNS 的根私钥路径,默认生成文件名为“embedded-bcdns-root-private-key.key”的新私钥 [可选]
+- `--outDir` String:保存文件的目录路径,默认当前目录。证书将保存为“embedded-bcdns-root.crt” [可选]
+
+用法如下:
+
+1. 直接运行,不指定任何字段,会生成证书和公私钥并保存。
+
+```
+relayer:> generate-bcdns-root-cert
+your bcdns root cert is:
+-----BEGIN BCDNS TRUST ROOT CERTIFICATE-----
+AADdAQAAAAABAAAAMQEABwAAAG15YmNkbnMCAAEAAAAAAwBrAAAAAABlAAAAAAAB
+AAAAAAEAWAAAADBWMBAGByqGSM49AgEGBSuBBAAKA0IABLbk30Th9fREt89fOGe3
+fsbUbOFrMjXlSjfbHEwu0RgaEt5+4+VUdVo5mU+pimkrlTXgfKm0e7nWM0+ZLvnF
+ce8EAAgAAAAT1rFmAAAAAAUACAAAAJMJk2gAAAAABgCKAAAAAACEAAAAAAAHAAAA
+bXliY2RucwEAawAAAAAAZQAAAAAAAQAAAAABAFgAAAAwVjAQBgcqhkjOPQIBBgUr
+gQQACgNCAAS25N9E4fX0RLfPXzhnt37G1GzhazI15Uo32xxMLtEYGhLefuPlVHVa
+OZlPqYppK5U14HyptHu51jNPmS75xXHvAgAAAAAABwCfAAAAAACZAAAAAAAKAAAA
+S0VDQ0FLLTI1NgEAIAAAAN1JM3fcwS62uLhbhZ7YdoYLTogja+b3GLlGhYRpZ5cT
+AgAWAAAAS2VjY2FrMjU2V2l0aFNlY3AyNTZrMQMAQQAAAPxlkECDdlt6O5nTxBlN
+PvqUBMIPXL2ya27m5fZms+zdJx/ZSUb2SYpOiKiy99nSxcfnZ1Yvj4YKu8HkTpjJ
+MK8A
+-----END BCDNS TRUST ROOT CERTIFICATE-----
+
+your bcdns root cert file is /AntChainBridgeRelayer/r-cli/target/r-cli/embedded-bcdns-root.crt
+your bcdns root private key file is /AntChainBridgeRelayer/r-cli/target/r-cli/embedded-bcdns-root-private-key.key
+your bcdns root public key file is /AntChainBridgeRelayer/r-cli/target/r-cli/embedded-bcdns-root-pubkey.key
+```
+
+2. 指定部分字段
+
+```
+relayer:> generate-bcdns-root-cert --certId test --credSubjectName test --hashAlgo SHA2_256 --signAlgo ED25519 --oidType BID
+your bcdns root cert is:
+-----BEGIN BCDNS TRUST ROOT CERTIFICATE-----
+AADfAQAAAAABAAAAMQEABAAAAHRlc3QCAAEAAAAAAwA7AAAAAAA1AAAAAAABAAAA
+AQEAKAAAAGRpZDpiaWQ6ZWZoTHpSaGNaWXhIdXd5THhxRW9iUGl4RUR1NWg0VGUE
+AAgAAAAZ2rFmAAAAAAUACAAAAJkNk2gAAAAABgDRAAAAAADLAAAAAAAEAAAAdGVz
+dAEAOwAAAAAANQAAAAAAAQAAAAEBACgAAABkaWQ6YmlkOmVmaEx6UmhjWll4SHV3
+eUx4cUVvYlBpeEVEdTVoNFRlAgB6AAAAeyJwdWJsaWNLZXkiOlt7InR5cGUiOiJF
+RDI1NTE5IiwicHVibGljS2V5SGV4IjoiYjA2NTY2YjlkNDMyYWU0YTU5OTQ1MmYw
+NjA3MjA3YmUwMzM3N2E1NjY4NjlkNmE2ZDY0MDJmMmQ1N2I5Mzg3YzJhZmQ3MSJ9
+XX0HAI0AAAAAAIcAAAAAAAgAAABTSEEyLTI1NgEAIAAAAH8zd6FasjxeGERqh9gg
+VngUv3EePrjpiS6rAu3tp29dAgAHAAAARWQyNTUxOQMAQAAAANcgHl5Ujxxn3zoG
+RP1pQmM7E/9/IpAcv++//HQM4Md/3NIHG5a3l6USm0yDAc5s4NOQLaoIId7A5dGB
+8X8Jxw8=
+-----END BCDNS TRUST ROOT CERTIFICATE-----
+
+your bcdns root cert file is /AntChainBridgeRelayer/r-cli/target/r-cli/embedded-bcdns-root.crt
+your bcdns root private key file is /AntChainBridgeRelayer/r-cli/target/r-cli/embedded-bcdns-root-private-key.key
+your bcdns root public key file is /AntChainBridgeRelayer/r-cli/target/r-cli/embedded-bcdns-root-pubkey.key
+your bid document is /AntChainBridgeRelayer/r-cli/target/r-cli/embedded-bcdns-root-bid-document.json
+```
+
+2. 指定特定公私钥运行
+
+```
+relayer:> generate-bcdns-root-cert --certId test --credSubjectName test --hashAlgo SHA2_256 --signAlgo ED25519 --oidType BID --privateKeyFile ./embedded-bcdns-root-private-key.key --pubkeyFile ./embedded-bcdns-root-pubkey.key
+your bcdns root cert is:
+-----BEGIN BCDNS TRUST ROOT CERTIFICATE-----
+AADfAQAAAAABAAAAMQEABAAAAHRlc3QCAAEAAAAAAwA7AAAAAAA1AAAAAAABAAAA
+AQEAKAAAAGRpZDpiaWQ6ZWZoTHpSaGNaWXhIdXd5THhxRW9iUGl4RUR1NWg0VGUE
+AAgAAACK27FmAAAAAAUACAAAAAoPk2gAAAAABgDRAAAAAADLAAAAAAAEAAAAdGVz
+dAEAOwAAAAAANQAAAAAAAQAAAAEBACgAAABkaWQ6YmlkOmVmaEx6UmhjWll4SHV3
+eUx4cUVvYlBpeEVEdTVoNFRlAgB6AAAAeyJwdWJsaWNLZXkiOlt7InR5cGUiOiJF
+RDI1NTE5IiwicHVibGljS2V5SGV4IjoiYjA2NTY2YjlkNDMyYWU0YTU5OTQ1MmYw
+NjA3MjA3YmUwMzM3N2E1NjY4NjlkNmE2ZDY0MDJmMmQ1N2I5Mzg3YzJhZmQ3MSJ9
+XX0HAI0AAAAAAIcAAAAAAAgAAABTSEEyLTI1NgEAIAAAALIrlWoLe34gHQ4hc+M0
+LGzIxwjSh/TSNkvNXf2qS9D1AgAHAAAARWQyNTUxOQMAQAAAADwCG0OukeuUNOhR
+9HIyqYHs30IR/fXVnoAvx7L6PE0iOPfd06BxweSLL89jL1qqXVuS+Mqo3zPlJQGH
+L0MTzgo=
+-----END BCDNS TRUST ROOT CERTIFICATE-----
+your bcdns root cert file is /Users/zouxyan/IdeaProjects/AntChainBridgeRelayer/r-cli/target/r-cli/embedded-bcdns-root.crt
+your bid document is /Users/zouxyan/IdeaProjects/AntChainBridgeRelayer/r-cli/target/r-cli/embedded-bcdns-root-bid-document.json
+```
+
+### 5.6 生成Relayer证书CSR
+
+证书申请需要申请者构造好`Certificate Signing Request`。
+
+命令:`generate-relayer-csr `以 Base64 格式生成中继器证书签名请求
+
+参数:
+
+- `--certVersion` String:要应用的Relayer跨链证书版本 [可选,默认值 = 1]
+- `--credSubjectName` String:跨链证书的Relayer凭证主体名称 [可选,默认值 = `myrelayer`]
+- `--oidType` ObjectIdentityType:拥有Relayer跨链证书的对象身份类型 [可选,默认值 = `X509_PUBLIC_KEY_INFO`],还支持BID
+- `--pubkeyFile` String:应用证书的Relayer公钥的路径 [强制]
+
+用法如下:
+
+```
+relayer:> generate-relayer-csr --pubkeyFile ./embedded-bcdns-root-pubkey.key
+your CSR is
+AADDAAAAAAABAAAAMQIAAQAAAAMEAAgAAAAAAAAAAAAAAAUACAAAAAAAAAAAAAAABgCTAAAAAACNAAAAAAABAAAAMQEACQAAAG15cmVsYXllcgMAawAAAAAAZQAAAAAAAQAAAAABAFgAAAAwVjAQBgcqhkjOPQIBBgUrgQQACgNCAAQrcI72jkNt107AeW04b9R4JsunCJ5qPx+XSTqqAiRfkDIB1FK/Sp8hbApRbLp0bT51l0ZJeVtNLlLM2/nhTPpyBAAAAAAA
+```
+
+### 5.7 生成PTC证书CSR
+
+证书申请需要申请者构造好`Certificate Signing Request`。
+
+命令:`generate-ptc-csr `以 Base64 格式生成PTC证书签名请求。
+
+参数:
+
+- `--certVersion` String:要应用的PTC跨链证书版本 [可选,默认值 = 1]
+- `--credSubjectName` String:跨链证书的PTC凭证主体名称 [可选,默认值 = `myrelayer`]
+- `--oidType` ObjectIdentityType:拥有PTC跨链证书的对象身份类型 [可选,默认值 = `X509_PUBLIC_KEY_INFO`],还支持BID
+- `--pubkeyFile` String:应用证书的PTC公钥的路径 [强制]
+
+```
+relayer:> generate-ptc-csr --pubkeyFile ./embedded-bcdns-root-pubkey.key --ptcType BLOCKCHAIN
+your CSR is
+AADGAAAAAAABAAAAMQIAAQAAAAIEAAgAAAAAAAAAAAAAAAUACAAAAAAAAAAAAAAABgCWAAAAAACQAAAAAAABAAAAMQEABQAAAG15cHRjAgABAAAAAQMAawAAAAAAZQAAAAAAAQAAAAABAFgAAAAwVjAQBgcqhkjOPQIBBgUrgQQACgNCAAQrcI72jkNt107AeW04b9R4JsunCJ5qPx+XSTqqAiRfkDIB1FK/Sp8hbApRbLp0bT51l0ZJeVtNLlLM2/nhTPpyBAAAAAAA
+```
+
diff --git a/r-cli/pom.xml b/r-cli/pom.xml
index 24f7280..a46b023 100644
--- a/r-cli/pom.xml
+++ b/r-cli/pom.xml
@@ -22,7 +22,7 @@
com.alipay.antchain.bridge
antchain-bridge-relayer
- 0.2.0
+ 0.3.0
r-cli
@@ -84,7 +84,7 @@
com.alipay.antchain.bridge
- antchain-bridge-bcdns
+ antchain-bridge-bcdns-factory
org.bouncycastle
diff --git a/r-cli/src/main/java/com/alipay/antchain/bridge/relayer/cli/command/UtilsCommands.java b/r-cli/src/main/java/com/alipay/antchain/bridge/relayer/cli/command/UtilsCommands.java
index 960ca7a..a95b6dd 100644
--- a/r-cli/src/main/java/com/alipay/antchain/bridge/relayer/cli/command/UtilsCommands.java
+++ b/r-cli/src/main/java/com/alipay/antchain/bridge/relayer/cli/command/UtilsCommands.java
@@ -21,11 +21,9 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.PublicKey;
-import java.security.Security;
+import java.security.*;
import java.security.interfaces.ECPublicKey;
+import java.util.Date;
import cn.ac.caict.bid.model.BIDDocumentOperation;
import cn.ac.caict.bid.model.BIDpublicKeyOperation;
@@ -35,6 +33,7 @@
import cn.bif.module.encryption.model.KeyMember;
import cn.bif.module.encryption.model.KeyType;
import cn.hutool.core.codec.Base64;
+import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.HexUtil;
import cn.hutool.core.util.ObjectUtil;
@@ -48,8 +47,17 @@
import com.alipay.antchain.bridge.bcdns.impl.bif.conf.BifCertificationServiceConfig;
import com.alipay.antchain.bridge.bcdns.impl.bif.conf.BifChainConfig;
import com.alipay.antchain.bridge.commons.bcdns.AbstractCrossChainCertificate;
+import com.alipay.antchain.bridge.commons.bcdns.BCDNSTrustRootCredentialSubject;
import com.alipay.antchain.bridge.commons.bcdns.CrossChainCertificateFactory;
+import com.alipay.antchain.bridge.commons.bcdns.utils.BIDHelper;
import com.alipay.antchain.bridge.commons.bcdns.utils.CrossChainCertificateUtil;
+import com.alipay.antchain.bridge.commons.core.base.BIDInfoObjectIdentity;
+import com.alipay.antchain.bridge.commons.core.base.ObjectIdentity;
+import com.alipay.antchain.bridge.commons.core.base.ObjectIdentityType;
+import com.alipay.antchain.bridge.commons.core.base.X509PubkeyInfoObjectIdentity;
+import com.alipay.antchain.bridge.commons.core.ptc.PTCTypeEnum;
+import com.alipay.antchain.bridge.commons.utils.crypto.HashAlgoEnum;
+import com.alipay.antchain.bridge.commons.utils.crypto.SignAlgoEnum;
import lombok.Getter;
import lombok.SneakyThrows;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
@@ -69,6 +77,14 @@ public class UtilsCommands {
Security.addProvider(new BouncyCastleProvider());
}
+ private static final String EMBEDDED_BCDNS_PUBKEY_DEFAULT_FILENAME = "embedded-bcdns-root-pubkey.key";
+
+ private static final String EMBEDDED_BCDNS_PRIVATE_KEY_DEFAULT_FILENAME = "embedded-bcdns-root-private-key.key";
+
+ private static final String EMBEDDED_BCDNS_ROOT_CERT = "embedded-bcdns-root.crt";
+
+ private static final String EMBEDDED_BCDNS_ROOT_BID_DOCUMENT = "embedded-bcdns-root-bid-document.json";
+
@ShellMethod(value = "Generate PEM files for the relayer private and public key")
public String generateRelayerAccount(
@ShellOption(help = "Key algorithm, default Ed25519", defaultValue = "Ed25519") String keyAlgo,
@@ -84,22 +100,12 @@ public String generateRelayerAccount(
KeyPair keyPair = keyPairGenerator.generateKeyPair();
// dump the private key into pem
- StringWriter stringWriter = new StringWriter(256);
- JcaPEMWriter jcaPEMWriter = new JcaPEMWriter(stringWriter);
- jcaPEMWriter.writeObject(keyPair.getPrivate());
- jcaPEMWriter.close();
- String privatePem = stringWriter.toString();
Path privatePath = Paths.get(outDir, "private_key.pem");
- Files.write(privatePath, privatePem.getBytes());
+ writePrivateKey(keyPair.getPrivate(), privatePath);
// dump the public key into pem
- stringWriter = new StringWriter(256);
- jcaPEMWriter = new JcaPEMWriter(stringWriter);
- jcaPEMWriter.writeObject(keyPair.getPublic());
- jcaPEMWriter.close();
- String pubkeyPem = stringWriter.toString();
Path publicPath = Paths.get(outDir, "public_key.pem");
- Files.write(publicPath, pubkeyPem.getBytes());
+ writePublicKey(keyPair.getPublic(), publicPath);
return StrUtil.format("private key path: {}\npublic key path: {}", privatePath.toAbsolutePath(), publicPath.toAbsolutePath());
} catch (Exception e) {
@@ -107,6 +113,128 @@ public String generateRelayerAccount(
}
}
+ @ShellMethod(value = "Generate the relayer certificate sign request in Base64 format")
+ public String generateRelayerCSR(
+ @ShellOption(
+ help = "Version of relayer crosschain certificate to apply",
+ defaultValue = CrossChainCertificateFactory.DEFAULT_VERSION
+ ) String certVersion,
+ @ShellOption(help = "Name of relayer credential subject for crosschain certificate", defaultValue = "myrelayer") String credSubjectName,
+ @ShellOption(
+ valueProvider = EnumValueProvider.class,
+ help = "Type of object identity who owned the relayer crosschain certificate",
+ defaultValue = "X509_PUBLIC_KEY_INFO"
+ ) ObjectIdentityType oidType,
+ @ShellOption(
+ valueProvider = FileValueProvider.class,
+ help = "Path to relayer public key who apply the certificate"
+ ) String pubkeyFile
+ ) {
+ try {
+ ObjectIdentity oid;
+ byte[] rootSubjectInfo = new byte[]{};
+ PublicKey publicKey;
+ Path pubkeyFilePath = Paths.get(pubkeyFile);
+ if (Files.isReadable(pubkeyFilePath)) {
+ publicKey = readPublicKeyFromPem(Files.readAllBytes(pubkeyFilePath));
+ } else {
+ return "please input the path to the correct applicant public key file";
+ }
+
+ if (oidType == ObjectIdentityType.X509_PUBLIC_KEY_INFO) {
+ oid = new X509PubkeyInfoObjectIdentity(publicKey.getEncoded());
+ } else {
+ BIDDocumentOperation bidDocumentOperation = getBid(publicKey);
+ oid = new BIDInfoObjectIdentity(
+ BIDHelper.encAddress(
+ bidDocumentOperation.getPublicKey()[0].getType(),
+ BIDHelper.getRawPublicKeyFromBIDDocument(bidDocumentOperation)
+ )
+ );
+ rootSubjectInfo = JsonUtils.toJSONString(bidDocumentOperation).getBytes();
+ }
+
+ return StrUtil.format(
+ "your CSR is \n{}",
+ Base64.encode(
+ CrossChainCertificateFactory.createRelayerCertificateSigningRequest(
+ certVersion,
+ credSubjectName,
+ oid,
+ rootSubjectInfo
+ ).encode()
+ )
+ );
+
+ } catch (Exception e) {
+ throw new RuntimeException("unexpected error please input stacktrace to check the detail", e);
+ }
+ }
+
+ @ShellMethod(value = "Generate the ptc certificate sign request in Base64 format")
+ public String generatePtcCSR(
+ @ShellOption(
+ help = "Version of ptc crosschain certificate to apply",
+ defaultValue = CrossChainCertificateFactory.DEFAULT_VERSION
+ ) String certVersion,
+ @ShellOption(help = "Name of ptc credential subject for crosschain certificate", defaultValue = "myptc") String credSubjectName,
+ @ShellOption(
+ valueProvider = EnumValueProvider.class,
+ help = "Type of object identity who owned the ptc crosschain certificate",
+ defaultValue = "X509_PUBLIC_KEY_INFO"
+ ) ObjectIdentityType oidType,
+ @ShellOption(
+ valueProvider = EnumValueProvider.class,
+ help = "Type of ptc to own the crosschain certificate",
+ defaultValue = "BLOCKCHAIN"
+ ) PTCTypeEnum ptcType,
+ @ShellOption(
+ valueProvider = FileValueProvider.class,
+ help = "Path to ptc public key who apply the certificate"
+ ) String pubkeyFile
+ ) {
+ try {
+ ObjectIdentity oid;
+ byte[] rootSubjectInfo = new byte[]{};
+ PublicKey publicKey;
+ Path pubkeyFilePath = Paths.get(pubkeyFile);
+ if (Files.isReadable(pubkeyFilePath)) {
+ publicKey = readPublicKeyFromPem(Files.readAllBytes(pubkeyFilePath));
+ } else {
+ return "please input the path to the correct applicant public key file";
+ }
+
+ if (oidType == ObjectIdentityType.X509_PUBLIC_KEY_INFO) {
+ oid = new X509PubkeyInfoObjectIdentity(publicKey.getEncoded());
+ } else {
+ BIDDocumentOperation bidDocumentOperation = getBid(publicKey);
+ oid = new BIDInfoObjectIdentity(
+ BIDHelper.encAddress(
+ bidDocumentOperation.getPublicKey()[0].getType(),
+ BIDHelper.getRawPublicKeyFromBIDDocument(bidDocumentOperation)
+ )
+ );
+ rootSubjectInfo = JsonUtils.toJSONString(bidDocumentOperation).getBytes();
+ }
+
+ return StrUtil.format(
+ "your CSR is \n{}",
+ Base64.encode(
+ CrossChainCertificateFactory.createPTCCertificateSigningRequest(
+ certVersion,
+ credSubjectName,
+ ptcType,
+ oid,
+ rootSubjectInfo
+ ).encode()
+ )
+ );
+
+ } catch (Exception e) {
+ throw new RuntimeException("unexpected error please input stacktrace to check the detail", e);
+ }
+ }
+
@ShellMethod(value = "Generate the BID document file containing the raw public key")
public String generateBidDocument(
@ShellOption(valueProvider = FileValueProvider.class, help = "The path to public key in PEM") String publicKeyPath,
@@ -212,6 +340,120 @@ public String convertCrossChainCertToPem(
}
}
+ @ShellMethod(value = "Generate self-signed BCDNS root crosschain certificate in PEM")
+ public String generateBcdnsRootCert(
+ @ShellOption(
+ help = "Version of crosschain certificate to generate",
+ defaultValue = CrossChainCertificateFactory.DEFAULT_VERSION
+ ) String certVersion,
+ @ShellOption(help = "ID for crosschain certificate", defaultValue = "mybcdns") String certId,
+ @ShellOption(help = "Name of credential subject for crosschain certificate", defaultValue = "mybcdns") String credSubjectName,
+ @ShellOption(
+ valueProvider = EnumValueProvider.class,
+ help = "Hash algorithm of issue proof for bcdns root crosschain certificate to generate",
+ defaultValue = "KECCAK_256"
+ ) HashAlgoEnum hashAlgo,
+ @ShellOption(
+ valueProvider = EnumValueProvider.class,
+ help = "Signature algorithm of crosschain certificate to generate",
+ defaultValue = "KECCAK256_WITH_SECP256K1"
+ ) SignAlgoEnum signAlgo,
+ @ShellOption(
+ valueProvider = EnumValueProvider.class,
+ help = "Type of object identity who owned the crosschain certificate",
+ defaultValue = "X509_PUBLIC_KEY_INFO"
+ ) ObjectIdentityType oidType,
+ @ShellOption(
+ valueProvider = FileValueProvider.class,
+ help = "Path to root public key for embedded BCDNS, default generate new public key with filename \"embedded-bcdns-root-pubkey.key\"",
+ defaultValue = ""
+ ) String pubkeyFile,
+ @ShellOption(
+ valueProvider = FileValueProvider.class,
+ help = "Path to root private key for embedded BCDNS, default generate new private key with filename \"embedded-bcdns-root-private-key.key\"",
+ defaultValue = ""
+ ) String privateKeyFile,
+ @ShellOption(
+ valueProvider = FileValueProvider.class,
+ help = "Directory path to save the files default current directory. Certificate would save as \"embedded-bcdns-root.crt\"",
+ defaultValue = ""
+ ) String outDir
+ ) {
+ try {
+ if (oidType == ObjectIdentityType.BID && SignAlgoEnum.ED25519 != signAlgo) {
+ return "BID object identity only support Ed25519 for now";
+ }
+
+ ObjectIdentity oid;
+ byte[] rootSubjectInfo = new byte[]{};
+ PrivateKey privateKey;
+ PublicKey publicKey;
+ if (StrUtil.isAllNotEmpty(pubkeyFile, privateKeyFile)) {
+ privateKey = signAlgo.getSigner().readPemPrivateKey(Files.readAllBytes(Paths.get(privateKeyFile)));
+ publicKey = readPublicKeyFromPem(Files.readAllBytes(Paths.get(pubkeyFile)));
+ } else {
+ KeyPair keyPair = signAlgo.getSigner().generateKeyPair();
+ privateKey = keyPair.getPrivate();
+ publicKey = keyPair.getPublic();
+ writePrivateKey(privateKey, Paths.get(outDir, EMBEDDED_BCDNS_PRIVATE_KEY_DEFAULT_FILENAME));
+ writePublicKey(publicKey, Paths.get(outDir, EMBEDDED_BCDNS_PUBKEY_DEFAULT_FILENAME));
+ }
+
+ if (oidType == ObjectIdentityType.X509_PUBLIC_KEY_INFO) {
+ oid = new X509PubkeyInfoObjectIdentity(publicKey.getEncoded());
+ } else {
+ BIDDocumentOperation bidDocumentOperation = getBid(publicKey);
+ oid = new BIDInfoObjectIdentity(
+ BIDHelper.encAddress(
+ bidDocumentOperation.getPublicKey()[0].getType(),
+ BIDHelper.getRawPublicKeyFromBIDDocument(bidDocumentOperation)
+ )
+ );
+ rootSubjectInfo = JsonUtils.toJSONString(bidDocumentOperation).getBytes();
+ Files.write(Paths.get(outDir, EMBEDDED_BCDNS_ROOT_BID_DOCUMENT), rootSubjectInfo);
+ }
+
+ AbstractCrossChainCertificate certificate = CrossChainCertificateFactory.createCrossChainCertificate(
+ certVersion,
+ certId,
+ oid,
+ DateUtil.currentSeconds(),
+ DateUtil.offsetDay(new Date(), 365).getTime() / 1000,
+ new BCDNSTrustRootCredentialSubject(
+ credSubjectName, oid, rootSubjectInfo
+ )
+ );
+
+ certificate.setProof(
+ new AbstractCrossChainCertificate.IssueProof(
+ hashAlgo.getName(),
+ hashAlgo.hash(certificate.getEncodedToSign()),
+ signAlgo.getName(),
+ signAlgo.getSigner().sign(privateKey, certificate.getEncodedToSign())
+ )
+ );
+ String rootCertPem = CrossChainCertificateUtil.formatCrossChainCertificateToPem(certificate);
+ Files.write(Paths.get(outDir, EMBEDDED_BCDNS_ROOT_CERT), rootCertPem.getBytes());
+ return StrUtil.format(
+ "your bcdns root cert is:\n{}{}{}",
+ rootCertPem,
+ StrUtil.format(
+ "your bcdns root cert file is {}{}",
+ Paths.get(outDir, EMBEDDED_BCDNS_ROOT_CERT).toAbsolutePath().toString(),
+ StrUtil.isAllEmpty(pubkeyFile, privateKeyFile) ? StrUtil.format(
+ "\nyour bcdns root private key file is {}\n" +
+ "your bcdns root public key file is {}",
+ Paths.get(outDir, EMBEDDED_BCDNS_PRIVATE_KEY_DEFAULT_FILENAME).toAbsolutePath().toString(),
+ Paths.get(outDir, EMBEDDED_BCDNS_PUBKEY_DEFAULT_FILENAME).toAbsolutePath().toString()
+ ) : ""
+ ), oidType == ObjectIdentityType.BID ?
+ StrUtil.format("\nyour bid document is {}", Paths.get(outDir, EMBEDDED_BCDNS_ROOT_BID_DOCUMENT).toAbsolutePath().toString()) : ""
+ );
+ } catch (Exception e) {
+ throw new RuntimeException("unexpected error please input stacktrace to check the detail", e);
+ }
+ }
+
private String convertToBIFAddress(byte[] rawPublicKey) {
PublicKeyManager publicKeyManager = new PublicKeyManager();
publicKeyManager.setRawPublicKey(rawPublicKey);
@@ -280,4 +522,26 @@ private BIDDocumentOperation getBid(PublicKey publicKey) {
return bidDocumentOperation;
}
+
+ @SneakyThrows
+ private void writePrivateKey(PrivateKey privateKey, Path outputFile) {
+ // dump the private key into pem
+ StringWriter stringWriter = new StringWriter(256);
+ JcaPEMWriter jcaPEMWriter = new JcaPEMWriter(stringWriter);
+ jcaPEMWriter.writeObject(privateKey);
+ jcaPEMWriter.close();
+ String privatePem = stringWriter.toString();
+ Files.write(outputFile, privatePem.getBytes());
+ }
+
+ @SneakyThrows
+ private void writePublicKey(PublicKey publicKey, Path outputFile) {
+ // dump the public key into pem
+ StringWriter stringWriter = new StringWriter(256);
+ JcaPEMWriter jcaPEMWriter = new JcaPEMWriter(stringWriter);
+ jcaPEMWriter.writeObject(publicKey);
+ jcaPEMWriter.close();
+ String pubkeyPem = stringWriter.toString();
+ Files.write(outputFile, pubkeyPem.getBytes());
+ }
}
diff --git a/r-commons/pom.xml b/r-commons/pom.xml
index a2f55bd..0535609 100644
--- a/r-commons/pom.xml
+++ b/r-commons/pom.xml
@@ -6,7 +6,7 @@
com.alipay.antchain.bridge
antchain-bridge-relayer
- 0.2.0
+ 0.3.0
r-commons
@@ -36,7 +36,7 @@
com.alipay.antchain.bridge
- antchain-bridge-bcdns
+ antchain-bridge-bcdns-factory
org.bouncycastle
diff --git a/r-core/pom.xml b/r-core/pom.xml
index 3e73462..d11cf9f 100644
--- a/r-core/pom.xml
+++ b/r-core/pom.xml
@@ -6,7 +6,7 @@
com.alipay.antchain.bridge
antchain-bridge-relayer
- 0.2.0
+ 0.3.0
r-core
@@ -64,9 +64,9 @@
protobuf-maven-plugin
${protobuf-plugin.version}
- com.google.protobuf:protoc:${protobuf.version}:exe:${os.detected.classifier}
+ com.google.protobuf:protoc:${protobuf.version}:exe:osx-x86_64
grpc-java
- io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}
+ io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:osx-x86_64
diff --git a/r-core/src/main/java/com/alipay/antchain/bridge/relayer/core/manager/bcdns/BCDNSWrapper.java b/r-core/src/main/java/com/alipay/antchain/bridge/relayer/core/manager/bcdns/BCDNSWrapper.java
index b844fe1..cb556c5 100644
--- a/r-core/src/main/java/com/alipay/antchain/bridge/relayer/core/manager/bcdns/BCDNSWrapper.java
+++ b/r-core/src/main/java/com/alipay/antchain/bridge/relayer/core/manager/bcdns/BCDNSWrapper.java
@@ -18,7 +18,7 @@
import java.util.concurrent.locks.Lock;
-import com.alipay.antchain.bridge.bcdns.impl.BlockChainDomainNameServiceFactory;
+import com.alipay.antchain.bridge.bcdns.factory.BlockChainDomainNameServiceFactory;
import com.alipay.antchain.bridge.bcdns.service.IBlockChainDomainNameService;
import com.alipay.antchain.bridge.bcdns.types.base.DomainRouter;
import com.alipay.antchain.bridge.bcdns.types.exception.AntChainBridgeBCDNSException;
diff --git a/r-dal/pom.xml b/r-dal/pom.xml
index f6b5a2a..fdebcdc 100644
--- a/r-dal/pom.xml
+++ b/r-dal/pom.xml
@@ -6,7 +6,7 @@
com.alipay.antchain.bridge
antchain-bridge-relayer
- 0.2.0
+ 0.3.0
r-dal
diff --git a/r-engine/pom.xml b/r-engine/pom.xml
index 0576346..064e3d9 100644
--- a/r-engine/pom.xml
+++ b/r-engine/pom.xml
@@ -6,7 +6,7 @@
com.alipay.antchain.bridge
antchain-bridge-relayer
- 0.2.0
+ 0.3.0
r-engine
diff --git a/r-engine/src/main/java/com/alipay/antchain/bridge/relayer/engine/DistributedTaskEngine.java b/r-engine/src/main/java/com/alipay/antchain/bridge/relayer/engine/DistributedTaskEngine.java
index 0255d4f..8fa55dc 100644
--- a/r-engine/src/main/java/com/alipay/antchain/bridge/relayer/engine/DistributedTaskEngine.java
+++ b/r-engine/src/main/java/com/alipay/antchain/bridge/relayer/engine/DistributedTaskEngine.java
@@ -59,7 +59,7 @@ public class DistributedTaskEngine implements ApplicationRunner {
@Value("${relayer.engine.schedule.duty.period:100}")
private long dutyPeriod;
- @Value("${relayer.engine.schedule.duty.period:3000}")
+ @Value("${relayer.engine.schedule.duty.biz-period:3000}")
private long bizDutyPeriod;
@Value("${relayer.engine.schedule.marker.period:300}")
diff --git a/r-server/pom.xml b/r-server/pom.xml
index 9f12a06..94d71a7 100644
--- a/r-server/pom.xml
+++ b/r-server/pom.xml
@@ -6,7 +6,7 @@
com.alipay.antchain.bridge
antchain-bridge-relayer
- 0.2.0
+ 0.3.0
r-server