mirror of
https://github.com/planetmint/planetmint-go.git
synced 2025-07-02 02:42:30 +00:00
154 lines
4.3 KiB
Go
154 lines
4.3 KiB
Go
package keeper
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
config "github.com/planetmint/planetmint-go/config"
|
|
"github.com/planetmint/planetmint-go/util"
|
|
"github.com/planetmint/planetmint-go/x/machine/types"
|
|
|
|
"github.com/btcsuite/btcd/btcutil/hdkeychain"
|
|
"github.com/btcsuite/btcd/chaincfg"
|
|
|
|
errorsmod "cosmossdk.io/errors"
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
"github.com/rddl-network/go-utils/signature"
|
|
)
|
|
|
|
func (k msgServer) AttestMachine(goCtx context.Context, msg *types.MsgAttestMachine) (*types.MsgAttestMachineResponse, error) {
|
|
if err := k.validateMachineAttestation(msg.Machine); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if err := k.processMachineAttestation(goCtx, msg.Machine); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &types.MsgAttestMachineResponse{}, nil
|
|
}
|
|
|
|
func (k msgServer) validateMachineAttestation(machine *types.Machine) error {
|
|
// Validate machine signature
|
|
if err := k.validateMachineSignature(machine); err != nil {
|
|
return err
|
|
}
|
|
|
|
// Validate issuer keys
|
|
if err := k.validateIssuerKeys(machine); err != nil {
|
|
return err
|
|
}
|
|
|
|
// Validate machine type
|
|
if machine.GetType() == 0 { // 0 == RDDL_MACHINE_UNDEFINED
|
|
return types.ErrMachineTypeUndefined
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (k msgServer) validateMachineSignature(machine *types.Machine) error {
|
|
isValidSecp256r1, errR1 := signature.ValidateSECP256R1Signature(
|
|
machine.MachineId,
|
|
machine.MachineIdSignature,
|
|
machine.MachineId,
|
|
)
|
|
|
|
if errR1 == nil && isValidSecp256r1 {
|
|
return nil
|
|
}
|
|
|
|
isValidSecp256k1, errK1 := signature.ValidateSignature(
|
|
machine.MachineId,
|
|
machine.MachineIdSignature,
|
|
machine.MachineId,
|
|
)
|
|
|
|
if errK1 == nil && isValidSecp256k1 {
|
|
return nil
|
|
}
|
|
|
|
return fmt.Errorf("invalid machine signature: %s, %s", errR1.Error(), errK1.Error())
|
|
}
|
|
|
|
func (k msgServer) validateIssuerKeys(machine *types.Machine) error {
|
|
if !validateExtendedPublicKey(machine.IssuerPlanetmint, config.PlmntNetParams) {
|
|
return errorsmod.Wrap(types.ErrInvalidKey, "planetmint")
|
|
}
|
|
|
|
if !validateExtendedPublicKey(machine.IssuerLiquid, config.LiquidNetParams) {
|
|
return errorsmod.Wrap(types.ErrInvalidKey, "liquid")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (k msgServer) processMachineAttestation(goCtx context.Context, machine *types.Machine) error {
|
|
ctx := sdk.UnwrapSDKContext(goCtx)
|
|
params := k.GetParams(ctx)
|
|
|
|
// Process NFT issuance if validator is block proposer
|
|
if util.IsValidatorBlockProposer(ctx, k.rootDir) {
|
|
if err := k.handleNFTIssuance(goCtx, machine, params); err != nil {
|
|
return err
|
|
}
|
|
k.sendInitialFundingTokensToMachine(goCtx, machine.GetAddress(), params)
|
|
} else {
|
|
util.GetAppLogger().Info(ctx, "Not block proposer: skipping Machine NFT issuance")
|
|
}
|
|
|
|
// Store machine data
|
|
k.StoreMachine(ctx, *machine)
|
|
k.StoreMachineIndex(ctx, *machine)
|
|
|
|
// Store trust anchor
|
|
ta, _, _ := k.GetTrustAnchor(ctx, machine.MachineId)
|
|
if err := k.StoreTrustAnchor(ctx, ta, true); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (k msgServer) handleNFTIssuance(goCtx context.Context, machine *types.Machine, params types.Params) error {
|
|
ctx := sdk.UnwrapSDKContext(goCtx)
|
|
logger := util.GetAppLogger()
|
|
logger.Info(ctx, "Issuing Machine NFT: "+machine.String())
|
|
|
|
err := util.IssueMachineNFT(goCtx, machine,
|
|
params.AssetRegistryScheme,
|
|
params.AssetRegistryDomain,
|
|
params.AssetRegistryPath,
|
|
)
|
|
|
|
if err != nil {
|
|
logger.Error(ctx, err, "Machine NFT issuance failed")
|
|
return err
|
|
}
|
|
|
|
logger.Info(ctx, "Machine NFT issuance successful: "+machine.String())
|
|
return nil
|
|
}
|
|
|
|
func (k msgServer) sendInitialFundingTokensToMachine(goCtx context.Context, machineAddressString string, keeperParams types.Params) {
|
|
ctx := sdk.UnwrapSDKContext(goCtx)
|
|
machineAddress, err := sdk.AccAddressFromBech32(machineAddressString)
|
|
if err != nil {
|
|
util.GetAppLogger().Error(ctx, err, "for provided address "+machineAddress.String())
|
|
return
|
|
}
|
|
|
|
logMsg := fmt.Sprintf("transferring %v tokens to address %s", keeperParams.GetDaoMachineFundingAmount(), machineAddress.String())
|
|
util.GetAppLogger().Info(ctx, logMsg)
|
|
util.SendTokens(goCtx, machineAddress, keeperParams.GetDaoMachineFundingAmount(), keeperParams.GetDaoMachineFundingDenom())
|
|
}
|
|
|
|
func validateExtendedPublicKey(issuer string, cfg chaincfg.Params) bool {
|
|
xpubKey, err := hdkeychain.NewKeyFromString(issuer)
|
|
if err != nil {
|
|
return false
|
|
}
|
|
isValidExtendedPublicKey := xpubKey.IsForNet(&cfg)
|
|
return isValidExtendedPublicKey
|
|
}
|