Skip to content
This repository was archived by the owner on Oct 25, 2024. It is now read-only.

Commit 30381d5

Browse files
Ruteriavalonche
authored andcommitted
Resubmit block build job periodically (#22)
1 parent 5118498 commit 30381d5

File tree

4 files changed

+124
-6
lines changed

4 files changed

+124
-6
lines changed

builder/builder.go

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package builder
33
import (
44
"errors"
55
_ "os"
6+
"time"
67

78
"github.com/ethereum/go-ethereum/common/hexutil"
89
"github.com/ethereum/go-ethereum/core/beacon"
@@ -41,6 +42,7 @@ type Builder struct {
4142
beaconClient IBeaconClient
4243
relay IRelay
4344
eth IEthereumService
45+
resubmitter Resubmitter
4446

4547
builderSecretKey *bls.SecretKey
4648
builderPublicKey boostTypes.PublicKey
@@ -56,6 +58,7 @@ func NewBuilder(sk *bls.SecretKey, bc IBeaconClient, relay IRelay, builderSignin
5658
beaconClient: bc,
5759
relay: relay,
5860
eth: eth,
61+
resubmitter: Resubmitter{},
5962
builderSecretKey: sk,
6063
builderPublicKey: pk,
6164

@@ -140,13 +143,23 @@ func (b *Builder) OnPayloadAttribute(attrs *BuilderPayloadAttributes) error {
140143
return errors.New("parent block not found in blocktree")
141144
}
142145

143-
executableData, block := b.eth.BuildBlock(attrs)
144-
if executableData == nil || block == nil {
145-
log.Error("did not receive the payload")
146-
return errors.New("could not build block")
147-
}
146+
firstBlockResult := b.resubmitter.newTask(12*time.Second, time.Second, func() error {
147+
executableData, block := b.eth.BuildBlock(attrs)
148+
if executableData == nil || block == nil {
149+
log.Error("did not receive the payload")
150+
return errors.New("did not receive the payload")
151+
}
152+
153+
err := b.onSealedBlock(executableData, block, proposerPubkey, vd.FeeRecipient, attrs.Slot)
154+
if err != nil {
155+
log.Error("could not run block hook", "err", err)
156+
return err
157+
}
158+
159+
return nil
160+
})
148161

149-
return b.onSealedBlock(executableData, block, proposerPubkey, vd.FeeRecipient, attrs.Slot)
162+
return firstBlockResult
150163
}
151164

152165
func executableDataToExecutionPayload(data *beacon.ExecutableDataV1) (*boostTypes.ExecutionPayload, error) {

builder/builder_test.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package builder
33
import (
44
"math/big"
55
"testing"
6+
"time"
67

78
"github.com/ethereum/go-ethereum/common"
89
"github.com/ethereum/go-ethereum/common/hexutil"
@@ -120,4 +121,10 @@ func TestOnPayloadAttributes(t *testing.T) {
120121
require.Equal(t, expectedSignature, testRelay.submittedMsg.Signature)
121122

122123
require.Equal(t, uint64(25), testRelay.requestedSlot)
124+
125+
// Clear the submitted message and check that the job will be ran again and a new message will be submitted
126+
testRelay.submittedMsg = nil
127+
time.Sleep(2 * time.Second)
128+
require.NotNil(t, testRelay.submittedMsg)
129+
require.Equal(t, expectedMessage, *testRelay.submittedMsg.Message)
123130
}

builder/resubmitter.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package builder
2+
3+
import (
4+
"context"
5+
"sync"
6+
"time"
7+
)
8+
9+
type Resubmitter struct {
10+
mu sync.Mutex
11+
cancel context.CancelFunc
12+
}
13+
14+
func (r *Resubmitter) newTask(repeatFor time.Duration, interval time.Duration, fn func() error) error {
15+
repeatUntilCh := time.After(repeatFor)
16+
17+
r.mu.Lock()
18+
if r.cancel != nil {
19+
r.cancel()
20+
}
21+
ctx, cancel := context.WithCancel(context.Background())
22+
r.cancel = cancel
23+
r.mu.Unlock()
24+
25+
firstRunErr := fn()
26+
27+
go func() {
28+
for ctx.Err() == nil {
29+
select {
30+
case <-ctx.Done():
31+
return
32+
case <-repeatUntilCh:
33+
cancel()
34+
return
35+
case <-time.After(interval):
36+
fn()
37+
}
38+
}
39+
}()
40+
41+
return firstRunErr
42+
}

builder/resubmitter_test.go

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package builder
2+
3+
import (
4+
"errors"
5+
"testing"
6+
"time"
7+
8+
"github.com/stretchr/testify/require"
9+
)
10+
11+
func TestResubmitter(t *testing.T) {
12+
13+
resubmitter := Resubmitter{}
14+
15+
pingCh := make(chan error)
16+
go func() {
17+
res := resubmitter.newTask(time.Second, 100*time.Millisecond, func() error {
18+
return <-pingCh
19+
})
20+
require.ErrorContains(t, res, "xx")
21+
}()
22+
23+
select {
24+
case pingCh <- errors.New("xx"):
25+
case <-time.After(time.Second):
26+
t.Error("timeout waiting for the function")
27+
}
28+
29+
select {
30+
case pingCh <- nil:
31+
t.Error("function restarted too soon")
32+
default:
33+
}
34+
35+
time.Sleep(200 * time.Millisecond)
36+
37+
select {
38+
case pingCh <- nil:
39+
default:
40+
t.Error("function restarted too late")
41+
}
42+
43+
time.Sleep(800 * time.Millisecond)
44+
45+
select {
46+
case pingCh <- nil:
47+
default:
48+
t.Error("function restarted too late")
49+
}
50+
51+
select {
52+
case pingCh <- nil:
53+
t.Error("function restarted after deadline")
54+
case <-time.After(200 * time.Millisecond):
55+
}
56+
}

0 commit comments

Comments
 (0)