主题
11 · 调用链路速查
每条业务链路的函数级调用链:
函数(路径:行号)— 作用。排查时配合 10 问题排查指南(按报错定段)使用;Transfer 主链 36 步逐行拆解见 03 交易跨包全链路,本页给可快速对照日志的浓缩版。路径未注明仓库的均在cbdc-chain/cbdc-biz/下。
1. 启动链
5 个 app 的 main() 共同骨架:加载配置 → 初始化 SDK → StartFSC(bizhub 除外)→ 注册 View → wire 注入 → app.Run 监听。每步失败即启动断点,按顺序比对日志。
| 步骤 | institution(app/institution/cmd/institution/main.go) | issuer(.../issuer/main.go) | auditor(.../auditor/main.go) | endorser(.../endorser/main.go) | bizhub(.../bizhub/main.go,无 FSC) |
|---|---|---|---|---|---|
| 配置 | config.Load :82-89 | :74-81 | :81-89 | :70-77 | :72-80 |
| 专属初始化 | TokenSelector :106 / bizhub 客户端 :139 / marked :149 / 身份解析 :170 / fee :176 | bizhub 客户端 :117 / 身份解析 :124 | 审计日志 :135 / auditor SDK :141 / marked :150 / 撤销缓存 :186 / 审计工作池 :198 | — | DB :108 / 种子资产标记 :117 / 种子审计规则 :121 |
| StartFSC | :203 | :128 | :171 | :100 | ❌ 无 |
| RegisterResponder | :210-224(AcceptTransfer/AcceptIdentityRequest/AcceptPreparedTransfer/AcceptCash) | :133-135(IssuerRedeemAccept) | :203-209(AuditView) | :106-110(AuditResponderView) | — |
| worker | wireApp :243(Approval+Finality) | — | indexer :220 | — | wireApp :131(Settlement Pending/Retry/Timeout ×3) |
| 监听 | app.Run :250 | :144 | :225 | :119 | :138 |
就绪标志:FSC 节点日志出现
Running fscnode <name>;endorser 就绪后还需手动调一次Init(见 §6)才能处理交易。
2. Transfer 链(浓缩版)
2a. 同步路径(服务端持钥,测试用)
TransferView.Call (pkg/views/transfer.go:58)
├─ ttx.NewTransaction (:100) → tx.Transfer(senderWallet,...) (:157/:205) # 选币+构造+ZK 证明
├─ AuditAndEndorseView (:217) # → §7 审计背书链
└─ ttx.NewOrderingAndFinalityView (:227) # 广播+等终局2b. 异步路径(外部签名,生产路径)
PrepareTransferView.Call (transfer.go:267)
├─ 收款人校验 RecipientValidator.ValidateTransfer (:302)
├─ tx.Transfer(...) (:488/:553) # 选币+ZK 证明
├─ tx.TokenRequest.MarshalToSign (:583) # 待签字节
└─ 返回 PendingTransaction{TxID, MessageToSign, SignerIdentity} (:595-625)
【客户端离线 ECDSA 签名】
SubmitSignatureView.Call (transfer.go:680)
├─ NewPreSubmittedSignatureSigner (:694) # 包装外部签名
├─ AuditAndEndorseView(tx, WithExternalWalletSigner) (:704) # → §7
├─ ttx.NewOrderingView (:725) # 只广播
└─ FinalityRegistry.Register (:736) # → §8 异步等终局2c. 背书内部(FSC 模型,跨 institution/endorser)
ttx.NewCollectEndorsementsView (fabric-token-sdk token/services/ttx/collectendorsements.go:95)
├─ requestSignaturesOnIssues/Transfers (:104-117) # owner/issuer 签名写入 TokenRequest
├─ requestAudit (:122,被 cbdc 用 WithSkipAuditing 跳过,σ 已注入)
└─ requestApproval (:131) → network.RequestApproval
└─ RequestApprovalView.Call (network/fabric/endorsement/fsc/initiator.go:64)
├─ tx.EndorseProposal (:77) # institution 节点签 proposal【KMS ①】
├─ CollectEndorsements(→endorser1) (:99)
│ └─ (endorser) RequestApprovalResponderView (responder.go:72)
│ receive→validateProposal(:202)→validate(:293)→endorse(:332)
│ # endorser 签背书【KMS ②】
└─ tx.Envelope (:106) # institution 签信封【KMS ③】
(auditor σ 为【KMS ④】,在 §7 审计链中产生)3. Issue 链(bizhub 触发的发行)
SettlementBiz.IssueTokenWithInstitution (app/bizhub/internal/biz/settlement_biz.go:131) # gRPC 入口,建 settlement_request
└─【SettlementPendingWorker 轮询 5s】ProcessIssuanceAsync (:221)
├─ sendReservation (:268) # RTGS SMT211 资金预留
├─ sendSettlement (:302) # RTGS SMT201 结算
└─ mintTokens (:336) # 调 issuer
└─ IssuerService.IssueToken (app/issuer/internal/service/issuer.go:21)
└─ IssuerBiz.IssueWithMarked (app/issuer/internal/biz/issuer.go:70)
└─ InitiateView(IssueCashView) (:82-96)
└─ IssueCashView.Call (pkg/views/issue.go:38)
├─ ResolveIdentity (:50) → tx.Issue (:72)
├─ marked.SetMarkedOutputsMetadata (:84)
├─ AuditAndEndorseView (:90) # → §7
└─ ttx.NewOrderingAndFinalityView (:97)失败回流:mintTokens 失败 → settlement_request 状态机走 retry(≤3 次)/timeout(5 分钟)/补偿,见 03·§9 状态机 与 10·§9。
4. Redeem 链(回笼)
同步: RedeemView.Call (pkg/views/redeem.go:68)
├─ tx.Redeem(senderWallet,...) (:95)
├─ AuditAndEndorseView (:100) # → §7
├─ 状态断言 pending (:111)
└─ OrderingAndFinality → 状态断言 confirmed (:123)
异步: PrepareRedeemView.Call (redeem.go:171)
├─ tx.Redeem (:199) → MarshalToSign (:214)
└─ 返回 PendingTransaction
【外部签名】→ SubmitSignatureView(同 §2b,transfer.go:680)
issuer 侧(被动): IssuerRedeemAcceptView.Call (redeem.go:140)
├─ ttx.ReceiveTransaction (:142)
└─ ttx.NewEndorseView (:149) # issuer 钱包对 redeem 背书【比 transfer 多的 1 签】5. 钱包创建链
InstitutionOpsService.GenerateWalletID (app/institution/internal/service/wallet_service.go:295) # 生成带类别前缀的 walletID
InstitutionOpsService.CreateWallet (:179) → executeCreateWalletSync (:231)
└─ InstitutionWalletBiz.ExecuteWalletCreation (app/institution/internal/biz/wallet_biz.go:251)
├─ ValidateWalletID # "invalid wallet_id"
├─ BizHubClients.CA.Register # 向 bizhub CA 注册身份("ca register")
├─ BizHubClients.CA.EnrollCsr # 签发证书("ca enroll csr")
├─ CreateX509Wallet (:211) # 本地注册 x509 身份到 Token SDK("register wallet")
│ └─ identity.NewX509ConfigBuilder → RegisterIdentity(Type:"x509")
└─ BizHubClients.Wallet.CreateWalletLifecycle # bizhub 落生命周期记录排查:卡在哪步看 10·§1 的钱包类错误;机构级/政府类钱包另需审批流(approval worker,internal/worker/approval_worker.go)。
6. Endorser Init(pp 部署链)
EndorserService.Init (app/endorser/internal/service/endorser.go:20) # grpcurl :9300 调用
└─ EndorserBiz.Init (app/endorser/internal/biz/endorser.go:41)
├─ tmsConfigurations (:79) # "no token configurations found"
├─ readPublicParams (:96) # 读 zkatdlognoghv1_pp.json("read PP file ...")
├─ shouldDeployPublicParams (:124)# 比对链上已有 pp("already deployed, skipping")
└─ tms.DeployTMSWithPP (:71) # 部署上链(经 submitter 签 namespace 背书+信封)这是全网 token 能力的开关:没跑 Init,所有节点都会报
cannot retrieve public params(token-sdktoken/core/tms.go:243,四级取参见 新手入门·pp)。
7. 审计背书链(AuditAndEndorseView 内部,三进程协作)
(institution) AuditAndEndorseView.Call (pkg/views/endorsement.go:34)
├─ Phase1: GetSession("endorser1") (:44) → Send(txRaw) (:55)
│ └─ (endorser) AuditResponderView.Call (pkg/views/audit.go:88)
│ └─ RequestAuditView.Call (:55)
│ ├─ GetSession("auditor") (:57) → Send (:65)
│ │ └─ (auditor) AuditView.Call (audit.go:136)
│ │ ├─ workerpool 准入 (:166 饱和即拒)
│ │ ├─ ZK 验证 + 合规规则(余额/标记/撤销) (:189-291)
│ │ └─ 签 σ 返回【auditor KMS 签名】
│ └─ 收 σ (:72-78)
│ └─ 回传 σ 给 institution (:121-125)
├─ Phase2: verifyAuditorSignature (:72) → AddAuditorSignature (:76)
└─ Phase3: ttx.NewCollectEndorsementsView(WithSkipAuditing) (:87) # → §2c8. finality 回流链(四种结局)
FinalityRegistry/Worker.Register (app/institution/internal/worker/finality_worker.go:128)
└─ goroutine watch (:186, 总超时 2 分钟)
└─ InitiateView(NewFinalityView(tx, Polling 5s)) (:231)
├─ COMMITTED → selector.ConfirmSpent (:236) # Redis 清锁,outcome="committed" (:260)
├─ FAILED → selector.UnlockAll (:251) # 归还锁币,outcome="failed"
├─ 超时/取消 → selector.UnlockAll (:244) # outcome="timeout" ⚠️ 若实际已上链需对账
└─ panic → selector.UnlockAll (:204) # outcome="panic"SDK 侧落账动作(所有 FSC 节点同款):finality 监听器在单个短 DB 事务里 AppendValid(写新币+删旧币)+ SetStatus(Confirmed)(fabric-token-sdk token/services/ttx/finality/listener.go:187-228 → services/tokens/tokens.go:95-161)。
9. 跨链路对照表
| 链路 | 发起进程 | 途经 | 上链? | KMS 签名次数 |
|---|---|---|---|---|
| Transfer | institution | endorser→auditor→endorser 背书→orderer→committer | ✅ | 4(inst 2 + endo 1 + aud 1) |
| Issue | bizhub→issuer | 同上(发起方为 issuer) | ✅ | 5(issuer 钱包 + issuer 节点 2 + endo 1 + aud 1) |
| Redeem | institution | 同 Transfer + issuer 背书 | ✅ | 5(Transfer 的 4 + issuer 背书 1) |
| 钱包创建 | institution | bizhub CA | ❌(仅证书/DB) | 0(CA 签发在 bizhub/KMS 侧另计) |
| pp 部署 | endorser(手动 Init) | orderer→committer(_meta/namespace) | ✅ | endorser 节点 2(namespace 背书+信封,submitter.go:103,126) |
| 清算 | bizhub | RTGS(链外)+ issuer | 间接 | 同 Issue |