Skip to content

Commit 228a588

Browse files
committed
feat(evm-reader): fast sync the last input check block when the application has no inputs
1 parent 85ee681 commit 228a588

2 files changed

Lines changed: 72 additions & 0 deletions

File tree

internal/evmreader/evmreader.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,10 @@ func (r *Service) watchForNewBlocks(ctx context.Context, ready chan<- struct{})
187187
r.Logger.Debug(fmt.Sprintf("Using block %d and not %d because of commitment policy: %s",
188188
mostRecentHeader.Number.Uint64(), header.Number.Uint64(), r.defaultBlock))
189189
}
190+
errs := r.syncApplicationsWithNoInput(ctx, apps, r.client, blockNumber)
191+
if len(errs) != 0 {
192+
r.Logger.Info("failed to fast sync applications, using checkForNewInputs method")
193+
}
190194

191195
r.checkForNewInputs(ctx, apps, blockNumber)
192196

internal/evmreader/input.go

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,80 @@ import (
77
"context"
88
"errors"
99
"fmt"
10+
"math/big"
1011

1112
. "github.com/cartesi/rollups-node/internal/model"
13+
"github.com/cartesi/rollups-node/pkg/contracts/iinputbox"
1214
"github.com/ethereum/go-ethereum/accounts/abi/bind"
1315
"github.com/ethereum/go-ethereum/common"
16+
"github.com/ethereum/go-ethereum/ethclient"
1417
)
1518

19+
// checkApplicationsWithNoInputAndSync is an optimization that updates the lastProcessedBlock of applications with
20+
// no inputs to the mostRecentBlockNumber, no need to check block ranges.
21+
// NOTE(mpolitzer): Ideally this only gets called when new applications are created or registered.
22+
func (r *Service) syncApplicationsWithNoInput(
23+
ctx context.Context,
24+
applications []appContracts,
25+
iclient EthClientInterface,
26+
mostRecentBlockNumber uint64,
27+
) []error {
28+
errs := []error{}
29+
30+
// we need the concrete client type to interact with the contracts so we type assert
31+
// that works via a type switch
32+
var client *ethclient.Client
33+
switch unwrapped := iclient.(type) {
34+
case *ethclient.Client:
35+
client = unwrapped
36+
default:
37+
return []error{fmt.Errorf("error: unexpected type for ethclient")}
38+
}
39+
40+
callOpts := bind.CallOpts{Context: ctx}
41+
zero := big.NewInt(0)
42+
for _, app := range applications {
43+
r.Logger.Debug("Check application for fast sync",
44+
"application", app.application.Name,
45+
"last_input_check_block", app.application.LastInputCheckBlock,
46+
"input_box_block", app.application.IInputBoxBlock,
47+
)
48+
49+
// Only for input box
50+
if !app.application.HasDataAvailabilitySelector(DataAvailability_InputBox) {
51+
continue
52+
}
53+
54+
// and for applications that have not been synced yet
55+
if app.application.LastInputCheckBlock > app.application.IInputBoxBlock {
56+
continue
57+
}
58+
59+
iib, err := iinputbox.NewIInputBox(app.application.IInputBoxAddress, client)
60+
if err != nil {
61+
errs = append(errs, fmt.Errorf("error: syncApplicationsWithNoInput failed to instantiate iinput box for application: %v", app.application.IApplicationAddress))
62+
continue
63+
}
64+
65+
nInputs, err := iib.GetNumberOfInputs(&callOpts, app.application.IApplicationAddress)
66+
if err != nil {
67+
errs = append(errs, fmt.Errorf("error: syncApplicationsWithNoInput failed retrieve the number of inputs for application: %v", app.application.IApplicationAddress))
68+
continue
69+
}
70+
71+
if nInputs.Cmp(zero) == 0 {
72+
r.Logger.Info("Fast sync last input block",
73+
"application", app.application.Name,
74+
"from", app.application.LastInputCheckBlock,
75+
"to", mostRecentBlockNumber)
76+
77+
// leave DB interaction to checkForNewInputs
78+
app.application.LastInputCheckBlock = mostRecentBlockNumber-1
79+
}
80+
}
81+
return nil
82+
}
83+
1684
// checkForNewInputs checks if is there new Inputs for all running Applications
1785
func (r *Service) checkForNewInputs(
1886
ctx context.Context,

0 commit comments

Comments
 (0)