主题
cbdc-biz/app/bizhub
业务中心:结算编排、RTGS 桥接、机构/钱包/审批/审计/费用配置管理。本仓库 submodule cbdc-chain/,本页所有路径相对该 submodule 根。
基本事实
| 项 | 值 | 出处 |
|---|---|---|
| 路径 | cbdc-biz/app/bizhub/ | — |
| 独立 go.mod | 无(共用 cbdc-biz/go.mod) | — |
| Go 文件数 | 总 72(含 ent 生成、_test.go、wire_gen.go) | — |
| 端口 | 9000(gRPC,无 FSC p2p) | cbdc-biz/conf/bizhub/core.yaml:50 |
_test.go | 7 个(见下) | — |
目录:
cbdc-biz/app/bizhub/
├── cmd/bizhub/{main.go,wire.go,wire_gen.go,config_provider.go}
├── internal/
│ ├── biz/ 9+ 业务文件
│ ├── client/ 上游 gRPC 客户端(Issuer + InstitutionOps)
│ ├── conf/ conf.proto + conf.pb.go
│ ├── data/ ent ORM client + 各 Repo
│ ├── data/ent/ ent schema(18 张表)
│ ├── errors/ 错误类型
│ ├── server/ server.go + grpc.go + mtls_middleware.go
│ ├── service/ 9 个 gRPC service 实现
│ ├── types/ 共享类型
│ └── worker/ 3 个 Settlement Worker
├── generate.go
├── Makefile
└── README.md(极简)入口启动(main.go)
来源:cbdc-biz/app/bizhub/cmd/bizhub/main.go。
-conf flag 默认 ../../configs(main.go:39)。若 bc.Data 为空仅输出 warning 不启动数据层(main.go:127-129)。
Wire DI
来源:cbdc-biz/app/bizhub/cmd/bizhub/wire.go:24-40、wire_gen.go:29-93、config_provider.go。
wireApp(*conf.Bootstrap, log.Logger)
↓ wire.Build
provide{Server,Data,CA,Upstream,RTGS,Institution}Config(拆 Bootstrap 子配置)+
server.ProviderSet + data.ProviderSet + biz.ProviderSet +
service.ProviderSet + client.ProviderSet + worker.ProviderSet + newApp关键依赖链(节选):
internal/biz
来源:cbdc-biz/app/bizhub/internal/biz/。
| 文件 | struct / 函数 | file:line | 职责 |
|---|---|---|---|
biz.go | NewRTGSClient | :22-69 | RTGS SMB/SWIFT 客户端 + cleanup |
NewIssuerClient(clients) | :72-77 | Issuer gRPC 客户端取出 | |
NewInstitutionOpsResolver(clients) | :80-85 | 按 institution_code 解析机构节点客户端 | |
NewRetryConfig | :88-90 | 默认重试(MaxRetries=3, ProcessingTimeout=5m) | |
settlement_biz.go | RetryConfig + DefaultRetryConfig | :22-50 | 重试策略 |
SettlementBiz + NewSettlementBiz | :52-85 | 结算业务核心 | |
resolveRTGSAccount | :87-102 | institution_code → RTGS 账户 | |
manage_biz.go | ManageBiz + NewManageBiz | :29-39 | 资产标记 / 钱包标签 / 费用配置 / 审计规则 / 拒绝日志 |
SeedDefaultAssetMarks | :60 | 启动 seed 默认资产标记 | |
SeedDefaultAuditorRuleset | :458 | 启动 seed 默认审计规则集 | |
CreateAssetMark | :90 | 新建资产标记 | |
institution_biz.go | InstitutionBiz + NewInstitutionBiz | :15-22 | 机构管理(自动生成 3 位代码,generateNextCode :122) |
wallet_biz.go | WalletBiz + NewWalletBiz | :15-21 | 钱包元数据 + 标记类型注册 |
wallet_lifecycle_biz.go | WalletLifecycleBiz | — | 钱包生命周期事件日志 |
approval_biz.go | ApprovalBiz + ApprovalTaskType | :23-62 | 审批:INSTITUTION:{CREATE,DELETE}、WHOLESALE_WALLET: |
ledger_indexer_biz.go | LedgerIndexerBiz + NewLedgerIndexerBiz | :19-24 | Auditor 上送的链上交易持久化(AppendBatch / GetCursor / UpdateStatus / List / GetByTxID) |
ca.go | CaBiz(Register / Enroll / EnrollCsr / RevokeCertificate) | :54-76 | fabric-ca 身份注册 / enroll / 吊销 |
auditlog_biz.go | RejectionLogInput / RejectionLogResult / ListRejectionParams(拒绝日志类型,逻辑在 ManageBiz) | :17-47 | 拒绝日志 DTO |
client_auth_biz.go | ClientAuthBiz | :19-26 | 客户端与机构管理 |
rule_node.go | MatchRuleTree(自由函数,非 Biz struct) | :14 | 交易选择器规则节点评估 |
ProviderSet(biz.go:99-113)注册:NewManageBiz / NewWalletBiz / NewClientAuthBiz / NewCaBiz / NewWalletLifecycleBiz / NewInstitutionBiz / NewSettlementBiz / NewApprovalBiz / NewLedgerIndexerBiz / NewRetryConfig / NewRTGSClient / NewIssuerClient / NewInstitutionOpsResolver。
internal/data 与 ent schema
来源:cbdc-biz/app/bizhub/internal/data/。
DBClient(ent_client.go:16-63)
go
type DBClient struct {
Client *ent.Client
DB *sql.DB
}- 驱动:PostgreSQL(
lib/pq),读c.Database.Driver/Source - 连接池:
MaxIdleConns=15、MaxOpenConns=50、ConnMaxLifetime=30m、ConnMaxIdleTime=5m - 启动时自动迁移:
client.Schema.Create(context.Background())(ent_client.go:55)
Repository 接口与实现
| Repo | 接口 / 构造 | file:line |
|---|---|---|
SettlementRepo | Create / GetByID / GetByRequestID / List / UpdateStatus / FetchAndUpdatePendingRequests / FetchAndUpdateRetryableRequests / FetchAndMarkTimedOutRequests | settlement_repo.go:57-100+ |
NewSettlementRepo | — | settlement_repo.go:162 |
WalletLifecycleRepo | NewWalletLifecycleRepo | wallet_lifecycle_repo.go:76 |
WalletStatusLogRepo | NewWalletStatusLogRepo | wallet_lifecycle_repo.go:334 |
ClientRepo | NewClientRepo | client_repo.go:45 |
InstitutionRepo | NewInstitutionRepo | institution_repo.go:44 |
ApprovalRepo | NewApprovalRepo | approval_repo.go:71 |
LedgerIndexerRepo | BatchUpsertWithCursor / GetCursor / UpdateStatus / List / GetByTxID;NewLedgerIndexerRepo | ledger_indexer_repo.go:102/119 |
ProviderSet(data.go:11-24)声明全部 Repo + wire.Bind 多个接口。
Ent Schema 表
来源:cbdc-biz/app/bizhub/internal/data/ent/schema/。
| 表 | 文件 |
|---|---|
settlement_request | settlement_request.go |
wallet_lifecycle | wallet_lifecycle.go |
wallet_status_log | wallet_status_log.go |
wallet_meta | wallet_meta.go |
institution | institution.go |
client | client.go |
asset_mark | asset_mark.go |
asset_mark_limit | asset_mark_limit.go |
wallet_tag | wallet_tag.go |
approval_request | approval_request.go |
fee_config | fee_config.go |
fee_transaction | fee_transaction.go |
tx_selector_group | tx_selector_group.go |
audit_rejection_log | audit_rejection_log.go |
account_type | account_type.go |
index_cursor | index_cursor.go |
ledger_transaction | ledger_transaction.go |
auditor_ruleset | auditor_ruleset.go |
settlement_request 关键字段(示例)
| 字段 | 说明 |
|---|---|
request_id (Unique) | 系统生成唯一 ID |
reference_id (Unique) | 商行流水号(幂等键) |
request_type | ISSUANCE / REDEMPTION |
status | PENDING / PROCESSING / AWAITING_SIGNATURE / COMPLETED / FAILED / COMPENSATION_COMPLETED |
current_step | 流程步骤(types/settlement.go) |
error_code / error_message / error_type | RETRYABLE / UNRECOVERABLE / MANUAL_REVIEW |
retry_count / last_retry_at / next_retry_at | 重试 |
rtgs_settled_at / ledger_completed_at | 关键时间戳 |
created_at / updated_at / completed_at | 审计时间戳 |
索引(settlement_request.go:84-101)
(status, request_type, created_at)— Pending Worker 热查询,列顺序支持无 Sort 过滤(institution_id, created_at)— 权限过滤快速索引- 保留旧索引
(request_type, status)维持向后兼容
internal/service
来源:cbdc-biz/app/bizhub/internal/service/、server/grpc.go:51-59。
9 个 gRPC service 注册:
| Service | 文件 | 主要 RPC | 注册位置 |
|---|---|---|---|
CAService | ca_service.go | Register / Enroll / EnrollCsr / RevokeCertificate | grpc.go:51 |
ManageService | manage_service.go | AddWalletTag / DeleteWalletTag / UpdateWalletTag / GetWalletTags / CreateAssetMark / GetAssetMarks / SetFeeConfig / GetFeeConfig / RegisterAuditorRuleset / ListRejectedTransactions 等 | grpc.go:52 |
WalletService | wallet_service.go | UpdateWalletMetadata / GetWalletMetadata / CreateWalletLifecycle / UpdateWalletStatus / RenewWalletCertificate / ListWalletLifecycles / GetWalletStatus / BatchGetWalletCertificates | grpc.go:53 |
ClientAuthManagementService | client_auth_management.go | CreateClient / GetClient / ListClients / UpdateClient / DeleteClient | grpc.go:54 |
SettlementService | settlement_service.go | CreateRequest(:31)/ QueryRequest(:78)/ SubmitRedeemSignature / ResolveSettlement / GetSettlementStatistics / ListRequests | grpc.go:55 |
InstitutionManageService | institution_manage_service.go | CreateInstitution / GetInstitution / ListInstitutions / UpdateInstitution / DeleteInstitution | grpc.go:56 |
ApprovalService | approval_service.go | SubmitApproval / ReviewApproval / CancelApproval / ClaimApproval / CompleteApproval / GetApproval / ListApprovals | grpc.go:57 |
BizhubAuditorService | auditlog_service.go | InsertRejectionLogs(由 ManageBiz 支撑) | grpc.go:58 |
IndexerService | ledger_indexer_service.go | GetCursor / AppendBatch / UpdateStatus / ListLedgerTransactions / GetLedgerTransaction | grpc.go:59 |
中间件链(grpc.go:22-26):recovery.Recovery → signet.Middlewares → MTLSInstitutionMiddleware(logger)(mTLS 启用 RequireClientCert 时从客户端证书提取 institution_code)。
ProviderSet:service.go:11。
internal/worker — 3 个 Settlement Worker
来源:cbdc-biz/app/bizhub/internal/worker/。
| Worker | 默认配置 | 文件 | 行为 |
|---|---|---|---|
| SettlementPendingWorker | PollInterval=5s、ConcurrentJobs=10、BatchSize=100(worker.go:17-23) | settlement_pending_worker.go:21-55 | FetchAndUpdatePendingRequests(PENDING→PROCESSING)→ b.ProcessIssuanceAsync / b.ProcessRedemptionAsync |
| SettlementRetryWorker | PollInterval=5s、ConcurrentJobs=10、BatchSize=100(worker.go:33-39) | settlement_retry_worker.go:21-58 | 取可重试且 retry_count < maxRetries(默认 3)→ ProcessIssuanceRetry / ProcessRedemptionRetry |
| SettlementTimeoutWorker | CheckInterval=30s、BatchSize=50(worker.go:48-53);scheduler 用 ConcurrentJobs=0 串行(settlement_timeout_worker.go:38) | settlement_timeout_worker.go:22-55 | FetchAndMarkTimedOutRequests:status=PROCESSING 且 updated_at 超过 processingTimeout(默认 5m)→ SQL 置 status=FAILED、error_type=RETRYABLE、error_code=PROCESSING_TIMEOUT、retry_count+1、next_retry_at=NOW()(settlement_repo.go:563-582),handler 仅记 warning |
每个 Worker 都继承自 cbdc-biz/pkg/scheduler.Scheduler[*ent.SettlementRequest](泛型调度框架),同时实现 kratos.Server 接口由 app.Run() 启动。
ProviderSet(worker.go:71-78)注册 3 个 Worker 与 3 个 Config 构造。
internal/conf
来源:cbdc-biz/app/bizhub/internal/conf/conf.proto。
proto
message Bootstrap { // :8-16
Server server = 1;
Data data = 2;
CA ca = 3;
Upstream upstream = 4;
RTGS rtgs = 5;
Observability observability = 6;
repeated Institution institutions = 7; // per-bank registry(节点 endpoint + CA admin)
}
message Server { // :81-86
string network = 1;
string addr = 2;
google.protobuf.Duration timeout = 3;
ServerTLS tls = 4;
}
message ServerTLS { // :88-94
bool enabled, require_client_cert;
string cert, key, ca_cert;
}
message CA { // :64-79
PKCS11Defaults pkcs11_defaults = 1; // library / hash / security / label
}
message Institution { // :25-30
string code = 1; // 机构代码,如 "001"
Endpoint endpoint = 2; // 赎回流程调用的 bank node gRPC
InstitutionCA ca = 3; // 该机构 fabric-ca URL + admin MSP + PIN(:32-39)
}
message Upstream { // :18-20
Endpoint issuer = 1; // 仅 issuer,无 institution 字段
}
message Endpoint { // :41-45
string addr;
google.protobuf.Duration timeout;
TLS tls;
}RTGS(:131-138)含 request_signing_enabled / response_verify_enabled 及子消息 SWIFTConfig(:140-148:session_id / sender_bic / receiver_bic / issuer_account_bic / settlement_payment_code / reservation_payment_code / redemption_settlement_payment_code)、SMBConfig(:150-165:host / port / username / password / domain / workstation / target_spn / in_share / out_share / in_path / out_path / max_idle_conns / poll_interval / response_timeout)、KeystoreConfig(:167-173:type / path / password / key_alias / key_password)。
configs
bizhub app 内无 configs/ 目录(main.go:39 的 -conf 默认 ../../configs 仅为本地占位)。实际运行配置为 cbdc-biz/conf/bizhub/core.yaml,docker compose 把 ${CONF_ROOT}/bizhub 挂到容器 /conf、暴露 9000:9000(cbdc-biz/docker/compose-local-run.yml:157-164)。core.yaml 关键项:cbdc.symbol、institutions[](含 endpoint + ca)、ca.pkcs11Defaults、server.addr=0.0.0.0:9000 + mTLS、data.database(postgres cbdc_bizhub)、upstream.issuer、rtgs(swift/smb/keystore)。
与其他 app 的关系
bizhub → 上游
来源:internal/client/grpc.go:56-108。NewClients(cfg *conf.Upstream, institutions []*conf.Institution):
| 目标 | 接口 | 触发 |
|---|---|---|
| Issuer | pb.IssuerServiceClient | cfg.Issuer.Addr != ""(grpc.go:67-75) |
| Institution Ops | map[code]pb.InstitutionOpsServiceClient,按 institution_code 查(GetInstitutionOpsByCode :39) | 遍历 institutions[],每条 endpoint.addr 各拨一条连接(grpc.go:83-105,至少需 1 个机构) |
bizhub SettlementBiz 调用 Issuer:
| 调用 | 出处 |
|---|---|
IssueToken(通用) | biz/settlement_biz.go:351 |
IssueToken(settlement 流程) | biz/settlement_biz.go:1174 |
TotalSupply | biz/settlement_biz.go:1327 |
issuerClient 字段定义于 settlement_biz.go:57;机构节点客户端经 institutionOps InstitutionOpsResolver 字段(:58)按 code 解析。
→ bizhub(被入站调用)
- Institution 通过 7 个 gRPC 客户端调 bizhub(
CA / Wallet / ClientAuth / Settlement / InstitutionManage / Approval / Manage)。 - Auditor → bizhub:拒绝日志(
InsertRejectionLogs)、indexer cursor(GetCursor / AppendBatch)、rulesets / ruleGroups / assetMarks 同步。 - Endorser:不直接调 bizhub。
与 cbdc-biz/pkg/
| pkg | 用途 | 出处 |
|---|---|---|
pkg/constants | TokenSymbol 初始化 | main.go:12 |
pkg/runtime | 启动日志 | main.go:13 |
pkg/signet | OTel / mTLS context / gRPC 中间件 | main.go:14、server/grpc.go |
pkg/rtgs | RTGS SMB/SWIFT 客户端 | biz/biz.go:9 |
pkg/scheduler | Settlement Worker 调度基类 | worker/*.go |
pkg/common/wallet_common | 钱包通用类型 | biz/*.go |
pkg/common/marked | 资产标记枚举与验证 | biz/manage_biz.go:15 |
pkg/common/auditor | 审计规则枚举 | biz/manage_biz.go:14 |
pkg/common/auth | 权限检查 | service/*.go |
pkg/errx | 自定义错误(RetryableError) | errors/settlement.go:11 |
RTGS 与结算流程
来源:biz/biz.go:22-69、types/settlement.go、errors/settlement.go:17-79。
Issuance(发行)
PENDING → FUNDS_RESERVED → RTGS_SETTLED → TOKENS_MINTED → COMPLETEDRedemption(赎回,burn-first 模型)
PENDING → AWAITING_SIGNATURE → TOKENS_BURNED → RTGS_SETTLED → COMPLETEDRTGS NAK 时:
→ COMPENSATING → COMPENSATION_COMPLETEDerror_type 分类(types/settlement.go:36-41)
| 值 | 含义 |
|---|---|
RETRYABLE | 网络超时、RTGS 暂不可用等 |
UNRECOVERABLE | 余额不足等永久失败 |
MANUAL_REVIEW | 模糊(如 RTGS NAK 原因不明) |
SettlementError 类型(errors/settlement.go:18-79)
go
type SettlementError struct { // :18-25
Code, Message, ErrorType, Step string
Cause error
NAK bool
}
func (e *SettlementError) IsRetryable() bool // :41
func (e *SettlementError) IsExplicitNAK() bool // :48
func ToSettlementError(err error, operation string) *SettlementError // :55错误代码常量(types/settlement.go:44-52):RTGS_NAK / RTGS_STATE_UNKNOWN / REMINT_FAILED / RTGS_UNAVAILABLE / SUBMIT_REDEEM_FAILED / INVALID_STATE / RTGS_SETTLED_DB_FAILURE(7 个)。
Makefile
来源:cbdc-biz/app/bizhub/Makefile:18-62。
| target | 用途 |
|---|---|
init | 安装 protoc 插件 + wire |
config | 从 conf.proto 生成 Go |
ent | 从 ent schema 生成 ORM |
wire | 生成 DI 代码 |
build | 编译(含 -tags pkcs11) |
generate | ent + wire + go mod tidy |
all | config + generate + build |
测试
| 文件 | 覆盖 |
|---|---|
internal/biz/ca_test.go | CaBiz fabric-ca 操作 |
internal/biz/ledger_indexer_biz_test.go | LedgerIndexerBiz batch 追加 |
internal/service/ca_service_test.go | CAService gRPC |
internal/service/ledger_indexer_service_test.go | IndexerService 接口 |
internal/server/mtls_middleware_test.go | mTLS institution_code 提取 |
internal/data/ledger_indexer_repo_dbtest_test.go | LedgerIndexerRepo 数据库测试 |
internal/client/grpc_test.go | 上游 gRPC 客户端构建 |
看代码推荐路径
cmd/bizhub/main.go:58-141→ 启动 + 3 Worker 注册。cmd/bizhub/wire_gen.go:29-93+config_provider.go→ 依赖注入图与 Bootstrap 拆分。internal/data/ent_client.go:16-63+internal/data/ent/schema/→ 数据层与 18 张表。internal/worker/settlement_pending_worker.go:21-55+_retry_worker.go+_timeout_worker.go→ Worker 三件套。internal/biz/settlement_biz.go:22-102→ 结算编排核心。internal/errors/settlement.go:18-79+types/settlement.go:36-52→ 错误模型与流程状态。internal/service/settlement_service.go:31-78→CreateRequest/QueryRequestgRPC 翻译层。
[未核]
settlement_biz.ProcessIssuanceAsync/ProcessRedemptionAsync全部实现细节。pkg/scheduler内部调度机制。-tags pkcs11在 bizhub 代码中的条件编译块(Makefile 启用但具体效果未核)。- 所有 gRPC 服务的完整 proto 定义。