diff --git a/cmd/planetmint-god/cmd/root.go b/cmd/planetmint-god/cmd/root.go index bf60e48..a50da6a 100644 --- a/cmd/planetmint-god/cmd/root.go +++ b/cmd/planetmint-god/cmd/root.go @@ -380,8 +380,6 @@ func initAppConfig(clientCtx client.Context) (string, interface{}) { srvCfg.MinGasPrices = "0stake" plmntConfig := planetmintconfig.GetConfig() - // CHANGE AGAIN - //plmntConfig.SetRoot(clientCtx.HomeDir) libConfig := lib.GetConfig() libConfig.SetChainID(clientCtx.ChainID) diff --git a/config/config.go b/config/config.go index 3994fac..e3e87a2 100644 --- a/config/config.go +++ b/config/config.go @@ -140,12 +140,6 @@ func (config *Config) GetRPCURL() (url string) { return } -// CHANGE AGAIN -// func (config *Config) SetRoot(root string) *Config { -// config.ConfigRootDir = root -// return config -// } - // SetPlanetmintConfig sets Planetmint's configuration func (config *Config) SetPlanetmintConfig(planetmintconfig interface{}) { jsonConfig, err := json.Marshal(planetmintconfig) diff --git a/testutil/network/loader.go b/testutil/network/loader.go index 279205f..09d3ecb 100644 --- a/testutil/network/loader.go +++ b/testutil/network/loader.go @@ -14,7 +14,6 @@ import ( simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - "github.com/golang/mock/gomock" "github.com/planetmint/planetmint-go/app" "github.com/planetmint/planetmint-go/config" "github.com/planetmint/planetmint-go/lib" @@ -22,8 +21,6 @@ import ( "github.com/planetmint/planetmint-go/util" "github.com/planetmint/planetmint-go/util/mocks" daotypes "github.com/planetmint/planetmint-go/x/dao/types" - machine "github.com/planetmint/planetmint-go/x/machine/keeper" - machinetestutil "github.com/planetmint/planetmint-go/x/machine/testutil" elements "github.com/rddl-network/elements-rpc" elementsmocks "github.com/rddl-network/elements-rpc/utils/mocks" "github.com/stretchr/testify/require" @@ -46,14 +43,7 @@ func Load(t *testing.T, configs ...Config) *Network { // use mock client for testing util.MQTTClient = &mocks.MockMQTTClient{} elements.Client = &elementsmocks.MockClient{} - - // call to set sync.Once - _ = machine.GetAssetServiceClient() - ctrl := gomock.NewController(t) - ascMock := machinetestutil.NewMockIAssetServiceClient(ctrl) - ascMock.EXPECT().RegisterAsset(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes() - ascMock.EXPECT().IssueMachineNFT(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes() - machine.SetAssetServiceClient(ascMock) + util.RegisterAssetServiceHTTPClient = &mocks.MockClient{} // enable application logger in tests appLogger := util.GetAppLogger() @@ -61,8 +51,6 @@ func Load(t *testing.T, configs ...Config) *Network { // set the proper root dir for the test environment so that the abci.go logic works conf := config.GetConfig() - // CHANGE AGAIN - // conf.SetRoot(validatorTmpDir + "/node0/simd") net, err := New(t, validatorTmpDir, cfg) require.NoError(t, err) diff --git a/x/machine/keeper/register_nft.go b/util/machine_nft.go similarity index 70% rename from x/machine/keeper/register_nft.go rename to util/machine_nft.go index 2f886fa..87000dd 100644 --- a/x/machine/keeper/register_nft.go +++ b/util/machine_nft.go @@ -1,4 +1,4 @@ -package keeper +package util import ( "bytes" @@ -11,42 +11,27 @@ import ( "net/http" "strconv" "strings" - "sync" errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" config "github.com/planetmint/planetmint-go/config" - "github.com/planetmint/planetmint-go/util" "github.com/planetmint/planetmint-go/x/machine/types" elements "github.com/rddl-network/elements-rpc" ) +type HTTPClient interface { + Do(req *http.Request) (*http.Response, error) +} + var ( - assetClientService IAssetServiceClient - initAssetServiceClient sync.Once + RegisterAssetServiceHTTPClient HTTPClient ) -type IAssetServiceClient interface { - IssueNFTAsset(goCtx context.Context, name string, machineAddress string, domain string) (assetID string, contract string, err error) - IssueMachineNFT(goCtx context.Context, machine *types.Machine, scheme string, domain string, path string) error - RegisterAsset(goCtx context.Context, assetID string, contract string, assetRegistryEndpoint string) error +func init() { + RegisterAssetServiceHTTPClient = &http.Client{} } -type AssetServiceClient struct{} - -func GetAssetServiceClient() IAssetServiceClient { - initAssetServiceClient.Do(func() { - assetClientService = &AssetServiceClient{} - }) - return assetClientService -} - -func SetAssetServiceClient(asc IAssetServiceClient) { - assetClientService = asc -} - -func (asc *AssetServiceClient) IssueNFTAsset(goCtx context.Context, name string, machineAddress string, domain string) (assetID string, contract string, err error) { - ctx := sdk.UnwrapSDKContext(goCtx) +func IssueNFTAsset(name string, machineAddress string, domain string) (assetID string, contract string, hexTx string, err error) { conf := config.GetConfig() url := conf.GetRPCURL() @@ -134,26 +119,25 @@ func (asc *AssetServiceClient) IssueNFTAsset(goCtx context.Context, name string, return } - util.GetAppLogger().Info(ctx, "Liquid Token Issuance assetID: "+assetID+" contract: "+contract+" tx: "+hex) - return assetID, contract, err + return assetID, contract, hex, err } -func (asc *AssetServiceClient) IssueMachineNFT(goCtx context.Context, machine *types.Machine, scheme string, domain string, path string) error { +func IssueMachineNFT(goCtx context.Context, machine *types.Machine, scheme string, domain string, path string) error { ctx := sdk.UnwrapSDKContext(goCtx) // asset registration is in order to have the contact published var notarizedAsset types.LiquidAsset notarizedAsset.Registered = true - assetID, contract, err := asc.IssueNFTAsset(goCtx, machine.Name, machine.Address, domain) + assetID, contract, hex, err := IssueNFTAsset(machine.Name, machine.Address, domain) if err != nil { - util.GetAppLogger().Error(ctx, err.Error()) + GetAppLogger().Error(ctx, err.Error()) return err } assetRegistryEndpoint := fmt.Sprintf("%s://%s/%s", scheme, domain, path) - fmt.Println(" Register Asset: " + assetRegistryEndpoint) - fmt.Println(" CONTRACT: " + contract) - err = asc.RegisterAsset(goCtx, assetID, contract, assetRegistryEndpoint) + + GetAppLogger().Info(ctx, "Liquid Token Issuance assetID: "+assetID+" contract: "+contract+" tx: "+hex) + err = RegisterAsset(goCtx, assetID, contract, assetRegistryEndpoint) if err != nil { - util.GetAppLogger().Error(ctx, err.Error()) + GetAppLogger().Error(ctx, err.Error()) notarizedAsset.Registered = false } // issue message with: @@ -161,11 +145,11 @@ func (asc *AssetServiceClient) IssueMachineNFT(goCtx context.Context, machine *t notarizedAsset.MachineID = machine.GetMachineId() notarizedAsset.MachineAddress = machine.Address - util.SendLiquidAssetRegistration(goCtx, notarizedAsset) + SendLiquidAssetRegistration(goCtx, notarizedAsset) return err } -func (asc *AssetServiceClient) RegisterAsset(goCtx context.Context, assetID string, contract string, assetRegistryEndpoint string) error { +func RegisterAsset(goCtx context.Context, assetID string, contract string, assetRegistryEndpoint string) error { var contractMap map[string]interface{} err := json.Unmarshal([]byte(contract), &contractMap) if err != nil { @@ -192,8 +176,7 @@ func (asc *AssetServiceClient) RegisterAsset(goCtx context.Context, assetID stri req.Header.Set("accept", "application/json") // Send request - client := &http.Client{} - resp, err := client.Do(req) + resp, err := RegisterAssetServiceHTTPClient.Do(req) if err != nil { return errorsmod.Wrap(types.ErrAssetRegistryReqSending, err.Error()) } diff --git a/util/machine_nft_test.go b/util/machine_nft_test.go new file mode 100644 index 0000000..18aa82d --- /dev/null +++ b/util/machine_nft_test.go @@ -0,0 +1,42 @@ +package util_test + +import ( + "context" + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/planetmint/planetmint-go/testutil/keeper" + "github.com/planetmint/planetmint-go/testutil/sample" + "github.com/planetmint/planetmint-go/util" + "github.com/planetmint/planetmint-go/util/mocks" + elements "github.com/rddl-network/elements-rpc" + elementsmocks "github.com/rddl-network/elements-rpc/utils/mocks" + "github.com/stretchr/testify/assert" +) + +func TestRegisterNFT(t *testing.T) { + t.Parallel() + url := "https://testnet-assets.rddl.io/register_asset" + contract := `{"entity":{"domain":"testnet-assets.rddl.io"},"issuer_pubkey":"020000000000000000000000000000000000000000000000000000000000000000","machine_addr":"plmnt10mq5nj8jhh27z7ejnz2ql3nh0qhzjnfvy50877","name":"machine","precision":0,"version":0}` + asset := "0000000000000000000000000000000000000000000000000000000000000000" + goctx := context.Background() + + util.RegisterAssetServiceHTTPClient = &mocks.MockClient{} + err := util.RegisterAsset(goctx, asset, contract, url) + assert.NoError(t, err) +} + +func TestMachineNFTIssuance(t *testing.T) { + t.Parallel() + + elements.Client = &elementsmocks.MockClient{} + util.RegisterAssetServiceHTTPClient = &mocks.MockClient{} + _, ctx := keeper.MachineKeeper(t) + sk, pk := sample.KeyPair() + machine := sample.Machine(pk, pk, sk, "") + goCtx := sdk.WrapSDKContext(ctx) + + err := util.IssueMachineNFT(goCtx, &machine, "https", "testnet-asset.rddl.io", "/register_asset") + + assert.NoError(t, err) +} diff --git a/util/mocks/register_nft_mock.go b/util/mocks/register_nft_mock.go new file mode 100644 index 0000000..da8fef0 --- /dev/null +++ b/util/mocks/register_nft_mock.go @@ -0,0 +1,47 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: x/machine/keeper/register_nft.go + +// Package testutil is a generated GoMock package. +package mocks + +import ( + "encoding/json" + "io" + "net/http" + "strings" +) + +type Body struct { + Jsonrpc string `json:"jsonrpc"` + Method string `json:"method"` + Params []any `json:"params"` +} + +type MockClient struct { + DoFunc func(req *http.Request) (*http.Response, error) +} + +// GetDoFunc fetches the mock client's `Do` func +func GetDoFunc(req *http.Request) (*http.Response, error) { + var body Body + bodyBytes, err := io.ReadAll(req.Body) + if err != nil { + return nil, err + } + err = json.Unmarshal(bodyBytes, &body) + if err != nil { + return nil, err + } + + result := `{ "assetid": "0000000000000000000000000000000000000000000000000000000000000000"}` + resp := &http.Response{ + StatusCode: http.StatusOK, + Body: io.NopCloser(strings.NewReader(result)), + } + return resp, nil +} + +// Do is the mock client's `Do` func +func (m *MockClient) Do(req *http.Request) (*http.Response, error) { + return GetDoFunc(req) +} diff --git a/x/machine/keeper/msg_server_attest_machine.go b/x/machine/keeper/msg_server_attest_machine.go index d01ae9a..f93e38d 100644 --- a/x/machine/keeper/msg_server_attest_machine.go +++ b/x/machine/keeper/msg_server_attest_machine.go @@ -38,21 +38,20 @@ func (k msgServer) AttestMachine(goCtx context.Context, msg *types.MsgAttestMach if msg.Machine.GetType() == 0 { // 0 == RDDL_MACHINE_UNDEFINED return nil, types.ErrMachineTypeUndefined } - + params := k.GetParams(ctx) if util.IsValidatorBlockProposer(ctx, ctx.BlockHeader().ProposerAddress, k.rootDir) { util.GetAppLogger().Info(ctx, "Issuing Machine NFT: "+msg.Machine.String()) - scheme := k.GetParams(ctx).AssetRegistryScheme - domain := k.GetParams(ctx).AssetRegistryDomain - path := k.GetParams(ctx).AssetRegistryPath - //go func() { - asc := GetAssetServiceClient() - localErr := asc.IssueMachineNFT(goCtx, msg.Machine, scheme, domain, path) + scheme := params.AssetRegistryScheme + domain := params.AssetRegistryDomain + path := params.AssetRegistryPath + // go func() { + localErr := util.IssueMachineNFT(goCtx, msg.Machine, scheme, domain, path) if localErr != nil { util.GetAppLogger().Error(ctx, "Machine NFT issuance failed : "+localErr.Error()) } else { util.GetAppLogger().Info(ctx, "Machine NFT issuance successful: "+msg.Machine.String()) } - //}() + // }() } else { util.GetAppLogger().Info(ctx, "Not block proposer: skipping Machine NFT issuance") } diff --git a/x/machine/keeper/register_nft_test.go b/x/machine/keeper/register_nft_test.go deleted file mode 100644 index 5d7dc0c..0000000 --- a/x/machine/keeper/register_nft_test.go +++ /dev/null @@ -1,33 +0,0 @@ -package keeper_test - -import ( - "testing" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/golang/mock/gomock" - keepertest "github.com/planetmint/planetmint-go/testutil/keeper" - "github.com/planetmint/planetmint-go/x/machine/keeper" - "github.com/planetmint/planetmint-go/x/machine/testutil" - "github.com/stretchr/testify/assert" -) - -func TestRegisterNFT(t *testing.T) { - _, ctx := keepertest.MachineKeeper(t) - url := "https://testnet-assets.rddl.io/register_asset" - contract := `{"entity":{"domain":"testnet-assets.rddl.io"},"issuer_pubkey":"020000000000000000000000000000000000000000000000000000000000000000","machine_addr":"plmnt10mq5nj8jhh27z7ejnz2ql3nh0qhzjnfvy50877","name":"machine","precision":0,"version":0}` - asset := "0000000000000000000000000000000000000000000000001000000000000000" - goctx := sdk.WrapSDKContext(ctx) - - // Call to set sync.Once - _ = keeper.GetAssetServiceClient() - - ctrl := gomock.NewController(t) - ascMock := testutil.NewMockIAssetServiceClient(ctrl) - ascMock.EXPECT().RegisterAsset(goctx, asset, contract, url).Return(nil).AnyTimes() - keeper.SetAssetServiceClient(ascMock) - - asc := keeper.GetAssetServiceClient() - - err := asc.RegisterAsset(goctx, asset, contract, url) - assert.NoError(t, err) -} diff --git a/x/machine/testutil/register_nft_mock.go b/x/machine/testutil/register_nft_mock.go deleted file mode 100644 index 25e9ef5..0000000 --- a/x/machine/testutil/register_nft_mock.go +++ /dev/null @@ -1,80 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: x/machine/keeper/register_nft.go - -// Package testutil is a generated GoMock package. -package testutil - -import ( - context "context" - reflect "reflect" - - gomock "github.com/golang/mock/gomock" - types "github.com/planetmint/planetmint-go/x/machine/types" -) - -// MockIAssetServiceClient is a mock of IAssetServiceClient interface. -type MockIAssetServiceClient struct { - ctrl *gomock.Controller - recorder *MockIAssetServiceClientMockRecorder -} - -// MockIAssetServiceClientMockRecorder is the mock recorder for MockIAssetServiceClient. -type MockIAssetServiceClientMockRecorder struct { - mock *MockIAssetServiceClient -} - -// NewMockIAssetServiceClient creates a new mock instance. -func NewMockIAssetServiceClient(ctrl *gomock.Controller) *MockIAssetServiceClient { - mock := &MockIAssetServiceClient{ctrl: ctrl} - mock.recorder = &MockIAssetServiceClientMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockIAssetServiceClient) EXPECT() *MockIAssetServiceClientMockRecorder { - return m.recorder -} - -// IssueMachineNFT mocks base method. -func (m *MockIAssetServiceClient) IssueMachineNFT(goCtx context.Context, machine *types.Machine, scheme, domain, path string) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "IssueMachineNFT", goCtx, machine, scheme, domain, path) - ret0, _ := ret[0].(error) - return ret0 -} - -// IssueMachineNFT indicates an expected call of IssueMachineNFT. -func (mr *MockIAssetServiceClientMockRecorder) IssueMachineNFT(goCtx, machine, scheme, domain, path interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IssueMachineNFT", reflect.TypeOf((*MockIAssetServiceClient)(nil).IssueMachineNFT), goCtx, machine, scheme, domain, path) -} - -// IssueNFTAsset mocks base method. -func (m *MockIAssetServiceClient) IssueNFTAsset(goCtx context.Context, name, machineAddress, domain string) (string, string, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "IssueNFTAsset", goCtx, name, machineAddress, domain) - ret0, _ := ret[0].(string) - ret1, _ := ret[1].(string) - ret2, _ := ret[2].(error) - return ret0, ret1, ret2 -} - -// IssueNFTAsset indicates an expected call of IssueNFTAsset. -func (mr *MockIAssetServiceClientMockRecorder) IssueNFTAsset(goCtx, name, machineAddress, domain interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IssueNFTAsset", reflect.TypeOf((*MockIAssetServiceClient)(nil).IssueNFTAsset), goCtx, name, machineAddress, domain) -} - -// RegisterAsset mocks base method. -func (m *MockIAssetServiceClient) RegisterAsset(goCtx context.Context, assetID, contract, assetRegistryEndpoint string) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "RegisterAsset", goCtx, assetID, contract, assetRegistryEndpoint) - ret0, _ := ret[0].(error) - return ret0 -} - -// RegisterAsset indicates an expected call of RegisterAsset. -func (mr *MockIAssetServiceClientMockRecorder) RegisterAsset(goCtx, assetID, contract, assetRegistryEndpoint interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterAsset", reflect.TypeOf((*MockIAssetServiceClient)(nil).RegisterAsset), goCtx, assetID, contract, assetRegistryEndpoint) -}