@@ -17,11 +17,12 @@ import (
1717 "github.com/cartesi/rollups-node/internal/config/auth"
1818 "github.com/cartesi/rollups-node/internal/model"
1919 "github.com/cartesi/rollups-node/internal/repository/factory"
20+ "github.com/cartesi/rollups-node/pkg/contracts/dataavailability"
2021 "github.com/cartesi/rollups-node/pkg/contracts/iapplicationfactory"
2122 "github.com/cartesi/rollups-node/pkg/contracts/iauthorityfactory"
2223 "github.com/cartesi/rollups-node/pkg/contracts/iconsensus"
24+ "github.com/cartesi/rollups-node/pkg/contracts/iinputbox"
2325
24- "github.com/ethereum/go-ethereum/accounts/abi"
2526 "github.com/ethereum/go-ethereum/accounts/abi/bind"
2627 "github.com/ethereum/go-ethereum/common"
2728 "github.com/ethereum/go-ethereum/ethclient"
@@ -46,11 +47,12 @@ var (
4647 templatePath string
4748 templateHash string
4849 consensusAddr string
50+ inputBoxAddress string
51+ dataAvailability string
4952 appFactoryAddr string
5053 authorityFactoryAddr string
5154 blockchainHttpEndpoint string
5255 salt string
53- inputBoxBlockNumber uint64
5456 epochLength uint64
5557 disabled bool
5658 printAsJSON bool
@@ -76,6 +78,10 @@ func init() {
7678 "Application template hash. If not provided, it will be read from the template path" ,
7779 )
7880
81+ Cmd .Flags ().StringVarP (& dataAvailability , "data-availability" , "D" , "" ,
82+ "Application ABI encoded Data Availability. If not provided, it will be read from the InputBox Address" ,
83+ )
84+
7985 Cmd .Flags ().StringVarP (& appFactoryAddr , "application-factory" , "a" , "" , "Application Factory Address" )
8086 viper .BindPFlag (config .CONTRACTS_APPLICATION_FACTORY_ADDRESS , Cmd .Flags ().Lookup ("application-factory" ))
8187
@@ -90,8 +96,8 @@ func init() {
9096 "Consensus Epoch length. If consensus address is provided, the value will be read from the contract" ,
9197 )
9298
93- Cmd .Flags ().Uint64VarP ( & inputBoxBlockNumber , "inputbox-block-number " , "i " , 0 , "InputBox deployment block number " )
94- viper .BindPFlag (config .CONTRACTS_INPUT_BOX_DEPLOYMENT_BLOCK_NUMBER , Cmd .Flags ().Lookup ("inputbox-block-number " ))
99+ Cmd .Flags ().StringVar ( & inputBoxAddress , "inputbox" , "" , "Input Box contract address " )
100+ viper .BindPFlag (config .CONTRACTS_INPUT_BOX_ADDRESS , Cmd .Flags ().Lookup ("inputbox" ))
95101
96102 Cmd .Flags ().StringVar (& salt , "salt" , "0000000000000000000000000000000000000000000000000000000000000000" , "salt" )
97103
@@ -133,8 +139,18 @@ func run(cmd *cobra.Command, args []string) {
133139 txOpts , err := auth .GetTransactOpts (chainId )
134140 cobra .CheckErr (err )
135141
142+ inputBoxAddress , inputBoxBlock , encodedDA , err := processDataAvailability (client , cmd .Flags ().Changed ("data-availability" ))
143+ cobra .CheckErr (err )
144+
136145 var consensus common.Address
137- if consensusAddr == "" {
146+ if cmd .Flags ().Changed ("consensus" ) {
147+ consensus = common .HexToAddress (consensusAddr )
148+ epochLength , err = getEpochLength (consensus )
149+ if err != nil {
150+ fmt .Fprintf (os .Stderr , "Failed to get epoch length from consensus: %v\n " , err )
151+ os .Exit (1 )
152+ }
153+ } else {
138154 var owner common.Address
139155 authorityFactoryAddress , err := config .GetContractsAuthorityFactoryAddress ()
140156 cobra .CheckErr (err )
@@ -148,24 +164,20 @@ func run(cmd *cobra.Command, args []string) {
148164 fmt .Fprintf (os .Stderr , "Authoriy contract creation failed: %v\n " , err )
149165 os .Exit (1 )
150166 }
151- } else {
152- consensus = common .HexToAddress (consensusAddr )
153- epochLength , err = getEpochLength (consensus )
154- if err != nil {
155- fmt .Fprintf (os .Stderr , "Failed to get epoch length from consensus: %v\n " , err )
156- os .Exit (1 )
157- }
158167 }
159168
169+ var daSelector model.DataAvailabilitySelector
170+ copy (daSelector [:], encodedDA [:model .DATA_AVAILABILITY_SELECTOR_SIZE ])
171+
160172 var owner common.Address
161173 if cmd .Flags ().Changed ("application-owner" ) {
162174 owner = common .HexToAddress (applicationOwner )
163175 } else {
164176 owner = txOpts .From
165177 }
166- applicationFactoryAddress , err := config .GetContractsApplicationFactoryAddress ()
178+ appFactoryAddress , err := config .GetContractsApplicationFactoryAddress ()
167179 cobra .CheckErr (err )
168- appAddr , err := deployApplication (ctx , client , txOpts , applicationFactoryAddress , consensus , owner , templateHash , salt )
180+ appAddr , err := deployApplication (ctx , client , txOpts , appFactoryAddress , consensus , owner , templateHash , encodedDA , salt )
169181 if err != nil {
170182 fmt .Fprintf (os .Stderr , "Application contract creation failed: %v\n " , err )
171183 os .Exit (1 )
@@ -175,13 +187,16 @@ func run(cmd *cobra.Command, args []string) {
175187 Name : name ,
176188 IApplicationAddress : appAddr ,
177189 IConsensusAddress : consensus ,
190+ IInputBoxAddress : * inputBoxAddress ,
178191 TemplateURI : templatePath ,
179192 TemplateHash : common .HexToHash (templateHash ),
180193 EpochLength : epochLength ,
194+ DataAvailability : daSelector ,
181195 State : applicationState ,
182- LastProcessedBlock : inputBoxBlockNumber ,
183- LastOutputCheckBlock : inputBoxBlockNumber ,
184- LastClaimCheckBlock : inputBoxBlockNumber ,
196+ IInputBoxBlock : inputBoxBlock .Uint64 (),
197+ LastProcessedBlock : 0 ,
198+ LastOutputCheckBlock : 0 ,
199+ LastClaimCheckBlock : 0 ,
185200 }
186201
187202 if ! noRegister {
@@ -208,7 +223,7 @@ func run(cmd *cobra.Command, args []string) {
208223 }
209224}
210225
211- // FIXME remove this
226+ // FIXME move this to ethutil
212227func deployApplication (
213228 ctx context.Context ,
214229 client * ethclient.Client ,
@@ -217,6 +232,7 @@ func deployApplication(
217232 authorityAddr common.Address ,
218233 owner common.Address ,
219234 templateHash string ,
235+ dataAvailability []byte ,
220236 salt string ,
221237) (common.Address , error ) {
222238
@@ -234,7 +250,7 @@ func deployApplication(
234250 return common.Address {}, fmt .Errorf ("Failed to instantiate contract: %v" , err )
235251 }
236252
237- tx , err := factory .NewApplication (txOpts , authorityAddr , owner , toBytes32 (templateHashBytes ), toBytes32 (saltBytes ))
253+ tx , err := factory .NewApplication (txOpts , authorityAddr , owner , toBytes32 (templateHashBytes ), dataAvailability , toBytes32 (saltBytes ))
238254 if err != nil {
239255 return common.Address {}, fmt .Errorf ("Transaction failed: %v" , err )
240256 }
@@ -257,23 +273,10 @@ func deployApplication(
257273 return common.Address {}, fmt .Errorf ("Transaction failed!" )
258274 }
259275
260- // Parse logs to get the address of the new application contract
261- contractABI , err := abi .JSON (strings .NewReader (iapplicationfactory .IApplicationFactoryABI ))
262- if err != nil {
263- return common.Address {}, fmt .Errorf ("Failed to parse ABI: %v" , err )
264- }
265-
266276 // Look for the specific event in the receipt logs
267277 for _ , vLog := range receipt .Logs {
268- event := struct {
269- Consensus common.Address
270- AppOwner common.Address
271- TemplateHash [32 ]byte
272- AppContract common.Address
273- }{}
274-
275278 // Parse log for ApplicationCreated event
276- err := contractABI . UnpackIntoInterface ( & event , "ApplicationCreated" , vLog . Data )
279+ event , err := factory . ParseApplicationCreated ( * vLog )
277280 if err != nil {
278281 continue // Skip logs that don't match
279282 }
@@ -330,20 +333,10 @@ func deployAuthority(
330333 return common.Address {}, fmt .Errorf ("Transaction failed!" )
331334 }
332335
333- // Parse logs to get the address of the new application contract
334- contractABI , err := abi .JSON (strings .NewReader (iauthorityfactory .IAuthorityFactoryABI ))
335- if err != nil {
336- return common.Address {}, fmt .Errorf ("Failed to parse ABI: %v" , err )
337- }
338-
339336 // Look for the specific event in the receipt logs
340337 for _ , vLog := range receipt .Logs {
341- event := struct {
342- Authority common.Address
343- }{}
344-
345338 // Parse log for ApplicationCreated event
346- err := contractABI . UnpackIntoInterface ( & event , "AuthorityCreated" , vLog . Data )
339+ event , err := contract . ParseAuthorityCreated ( * vLog )
347340 if err != nil {
348341 continue // Skip logs that don't match
349342 }
@@ -380,6 +373,79 @@ func getEpochLength(
380373 return epochLengthRaw .Uint64 (), nil
381374}
382375
376+ func processDataAvailability (
377+ client * ethclient.Client ,
378+ hasDataAvailabilityFlag bool ,
379+ ) (* common.Address , * big.Int , []byte , error ) {
380+ var inputBoxAddress common.Address
381+ var encodedDA []byte
382+ var err error
383+
384+ parsedAbi , err := dataavailability .DataAvailabilityMetaData .GetAbi ()
385+ if err != nil {
386+ return nil , nil , nil , fmt .Errorf ("failed to get ABI: %w" , err )
387+ }
388+
389+ if hasDataAvailabilityFlag {
390+ if len (dataAvailability ) < 3 || (! strings .HasPrefix (dataAvailability , "0x" ) && ! strings .HasPrefix (dataAvailability , "0X" )) {
391+ return nil , nil , nil , fmt .Errorf ("data Availability should be an ABI encoded value" )
392+ }
393+
394+ s := dataAvailability [2 :]
395+ encodedDA , err = hex .DecodeString (s )
396+ if err != nil {
397+ return nil , nil , nil , fmt .Errorf ("error parsing Data Availability value: %w" , err )
398+ }
399+
400+ if len (encodedDA ) < model .DATA_AVAILABILITY_SELECTOR_SIZE {
401+ return nil , nil , nil , fmt .Errorf ("invalid Data Availability" )
402+ }
403+
404+ method , err := parsedAbi .MethodById (encodedDA [:model .DATA_AVAILABILITY_SELECTOR_SIZE ])
405+ if err != nil {
406+ return nil , nil , nil , fmt .Errorf ("failed to get method by ID: %w" , err )
407+ }
408+
409+ args , err := method .Inputs .Unpack (encodedDA [model .DATA_AVAILABILITY_SELECTOR_SIZE :])
410+ if err != nil {
411+ return nil , nil , nil , fmt .Errorf ("failed to unpack inputs: %w" , err )
412+ }
413+
414+ if len (args ) == 0 {
415+ return nil , nil , nil , fmt .Errorf ("invalid Data Availability. Should at least contain InputBox Address" )
416+ }
417+
418+ switch addr := args [0 ].(type ) {
419+ case common.Address :
420+ inputBoxAddress = addr
421+ default :
422+ return nil , nil , nil , fmt .Errorf ("first argument in Data Availability is not an address (got %T)" , args [0 ])
423+ }
424+ } else {
425+ inputBoxAddress , err = config .GetContractsInputBoxAddress ()
426+ if err != nil {
427+ return nil , nil , nil , fmt .Errorf ("failed to get input box address: %w" , err )
428+ }
429+
430+ encodedDA , err = parsedAbi .Pack ("InputBox" , inputBoxAddress )
431+ if err != nil {
432+ return nil , nil , nil , fmt .Errorf ("failed to pack InputBox: %w" , err )
433+ }
434+ }
435+
436+ inputbox , err := iinputbox .NewIInputBox (inputBoxAddress , client )
437+ if err != nil {
438+ return nil , nil , nil , fmt .Errorf ("failed to create input box instance: %w" , err )
439+ }
440+
441+ inputBoxBlock , err := inputbox .GetDeploymentBlockNumber (nil )
442+ if err != nil {
443+ return nil , nil , nil , fmt .Errorf ("failed to get deployment block number: %w" , err )
444+ }
445+
446+ return & inputBoxAddress , inputBoxBlock , encodedDA , nil
447+ }
448+
383449func toBytes32 (data []byte ) [32 ]byte {
384450 var arr [32 ]byte
385451 if len (data ) != 32 {
0 commit comments