Skip to content

Commit d0ab7dc

Browse files
committed
tapchannelmsg: send+recv chunks of the input proofs
In this commit, we start to send+recv chunks of the input proofs. This ensures that if a suffix proof is larger than the `lnwire` message size, then we'll be able to still send+recv it.
1 parent 41de444 commit d0ab7dc

File tree

1 file changed

+83
-12
lines changed

1 file changed

+83
-12
lines changed

tapchannel/aux_funding_controller.go

Lines changed: 83 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,10 @@ const (
7474
// maxNumHTLCsPerParty is the maximum number of HTLCs that can be added
7575
// by a single party to a channel.
7676
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
7781
)
7882

7983
// ErrorReporter is used to report an error back to the caller and/or peer that
@@ -420,7 +424,9 @@ type pendingAssetFunding struct {
420424
fundingAckChan chan bool
421425

422426
fundingFinalizedSignal chan struct{}
423-
finalizedCloseOnce sync.Once
427+
428+
finalizedCloseOnce sync.Once
429+
inputProofChunks map[chainhash.Hash][]cmsg.ProofChunk
424430
}
425431

426432
// 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 {
461467
return p.fundingAssetCommitment.Merge(newCommitment)
462468
}
463469

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+
464498
// newCommitBlobAndLeaves creates a new commitment blob that'll be stored in
465499
// the channel state for the specified party.
466500
func newCommitBlobAndLeaves(pendingFunding *pendingAssetFunding,
@@ -699,6 +733,7 @@ func (f *fundingFlowIndex) fromMsg(chainParams *address.ChainParams,
699733
amt: assetProof.Amt().UnwrapOr(0),
700734
fundingAckChan: make(chan bool, 1),
701735
fundingFinalizedSignal: make(chan struct{}),
736+
inputProofChunks: make(map[chainhash.Hash][]cmsg.ProofChunk),
702737
}
703738
(*f)[pid] = assetFunding
704739
}
@@ -827,15 +862,33 @@ func (f *FundingController) sendInputOwnershipProofs(peerPub btcec.PublicKey,
827862
log.Tracef("Sending input ownership proof to remote party: %x",
828863
proofBytes)
829864

830-
inputProof := cmsg.NewTxAssetInputProof(
831-
fundingState.pid, *fundingState.inputProofs[i],
832-
)
865+
inputProof := fundingState.inputProofs[i]
866+
inputAsset := inputProof.Asset
833867

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+
)
836873
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+
}
839892
}
840893
}
841894

@@ -1295,9 +1348,27 @@ func (f *FundingController) processFundingMsg(ctx context.Context,
12951348
// This is input proof, so we'll verify the challenge witness, then
12961349
// store the proof.
12971350
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+
//
12981369
// Before we proceed, we'll make sure that we already know of
12991370
// the genesis proof for the incoming asset.
1300-
_, err := f.cfg.AssetSyncer.QueryAssetInfo(
1371+
_, err = f.cfg.AssetSyncer.QueryAssetInfo(
13011372
ctx, assetProof.AssetID.Val,
13021373
)
13031374
if err != nil {
@@ -1306,10 +1377,10 @@ func (f *FundingController) processFundingMsg(ctx context.Context,
13061377
assetProof.AssetID.Val, err)
13071378
}
13081379

1309-
p := assetProof.Proof.Val
1380+
p := finalProof
13101381
log.Infof("Validating input proof, prev_out=%v", p.OutPoint())
13111382

1312-
l, err := f.cfg.ChainBridge.GenProofChainLookup(&p)
1383+
l, err := f.cfg.ChainBridge.GenProofChainLookup(p)
13131384
if err != nil {
13141385
return tempPID, fmt.Errorf("unable to create proof "+
13151386
"lookup: %w", err)
@@ -1331,7 +1402,7 @@ func (f *FundingController) processFundingMsg(ctx context.Context,
13311402
// Now that we know the proof is valid, we'll add it to the
13321403
// funding state.
13331404
assetFunding.addInputProof(
1334-
&assetProof.Proof.Val,
1405+
finalProof,
13351406
)
13361407

13371408
// This is an output proof, so now we should be able to verify the

0 commit comments

Comments
 (0)