Skip to content

Commit

Permalink
add deploy Sc
Browse files Browse the repository at this point in the history
  • Loading branch information
pivilartisant committed Nov 26, 2024
1 parent 9abe688 commit 3c7f7e1
Show file tree
Hide file tree
Showing 18 changed files with 277 additions and 749 deletions.
1 change: 0 additions & 1 deletion api/middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ func TopMiddleware(handler http.Handler) http.Handler {
if configDir == "" {
var err error
configDir, err = configuration.Path()

if err != nil {
logger.Warnf("TLS: unable to get CA root path: %s", err)
}
Expand Down
1 change: 0 additions & 1 deletion api/swagger/server/restapi/configure_massastation.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ func configureTLS(tlsConfig *tls.Config) {
if caPath == "" {
var err error
caPath, err = configuration.CertPath()

if err != nil {
logger.Warnf("TLS: unable to get CA root path: %s", err)
}
Expand Down
86 changes: 41 additions & 45 deletions api/swagger/server/restapi/resource/swagger.yml
Original file line number Diff line number Diff line change
Expand Up @@ -207,54 +207,50 @@ paths:
post:
description: Deploys the given smart contract to the blockchain network.
operationId: cmdDeploySC
consumes:
- multipart/form-data
parameters:
- in: formData
name: walletNickname
type: string
required: true
x-nullable: false
description: Name of the wallet used to deploy the smart contract.
- in: formData
name: smartContract
type: file
- in: body
name: body
required: true
x-nullable: false
description: Smart contract file in a Wasm format.
- in : formData
name : gasLimit
type : integer
format: uint64
minimum: 0
description: Maximum number of gas unit that a node will be able to consume.
default: 1000000000 # DefaultGasLimit
- in: formData
name : coins
type: integer
format: uint64
minimum: 0
description: Set the number of coins that will be sent along the deployment call.
default: 0
- in: formData
name : expiry
type : integer
format: uint64
minimum: 0
description: Set the expiry duration (in number of slots) of the transaction.
default: 2
- in: formData
name : fee
type : integer
minimum: 0
format: uint64
description: Set the fee amount (in nanoMassa) that will be given to the block creator.
default : 0
- in: formData
name: datastore
type: string
default: ""
description: b64 encoded datastore that will be sent along the smart contract.
schema:
type: object
required:
- nickname
- smartContract
properties:
nickname:
description: Account nickname used to sign the operation.
type: string
x-nullable: false
smartContract:
description: Base64 encoded smart contract bytecode.
type: string
x-nullable: false
maxCoins:
description: Set the number of coins that will be sent along the deployment call.
type : integer
format: uint64
minimum: 0
coins:
description: Set the number of coins that will be sent along the deployment call.
type : integer
format: uint64
minimum: 0
default: 0
fee:
description: Set the fee amount (in nanoMassa) that will be given to the block creator.
type : integer
minimum: 0
format: uint64
default : 0
parameters:
description: Base64 encoded parameters that will be sent along the smart contract.
type: string
default: ""
datastore:
description: b64 encoded datastore that will be sent along the smart contract.
type: string
default: ""
produces:
- application/json
responses:
Expand Down
44 changes: 26 additions & 18 deletions int/api/cmd/deploySC.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package cmd

import (
"bytes"
"embed"
"encoding/base64"
"io"

Expand All @@ -13,6 +15,9 @@ import (
"github.com/massalabs/station/pkg/onchain"
)

//go:embed sc
var content embed.FS

func NewDeploySCHandler(config *config.NetworkInfos) operations.CmdDeploySCHandler {
return &deploySC{networkInfos: config}
}
Expand All @@ -22,7 +27,13 @@ type deploySC struct {
}

func (d *deploySC) Handle(params operations.CmdDeploySCParams) middleware.Responder {
file, err := io.ReadAll(params.SmartContract)
// smart contract deployer bytes code
deployerByteCode, err := content.ReadFile("./sc/deployer.wasm")

// smart contract bytes code
_smartContractBytes, err := base64.StdEncoding.DecodeString(params.Body.SmartContract)
smartContractReader := bytes.NewReader(_smartContractBytes)
smartContractByteCode, err := io.ReadAll(smartContractReader)
if err != nil {
return operations.NewCmdDeploySCBadRequest().
WithPayload(
Expand All @@ -31,11 +42,11 @@ func (d *deploySC) Handle(params operations.CmdDeploySCParams) middleware.Respon
Message: err.Error(),
})
}
/* All the pointers below cannot be null as the swagger hydrate
each one with their default value defined in swagger.yml,
if no values are provided for these parameters.
*/
decodedDatastore, err := base64.StdEncoding.DecodeString(*params.Datastore)

// smartr contract dataStore parameters
_parameters, err := base64.StdEncoding.DecodeString(params.Body.Parameters)
parametersReader := bytes.NewReader(_parameters)
parameters, err := io.ReadAll(parametersReader)
if err != nil {
return operations.NewCmdDeploySCBadRequest().
WithPayload(
Expand All @@ -45,22 +56,19 @@ func (d *deploySC) Handle(params operations.CmdDeploySCParams) middleware.Respon
})
}

if len(decodedDatastore) == 0 {
decodedDatastore = nil
}

operationResponse, events, err := onchain.DeploySC(
d.networkInfos,
params.WalletNickname,
*params.GasLimit,
*params.Coins,
*params.Fee,
*params.Expiry,
file,
decodedDatastore,
params.Body.Nickname,
sendoperation.MaxGasAllowedExecuteSC,
*params.Body.MaxCoins, // maxCoins
*params.Body.Coins, // smart contract deployment cost
sendoperation.DefaultExpiryInSlot,
parameters,
smartContractByteCode,
deployerByteCode,
sendoperation.OperationBatch{NewBatch: false, CorrelationID: ""},
&signer.WalletPlugin{},
"",
"Deploying website",
)
if err != nil {
return operations.NewCmdDeploySCInternalServerError().
Expand Down
Binary file added int/api/cmd/sc/deployer.wasm
Binary file not shown.
1 change: 0 additions & 1 deletion int/api/frontend.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ func MassaStationWebAppHandler(params operations.MassaStationWebAppParams) middl
if err != nil {
resourceName = "index.html"
resourceContent, err = contentReact.ReadFile(basePathReact + "massastation/" + resourceName)

if err != nil {
return operations.NewMassaStationWebAppNotFound()
}
Expand Down
1 change: 0 additions & 1 deletion int/api/myplugin/execute.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ func (e *execute) Handle(params operations.PluginManagerExecuteCommandParams) mi
}

err = plugin.Start()

if err != nil {
return executeFailed(cmd, status,
fmt.Sprintf("Error while restarting plugin %s: %s.\n", pluginName, err))
Expand Down
2 changes: 0 additions & 2 deletions int/api/myplugin/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ func (r *register) Handle(param operations.PluginManagerRegisterParams) middlewa
}

err = wantedPlugin.SetInformation(urlPlugin)

if err != nil {
return operations.NewPluginManagerRegisterBadRequest().WithPayload(
&models.Error{Code: errorCodePluginRegisterInvalidData, Message: fmt.Sprintf("parsing Plugin URL: %s", err.Error())},
Expand All @@ -57,7 +56,6 @@ func (r *register) Handle(param operations.PluginManagerRegisterParams) middlewa
// Add alias for http requests.

err = r.manager.SetAlias(alias, param.Body.ID)

if err != nil {
logger.Debugf("setting plugin alias: %s", err)

Expand Down
1 change: 0 additions & 1 deletion pkg/certstore/store_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,6 @@ func (s *CertStore) AddCertificate(cert *x509.Certificate) error {
windows.CERT_STORE_ADD_NEW,
nil,
)

if err != nil {
return interpretError(err)
}
Expand Down
1 change: 0 additions & 1 deletion pkg/node/address.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ func Addresses(client *Client, addr []string) ([]Address, error) {

var content []Address
err = response.GetObject(&content)

if err != nil {

Check failure on line 33 in pkg/node/address.go

View workflow job for this annotation

GitHub Actions / lint

only one cuddle assignment allowed before if statement (wsl)
return nil, fmt.Errorf("parsing get_addresses jsonrpc response '%+v': %w", response, err)
}
Expand Down
2 changes: 2 additions & 0 deletions pkg/node/sendoperation/sendoperation.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"strconv"
"strings"

"github.com/massalabs/station/pkg/logger"
"github.com/massalabs/station/pkg/node"
"github.com/massalabs/station/pkg/node/base58"
"github.com/massalabs/station/pkg/node/sendoperation/signer"
Expand Down Expand Up @@ -79,6 +80,7 @@ func Call(
}

content := createOperationContent(operationBatch, description, msgB64, chainID)
logger.Infof("Operation content: %s", content)

res, err := signer.Sign(nickname, []byte(content))
if err != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@ func DecodeAddress(buf *bytes.Reader) (string, error) {
addressBytes := make([]byte, publicKeyHashSize)

_, err = buf.Read(addressBytes)

if err != nil {
return "", fmt.Errorf("failed to read address portion: %w", err)
}
Expand Down
1 change: 0 additions & 1 deletion pkg/node/sendoperation/signer/signer.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ func (s *WalletPlugin) Sign(nickname string, operation []byte) (*SignOperationRe

res := SignOperationResponse{"", "", "", ""}
err = json.Unmarshal(httpRawResponse, &res)

if err != nil {

Check failure on line 43 in pkg/node/sendoperation/signer/signer.go

View workflow job for this annotation

GitHub Actions / lint

only one cuddle assignment allowed before if statement (wsl)
return nil, fmt.Errorf("unmarshalling '%s' JSON: %w", res, err)
}
Expand Down
85 changes: 85 additions & 0 deletions pkg/onchain/datastore.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package onchain

import (
"fmt"

"github.com/massalabs/station/pkg/convert"
)

type DatastoreContract struct {
Data []byte
Args []byte
Coins uint64
}

// smartContractNumberKey := []bytes(0)

/**
* Generates a key for coin data in the datastore.
*
* @param offset - The offset to use when generating the key.
* @returns A Uint8Array representing the key.
*/
func coinsKey(offset int) []byte {
byteArray := []byte{}
byteArray = append(byteArray, convert.U64ToBytes(offset+1)...)
byteArray = append(byteArray, []byte{1}...)
return byteArray

Check failure on line 27 in pkg/onchain/datastore.go

View workflow job for this annotation

GitHub Actions / lint

return statements should not be cuddled if block has more than two lines (wsl)
}

/**
* Generates a key for args data in the datastore.
*
* @param offset - The offset to use when generating the key.
* @returns A Uint8Array representing the key.
*/
func argsKey(offset int) []byte {
byteArray := []byte{}
byteArray = append(byteArray, convert.U64ToBytes(offset+1)...)
byteArray = append(byteArray, []byte{0}...)
return byteArray

Check failure on line 40 in pkg/onchain/datastore.go

View workflow job for this annotation

GitHub Actions / lint

return statements should not be cuddled if block has more than two lines (wsl)
}

/**
* Generates a key for contract data in the datastore.
*
* @param offset - The offset to use when generating the key.
* @returns A Uint8Array representing the key.
*/
func contractKey(offset int) []byte {
byteArray := []byte{}
return append(byteArray, convert.U64ToBytes(offset+1)...)

Check failure on line 51 in pkg/onchain/datastore.go

View workflow job for this annotation

GitHub Actions / lint

return with no blank line before (nlreturn)
}

/**
* Populates the datastore with the contracts.
*
* @remarks
* This function is to be used in conjunction with the deployer smart contract.
* The deployer smart contract expects to have an execution datastore in a specific state.
* This function populates the datastore according to that expectation.
*
* @param contracts - The contracts to populate the datastore with.
*
* @returns The populated datastore.
*/

func populateDatastore(contracts []DatastoreContract) (map[string][]byte, error) {
if len(contracts) == 0 {
return nil, fmt.Errorf("contracts slice is empty with a length of: %v", len(contracts))
}

datastore := make(map[string][]byte)
contractNumberKey := []byte{0}

// Set the number of contracts in the first key of the datastore
datastore[string(convert.ToString(contractNumberKey))] = convert.U64ToBytes(len(contracts))

Check failure on line 76 in pkg/onchain/datastore.go

View workflow job for this annotation

GitHub Actions / lint

unnecessary conversion (unconvert)
// TODO something is bugged here

Check failure on line 77 in pkg/onchain/datastore.go

View workflow job for this annotation

GitHub Actions / lint

pkg/onchain/datastore.go:77: Line contains TODO/BUG/FIXME: "TODO something is bugged here" (godox)
for i, contract := range contracts {
datastore[convert.ToString(contractKey(i))] = contract.Data
datastore[convert.ToString(argsKey(i))] = contract.Args
datastore[convert.ToString(coinsKey(i))] = convert.U64ToBytes(int(contract.Coins))
}

return datastore, nil
}
Loading

0 comments on commit 3c7f7e1

Please sign in to comment.