@@ -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
5954var (
@@ -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 */
415325func (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