From f11f66e14f2d681ba0e9a4759063543d75037e60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrgen=20Eckel?= Date: Thu, 5 Oct 2023 12:38:35 +0200 Subject: [PATCH] 112 direct call to issue2liquid (#121) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * removed IssueResponseHandler * added asset-registration endpoint config * added methods to locally issue the asset and register it * added issue_service directory configuration * removed obsolete configuration options Signed-off-by: Jürgen Eckel --------- Signed-off-by: Jürgen Eckel --- app/app.go | 1 - config/config.go | 45 ++++---- x/machine/keeper/issue_response.go | 29 ----- x/machine/keeper/msg_server_attest_machine.go | 108 +++++++++++++++--- x/machine/types/errors.go | 5 + 5 files changed, 117 insertions(+), 71 deletions(-) delete mode 100644 x/machine/keeper/issue_response.go diff --git a/app/app.go b/app/app.go index f720489..06734de 100644 --- a/app/app.go +++ b/app/app.go @@ -550,7 +550,6 @@ func New( app.GetSubspace(machinemoduletypes.ModuleName), ) machineModule := machinemodule.NewAppModule(appCodec, app.MachineKeeper, app.AccountKeeper, app.BankKeeper) - go app.MachineKeeper.IssueResponseHandler(logger) app.AssetKeeper = *assetmodulekeeper.NewKeeper( appCodec, diff --git a/config/config.go b/config/config.go index d3c3af2..05d74d2 100644 --- a/config/config.go +++ b/config/config.go @@ -13,9 +13,8 @@ const DefaultConfigTemplate = ` ############################################################################### [planetmint] -osc-service-port = {{ .PlmntConfig.OSCServicePort }} -watchmen-endpoint = "{{ .PlmntConfig.WatchmenEndpoint }}" -watchmen-port = {{ .PlmntConfig.WatchmenPort }} + +asset-registry-endpoint = "{{ .PlmntConfig.AssetRegistryEndpoint }}" token-denom = "{{ .PlmntConfig.TokenDenom }}" stake-denom = "{{ .PlmntConfig.StakeDenom }}" fee-denom = "{{ .PlmntConfig.FeeDenom }}" @@ -23,20 +22,21 @@ config-root-dir = "{{ .PlmntConfig.ConfigRootDir }}" pop-epochs = {{ .PlmntConfig.PoPEpochs }} issuance-endpoint = "{{ .PlmntConfig.IssuanceEndpoint }}" issuance-port = {{ .PlmntConfig.IssuancePort }} +issuance-service-dir = {{ .PlmntConfig.IssuanceServiceDir }} + ` // Config defines Planetmint's top level configuration type Config struct { - OSCServicePort int `mapstructure:"osc-service-port" json:"osc-service-port"` - WatchmenEndpoint string `mapstructure:"watchmen-endpoint" json:"watchmen-endpoint"` - WatchmenPort int `mapstructure:"watchmen-port" json:"watchmen-port"` - TokenDenom string `mapstructure:"token-denom" json:"token-denom"` - StakeDenom string `mapstructure:"stake-denom" json:"stake-denom"` - FeeDenom string `mapstructure:"fee-denom" json:"fee-denom"` - ConfigRootDir string `mapstructure:"config-root-dir" json:"config-root-dir"` - PoPEpochs int `mapstructure:"pop-epochs" json:"pop-epochs"` - IssuanceEndpoint string `mapstructure:"issuance-endpoint" json:"issuance-endpoint"` - IssuancePort int `mapstructure:"issuance-port" json:"issuance-port"` + AssetRegistryEndpoint string `mapstructure:"asset-registry-endpoint " json:"asset-registry-endpoint "` + TokenDenom string `mapstructure:"token-denom" json:"token-denom"` + StakeDenom string `mapstructure:"stake-denom" json:"stake-denom"` + FeeDenom string `mapstructure:"fee-denom" json:"fee-denom"` + ConfigRootDir string `mapstructure:"config-root-dir" json:"config-root-dir"` + PoPEpochs int `mapstructure:"pop-epochs" json:"pop-epochs"` + IssuanceEndpoint string `mapstructure:"issuance-endpoint" json:"issuance-endpoint"` + IssuancePort int `mapstructure:"issuance-port" json:"issuance-port"` + IssuanceServiceDir string `mapstructure:"issuance-service-dir" json:"issuance-service-dir"` } // cosmos-sdk wide global singleton @@ -53,16 +53,15 @@ func DefaultConfig() *Config { } return &Config{ - OSCServicePort: 8766, - WatchmenEndpoint: "lab.r3c.network", - WatchmenPort: 7401, - TokenDenom: "plmnt", - StakeDenom: "plmntstake", - FeeDenom: "plmnt", - ConfigRootDir: filepath.Join(currentUser.HomeDir, ".planetmint-go"), - PoPEpochs: 24, // 24 CometBFT epochs of 5s equate 120s - IssuanceEndpoint: "lab.r3c.network", - IssuancePort: 7401, + AssetRegistryEndpoint: "https://assets.rddl.io/register_asset", + TokenDenom: "plmnt", + StakeDenom: "plmntstake", + FeeDenom: "plmnt", + ConfigRootDir: filepath.Join(currentUser.HomeDir, ".planetmint-go"), + PoPEpochs: 24, // 24 CometBFT epochs of 5s equate 120s + IssuanceEndpoint: "lab.r3c.network", + IssuancePort: 7401, + IssuanceServiceDir: "/opt/issuer_service", } } diff --git a/x/machine/keeper/issue_response.go b/x/machine/keeper/issue_response.go deleted file mode 100644 index 66a9ae8..0000000 --- a/x/machine/keeper/issue_response.go +++ /dev/null @@ -1,29 +0,0 @@ -package keeper - -import ( - config "github.com/planetmint/planetmint-go/config" - "strconv" - - "github.com/cometbft/cometbft/libs/log" - "github.com/hypebeast/go-osc/osc" -) - -func (k Keeper) IssueResponseHandler(logger log.Logger) { - conf := config.GetConfig() - addr := "0.0.0.0:" + strconv.FormatInt(int64(conf.OSCServicePort), 10) - d := osc.NewStandardDispatcher() - err := d.AddMsgHandler("/rddl/resp", func(msg *osc.Message) { - logger.Info("Issue Response: " + msg.String()) - }) - if err != nil { - logger.Error("Unable to add handler to OSC service.") - } - server := &osc.Server{ - Addr: addr, - Dispatcher: d, - } - err = server.ListenAndServe() - if err != nil { - logger.Error("Unable to start the OSC service.") - } -} diff --git a/x/machine/keeper/msg_server_attest_machine.go b/x/machine/keeper/msg_server_attest_machine.go index 1e8bdad..c066ba7 100644 --- a/x/machine/keeper/msg_server_attest_machine.go +++ b/x/machine/keeper/msg_server_attest_machine.go @@ -1,8 +1,15 @@ package keeper import ( + "bytes" "context" + "encoding/json" + "io" + "log" + "net/http" + "os/exec" "strconv" + "strings" config "github.com/planetmint/planetmint-go/config" "github.com/planetmint/planetmint-go/util" @@ -10,7 +17,6 @@ import ( "github.com/btcsuite/btcd/btcutil/hdkeychain" "github.com/btcsuite/btcd/chaincfg" - "github.com/crgimenes/go-osc" errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" @@ -72,24 +78,90 @@ func validateExtendedPublicKey(issuer string, cfg chaincfg.Params) bool { return isValidExtendedPublicKey } -func (k msgServer) issueMachineNFT(machine *types.Machine) error { +func (k msgServer) issueNFTAsset(name string, machine_address string) (asset_id string, contract string, err error) { conf := config.GetConfig() - client := osc.NewClient(conf.WatchmenEndpoint, conf.WatchmenPort) - machine_precision := strconv.FormatInt(int64(machine.Precision), 10) - machine_amount := strconv.FormatInt(int64(machine.Amount), 10) - machine_type := strconv.FormatUint(uint64(machine.GetType()), 10) - msg := osc.NewMessage("/rddl/issue") - msg.Append(machine.Name) - msg.Append(machine.Ticker) - msg.Append(machine.Domain) - msg.Append(machine_amount) - msg.Append("1") - msg.Append(machine_precision) - msg.Append(machine.Metadata.GetAdditionalDataCID()) - msg.Append(machine.GetIssuerPlanetmint()) - msg.Append(machine_type) - err := client.Send(msg) + cmdName := "poetry" + cmdArgs := []string{"run", "python", "issuer_service/issue2liquid.py", name, machine_address} - return err + // Create a new command + cmd := exec.Command(cmdName, cmdArgs...) + + // If you want to set the working directory + cmd.Dir = conf.IssuanceServiceDir + + // Capture the output + var stdout, stderr bytes.Buffer + cmd.Stdout = &stdout + cmd.Stderr = &stderr + + // Execute the command + err = cmd.Run() + if err != nil { + log.Fatalf("cmd.Run() failed with %s\n", err) + err = errorsmod.Wrap(types.ErrMachineNFTIssuance, stderr.String()) + } + lines := strings.Split(stdout.String(), "\n") + if len(lines) == 3 { + asset_id = lines[0] + contract = lines[1] + } else { + err = errorsmod.Wrap(types.ErrMachineNFTIssuanceNoOutput, stderr.String()) + } + return asset_id, contract, err +} +func (k msgServer) registerAsset(asset_id string, contract string) error { + + conf := config.GetConfig() + + // Create your request payload + data := map[string]interface{}{ + "asset_id": asset_id, + "contract": contract, + } + + jsonData, err := json.Marshal(data) + if err != nil { + return errorsmod.Wrap(types.ErrAssetRegistryReqFailure, "Marshall "+err.Error()) + } + + req, err := http.NewRequest("POST", conf.AssetRegistryEndpoint, bytes.NewBuffer(jsonData)) + if err != nil { + return errorsmod.Wrap(types.ErrAssetRegistryReqFailure, "Request creation: "+err.Error()) + } + + // Set headers + req.Header.Set("Content-Type", "application/json") + req.Header.Set("accept", "application/json") + + // Send request + client := &http.Client{} + resp, err := client.Do(req) + if err != nil { + return errorsmod.Wrap(types.ErrAssetRegistryReqSending, err.Error()) + } + defer resp.Body.Close() + + // Read response + if resp.StatusCode > 299 { + return errorsmod.Wrap(types.ErrAssetRegistryRepsonse, "Error reading response body:"+strconv.Itoa(resp.StatusCode)) + } + body, err := io.ReadAll(resp.Body) + if err != nil { + return errorsmod.Wrap(types.ErrAssetRegistryRepsonse, "Error reading response body:"+err.Error()) + } + result_obj := string(body) + if strings.Contains(result_obj, asset_id) { + return nil + } else { + return errorsmod.Wrap(types.ErrAssetRegistryRepsonse, "does not confirm asset registration") + } +} + +func (k msgServer) issueMachineNFT(machine *types.Machine) error { + asset_id, contract, err := k.issueNFTAsset(machine.Name, machine.Address) + if err != nil { + return err + } + return k.registerAsset(asset_id, contract) } diff --git a/x/machine/types/errors.go b/x/machine/types/errors.go index 08557f2..3dea164 100644 --- a/x/machine/types/errors.go +++ b/x/machine/types/errors.go @@ -17,4 +17,9 @@ var ( ErrMachineTypeUndefined = errorsmod.Register(ModuleName, 8, "the machine type has to be defined") ErrInvalidTrustAnchorKey = errorsmod.Register(ModuleName, 9, "invalid trust anchor pubkey") ErrTrustAnchorAlreadyRegistered = errorsmod.Register(ModuleName, 10, "trust anchor is already registered") + ErrMachineNFTIssuance = errorsmod.Register(ModuleName, 11, "the machine NFT could not be issued") + ErrMachineNFTIssuanceNoOutput = errorsmod.Register(ModuleName, 12, "the machine NFT issuing process derivated") + ErrAssetRegistryReqFailure = errorsmod.Register(ModuleName, 13, "request to asset registry could not be created") + ErrAssetRegistryReqSending = errorsmod.Register(ModuleName, 14, "request to asset registry could not be sent") + ErrAssetRegistryRepsonse = errorsmod.Register(ModuleName, 15, "request response issue") )