Skip to content

Commit 21d460b

Browse files
committed
refactor(claimer): code organization and add consensus changed check
1 parent 7323d95 commit 21d460b

4 files changed

Lines changed: 284 additions & 184 deletions

File tree

Lines changed: 32 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@ import (
99
"iter"
1010
"log/slog"
1111
"math/big"
12-
"time"
1312

1413
"github.com/cartesi/rollups-node/internal/config"
1514
"github.com/cartesi/rollups-node/internal/model"
1615
. "github.com/cartesi/rollups-node/internal/model"
1716
"github.com/cartesi/rollups-node/pkg/contracts/iconsensus"
1817
"github.com/cartesi/rollups-node/pkg/ethutil"
18+
1919
"github.com/ethereum/go-ethereum"
2020
"github.com/ethereum/go-ethereum/accounts/abi"
2121
"github.com/ethereum/go-ethereum/accounts/abi/bind"
@@ -25,40 +25,6 @@ import (
2525
"github.com/ethereum/go-ethereum/rpc"
2626
)
2727

28-
type iclaimerRepository interface {
29-
SelectSubmissionClaimPairsPerApp(ctx context.Context) (
30-
map[common.Address]*ClaimRow,
31-
map[common.Address]*ClaimRow,
32-
error,
33-
)
34-
SelectAcceptanceClaimPairsPerApp(ctx context.Context) (
35-
map[common.Address]*ClaimRow,
36-
map[common.Address]*ClaimRow,
37-
error,
38-
)
39-
UpdateEpochWithSubmittedClaim(
40-
ctx context.Context,
41-
application_id int64,
42-
index uint64,
43-
transaction_hash common.Hash,
44-
) error
45-
UpdateEpochWithAcceptedClaim(
46-
ctx context.Context,
47-
application_id int64,
48-
index uint64,
49-
) error
50-
51-
UpdateApplicationState(
52-
ctx context.Context,
53-
appID int64,
54-
state ApplicationState,
55-
reason *string,
56-
) error
57-
58-
SaveNodeConfigRaw(ctx context.Context, key string, rawJSON []byte) error
59-
LoadNodeConfigRaw(ctx context.Context, key string) (rawJSON []byte, createdAt, updatedAt time.Time, err error)
60-
}
61-
6228
type iclaimerBlockchain interface {
6329
findClaimSubmissionEventAndSucc(
6430
ctx context.Context,
@@ -94,6 +60,12 @@ type iclaimerBlockchain interface {
9460
)
9561

9662
getBlockNumber(ctx context.Context) (*big.Int, error)
63+
64+
checkApplicationsForConsensusAddressChange(
65+
ctx context.Context,
66+
apps []*model.Application,
67+
endBlock *big.Int,
68+
) ([]consensusChanged, []error)
9769
}
9870

9971
type claimerBlockchain struct {
@@ -103,6 +75,11 @@ type claimerBlockchain struct {
10375
defaultBlock config.DefaultBlock
10476
}
10577

78+
type consensusChanged struct {
79+
application *model.Application
80+
newAddress *common.Address
81+
}
82+
10683
func (self *claimerBlockchain) submitClaimToBlockchain(
10784
ic *iconsensus.IConsensus,
10885
claim *ClaimRow,
@@ -288,6 +265,26 @@ func (self *claimerBlockchain) findClaimAcceptanceEventAndSucc(
288265
}
289266
}
290267

268+
func (self *claimerBlockchain) checkApplicationsForConsensusAddressChange(
269+
ctx context.Context,
270+
apps []*model.Application,
271+
endBlock *big.Int,
272+
) ([]consensusChanged, []error) {
273+
var changed []consensusChanged
274+
var errs []error
275+
for _, app := range apps {
276+
consensusAddr, err := ethutil.GetConsensus(ctx, self.client, app.IApplicationAddress)
277+
if err != nil {
278+
errs = append(errs, err)
279+
continue
280+
}
281+
if app.IConsensusAddress != consensusAddr {
282+
changed = append(changed, consensusChanged{app, &consensusAddr})
283+
}
284+
}
285+
return changed, errs
286+
}
287+
291288
/* poll a transaction hash for its submission status and receipt */
292289
func (self *claimerBlockchain) pollTransaction(
293290
ctx context.Context,

internal/claimer/claimer.go

Lines changed: 65 additions & 149 deletions
Original file line numberDiff line numberDiff line change
@@ -41,19 +41,14 @@ import (
4141
"context"
4242
"errors"
4343
"fmt"
44-
"log/slog"
4544
"math/big"
45+
"time"
4646

47-
"github.com/cartesi/rollups-node/internal/config"
48-
"github.com/cartesi/rollups-node/internal/config/auth"
4947
. "github.com/cartesi/rollups-node/internal/model"
5048
"github.com/cartesi/rollups-node/internal/repository"
5149
"github.com/cartesi/rollups-node/pkg/contracts/iconsensus"
52-
"github.com/cartesi/rollups-node/pkg/service"
5350

54-
"github.com/ethereum/go-ethereum/accounts/abi/bind"
5551
"github.com/ethereum/go-ethereum/common"
56-
"github.com/ethereum/go-ethereum/ethclient"
5752
)
5853

5954
var (
@@ -62,119 +57,65 @@ var (
6257
ErrMissingEvent = fmt.Errorf("accepted claim has no matching blockchain event")
6358
)
6459

65-
type CreateInfo struct {
66-
service.CreateInfo
67-
68-
Config config.Config
69-
70-
EthConn *ethclient.Client
71-
Repository repository.Repository
72-
}
73-
74-
type Service struct {
75-
service.Service
76-
77-
repository iclaimerRepository
78-
blockchain iclaimerBlockchain
79-
claimsInFlight map[common.Address]common.Hash // -> txHash
80-
submissionEnabled bool
81-
}
82-
83-
const ClaimerConfigKey = "claimer"
84-
85-
type PersistentConfig struct {
86-
DefaultBlock DefaultBlock
87-
ClaimSubmissionEnabled bool
88-
ChainID uint64
60+
type iclaimerRepository interface {
61+
ListApplications(ctx context.Context, f repository.ApplicationFilter, p repository.Pagination) ([]*Application, uint64, error)
62+
63+
SelectSubmissionClaimPairsPerApp(ctx context.Context) (
64+
map[common.Address]*ClaimRow,
65+
map[common.Address]*ClaimRow,
66+
error,
67+
)
68+
SelectAcceptanceClaimPairsPerApp(ctx context.Context) (
69+
map[common.Address]*ClaimRow,
70+
map[common.Address]*ClaimRow,
71+
error,
72+
)
73+
UpdateEpochWithSubmittedClaim(
74+
ctx context.Context,
75+
application_id int64,
76+
index uint64,
77+
transaction_hash common.Hash,
78+
) error
79+
UpdateEpochWithAcceptedClaim(
80+
ctx context.Context,
81+
application_id int64,
82+
index uint64,
83+
) error
84+
85+
UpdateApplicationState(
86+
ctx context.Context,
87+
appID int64,
88+
state ApplicationState,
89+
reason *string,
90+
) error
91+
92+
SaveNodeConfigRaw(ctx context.Context, key string, rawJSON []byte) error
93+
LoadNodeConfigRaw(ctx context.Context, key string) (rawJSON []byte, createdAt, updatedAt time.Time, err error)
8994
}
9095

91-
func Create(ctx context.Context, c *CreateInfo) (*Service, error) {
92-
var err error
93-
if err = ctx.Err(); err != nil {
94-
return nil, err // This returns context.Canceled or context.DeadlineExceeded.
95-
}
96-
if c.Repository == nil {
97-
return nil, fmt.Errorf("repository on claimer service Create is nil")
98-
}
99-
if c.EthConn == nil {
100-
return nil, fmt.Errorf("ethclient on claimer service Create is nil")
101-
}
102-
103-
s := &Service{}
104-
c.CreateInfo.Impl = s
105-
106-
err = service.Create(ctx, &c.CreateInfo, &s.Service)
107-
if err != nil {
108-
return nil, err
96+
func (s *Service) checkApplicationConsensus(endBlock *big.Int) []error {
97+
f := repository.ApplicationFilter{
98+
State: Pointer(ApplicationState_Enabled),
10999
}
110-
111-
nodeConfig, err := setupPersistentConfig(ctx, s.Logger, c.Repository, &c.Config)
100+
apps, _, err := s.repository.ListApplications(s.Context, f, repository.Pagination{})
112101
if err != nil {
113-
return nil, err
114-
}
115-
116-
chainId, err := c.EthConn.ChainID(ctx)
117-
if err != nil {
118-
return nil, err
119-
}
120-
if chainId.Uint64() != c.Config.BlockchainId {
121-
return nil, fmt.Errorf("chainId mismatch: network %d != provided %d", chainId.Uint64(), c.Config.BlockchainId)
122-
}
123-
124-
if chainId.Uint64() != nodeConfig.ChainID {
125-
return nil, fmt.Errorf("NodeConfig chainId mismatch: network %d != config %d",
126-
chainId.Uint64(), nodeConfig.ChainID)
127-
}
128-
s.submissionEnabled = nodeConfig.ClaimSubmissionEnabled
129-
s.claimsInFlight = map[common.Address]common.Hash{}
130-
131-
var txOpts *bind.TransactOpts = nil
132-
if s.submissionEnabled {
133-
txOpts, err = auth.GetTransactOpts(chainId)
134-
if err != nil {
135-
return nil, err
136-
}
137-
}
138-
139-
s.repository = c.Repository
140-
141-
s.blockchain = &claimerBlockchain{
142-
logger: s.Logger,
143-
client: c.EthConn,
144-
txOpts: txOpts,
145-
defaultBlock: c.Config.BlockchainDefaultBlock,
102+
s.Logger.Error("Error retrieving enabled applications", "error", err)
103+
return []error{err}
146104
}
147105

148-
return s, nil
149-
}
150-
151-
func (s *Service) Alive() bool {
152-
return true
153-
}
154-
155-
func (s *Service) Ready() bool {
156-
return true
157-
}
158-
159-
func (s *Service) Reload() []error {
160-
return nil
161-
}
162-
163-
func (s *Service) Stop(bool) []error {
164-
return nil
165-
}
166-
167-
func (s *Service) Tick() []error {
168-
errs := []error{}
169-
endBlock, err := s.blockchain.getBlockNumber(s.Context)
170-
if err != nil {
171-
errs = append(errs, err)
172-
return errs
106+
var errs []error
107+
changedList, errs := s.blockchain.checkApplicationsForConsensusAddressChange(s.Context, apps, endBlock)
108+
for _, changed := range changedList {
109+
err = s.setApplicationInoperable(
110+
s.Context,
111+
changed.application.IApplicationAddress,
112+
changed.application.ID,
113+
"Application consensus address has changed. Application: %v, previous: %v, current: %v.",
114+
changed.application.IApplicationAddress,
115+
changed.application.IConsensusAddress,
116+
changed.newAddress,
117+
)
173118
}
174-
175-
errs = append(errs, s.submitClaimsAndUpdateDatabase(endBlock)...)
176-
errs = append(errs, s.acceptClaimsAndUpdateDatabase(endBlock)...)
177-
178119
return errs
179120
}
180121

@@ -223,9 +164,9 @@ func (s *Service) submitClaimsAndUpdateDatabase(endBlock *big.Int) []error {
223164

224165
// check computed claims
225166
for key, computedClaim := range computedClaims {
226-
var ic *iconsensus.IConsensus = nil
227-
var prevEvent *iconsensus.IConsensusClaimSubmission = nil
228-
var currEvent *iconsensus.IConsensusClaimSubmission = nil
167+
var ic *iconsensus.IConsensus
168+
var prevEvent *iconsensus.IConsensusClaimSubmission
169+
var currEvent *iconsensus.IConsensusClaimSubmission
229170

230171
if _, isInFlight := s.claimsInFlight[key]; isInFlight {
231172
continue
@@ -380,37 +321,6 @@ func (s *Service) submitClaimsAndUpdateDatabase(endBlock *big.Int) []error {
380321
return errs
381322
}
382323

383-
func setupPersistentConfig(
384-
ctx context.Context,
385-
logger *slog.Logger,
386-
repo iclaimerRepository,
387-
c *config.Config,
388-
) (*PersistentConfig, error) {
389-
config, err := repository.LoadNodeConfig[PersistentConfig](ctx, repo, ClaimerConfigKey)
390-
if config == nil && err == nil {
391-
nc := NodeConfig[PersistentConfig]{
392-
Key: ClaimerConfigKey,
393-
Value: PersistentConfig{
394-
DefaultBlock: c.BlockchainDefaultBlock,
395-
ClaimSubmissionEnabled: c.FeatureClaimSubmissionEnabled,
396-
ChainID: c.BlockchainId,
397-
},
398-
}
399-
logger.Info("Initializing claimer persistent config", "config", nc.Value)
400-
err = repository.SaveNodeConfig(ctx, repo, &nc)
401-
if err != nil {
402-
return nil, err
403-
}
404-
return &nc.Value, nil
405-
} else if err == nil {
406-
logger.Info("Claimer was already configured. Using previous persistent config", "config", config.Value)
407-
return &config.Value, nil
408-
}
409-
410-
logger.Error("Could not retrieve persistent config from Database. %w", "error", err)
411-
return nil, err
412-
}
413-
414324
/* transition claims from submitted to accepted */
415325
func (s *Service) acceptClaimsAndUpdateDatabase(endBlock *big.Int) []error {
416326
errs := []error{}
@@ -422,8 +332,8 @@ func (s *Service) acceptClaimsAndUpdateDatabase(endBlock *big.Int) []error {
422332

423333
// check submitted claims
424334
for key, submittedClaim := range submittedClaims {
425-
var prevEvent *iconsensus.IConsensusClaimAcceptance = nil
426-
var currEvent *iconsensus.IConsensusClaimAcceptance = nil
335+
var prevEvent *iconsensus.IConsensusClaimAcceptance
336+
var currEvent *iconsensus.IConsensusClaimAcceptance
427337

428338
acceptedClaim, prevExists := acceptedClaims[key]
429339
if prevExists {
@@ -520,7 +430,13 @@ func (s *Service) acceptClaimsAndUpdateDatabase(endBlock *big.Int) []error {
520430

521431
// setApplicationInoperable marks an application as inoperable with the given reason,
522432
// logs any error that occurs during the update, and returns an error with the reason.
523-
func (s *Service) setApplicationInoperable(ctx context.Context, iApplicationAddress common.Address, id int64, reasonFmt string, args ...any) error {
433+
func (s *Service) setApplicationInoperable(
434+
ctx context.Context,
435+
iApplicationAddress common.Address,
436+
id int64,
437+
reasonFmt string,
438+
args ...any,
439+
) error {
524440
reason := fmt.Sprintf(reasonFmt, args...)
525441
appAddress := iApplicationAddress.String()
526442

0 commit comments

Comments
 (0)