@@ -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,15 @@ 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+ LastInputCheckBlock : 0 ,
198+ LastOutputCheckBlock : 0 ,
185199 }
186200
187201 if ! noRegister {
@@ -208,7 +222,7 @@ func run(cmd *cobra.Command, args []string) {
208222 }
209223}
210224
211- // FIXME remove this
225+ // FIXME move this to ethutil
212226func deployApplication (
213227 ctx context.Context ,
214228 client * ethclient.Client ,
@@ -217,6 +231,7 @@ func deployApplication(
217231 authorityAddr common.Address ,
218232 owner common.Address ,
219233 templateHash string ,
234+ dataAvailability []byte ,
220235 salt string ,
221236) (common.Address , error ) {
222237
@@ -234,7 +249,7 @@ func deployApplication(
234249 return common.Address {}, fmt .Errorf ("Failed to instantiate contract: %v" , err )
235250 }
236251
237- tx , err := factory .NewApplication (txOpts , authorityAddr , owner , toBytes32 (templateHashBytes ), toBytes32 (saltBytes ))
252+ tx , err := factory .NewApplication (txOpts , authorityAddr , owner , toBytes32 (templateHashBytes ), dataAvailability , toBytes32 (saltBytes ))
238253 if err != nil {
239254 return common.Address {}, fmt .Errorf ("Transaction failed: %v" , err )
240255 }
@@ -257,23 +272,10 @@ func deployApplication(
257272 return common.Address {}, fmt .Errorf ("Transaction failed!" )
258273 }
259274
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-
266275 // Look for the specific event in the receipt logs
267276 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-
275277 // Parse log for ApplicationCreated event
276- err := contractABI . UnpackIntoInterface ( & event , "ApplicationCreated" , vLog . Data )
278+ event , err := factory . ParseApplicationCreated ( * vLog )
277279 if err != nil {
278280 continue // Skip logs that don't match
279281 }
@@ -330,20 +332,10 @@ func deployAuthority(
330332 return common.Address {}, fmt .Errorf ("Transaction failed!" )
331333 }
332334
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-
339335 // Look for the specific event in the receipt logs
340336 for _ , vLog := range receipt .Logs {
341- event := struct {
342- Authority common.Address
343- }{}
344-
345337 // Parse log for ApplicationCreated event
346- err := contractABI . UnpackIntoInterface ( & event , "AuthorityCreated" , vLog . Data )
338+ event , err := contract . ParseAuthorityCreated ( * vLog )
347339 if err != nil {
348340 continue // Skip logs that don't match
349341 }
@@ -380,6 +372,79 @@ func getEpochLength(
380372 return epochLengthRaw .Uint64 (), nil
381373}
382374
375+ func processDataAvailability (
376+ client * ethclient.Client ,
377+ hasDataAvailabilityFlag bool ,
378+ ) (* common.Address , * big.Int , []byte , error ) {
379+ var inputBoxAddress common.Address
380+ var encodedDA []byte
381+ var err error
382+
383+ parsedAbi , err := dataavailability .DataAvailabilityMetaData .GetAbi ()
384+ if err != nil {
385+ return nil , nil , nil , fmt .Errorf ("failed to get ABI: %w" , err )
386+ }
387+
388+ if hasDataAvailabilityFlag {
389+ if len (dataAvailability ) < 3 || (! strings .HasPrefix (dataAvailability , "0x" ) && ! strings .HasPrefix (dataAvailability , "0X" )) {
390+ return nil , nil , nil , fmt .Errorf ("data Availability should be an ABI encoded value" )
391+ }
392+
393+ s := dataAvailability [2 :]
394+ encodedDA , err = hex .DecodeString (s )
395+ if err != nil {
396+ return nil , nil , nil , fmt .Errorf ("error parsing Data Availability value: %w" , err )
397+ }
398+
399+ if len (encodedDA ) < model .DATA_AVAILABILITY_SELECTOR_SIZE {
400+ return nil , nil , nil , fmt .Errorf ("invalid Data Availability" )
401+ }
402+
403+ method , err := parsedAbi .MethodById (encodedDA [:model .DATA_AVAILABILITY_SELECTOR_SIZE ])
404+ if err != nil {
405+ return nil , nil , nil , fmt .Errorf ("failed to get method by ID: %w" , err )
406+ }
407+
408+ args , err := method .Inputs .Unpack (encodedDA [model .DATA_AVAILABILITY_SELECTOR_SIZE :])
409+ if err != nil {
410+ return nil , nil , nil , fmt .Errorf ("failed to unpack inputs: %w" , err )
411+ }
412+
413+ if len (args ) == 0 {
414+ return nil , nil , nil , fmt .Errorf ("invalid Data Availability. Should at least contain InputBox Address" )
415+ }
416+
417+ switch addr := args [0 ].(type ) {
418+ case common.Address :
419+ inputBoxAddress = addr
420+ default :
421+ return nil , nil , nil , fmt .Errorf ("first argument in Data Availability is not an address (got %T)" , args [0 ])
422+ }
423+ } else {
424+ inputBoxAddress , err = config .GetContractsInputBoxAddress ()
425+ if err != nil {
426+ return nil , nil , nil , fmt .Errorf ("failed to get input box address: %w" , err )
427+ }
428+
429+ encodedDA , err = parsedAbi .Pack ("InputBox" , inputBoxAddress )
430+ if err != nil {
431+ return nil , nil , nil , fmt .Errorf ("failed to pack InputBox: %w" , err )
432+ }
433+ }
434+
435+ inputbox , err := iinputbox .NewIInputBox (inputBoxAddress , client )
436+ if err != nil {
437+ return nil , nil , nil , fmt .Errorf ("failed to create input box instance: %w" , err )
438+ }
439+
440+ inputBoxBlock , err := inputbox .GetDeploymentBlockNumber (nil )
441+ if err != nil {
442+ return nil , nil , nil , fmt .Errorf ("failed to get deployment block number: %w" , err )
443+ }
444+
445+ return & inputBoxAddress , inputBoxBlock , encodedDA , nil
446+ }
447+
383448func toBytes32 (data []byte ) [32 ]byte {
384449 var arr [32 ]byte
385450 if len (data ) != 32 {
0 commit comments