Skip to content

Commit

Permalink
refactor: postgres schema and repository API (WIP)
Browse files Browse the repository at this point in the history
  • Loading branch information
vfusco committed Jan 28, 2025
1 parent 79d0b67 commit c748b20
Show file tree
Hide file tree
Showing 102 changed files with 6,654 additions and 6,117 deletions.
2 changes: 1 addition & 1 deletion .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ linters:
- misspell
linters-settings:
lll:
line-length: 120
line-length: 140
tab-width: 4
mnd:
ignored-functions:
Expand Down
25 changes: 7 additions & 18 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,12 @@ migrate: ## Run migration on development database
@echo "Running PostgreSQL migration"
@go run $(GO_BUILD_PARAMS) dev/migrate/main.go

generate-db: ## Generate repository/db with Jet
@echo "Generating internal/repository/postgres/db with jet"
@rm -rf internal/repository/postgres/db
@go run github.com/go-jet/jet/v2/cmd/jet -dsn=$$CARTESI_POSTGRES_ENDPOINT -schema=public -path=./internal/repository/postgres/db
@rm -rf internal/repository/postgres/db/rollupsdb/public/model

# =============================================================================
# Clean
# =============================================================================
Expand Down Expand Up @@ -169,7 +175,7 @@ applications/echo-dapp: ## Create echo-dapp test application

deploy-echo-dapp: applications/echo-dapp ## Deploy echo-dapp test application
@echo "Deploying echo-dapp test application"
@./cartesi-rollups-cli app deploy -t applications/echo-dapp/ -v
@./cartesi-rollups-cli app deploy -n echo-dapp -t applications/echo-dapp/ -v

# =============================================================================
# Static Analysis
Expand Down Expand Up @@ -224,23 +230,6 @@ run-postgres: ## Run the PostgreSQL 16 docker container
@echo "Starting portgres"
@docker run --rm --name postgres -p 5432:5432 -d -e POSTGRES_PASSWORD=password -e POSTGRES_DB=rollupsdb -v $(CURDIR)/test/postgres/init-test-db.sh:/docker-entrypoint-initdb.d/init-test-db.sh postgres:16-alpine

run-postgraphile: ## Run the GraphQL server docker container
@docker run --rm --name postgraphile -p 10004:10004 -d --init \
graphile/postgraphile:4.14.0 \
--retry-on-init-fail \
--dynamic-json \
--no-setof-functions-contain-nulls \
--no-ignore-rbac \
--enable-query-batching \
--enhance-graphiql \
--extended-errors errcode \
--legacy-relations omit \
--connection "postgres://postgres:[email protected]:5432/rollupsdb?sslmode=disable" \
--schema graphql \
--host "0.0.0.0" \
--port 10004
# --append-plugins @graphile-contrib/pg-simplify-inflector \
start: run-postgres run-devnet ## Start the anvil devnet and PostgreSQL 16 docker containers
@$(MAKE) migrate

Expand Down
57 changes: 8 additions & 49 deletions api/openapi/inspect.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ openapi: 3.0.0

info:
title: Inspect-state HTTP API for Cartesi Rollups
version: 0.6.0
version: 0.7.0
license:
name: Apache-2.0
url: https://www.apache.org/licenses/LICENSE-2.0.html
Expand All @@ -11,68 +11,27 @@ info:
API that allows the DApp frontend to make inspect-state requests to the DApp backend.
paths:
inspect/{dapp}/{payload}:
get:
operationId: inspect
summary: Inspect DApp state via GET
description: |
This method sends an inspect-state request to the DApp backend, passing the payload string in the URL.
The payload string should be URL-encoded; the inspect server will decode the string to UTF-8.
If the DApp frontend needs to pass a binary string to the backend then it is advised to use the POST method.
The response contains a status string and the reports generated by the DApp backend.
The status string can be either 'accept', 'reject', or 'exception'.
In case of exception, the field exception_payload will contain the exception payload;
Otherwise, this field will be null.
When running on machine mode, the whole Cartesi machine is rolled back after processing the inspect-state request.
On host mode, it is advised against changing the DApp backend state when processing an inspect-state request.
Notice that this method is synchronous, so it is not advised to be used for performing resource-intensive operations.
parameters:
- in: path
name: dapp
required: true
schema:
type: string
- in: path
name: payload
required: true
schema:
type: string

responses:
"200":
description: Inspect state response.
content:
application/json:
schema:
$ref: "#/components/schemas/InspectResult"

default:
description: Error response.
content:
text/plain:
schema:
$ref: "#/components/schemas/Error"

