Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add deploy Sc #1370

Closed
wants to merge 26 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Comment on lines +236 to +237
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should not use "integer" type for MAS amount, but string. (same for fee).
Because json number cannot handle of range of uint64

Copy link
Contributor Author

@pivilartisant pivilartisant Dec 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so that would concern fee, maxCoins & coins fields ?

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

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: ""
description:
description: "Description of the operation"
type: string
default: ""
produces:
- application/json
responses:
Expand Down
40 changes: 21 additions & 19 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/deployer.wasm
var deployerSCByteCode []byte

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

func (d *deploySC) Handle(params operations.CmdDeploySCParams) middleware.Responder {
file, err := io.ReadAll(params.SmartContract)
_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 +38,10 @@ 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)

_parameters, err := base64.StdEncoding.DecodeString(params.Body.Parameters)
parameterReader := bytes.NewReader(_parameters)
parameters, err := io.ReadAll(parameterReader)
Comment on lines +42 to +44
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as before

if err != nil {
return operations.NewCmdDeploySCBadRequest().
WithPayload(
Expand All @@ -45,22 +51,18 @@ 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,
sendoperation.OperationBatch{NewBatch: false, CorrelationID: ""},
params.Body.Nickname,
sendoperation.MaxGasAllowedExecuteSC, // default
*params.Body.MaxCoins, // maxCoins
*params.Body.Coins, // smart contract deployment "fee"
sendoperation.DefaultExpiryInSlot,
parameters,
smartContractByteCode,
deployerSCByteCode,
&signer.WalletPlugin{},
"",
"Deploying contract "+params.Body.Description,
)
if err != nil {
return operations.NewCmdDeploySCInternalServerError().
Expand Down
1 change: 0 additions & 1 deletion int/api/cmd/execute_function.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ func (e *executeFunction) Handle(params operations.CmdExecuteFunctionParams) mid
uint64(params.Body.Coins),
expiry,
asyncReq,
sendOperation.OperationBatch{NewBatch: false, CorrelationID: ""},
&signer.WalletPlugin{},
params.Body.Description,
)
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
4 changes: 2 additions & 2 deletions pkg/convert/byteConverter.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const (
)

// Encode uint64 to byte array.
func U64ToBytes(nb int) (bytes []byte) {
func U64ToBytes(nb uint64) (bytes []byte) {
u64 := uint64(nb)
bytes = make([]byte, BytesPerUint64)
binary.LittleEndian.PutUint64(bytes, u64)
Expand All @@ -39,7 +39,7 @@ func I32ToBytes(nb int) (bytes []byte) {
return
}

func ToBytes(str string) []byte {
func StrToBytes(str string) []byte {
return []byte(str)
}

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 {
return nil, fmt.Errorf("parsing get_addresses jsonrpc response '%+v': %w", response, err)
}
Expand Down
21 changes: 0 additions & 21 deletions pkg/node/sendoperation/executesc/executesc.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,6 @@ func (e *ExecuteSC) Content() (interface{}, error) {
}, nil
}

// To date the datastore sent by the deploySC endpoint is always serialized.
// However the web on chain features make use of a non-serialized, nil datastore.
// Hence here we check that if datastore is not nil (and it means it comes from the deploySC endpoint)
// we do not encode it further but rather send it as is to the node.
func (e *ExecuteSC) Message() []byte {
msg := make([]byte, 0)
buf := make([]byte, binary.MaxVarintLen64)
Expand All @@ -84,25 +80,8 @@ func (e *ExecuteSC) Message() []byte {
msg = append(msg, buf[:nbBytes]...)
msg = append(msg, e.data...)

// datastore
// If the datastore is not nil, no need to serialize it.
if e.dataStore != nil {
msg = append(msg, e.dataStore...)

return msg
}

// If the datastore is nil, we need to serialize it.
// Number of entries in the datastore.
nbBytes = binary.PutUvarint(buf, uint64(len(e.dataStore)))
msg = append(msg, buf[:nbBytes]...)
msg = append(msg, e.dataStore...)

for key, value := range e.dataStore {
compactAndAppendBytes(&msg, key)
compactAndAppendBytes(&msg, value)
}

return msg
}

Expand Down
38 changes: 16 additions & 22 deletions pkg/node/sendoperation/sendoperation.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,14 @@ import (
"context"
b64 "encoding/base64"
"encoding/binary"
"encoding/json"
"fmt"
"log"
"strconv"
"strings"

"github.com/massalabs/station/pkg/convert"
"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 @@ -42,11 +46,6 @@ type OperationResponse struct {
CorrelationID string
}

type OperationBatch struct {
NewBatch bool
CorrelationID string
}

type JSONableSlice []uint8

func (u JSONableSlice) MarshalJSON() ([]byte, error) {
Expand All @@ -69,7 +68,6 @@ func Call(
fee uint64,
operation Operation,
nickname string,
operationBatch OperationBatch,
signer signer.Signer,
description string,
) (*OperationResponse, error) {
Expand All @@ -78,7 +76,8 @@ func Call(
return nil, err
}

content := createOperationContent(operationBatch, description, msgB64, chainID)
content := createOperationContent(description, msgB64, chainID)
logger.Infof("json content: %v",content)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to delete


res, err := signer.Sign(nickname, []byte(content))
if err != nil {
Expand All @@ -105,24 +104,19 @@ func Call(
return &OperationResponse{CorrelationID: res.CorrelationID, OperationID: resp[0]}, nil
}

func createOperationContent(operationBatch OperationBatch, description string, msgB64 string, chainID uint64) string {
var content string

const descriptionLabel = `{"description": "`
func createOperationContent(description string, msgB64 string, chainID uint64) string {
data := map[string]interface{}{
"description": description,
"operation": msgB64,
"chainId": strconv.FormatUint(chainID, 10),
}

switch {
case operationBatch.NewBatch:
content = descriptionLabel + description + `", "operation": "` + msgB64 + `",
"batch": true, "chainId": ` + strconv.FormatUint(chainID, 10) + `}`
case operationBatch.CorrelationID != "":
content = descriptionLabel + description + `", "operation": "` + msgB64 + `",
"correlationId": "` + operationBatch.CorrelationID + `", "chainId": ` + strconv.FormatUint(chainID, 10) + `}`
default:
content = descriptionLabel + description + `",
"operation": "` + msgB64 + `", "chainId": ` + strconv.FormatUint(chainID, 10) + `}`
content, err := json.Marshal(data)
if err != nil {
log.Fatalf("Error marshaling JSON: %v", err)
}

return content
return convert.ToString(content)
}

func MakeRPCCall(msg []byte, signature []byte, publicKey string, client *node.Client) ([]string, error) {
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 {
return nil, fmt.Errorf("unmarshalling '%s' JSON: %w", res, err)
}
Expand Down
Loading
Loading