@@ -1027,6 +1027,18 @@ func (cs *State) handleMsg(ctx context.Context, mi msgInfo, fsyncUponCompletion
1027
1027
// will not cause transition.
1028
1028
// once proposal is set, we can receive block parts
1029
1029
err = cs .setProposal (msg .Proposal , mi .ReceiveTime )
1030
+ if cs .config .GossipTransactionHashOnly && ! cs .isProposer (cs .privValidatorPubKey .Address ()) {
1031
+ created := cs .tryCreateProposalBlock (msg .Proposal .Height , msg .Proposal .Round , msg .Proposal .Header , msg .Proposal .LastCommit , msg .Proposal .Evidence , msg .Proposal .ProposerAddress )
1032
+ if created {
1033
+ if fsyncUponCompletion {
1034
+ if err := cs .wal .FlushAndSync (); err != nil { // fsync
1035
+ panic ("error flushing wal after receiving all block parts" )
1036
+ }
1037
+ }
1038
+ cs .handleCompleteProposal (ctx , msg .Proposal .Height , span )
1039
+
1040
+ }
1041
+ }
1030
1042
1031
1043
case * BlockPartMessage :
1032
1044
spanCtx , span := cs .tracer .Start (cs .getTracingCtx (ctx ), "cs.state.handleBlockPartMsg" )
@@ -1482,7 +1494,7 @@ func (cs *State) defaultDecideProposal(ctx context.Context, height int64, round
1482
1494
1483
1495
// Make proposal
1484
1496
propBlockID := types.BlockID {Hash : block .Hash (), PartSetHeader : blockParts .Header ()}
1485
- proposal := types .NewProposal (height , round , cs .ValidRound , propBlockID , block .Header .Time , block .Data .TxKeys )
1497
+ proposal := types .NewProposal (height , round , cs .ValidRound , propBlockID , block .Header .Time , block .Data .TxKeys , block . Header , block . LastCommit , block . Evidence , cs . privValidatorPubKey . Address () )
1486
1498
p := proposal .ToProto ()
1487
1499
cs .logger .Info ("PSULOG - converted proposal to proto" , "txkeys" , p .TxKeys , "height" , p .Height , "round" , p .Round )
1488
1500
@@ -1835,6 +1847,7 @@ func (cs *State) enterPrecommit(ctx context.Context, height int64, round int32,
1835
1847
"entering precommit step with invalid args" ,
1836
1848
"current" , fmt .Sprintf ("%v/%v/%v" , cs .Height , cs .Round , cs .Step ),
1837
1849
"time" , time .Now ().UnixMilli (),
1850
+ "expected" , fmt .Sprintf ("#%v/%v" , height , round ),
1838
1851
)
1839
1852
return
1840
1853
}
@@ -2444,6 +2457,46 @@ func (cs *State) addProposalBlockPart(
2444
2457
2445
2458
return added , nil
2446
2459
}
2460
+
2461
+ func (cs * State ) tryCreateProposalBlock (height int64 , round int32 , header types.Header , lastCommit * types.Commit , evidence []types.Evidence , proposerAddress types.Address ) bool {
2462
+ cs .logger .Info ("PSULOG - trying to create proposal block" )
2463
+
2464
+ // Blocks might be reused, so round mismatch is OK
2465
+ if cs .Height != height {
2466
+ cs .logger .Info ("received block part from wrong height" , "height" , height , "round" , round )
2467
+ cs .metrics .BlockGossipPartsReceived .With ("matches_current" , "false" ).Add (1 )
2468
+ return false
2469
+ }
2470
+
2471
+ if cs .Proposal == nil || len (cs .blockExec .GetMissingTxs (cs .Proposal .TxKeys )) != 0 {
2472
+ cs .logger .Info ("PSULOG - cannot create block, either proposal is missing or we have missing keys" , "proposal" , cs .Proposal )
2473
+ return false
2474
+ } else {
2475
+ txKeys := cs .Proposal .TxKeys
2476
+ //block := types.MakeBlock(height, cs.blockExec.GetTxsForKeys(txKeys), lastCommit, evidence, false)
2477
+ block := cs .state .MakeBlock (height , cs .blockExec .GetTxsForKeys (txKeys ), lastCommit , evidence , proposerAddress , false )
2478
+ // We have full proposal block. Set txs in proposal block from mempool
2479
+ cs .logger .Info ("PSULOG - populating txs with keys" , "keys" , txKeys )
2480
+ cs .logger .Info ("PSULOG - recreating proposal block" , "block" , block )
2481
+ txs := cs .blockExec .GetTxsForKeys (txKeys )
2482
+ block .Version = header .Version
2483
+ block .Data .Txs = txs
2484
+ block .DataHash = block .Data .Hash ()
2485
+ block .Header .Time = header .Time
2486
+ block .Header .ProposerAddress = header .ProposerAddress
2487
+ cs .ProposalBlock = block
2488
+ cs .logger .Info ("PSULOG - setting proposal block" , "block" , block )
2489
+ partSet , err := block .MakePartSet (types .BlockPartSizeBytes )
2490
+ if err != nil {
2491
+ return false
2492
+ }
2493
+ cs .ProposalBlockParts = partSet
2494
+ // NOTE: it's possible to receive complete proposal blocks for future rounds without having the proposal
2495
+ cs .logger .Info ("Successfully recreated proposal block" , "block" , block )
2496
+ return true
2497
+ }
2498
+ }
2499
+
2447
2500
func (cs * State ) handleCompleteProposal (ctx context.Context , height int64 , handleBlockPartSpan otrace.Span ) {
2448
2501
cs .logger .Info ("PSULOG - handle complete proposal" , "height" , height , "proposal block parts" , cs .ProposalBlockParts )
2449
2502
// Update Valid* if we can.
0 commit comments