@@ -74,6 +74,10 @@ const (
74
74
// maxNumHTLCsPerParty is the maximum number of HTLCs that can be added
75
75
// by a single party to a channel.
76
76
maxNumHTLCsPerParty = maxNumHTLCs / 2
77
+
78
+ // proofChunk size is the chunk size of proofs, in the case that a proof
79
+ // is too large to be sent in a single message.
80
+ proofChunkSize = 60_000
77
81
)
78
82
79
83
// ErrorReporter is used to report an error back to the caller and/or peer that
@@ -420,7 +424,9 @@ type pendingAssetFunding struct {
420
424
fundingAckChan chan bool
421
425
422
426
fundingFinalizedSignal chan struct {}
423
- finalizedCloseOnce sync.Once
427
+
428
+ finalizedCloseOnce sync.Once
429
+ inputProofChunks map [chainhash.Hash ][]cmsg.ProofChunk
424
430
}
425
431
426
432
// addInputProof adds a new proof to the set of proofs that'll be used to fund
@@ -461,6 +467,34 @@ func (p *pendingAssetFunding) addToFundingCommitment(a *asset.Asset) error {
461
467
return p .fundingAssetCommitment .Merge (newCommitment )
462
468
}
463
469
470
+ // addInputProofChunk adds a new proof chunk to the set of proof chunks that'll
471
+ // be processed. If this is the last chunk for this proof, then true is
472
+ // returned.
473
+ func (p * pendingAssetFunding ) addInputProofChunk (chunk cmsg.ProofChunk ,
474
+ ) (* proof.Proof , error ) {
475
+
476
+ // Collect this proof chunk with the rest of the proofs.
477
+ chunkID := chunk .ChunkSumID .Val
478
+
479
+ proofChunks := p .inputProofChunks [chunkID ]
480
+ proofChunks = append (proofChunks , chunk )
481
+ p .inputProofChunks [chunkID ] = proofChunks
482
+
483
+ // If this isn't the last chunk, then we can just return nil and exit
484
+ if ! chunk .Last .Val {
485
+ return nil , nil
486
+ }
487
+
488
+ // Otherwise, this is the last chunk, so we'll extract all the chunks
489
+ // and assemble the final proof.
490
+ finalProof , err := cmsg .AssembleProofChunks (proofChunks )
491
+ if err != nil {
492
+ return nil , fmt .Errorf ("unable to assemble proof chunks: %w" , err )
493
+ }
494
+
495
+ return finalProof , nil
496
+ }
497
+
464
498
// newCommitBlobAndLeaves creates a new commitment blob that'll be stored in
465
499
// the channel state for the specified party.
466
500
func newCommitBlobAndLeaves (pendingFunding * pendingAssetFunding ,
@@ -699,6 +733,7 @@ func (f *fundingFlowIndex) fromMsg(chainParams *address.ChainParams,
699
733
amt : assetProof .Amt ().UnwrapOr (0 ),
700
734
fundingAckChan : make (chan bool , 1 ),
701
735
fundingFinalizedSignal : make (chan struct {}),
736
+ inputProofChunks : make (map [chainhash.Hash ][]cmsg.ProofChunk ),
702
737
}
703
738
(* f )[pid ] = assetFunding
704
739
}
@@ -827,15 +862,33 @@ func (f *FundingController) sendInputOwnershipProofs(peerPub btcec.PublicKey,
827
862
log .Tracef ("Sending input ownership proof to remote party: %x" ,
828
863
proofBytes )
829
864
830
- inputProof := cmsg .NewTxAssetInputProof (
831
- fundingState .pid , * fundingState .inputProofs [i ],
832
- )
865
+ inputProof := fundingState .inputProofs [i ]
866
+ inputAsset := inputProof .Asset
833
867
834
- // Finally, we'll send the proof to the remote peer.
835
- err := f .cfg .PeerMessenger .SendMessage (ctx , peerPub , inputProof )
868
+ // For each proof, we'll chunk them up optimistically to make
869
+ // sure we'll never exceed the upper message limit.
870
+ proofChunks , err := cmsg .CreateProofChunks (
871
+ * inputProof , proofChunkSize ,
872
+ )
836
873
if err != nil {
837
- return fmt .Errorf ("unable to send proof to peer: %w" ,
838
- err )
874
+ return fmt .Errorf ("unable to create proof " +
875
+ "chunks: %w" , err )
876
+ }
877
+
878
+ for _ , proofChunk := range proofChunks {
879
+ inputProof := cmsg .NewTxAssetInputProof (
880
+ fundingState .pid , inputAsset .ID (),
881
+ inputAsset .Amount , proofChunk ,
882
+ )
883
+
884
+ // Finally, we'll send the proof to the remote peer.
885
+ err := f .cfg .PeerMessenger .SendMessage (
886
+ ctx , peerPub , inputProof ,
887
+ )
888
+ if err != nil {
889
+ return fmt .Errorf ("unable to send " +
890
+ "proof to peer: %w" , err )
891
+ }
839
892
}
840
893
}
841
894
@@ -1295,9 +1348,27 @@ func (f *FundingController) processFundingMsg(ctx context.Context,
1295
1348
// This is input proof, so we'll verify the challenge witness, then
1296
1349
// store the proof.
1297
1350
case * cmsg.TxAssetInputProof :
1351
+ // By default, we'll get chunks of the proof sent to us. So
1352
+ // we'll add this set to the chunks, then proceed but only if we
1353
+ // have all the chunks.
1354
+ finalProof , err := assetFunding .addInputProofChunk (
1355
+ assetProof .ProofChunk .Val ,
1356
+ )
1357
+ if err != nil {
1358
+ return tempPID , fmt .Errorf ("unable to add input proof " +
1359
+ "chunk: %w" , err )
1360
+ }
1361
+
1362
+ // If there's no final proof yet, we can just return>
1363
+ if finalProof == nil {
1364
+ return tempPID , nil
1365
+ }
1366
+
1367
+ // Otherwise, we have all the proofs we need.
1368
+ //
1298
1369
// Before we proceed, we'll make sure that we already know of
1299
1370
// the genesis proof for the incoming asset.
1300
- _ , err : = f .cfg .AssetSyncer .QueryAssetInfo (
1371
+ _ , err = f .cfg .AssetSyncer .QueryAssetInfo (
1301
1372
ctx , assetProof .AssetID .Val ,
1302
1373
)
1303
1374
if err != nil {
@@ -1306,10 +1377,10 @@ func (f *FundingController) processFundingMsg(ctx context.Context,
1306
1377
assetProof .AssetID .Val , err )
1307
1378
}
1308
1379
1309
- p := assetProof . Proof . Val
1380
+ p := finalProof
1310
1381
log .Infof ("Validating input proof, prev_out=%v" , p .OutPoint ())
1311
1382
1312
- l , err := f .cfg .ChainBridge .GenProofChainLookup (& p )
1383
+ l , err := f .cfg .ChainBridge .GenProofChainLookup (p )
1313
1384
if err != nil {
1314
1385
return tempPID , fmt .Errorf ("unable to create proof " +
1315
1386
"lookup: %w" , err )
@@ -1331,7 +1402,7 @@ func (f *FundingController) processFundingMsg(ctx context.Context,
1331
1402
// Now that we know the proof is valid, we'll add it to the
1332
1403
// funding state.
1333
1404
assetFunding .addInputProof (
1334
- & assetProof . Proof . Val ,
1405
+ finalProof ,
1335
1406
)
1336
1407
1337
1408
// This is an output proof, so now we should be able to verify the
0 commit comments