Skip to content

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.goissuer(.../issuer/main.goauditor(.../auditor/main.goendorser(.../endorser/main.gobizhub(.../bizhub/main.go,无 FSC
配置config.Load :82-89:74-81:81-89:70-77:72-80
专属初始化TokenSelector :106 / bizhub 客户端 :139 / marked :149 / 身份解析 :170 / fee :176bizhub 客户端 :117 / 身份解析 :124审计日志 :135 / auditor SDK :141 / marked :150 / 撤销缓存 :186 / 审计工作池 :198DB :108 / 种子资产标记 :117 / 种子审计规则 :121
StartFSC:203:128:171:100❌ 无
RegisterResponder:210-224(AcceptTransfer/AcceptIdentityRequest/AcceptPreparedTransfer/AcceptCash):133-135(IssuerRedeemAccept):203-209(AuditView:106-110(AuditResponderView
workerwireApp :243(Approval+Finality)indexer :220wireApp :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-sdk token/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)   # → §2c

8. 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-228services/tokens/tokens.go:95-161)。

9. 跨链路对照表

链路发起进程途经上链?KMS 签名次数
Transferinstitutionendorser→auditor→endorser 背书→orderer→committer4(inst 2 + endo 1 + aud 1)
Issuebizhub→issuer同上(发起方为 issuer)5(issuer 钱包 + issuer 节点 2 + endo 1 + aud 1)
Redeeminstitution同 Transfer + issuer 背书5(Transfer 的 4 + issuer 背书 1)
钱包创建institutionbizhub CA❌(仅证书/DB)0(CA 签发在 bizhub/KMS 侧另计)
pp 部署endorser(手动 Init)orderer→committer(_meta/namespace)endorser 节点 2(namespace 背书+信封,submitter.go:103,126
清算bizhubRTGS(链外)+ issuer间接同 Issue