* integrated ante-handler

* added two new config variables: reissuance-asset and validator-address

Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com>
This commit is contained in:
Jürgen Eckel 2023-10-10 01:24:28 +02:00
parent dac2d96194
commit b4ddc44044
No known key found for this signature in database
12 changed files with 127 additions and 80 deletions

View File

@ -1,7 +1,10 @@
package ante
import (
errorsmod "cosmossdk.io/errors"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/planetmint/planetmint-go/config"
"github.com/planetmint/planetmint-go/x/dao"
daotypes "github.com/planetmint/planetmint-go/x/dao/types"
)
@ -15,12 +18,14 @@ func NewCheckReissuanceDecorator() CheckReissuanceDecorator {
func (cmad CheckReissuanceDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) {
for _, msg := range tx.GetMsgs() {
if sdk.MsgTypeURL(msg) == "/planetmintgo.dao.NewMsgReissueRDDLProposal" {
_, ok := msg.(*daotypes.MsgReissueRDDLProposal)
//reissueMsg, ok := msg.(*daotypes.NewMsgReissueRDDLProposal)
if sdk.MsgTypeURL(msg) == "/planetmintgo.dao.MsgReissueRDDLProposal" {
MsgProposal, ok := msg.(*daotypes.MsgReissueRDDLProposal)
if ok {
// TODO: verify if the messages related PoP (BlockHeight) reflects
// what is actually traded within the raw transaction
conf := config.GetConfig()
isValid := dao.IsValidReissuanceCommand(MsgProposal.GetTx(), conf.ReissuanceAsset, MsgProposal.GetBlockheight())
if !isValid {
return ctx, errorsmod.Wrapf(daotypes.ErrReissuanceProposal, "error during CheckTx or ReCheckTx")
}
}
}
}

View File

@ -26,6 +26,9 @@ rpc-user = "{{ .PlmntConfig.RPCUser }}"
rpc-password = "{{ .PlmntConfig.RPCPassword }}"
mint-address = "{{ .PlmntConfig.MintAddress }}"
issuance-service-dir = "{{ .PlmntConfig.IssuanceServiceDir }}"
reissuance-asset = "{{ .PlmntConfig.ReissuanceAsset }}"
validator-address = "{{ .PlmntConfig.ReissuanceAsset }}"
`
// Config defines Planetmint's top level configuration
@ -42,6 +45,8 @@ type Config struct {
RPCPassword string `mapstructure:"rpc-password" json:"rpc-password"`
IssuanceServiceDir string `mapstructure:"issuance-service-dir" json:"issuance-service-dir"`
MintAddress string `mapstructure:"mint-address" json:"mint-address"`
ReissuanceAsset string `mapstructure:"reissuance-asset" json:"reissuance-asset"`
ValidatorAddress string `mapstructure:"validator-address" json:"validator-address"`
}
// cosmos-sdk wide global singleton
@ -67,9 +72,11 @@ func DefaultConfig() *Config {
RPCHost: "localhost",
RPCPort: 18884,
RPCUser: "user",
RPCPassword: "password",
RPCPassword: "passwor",
IssuanceServiceDir: "/opt/issuer_service",
MintAddress: "default",
ReissuanceAsset: "asset-id-or-name",
ValidatorAddress: "plmnt1w5dww335zhh98pzv783hqre355ck3u4w4hjxcx",
}
}

6
go.mod
View File

@ -8,7 +8,6 @@ require (
cosmossdk.io/math v1.1.2
github.com/btcsuite/btcd v0.23.2
github.com/btcsuite/btcd/btcutil v1.1.2
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1
github.com/cometbft/cometbft v0.37.2
github.com/cometbft/cometbft-db v0.7.0
github.com/cosmos/cosmos-sdk v0.47.5
@ -50,9 +49,7 @@ require (
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect
github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 // indirect
github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f // indirect
github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd // indirect
github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792 // indirect
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 // indirect
github.com/cenkalti/backoff/v4 v4.1.3 // indirect
github.com/cespare/xxhash v1.1.0 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
@ -73,7 +70,6 @@ require (
github.com/creachadair/taskgroup v0.4.2 // indirect
github.com/danieljoos/wincred v1.1.2 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/decred/dcrd/crypto/blake256 v1.0.0 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect
github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect
github.com/dgraph-io/badger/v2 v2.2007.4 // indirect

3
go.sum
View File

@ -272,16 +272,13 @@ github.com/btcsuite/btcd/btcutil v1.1.2/go.mod h1:UR7dsSJzJUfMmFiiLlIrMq1lS9jh9E
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc=
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U=
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc=
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f h1:bAs4lUbRJpnnkd9VhRV3jjAVU7DJVjMaK+IsvSeZvFo=
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd h1:R/opQEbFEy9JGkIguV40SvRY1uliPX8ifOvi6ICsFCw=
github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg=
github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY=
github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I=
github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc=
github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc=
github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792 h1:R8vQdOQdZ9Y3SkEwmHoWBmX1DNXhXZqlTpq6s4tyJGc=
github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY=
github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs=
github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA=

View File

@ -1,49 +1,43 @@
package util
import (
"log"
"bytes"
"encoding/json"
"errors"
"fmt"
"os/exec"
"strconv"
"strings"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/rpcclient"
"github.com/btcsuite/btcd/wire"
"github.com/planetmint/planetmint-go/config"
)
// TODO: define the final issuance
func GetUnsignedReissuanceTransaction() (string, error) {
config := config.GetConfig()
// Create a new client instance
connCfg := &rpcclient.ConnConfig{
Host: config.RPCHost + ":" + strconv.Itoa(config.RPCPort),
User: config.RPCUser,
Pass: config.RPCPassword,
HTTPPostMode: true, // Bitcoin core only supports HTTP POST mode
DisableTLS: true, // Bitcoin core does not provide TLS by default
}
client, erro := rpcclient.New(connCfg, nil)
if erro != nil {
log.Fatal(erro)
}
defer client.Shutdown()
// Define the inputs and outputs for the raw transaction
txIn := wire.NewTxIn(&wire.OutPoint{
Hash: chainhash.Hash{},
Index: 0,
}, nil, nil)
txOut := wire.NewTxOut(1000, nil) // 1000 satoshis, replace with your desired amount
// Create the raw transaction
rawTx := wire.NewMsgTx(wire.TxVersion)
rawTx.AddTxIn(txIn)
rawTx.AddTxOut(txOut)
// Serialize the transaction and convert to hex
//buf := []byte{}
var txHex = "12341234123412312342342341234123412341231234234234"
return txHex, erro
type ReissueResult struct {
Txid string `json:"txid"`
Vin int `json:"vin"`
}
func ReissueAsset(reissue_tx string) (txid string, err error) {
conf := config.GetConfig()
cmd_args := strings.Split(reissue_tx, " ")
cmd := exec.Command("/usr/local/bin/elements-cli", "-rpcpassword="+conf.RPCPassword,
"-rpcuser="+conf.RPCUser, "-rpcport="+strconv.Itoa(conf.RPCPort), "-rpcconnect="+conf.RPCHost,
cmd_args[0], cmd_args[1], cmd_args[2])
var stdout, stderr bytes.Buffer
cmd.Stdout = &stdout
cmd.Stderr = &stderr
err = cmd.Run()
errstr := stderr.String()
if err != nil || len(errstr) > 0 {
fmt.Printf("Error starting command: %s\n", errstr)
err = errors.New("Reissuance of RDDL failed.")
} else {
var txobj ReissueResult
json.Unmarshal(stdout.Bytes(), &txobj)
txid = txobj.Txid
}
return txid, err
}

View File

@ -1,40 +1,63 @@
package util
import (
"bytes"
"errors"
"fmt"
"os/exec"
"strconv"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/planetmint/planetmint-go/config"
)
func InitRDDLReissuanceProcess(ctx sdk.Context, proposerAddress string, blk_height int64) error {
tx_unsigned, err := GetUnsignedReissuanceTransaction()
//blk_height := 0 //get_last_PoPBlockHeight() // TODO: to be read form the upcoming PoP-store
func InitRDDLReissuanceProcess(ctx sdk.Context, proposerAddress string, tx_unsigned string, blk_height int64) error {
//get_last_PoPBlockHeight() // TODO: to be read form the upcoming PoP-store
// Construct the command
cmd := exec.Command("planetmint-god", "tx", "dao", "reissue-rddl-proposal", proposerAddress, tx_unsigned, strconv.FormatInt(blk_height, 10))
sending_validator_address := config.GetConfig().ValidatorAddress
cmd := exec.Command("planetmint-god", "tx", "dao", "reissue-rddl-proposal",
"--from", sending_validator_address, "-y",
proposerAddress, tx_unsigned, strconv.FormatInt(blk_height, 10))
var stdout, stderr bytes.Buffer
cmd.Stdout = &stdout
cmd.Stderr = &stderr
// Start the command in a non-blocking way
err = cmd.Start()
if err != nil {
fmt.Printf("Error starting command: %s\n", err)
err := cmd.Start()
outstr := stdout.String()
errstr := stderr.String()
if err != nil || len(errstr) > 0 {
fmt.Printf("Error starting command: s\n", errstr)
if err == nil {
err = errors.New(errstr)
}
} else {
fmt.Println("Command started in background")
fmt.Println("Command started in background %s\n", outstr)
}
return err
}
func SendRDDLReissuanceResult(ctx sdk.Context, proposerAddress string, txID string, blk_height uint64) error {
// Construct the command
cmd := exec.Command("planetmint-god", "tx", "dao", "reissue-rddl-result", proposerAddress, txID, strconv.FormatUint(blk_height, 10))
sending_validator_address := config.GetConfig().ValidatorAddress
cmd := exec.Command("planetmint-god", "tx", "dao", "reissue-rddl-result",
"--from", sending_validator_address, "-y",
proposerAddress, txID, strconv.FormatUint(blk_height, 10))
var stdout, stderr bytes.Buffer
cmd.Stdout = &stdout
cmd.Stderr = &stderr
// Start the command in a non-blocking way
err := cmd.Start()
if err != nil {
fmt.Printf("Error starting command: %s\n", err)
outstr := stdout.String()
errstr := stderr.String()
if err != nil || len(errstr) > 0 {
fmt.Printf("Error starting command: s\n", errstr)
if err == nil {
err = errors.New(errstr)
}
} else {
fmt.Println("Command started in background")
fmt.Println("Command started in background %s\n", outstr)
}
return err
}

View File

@ -19,12 +19,15 @@ func BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock, k keeper.Keeper)
// Check if node is block proposer
if isPoPHeight(req.Header.GetHeight()) && util.IsValidatorBlockProposer(ctx, proposerAddress) {
blockHeight := req.Header.GetHeight()
// TODO: implement PoP trigger
fmt.Println("TODO: implement PoP trigger")
hexProposerAddress := hex.EncodeToString(proposerAddress)
err := util.InitRDDLReissuanceProcess(ctx, hexProposerAddress, req.Header.GetHeight())
conf := config.GetConfig()
tx_unsigned := GetReissuanceCommand(conf.ReissuanceAsset, blockHeight)
err := util.InitRDDLReissuanceProcess(ctx, hexProposerAddress, tx_unsigned, blockHeight)
if err != nil {
logger.Error("error while issuing RDDL", err)
logger.Error("error while initializing RDDL issuance", err)
}
}
}

View File

@ -15,10 +15,14 @@ func (k msgServer) ReissueRDDLProposal(goCtx context.Context, msg *types.MsgReis
if valid_result && msg.Proposer == validator_identity {
// 1. sign tx
// 2. broadcast tx
txID, err := util.ReissueAsset(msg.Tx)
if err == nil {
// 3. notarize result by notarizing the liquid tx-id
util.SendRDDLReissuanceResult(ctx, msg.GetProposer(), txID, msg.GetBlockheight())
} else {
//reissuance need to be initiated otherwise
}
txID := "asdlkufzaoisdfpoajf"
// 3. notarize result by notarizing the liquid tx-id
util.SendRDDLReissuanceResult(ctx, msg.GetProposer(), txID, msg.GetBlockheight())
}
var reissuance types.Reissuance

View File

@ -20,5 +20,10 @@ func (k Keeper) GetReissuances(goCtx context.Context, req *types.QueryGetReissua
req.Pagination.GetOffset(), req.Pagination.GetLimit(),
req.Pagination.GetCountTotal(), req.Pagination.GetReverse())
return &types.QueryGetReissuancesResponse{Reissuance: &reissuances[0]}, nil
if reissuances != nil {
return &types.QueryGetReissuancesResponse{Reissuance: &reissuances[0]}, nil
} else {
return &types.QueryGetReissuancesResponse{}, nil
}
}

View File

@ -17,4 +17,6 @@ var (
ErrReissuanceNotFound = errorsmod.Register(ModuleName, 8, "reissuance not found")
ErrInvalidProposer = errorsmod.Register(ModuleName, 9, "invalid proposer")
ErrTXAlreadySet = errorsmod.Register(ModuleName, 10, "tx already set")
ErrReissuanceProposal = errorsmod.Register(ModuleName, 11, "invalid reissuance proposal")
ErrReissuanceFailed = errorsmod.Register(ModuleName, 12, "reissuance of RDDL failed")
)

10
x/dao/util.go Normal file
View File

@ -0,0 +1,10 @@
package dao
func GetReissuanceCommand(asset_id string, BlockHeight int64) string {
return "reissueasset " + asset_id + " 998.69"
}
func IsValidReissuanceCommand(reissuance_str string, asset_id string, BlockHeight uint64) bool {
expected := "reissueasset " + asset_id + " 998.69"
return reissuance_str == expected
}

View File

@ -100,13 +100,14 @@ func (k msgServer) issueNFTAsset(name string, machine_address string) (asset_id
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())
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
}