@@ -11,6 +11,7 @@ import (
11
11
"github.com/iotaledger/iota-core/pkg/protocol/engine/blocks"
12
12
"github.com/iotaledger/iota-core/pkg/protocol/engine/filter/postsolidfilter"
13
13
"github.com/iotaledger/iota-core/pkg/protocol/engine/filter/presolidfilter"
14
+ "github.com/iotaledger/iota-core/pkg/retainer/txretainer"
14
15
iotago "github.com/iotaledger/iota.go/v4"
15
16
)
16
17
@@ -24,27 +25,53 @@ func (r *RequestHandler) SubmitBlockWithoutAwaitingBooking(block *model.Block) e
24
25
return r .submitBlock (block )
25
26
}
26
27
27
- // submitBlockAndAwaitEvent submits a block to be processed and waits for the event to be triggered .
28
- func (r * RequestHandler ) submitBlockAndAwaitEvent (ctx context.Context , block * model.Block , evt * event. Event1 [ * blocks. Block ] ) error {
28
+ // submitBlockAndAwaitRetainer submits a block to be processed and waits for the block gets retained .
29
+ func (r * RequestHandler ) submitBlockAndAwaitRetainer (ctx context.Context , block * model.Block ) error {
29
30
filtered := make (chan error , 1 )
30
31
exit := make (chan struct {})
31
32
defer close (exit )
32
33
33
34
// Make sure we don't wait forever here. If the block is not dispatched to the main engine,
34
35
// it will never trigger one of the below events.
35
- processingCtx , processingCtxCancel := context .WithTimeout (ctx , 5 * time .Second )
36
+ processingCtx , processingCtxCancel := context .WithTimeout (ctx , 10 * time .Second )
36
37
defer processingCtxCancel ()
37
38
// Calculate the blockID so that we don't capture the block pointer in the event handlers.
38
39
blockID := block .ID ()
39
- evtUnhook := evt .Hook (func (eventBlock * blocks.Block ) {
40
- if blockID != eventBlock .ID () {
41
- return
42
- }
43
- select {
44
- case filtered <- nil :
45
- case <- exit :
40
+
41
+ var successUnhook func ()
42
+ // Hook to TransactionAttached event if the block contains a transaction.
43
+ signedTx , isTx := block .SignedTransaction ()
44
+ if isTx {
45
+ txID := signedTx .Transaction .MustID ()
46
+ // Check if the transaction is already retained. The onTransactionAttached event is only triggered if it's a new transaction.
47
+ // If the transaction is already retained, we hook to the BlockRetained event.
48
+ _ , err := r .protocol .Engines .Main .Get ().TxRetainer .TransactionMetadata (txID )
49
+ if ierrors .Is (err , txretainer .ErrEntryNotFound ) {
50
+ successUnhook = r .protocol .Events .Engine .TransactionRetainer .TransactionRetained .Hook (func (transactionID iotago.TransactionID ) {
51
+ if transactionID != txID {
52
+ return
53
+ }
54
+ select {
55
+ case filtered <- nil :
56
+ case <- exit :
57
+ }
58
+ }, event .WithWorkerPool (r .workerPool )).Unhook
46
59
}
47
- }, event .WithWorkerPool (r .workerPool )).Unhook
60
+ }
61
+
62
+ // if no hook was set, hook to the block retained event.
63
+ if successUnhook == nil {
64
+ successUnhook = r .protocol .Events .Engine .BlockRetainer .BlockRetained .Hook (func (eventBlock * blocks.Block ) {
65
+ if blockID != eventBlock .ID () {
66
+ return
67
+ }
68
+ select {
69
+ case filtered <- nil :
70
+ case <- exit :
71
+ }
72
+ }, event .WithWorkerPool (r .workerPool )).Unhook
73
+ }
74
+
48
75
prefilteredUnhook := r .protocol .Events .Engine .PreSolidFilter .BlockPreFiltered .Hook (func (event * presolidfilter.BlockPreFilteredEvent ) {
49
76
if blockID != event .Block .ID () {
50
77
return
@@ -65,7 +92,7 @@ func (r *RequestHandler) submitBlockAndAwaitEvent(ctx context.Context, block *mo
65
92
}
66
93
}, event .WithWorkerPool (r .workerPool )).Unhook
67
94
68
- defer lo .BatchReverse (evtUnhook , prefilteredUnhook , postfilteredUnhook )()
95
+ defer lo .BatchReverse (successUnhook , prefilteredUnhook , postfilteredUnhook )()
69
96
70
97
if err := r .submitBlock (block ); err != nil {
71
98
return ierrors .Wrapf (err , "failed to issue block %s" , blockID )
@@ -82,13 +109,13 @@ func (r *RequestHandler) submitBlockAndAwaitEvent(ctx context.Context, block *mo
82
109
}
83
110
}
84
111
85
- func (r * RequestHandler ) SubmitBlockAndAwaitBooking (ctx context.Context , iotaBlock * iotago.Block ) (iotago.BlockID , error ) {
112
+ func (r * RequestHandler ) SubmitBlockAndAwaitRetainer (ctx context.Context , iotaBlock * iotago.Block ) (iotago.BlockID , error ) {
86
113
modelBlock , err := model .BlockFromBlock (iotaBlock )
87
114
if err != nil {
88
115
return iotago .EmptyBlockID , ierrors .Wrap (err , "error serializing block to model block" )
89
116
}
90
117
91
- if err = r .submitBlockAndAwaitEvent (ctx , modelBlock , r . protocol . Events . Engine . Retainer . BlockRetained ); err != nil {
118
+ if err = r .submitBlockAndAwaitRetainer (ctx , modelBlock ); err != nil {
92
119
return iotago .EmptyBlockID , ierrors .Wrap (err , "error issuing model block" )
93
120
}
94
121
0 commit comments