inspect/{dapp}:
post:
operationId: inspect_post
summary: Inspect DApp state via POST
description: |
Differently from the GET method, the POST method sends an inspect-state request to the DApp backend by passing its payload in the request body.
The payload should be a binary.
Other than that, it behaves the same way as described in the GET method.
This POST method sends an inspect-state request to the DApp backend, using the body contents as a binary payload for the inspect method.
The response includes a status string and reports generated by the DApp backend. If an exception occurs, the `exception_payload` field will contain the exception details; otherwise, this field will be null.
The inspect operation is executed on a temporary fork of the machine created upon request arrival, which is discarded afterward. Note that this method is synchronous and not recommended for resource-intensive operations.
parameters:
- in: path
name: dapp
description: dapp name or address
required: true
schema:
type: string

requestBody:
description: Binary payload
content:
application/octet-stream:
schema:
Expand Down
6 changes: 3 additions & 3 deletions cmd/cartesi-rollups-cli/root/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ import (
)

var Cmd = &cobra.Command{
Use: "app",
Short: "Application management related commands",
PersistentPreRun: common.Setup,
Use: "app",
Short: "Application management related commands",
PersistentPreRunE: common.PersistentPreRun,
}

func init() {
Expand Down
122 changes: 79 additions & 43 deletions cmd/cartesi-rollups-cli/root/app/deploy/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/cartesi/rollups-node/internal/model"
"github.com/cartesi/rollups-node/pkg/contracts/iapplicationfactory"
"github.com/cartesi/rollups-node/pkg/contracts/iauthorityfactory"
"github.com/cartesi/rollups-node/pkg/contracts/iconsensus"
"github.com/cartesi/rollups-node/pkg/ethutil"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
Expand All @@ -34,20 +35,15 @@ var Cmd = &cobra.Command{
}

const examples = `# Adds an application to Rollups Node:
cartesi-rollups-cli app deploy -a 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -i 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -t applications/echo-dapp` //nolint:lll

const (
statusRunning = "running"
statusNotRunning = "not-running"
)
cartesi-rollups-cli app deploy -n echo-dapp -a 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -c 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -t applications/echo-dapp` //nolint:lll

var (
name string
applicationOwner string
authorityOwner string
templatePath string
templateHash string
status string
iConsensusAddr string
consensusAddr string
appFactoryAddr string
authorityFactoryAddr string
rpcURL string
Expand All @@ -56,11 +52,21 @@ var (
salt string
inputBoxBlockNumber uint64
epochLength uint64
disabled bool
printAsJSON bool
noRegister bool
)

func init() {
Cmd.Flags().StringVarP(
&name,
"name",
"n",
"",
"Application name",
)
cobra.CheckErr(Cmd.MarkFlagRequired("name"))

Cmd.Flags().StringVarP(
&applicationOwner,
"app-owner",
Expand Down Expand Up @@ -94,12 +100,12 @@ func init() {
"Application template hash. If not provided, it will be read from the template URI",
)

Cmd.Flags().StringVarP(
&status,
"status",
"s",
statusRunning,
"Sets the application status",
Cmd.Flags().BoolVarP(
&disabled,
"disabled",
"d",
false,
"Sets the application state to disabled",
)

Cmd.Flags().StringVarP(
Expand All @@ -113,45 +119,46 @@ func init() {
Cmd.Flags().StringVarP(
&authorityFactoryAddr,
"authority-factory",
"c",
"C",
"0xB897F7Fe78f220aE34B7FA9493092701a873Ed45",
"Authority Factory Address",
)

Cmd.Flags().StringVarP(
&iConsensusAddr,
"iconsensus",
"i",
&consensusAddr,
"consensus",
"c",
"",
"Application IConsensus Address",
)

Cmd.Flags().Uint64VarP(
&epochLength,
"epoch-length",
"e",
10,
"Consensus Epoch length. If consensus address is provided, the value will be read from the contract",
)

Cmd.Flags().StringVarP(&rpcURL, "rpc-url", "r", "http://localhost:8545", "Ethereum RPC URL")
Cmd.Flags().StringVarP(&privateKey, "private-key", "k", "", "Private key for signing transactions")
Cmd.Flags().StringVarP(&mnemonic, "mnemonic", "m", ethutil.FoundryMnemonic, "Mnemonic for signing transactions")
Cmd.Flags().StringVar(&salt, "salt", "0000000000000000000000000000000000000000000000000000000000000000", "salt")
Cmd.Flags().Uint64VarP(&inputBoxBlockNumber, "inputbox-block-number", "n", 0, "InputBox deployment block number")
Cmd.Flags().Uint64VarP(&epochLength, "epoch-length", "e", 10, "Consensus Epoch length")
Cmd.Flags().Uint64VarP(&inputBoxBlockNumber, "inputbox-block-number", "i", 0, "InputBox deployment block number")
Cmd.Flags().BoolVarP(&printAsJSON, "print-json", "j", false, "Prints the application data as JSON")
Cmd.Flags().BoolVar(&noRegister, "no-register", false, "Don't register the application on the node. Only deploy contracts")
}

func run(cmd *cobra.Command, args []string) {
ctx := cmd.Context()

if cmdcommom.Database == nil {
if cmdcommom.Repository == nil {
panic("Database was not initialized")
}

var applicationStatus model.ApplicationStatus
switch status {
case statusRunning:
applicationStatus = model.ApplicationStatusRunning
case statusNotRunning:
applicationStatus = model.ApplicationStatusNotRunning
default:
fmt.Fprintf(os.Stderr, "Invalid application status: %s\n", status)
os.Exit(1)
applicationState := model.ApplicationState_Enabled
if disabled {
applicationState = model.ApplicationState_Disabled
}

if templateHash == "" {
Expand All @@ -163,37 +170,46 @@ func run(cmd *cobra.Command, args []string) {
}
}

var consensusAddr common.Address
var consensus common.Address
var err error
if iConsensusAddr == "" {
if consensusAddr == "" {
authorityFactoryAddress := common.HexToAddress(authorityFactoryAddr)
consensusAddr, err = deployAuthority(ctx, authorityOwner, authorityFactoryAddress, epochLength, salt)
consensus, err = deployAuthority(ctx, authorityOwner, authorityFactoryAddress, epochLength, salt)
if err != nil {
fmt.Fprintf(os.Stderr, "Authoriy contract creation failed: %v\n", err)
os.Exit(1)
}
} else {
consensusAddr = common.HexToAddress(iConsensusAddr)
consensus = common.HexToAddress(consensusAddr)
epochLength, err = getEpochLength(consensus)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to get epoch length from consensus: %v\n", err)
os.Exit(1)
}
}

applicationFactoryAddress := common.HexToAddress(appFactoryAddr)
appAddr, err := deployApplication(ctx, applicationOwner, applicationFactoryAddress, consensusAddr, templateHash, salt)
appAddr, err := deployApplication(ctx, applicationOwner, applicationFactoryAddress, consensus, templateHash, salt)
if err != nil {
fmt.Fprintf(os.Stderr, "Application contract creation failed: %v\n", err)
os.Exit(1)
}

application := model.Application{
ContractAddress: appAddr,
TemplateUri: templatePath,
TemplateHash: common.HexToHash(templateHash),
LastProcessedBlock: inputBoxBlockNumber,
Status: applicationStatus,
IConsensusAddress: consensusAddr,
Name: name,
IApplicationAddress: appAddr,
IConsensusAddress: consensus,
TemplateURI: templatePath,
TemplateHash: common.HexToHash(templateHash),
EpochLength: epochLength,
State: applicationState,
LastProcessedBlock: inputBoxBlockNumber,
LastOutputCheckBlock: inputBoxBlockNumber,
LastClaimCheckBlock: inputBoxBlockNumber,
}

if !noRegister {
_, err = cmdcommom.Database.InsertApplication(ctx, &application)
_, err = cmdcommom.Repository.CreateApplication(ctx, &application)
cobra.CheckErr(err)
}

Expand All @@ -205,7 +221,7 @@ func run(cmd *cobra.Command, args []string) {
}
fmt.Println(string(jsonData))
} else {
fmt.Printf("Application %v successfully deployed\n", application.ContractAddress)
fmt.Printf("Application %v successfully deployed\n", application.IApplicationAddress)
}
}

Expand Down Expand Up @@ -413,6 +429,26 @@ func getAuth(ctx context.Context, client *ethclient.Client) (*bind.TransactOpts,
return auth, nil
}

func getEpochLength(
consensusAddr common.Address,
) (uint64, error) {
client, err := ethclient.Dial(rpcURL)
if err != nil {
return 0, fmt.Errorf("Failed to connect to the Ethereum client: %v", err)
}

consensus, err := iconsensus.NewIConsensus(consensusAddr, client)
if err != nil {
return 0, fmt.Errorf("Failed to instantiate contract: %v", err)
}

epochLengthRaw, err := consensus.GetEpochLength(nil)
if err != nil {
return 0, fmt.Errorf("error retrieving application epoch length: %v", err)
}
return epochLengthRaw.Uint64(), nil
}

func toBytes32(data []byte) [32]byte {
var arr [32]byte
if len(data) != 32 {
Expand Down
Loading

0 comments on commit c748b20

Please sign in to comment.