Skip to content

Commit 85ee681

Browse files
committed
fix(cli): improve "deploy application" reporting
1 parent b11c320 commit 85ee681

13 files changed

Lines changed: 586 additions & 476 deletions

File tree

cmd/cartesi-rollups-cli/root/deploy/application.go

Lines changed: 260 additions & 312 deletions
Large diffs are not rendered by default.

cmd/cartesi-rollups-cli/root/deploy/authority.go

Lines changed: 45 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -72,40 +72,50 @@ func runDeployAuthority(cmd *cobra.Command, args []string) {
7272
txOpts, err := auth.GetTransactOpts(chainId)
7373
cobra.CheckErr(err)
7474

75-
authority, err := buildAuthorityDeployment(cmd, txOpts)
75+
deployment, err := buildAuthorityDeployment(cmd, txOpts)
7676
cobra.CheckErr(err)
7777

78-
if !asJson {
79-
fmt.Printf("Deploying authority...")
78+
if verboseParam {
79+
fmt.Fprint(os.Stderr, deployment)
80+
fmt.Fprintln(os.Stderr, "\twallet address: ", txOpts.From)
81+
82+
}
83+
84+
// factory check
85+
if verboseParam {
86+
fmt.Fprint(os.Stderr, "checking factory address...")
8087
}
81-
authority.Address, err = authority.Deploy(ctx, client, txOpts)
88+
89+
factoryAddress := deployment.FactoryAddress
90+
data, err := client.CodeAt(ctx, factoryAddress, nil)
8291
cobra.CheckErr(err)
8392

84-
if err != nil {
85-
if asJson {
86-
data := struct {
87-
Code int
88-
Message string
89-
}{
90-
Code: 1,
91-
Message: err.Error(),
92-
}
93-
report, err := json.MarshalIndent(&data, "", " ")
94-
cobra.CheckErr(err)
95-
fmt.Println(string(report))
96-
} else {
97-
fmt.Fprintf(os.Stderr, "%v.\n", err)
98-
}
99-
os.Exit(1)
100-
} else {
101-
if asJson {
102-
report, err := json.MarshalIndent(&authority, "", " ")
103-
cobra.CheckErr(err) // deployed, but fail to print
104-
fmt.Println(string(report))
105-
} else {
106-
fmt.Printf("success\n\n")
107-
fmt.Println("consensus address: ", authority.Address)
108-
}
93+
if len(data) == 0 {
94+
cobra.CheckErr(fmt.Errorf("No code at the factory address: %v", factoryAddress))
95+
}
96+
if verboseParam {
97+
fmt.Fprint(os.Stderr, "success\n")
98+
}
99+
100+
// deploy
101+
if verboseParam || !asJsonParam {
102+
fmt.Fprintf(os.Stderr, "deploying authority...")
103+
}
104+
deployment.Address, err = deployment.Deploy(ctx, client, txOpts)
105+
cobra.CheckErr(err)
106+
107+
// report
108+
if verboseParam || !asJsonParam {
109+
fmt.Fprintf(os.Stderr, "success\n")
110+
fmt.Fprintln(os.Stderr, "\tconsensus address: ", deployment.Address)
111+
fmt.Fprintln(os.Stderr, "\tepoch length: ", deployment.EpochLength)
112+
}
113+
114+
if asJsonParam {
115+
report, err := json.MarshalIndent(&deployment, "", " ")
116+
cobra.CheckErr(err) // deployed, but fail to print
117+
118+
fmt.Println(string(report))
109119
}
110120
}
111121

@@ -120,27 +130,28 @@ func buildAuthorityDeployment(cmd *cobra.Command, txOpts *bind.TransactOpts) (*e
120130
authorityFactoryAddress, err = parseHexAddress(authorityFactoryAddressParam)
121131
}
122132
if err != nil {
123-
return nil, err
133+
return nil, fmt.Errorf("error on parameter authority-factory: %w", err)
124134
}
125135

126136
if !cmd.Flags().Changed("authority-owner") {
127137
authorityOwnerAddress = txOpts.From
128138
} else {
129139
authorityOwnerAddress, err = parseHexAddress(authorityOwnerAddressParam)
130-
if err != nil {
131-
return nil, err
132-
}
140+
}
141+
if err != nil {
142+
return nil, fmt.Errorf("error on parameter authority-owner: %w", err)
133143
}
134144

135145
salt, err := ethutil.ParseSalt(saltParam)
136146
if err != nil {
137-
return nil, err
147+
return nil, fmt.Errorf("error on parameter salt: %w", err)
138148
}
139149

140150
return &ethutil.AuthorityDeployment{
141151
FactoryAddress: authorityFactoryAddress,
142152
OwnerAddress: authorityOwnerAddress,
143153
EpochLength: epochLengthParam,
144154
Salt: salt,
155+
Verbose: verboseParam,
145156
}, nil
146157
}

cmd/cartesi-rollups-cli/root/deploy/deploy.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ import (
1313
var (
1414
epochLengthParam uint64
1515
saltParam string
16-
asJson bool
17-
verbose bool
16+
asJsonParam bool
17+
verboseParam bool
1818
)
1919

2020
var Cmd = &cobra.Command{
@@ -30,10 +30,10 @@ func init() {
3030
Cmd.PersistentFlags().StringVar(&saltParam, "salt", "0000000000000000000000000000000000000000000000000000000000000000",
3131
"Salt value for contract deployment")
3232
Cmd.PersistentFlags().MarkHidden("salt")
33-
Cmd.PersistentFlags().BoolVarP(&asJson, "json", "", false,
33+
Cmd.PersistentFlags().BoolVarP(&asJsonParam, "json", "", false,
3434
"Print results as JSON")
3535
Cmd.PersistentFlags().MarkHidden("json")
36-
Cmd.PersistentFlags().BoolVarP(&verbose, "verbose", "", false,
36+
Cmd.PersistentFlags().BoolVarP(&verboseParam, "verbose", "", false,
3737
"Print extra information")
3838
Cmd.PersistentFlags().MarkHidden("verbose")
3939

cmd/cartesi-rollups-cli/root/deploy/selfhosted.go

Lines changed: 0 additions & 41 deletions
This file was deleted.

internal/repository/postgres/application.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ func (r *PostgresRepository) CreateApplication(
6565
var newID int64
6666
err = tx.QueryRow(ctx, sqlStr, args...).Scan(&newID)
6767
if err != nil {
68-
return 0, errors.Join(err, tx.Rollback(ctx))
68+
return 0, errors.Join(fmt.Errorf("unable to create database application: %w", err), tx.Rollback(ctx))
6969
}
7070

7171
sqlStr, args = table.ExecutionParameters.

pkg/ethutil/anvil.go

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,15 @@ func CreateAnvilSnapshotAndDeployApp(ctx context.Context, client *ethclient.Clie
5050
if err != nil {
5151
return zero, nil, fmt.Errorf("failed retrieve self hosted application factory address: %w", err)
5252
}
53-
deployment := &SelfhostedDeployment{
54-
FactoryAddress: selfHostedApplicationFactoryAddress,
55-
OwnerAddress: txOpts.From,
56-
TemplateHash: templateHash,
57-
EpochLength: 10,
53+
54+
deployment := &SelfhostedApplicationDeployment{
55+
FactoryAddress: selfHostedApplicationFactoryAddress,
56+
ApplicationOwnerAddress: txOpts.From,
57+
AuthorityOwnerAddress: txOpts.From,
58+
TemplateHash: templateHash,
59+
DataAvailability: dataAvailability,
60+
EpochLength: 10,
61+
Salt: [32]byte{},
5862
}
5963
applicationAddress, _, err := deployment.Deploy(ctx, client, txOpts)
6064

pkg/ethutil/application.go

Lines changed: 63 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4,66 +4,89 @@ package ethutil
44

55
import (
66
"context"
7+
"encoding/hex"
78
"fmt"
89

9-
"github.com/cartesi/rollups-node/internal/model"
1010
"github.com/cartesi/rollups-node/pkg/contracts/iapplicationfactory"
1111
"github.com/ethereum/go-ethereum/accounts/abi/bind"
1212
"github.com/ethereum/go-ethereum/common"
1313
"github.com/ethereum/go-ethereum/ethclient"
1414
)
1515

16-
// NOTE: json formatting breaks if we don't use a separate type, don't know why
16+
type IApplicationDeployment interface {
17+
Deploy(ctx context.Context, client *ethclient.Client, txOpts *bind.TransactOpts) (common.Address, IApplicationDeploymentResult, error)
18+
GetFactoryAddress() common.Address
19+
}
20+
type IApplicationDeploymentResult interface{}
21+
1722
type ApplicationDeployment struct {
18-
model.Application `json:"application"`
19-
FactoryAddress common.Address `json:"factory"`
20-
OwnerAddress common.Address `json:"owner"`
21-
Salt SaltBytes `json:"salt"`
22-
WithAuthority *AuthorityDeployment `json:"authority,omitempty"`
23-
WithSelfHosted *SelfhostedDeployment `json:"selfhosted,omitempty"`
23+
FactoryAddress common.Address `json:"factory"`
24+
Consensus common.Address `json:"consensus"`
25+
OwnerAddress common.Address `json:"owner"`
26+
DataAvailability []byte `json:"-"`
27+
TemplateHash common.Hash `json:"template_hash"`
28+
Salt SaltBytes `json:"salt"`
29+
30+
// needed by model.Application
31+
InputBoxAddress common.Address `json:"inputbox_address"`
32+
IInputBoxBlock uint64 `json:"inputbox_block"`
33+
EpochLength uint64 `json:"epoch_length"`
34+
35+
Verbose bool
2436
}
2537

26-
// function does one of 3 things:
27-
// - withSelfHosted != nil => application + authority (together via SelfHosted contract)
28-
// - withAuthority != nil => application + authority (as two separate deployments)
29-
// - withSelfHosted == nil && withAuthority == nil => application only
30-
func (me *ApplicationDeployment) Deploy(ctx context.Context, client *ethclient.Client, txOpts *bind.TransactOpts) (common.Address, error) {
31-
var err error
32-
zero := common.Address{}
33-
var applicationAddress common.Address
38+
type ApplicationDeploymentResult struct {
39+
Deployment *ApplicationDeployment `json:"deployment"`
3440

35-
if me.WithSelfHosted != nil {
36-
applicationAddress, me.IConsensusAddress, err = me.WithSelfHosted.Deploy(ctx, client, txOpts)
37-
if err != nil {
38-
return zero, err
39-
}
40-
return applicationAddress, nil
41-
}
41+
ApplicationAddress common.Address `json:"address"`
42+
}
4243

43-
if me.WithAuthority != nil {
44-
me.IConsensusAddress, err = me.WithAuthority.Deploy(ctx, client, txOpts)
45-
if err != nil {
46-
return zero, err
47-
}
44+
func (me *ApplicationDeployment) String() string {
45+
result := ""
46+
result += fmt.Sprintf("application deployment:\n")
47+
result += fmt.Sprintf("\tapplication owner: %v\n", me.OwnerAddress)
48+
result += fmt.Sprintf("\tconsensus address: %v\n", me.Consensus)
49+
if me.Verbose {
50+
result += fmt.Sprintf("\tfactory address: %v\n", me.FactoryAddress)
51+
result += fmt.Sprintf("\ttemplate hash: %v\n", me.TemplateHash)
52+
result += fmt.Sprintf("\tdata availability: 0x%v\n", hex.EncodeToString(me.DataAvailability))
53+
result += fmt.Sprintf("\tsalt: %v\n", me.Salt)
54+
result += fmt.Sprintf("\tepoch length: %v\n", me.EpochLength)
4855
}
56+
return result
57+
}
58+
59+
func (me *ApplicationDeploymentResult) String() string {
60+
result := ""
61+
result += fmt.Sprintf("\tapplication address: %v\n", me.ApplicationAddress)
62+
return result
63+
}
4964

65+
func (me *ApplicationDeployment) Deploy(
66+
ctx context.Context,
67+
client *ethclient.Client,
68+
txOpts *bind.TransactOpts,
69+
) (common.Address, IApplicationDeploymentResult, error) {
70+
zero := common.Address{}
71+
result := &ApplicationDeploymentResult{}
72+
result.Deployment = me
5073
factory, err := iapplicationfactory.NewIApplicationFactory(me.FactoryAddress, client)
5174
if err != nil {
52-
return zero, fmt.Errorf("failed to instantiate contract: %v", err)
75+
return zero, nil, fmt.Errorf("failed to instantiate contract: %v", err)
5376
}
5477

55-
tx, err := factory.NewApplication(txOpts, me.IConsensusAddress, me.OwnerAddress, me.TemplateHash, me.DataAvailability, me.Salt)
78+
tx, err := factory.NewApplication(txOpts, me.Consensus, me.OwnerAddress, me.TemplateHash, me.DataAvailability, me.Salt)
5679
if err != nil {
57-
return zero, fmt.Errorf("transaction failed: %v", err)
80+
return zero, nil, fmt.Errorf("transaction failed: %v", err)
5881
}
5982

6083
receipt, err := bind.WaitMined(ctx, client, tx)
6184
if err != nil {
62-
return zero, fmt.Errorf("failed to wait for transaction mining: %v", err)
85+
return zero, nil, fmt.Errorf("failed to wait for transaction mining: %v", err)
6386
}
6487

6588
if receipt.Status != 1 {
66-
return zero, fmt.Errorf("transaction failed")
89+
return zero, nil, fmt.Errorf("transaction failed")
6790
}
6891

6992
// Look for the specific event in the receipt logs
@@ -73,7 +96,12 @@ func (me *ApplicationDeployment) Deploy(ctx context.Context, client *ethclient.C
7396
if err != nil {
7497
continue // Skip logs that don't match
7598
}
76-
return event.AppContract, nil
99+
result.ApplicationAddress = event.AppContract
100+
return result.ApplicationAddress, result, nil
77101
}
78-
return zero, fmt.Errorf("failed to find ApplicationCreated event in receipt logs")
102+
return zero, nil, fmt.Errorf("failed to find ApplicationCreated event in receipt logs")
103+
}
104+
105+
func (me *ApplicationDeployment) GetFactoryAddress() common.Address {
106+
return me.FactoryAddress
79107
}

pkg/ethutil/authority.go

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,26 @@ type AuthorityDeployment struct {
1919
OwnerAddress common.Address `json:"owner"`
2020
EpochLength uint64 `json:"epoch_length"`
2121
Salt SaltBytes `json:"salt"`
22+
Verbose bool `json:"-"`
2223
}
2324

24-
func (me AuthorityDeployment) Deploy(ctx context.Context, client *ethclient.Client, txOpts *bind.TransactOpts) (common.Address, error) {
25+
func (me *AuthorityDeployment) String() string {
26+
result := ""
27+
result += fmt.Sprintf("authority deployment:\n")
28+
result += fmt.Sprintf("\tauthority owner: %v\n", me.OwnerAddress)
29+
if me.Verbose {
30+
result += fmt.Sprintf("\tfactory address: %v\n", me.FactoryAddress)
31+
result += fmt.Sprintf("\tsalt: %v\n", me.Salt)
32+
result += fmt.Sprintf("\tepoch length: %v\n", me.EpochLength)
33+
}
34+
return result
35+
}
36+
37+
func (me AuthorityDeployment) Deploy(
38+
ctx context.Context,
39+
client *ethclient.Client,
40+
txOpts *bind.TransactOpts,
41+
) (common.Address, error) {
2542
contract, err := iauthorityfactory.NewIAuthorityFactory(me.FactoryAddress, client)
2643
if err != nil {
2744
return common.Address{}, fmt.Errorf("failed to instantiate contract: %v", err)

0 commit comments

Comments
 (0)