From e11684a9507162e50f3e39f60645f0a55ffa952f Mon Sep 17 00:00:00 2001 From: Dmitrii Golubev Date: Fri, 21 Jul 2023 10:45:53 +0200 Subject: [PATCH] feat: add wait for masternode-status "ready" (#659) * feat: add wait for masternode-status ready * feat: use "READY" to the state field in masternode-status mocked response for e2e test * refactor: some modifications according to PR feedback * Update dash/core/client.go --- dash/core/client.go | 28 +++ dash/core/client_test.go | 94 +++++++++ dash/core/mocks/client.go | 212 +++++++++++++++++++++ go.mod | 10 +- go.sum | 19 ++ node/setup.go | 7 + test/e2e/pkg/mockcoreserver/core_server.go | 1 + 7 files changed, 370 insertions(+), 1 deletion(-) create mode 100644 dash/core/client_test.go create mode 100644 dash/core/mocks/client.go diff --git a/dash/core/client.go b/dash/core/client.go index b3cd0f051a..b4d6941585 100644 --- a/dash/core/client.go +++ b/dash/core/client.go @@ -1,7 +1,10 @@ +//go:generate ../../scripts/mockery_generate.sh Client + package core import ( "fmt" + "time" "github.com/dashpay/dashd-go/btcjson" rpc "github.com/dashpay/dashd-go/rpcclient" @@ -13,6 +16,8 @@ import ( const ModuleName = "rpcclient" +var sleep = time.Sleep + // QuorumVerifier represents subset of priv validator features that // allows verification of threshold signatures. type QuorumVerifier interface { @@ -220,3 +225,26 @@ func (rpcClient *RPCClient) QuorumVerify( return resp, err } + +// WaitForMNReady waits until the masternode is ready +func WaitForMNReady(client Client, retryTimeout time.Duration) error { + for { + result, err := client.MasternodeStatus() + if err != nil { + return fmt.Errorf("failed to get masternode status: %w", err) + } + switch result.State { + case btcjson.MNStatusStateReady: + return nil + case btcjson.MNStatusStateWaitingForProtx: + sleep(retryTimeout) + case btcjson.MNStatusStatePoseBanned, + btcjson.MNStatusStateRemoved, + btcjson.MNStatusStateOperatorKeyChanged, + btcjson.MNStatusStateProtxIpChanged, + btcjson.MNStatusStateError, + btcjson.MNStatusStateUnknown: + return fmt.Errorf("unexpected masternode state %s", result.State) + } + } +} diff --git a/dash/core/client_test.go b/dash/core/client_test.go new file mode 100644 index 0000000000..f7d0e7e729 --- /dev/null +++ b/dash/core/client_test.go @@ -0,0 +1,94 @@ +package core + +import ( + "errors" + "fmt" + "testing" + "time" + + "github.com/dashpay/dashd-go/btcjson" + "github.com/stretchr/testify/require" + + "github.com/tendermint/tendermint/dash/core/mocks" +) + +func TestWaitForMNReady(t *testing.T) { + retryTimeout := 1 * time.Millisecond + sleep = func(d time.Duration) { + require.Equal(t, d, retryTimeout) + } + defer func() { sleep = time.Sleep }() + testCases := []struct { + states []btcjson.MNStatusState + wantErr string + }{ + { + states: []btcjson.MNStatusState{btcjson.MNStatusStateReady}, + }, + { + states: []btcjson.MNStatusState{ + btcjson.MNStatusStateWaitingForProtx, + btcjson.MNStatusStateReady, + }, + }, + { + states: []btcjson.MNStatusState{ + btcjson.MNStatusStateWaitingForProtx, + btcjson.MNStatusStateWaitingForProtx, + btcjson.MNStatusStateWaitingForProtx, + btcjson.MNStatusStateReady, + }, + }, + { + states: []btcjson.MNStatusState{btcjson.MNStatusStatePoseBanned}, + wantErr: string(btcjson.MNStatusStatePoseBanned), + }, + { + states: []btcjson.MNStatusState{btcjson.MNStatusStateRemoved}, + wantErr: string(btcjson.MNStatusStateRemoved), + }, + { + states: []btcjson.MNStatusState{btcjson.MNStatusStateOperatorKeyChanged}, + wantErr: string(btcjson.MNStatusStateOperatorKeyChanged), + }, + { + states: []btcjson.MNStatusState{btcjson.MNStatusStateProtxIpChanged}, + wantErr: string(btcjson.MNStatusStateProtxIpChanged), + }, + { + states: []btcjson.MNStatusState{btcjson.MNStatusStateError}, + wantErr: string(btcjson.MNStatusStateError), + }, + { + states: []btcjson.MNStatusState{btcjson.MNStatusStateUnknown}, + wantErr: string(btcjson.MNStatusStateUnknown), + }, + } + for i, tc := range testCases { + t.Run(fmt.Sprintf("%d", i), func(t *testing.T) { + client := mocks.NewClient(t) + for _, state := range tc.states { + client. + On("MasternodeStatus"). + Once(). + Return(&btcjson.MasternodeStatusResult{State: state}, nil) + } + err := WaitForMNReady(client, 1*time.Millisecond) + if tc.wantErr != "" { + require.ErrorContains(t, err, tc.wantErr) + } else { + require.NoError(t, err) + } + }) + } +} + +func TestWaitForMNReadyError(t *testing.T) { + err := errors.New("some error") + client := mocks.NewClient(t) + client. + On("MasternodeStatus"). + Once(). + Return(nil, err) + require.ErrorContains(t, WaitForMNReady(client, 1), err.Error()) +} diff --git a/dash/core/mocks/client.go b/dash/core/mocks/client.go new file mode 100644 index 0000000000..8e6345597c --- /dev/null +++ b/dash/core/mocks/client.go @@ -0,0 +1,212 @@ +// Code generated by mockery. DO NOT EDIT. + +package mocks + +import ( + btcjson "github.com/dashpay/dashd-go/btcjson" + bytes "github.com/tendermint/tendermint/libs/bytes" + + mock "github.com/stretchr/testify/mock" +) + +// Client is an autogenerated mock type for the Client type +type Client struct { + mock.Mock +} + +// Close provides a mock function with given fields: +func (_m *Client) Close() error { + ret := _m.Called() + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// GetNetworkInfo provides a mock function with given fields: +func (_m *Client) GetNetworkInfo() (*btcjson.GetNetworkInfoResult, error) { + ret := _m.Called() + + var r0 *btcjson.GetNetworkInfoResult + var r1 error + if rf, ok := ret.Get(0).(func() (*btcjson.GetNetworkInfoResult, error)); ok { + return rf() + } + if rf, ok := ret.Get(0).(func() *btcjson.GetNetworkInfoResult); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*btcjson.GetNetworkInfoResult) + } + } + + if rf, ok := ret.Get(1).(func() error); ok { + r1 = rf() + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MasternodeListJSON provides a mock function with given fields: filter +func (_m *Client) MasternodeListJSON(filter string) (map[string]btcjson.MasternodelistResultJSON, error) { + ret := _m.Called(filter) + + var r0 map[string]btcjson.MasternodelistResultJSON + var r1 error + if rf, ok := ret.Get(0).(func(string) (map[string]btcjson.MasternodelistResultJSON, error)); ok { + return rf(filter) + } + if rf, ok := ret.Get(0).(func(string) map[string]btcjson.MasternodelistResultJSON); ok { + r0 = rf(filter) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(map[string]btcjson.MasternodelistResultJSON) + } + } + + if rf, ok := ret.Get(1).(func(string) error); ok { + r1 = rf(filter) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MasternodeStatus provides a mock function with given fields: +func (_m *Client) MasternodeStatus() (*btcjson.MasternodeStatusResult, error) { + ret := _m.Called() + + var r0 *btcjson.MasternodeStatusResult + var r1 error + if rf, ok := ret.Get(0).(func() (*btcjson.MasternodeStatusResult, error)); ok { + return rf() + } + if rf, ok := ret.Get(0).(func() *btcjson.MasternodeStatusResult); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*btcjson.MasternodeStatusResult) + } + } + + if rf, ok := ret.Get(1).(func() error); ok { + r1 = rf() + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Ping provides a mock function with given fields: +func (_m *Client) Ping() error { + ret := _m.Called() + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// QuorumInfo provides a mock function with given fields: quorumType, quorumHash +func (_m *Client) QuorumInfo(quorumType btcjson.LLMQType, quorumHash bytes.HexBytes) (*btcjson.QuorumInfoResult, error) { + ret := _m.Called(quorumType, quorumHash) + + var r0 *btcjson.QuorumInfoResult + var r1 error + if rf, ok := ret.Get(0).(func(btcjson.LLMQType, bytes.HexBytes) (*btcjson.QuorumInfoResult, error)); ok { + return rf(quorumType, quorumHash) + } + if rf, ok := ret.Get(0).(func(btcjson.LLMQType, bytes.HexBytes) *btcjson.QuorumInfoResult); ok { + r0 = rf(quorumType, quorumHash) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*btcjson.QuorumInfoResult) + } + } + + if rf, ok := ret.Get(1).(func(btcjson.LLMQType, bytes.HexBytes) error); ok { + r1 = rf(quorumType, quorumHash) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// QuorumSign provides a mock function with given fields: quorumType, requestID, messageHash, quorumHash +func (_m *Client) QuorumSign(quorumType btcjson.LLMQType, requestID bytes.HexBytes, messageHash bytes.HexBytes, quorumHash bytes.HexBytes) (*btcjson.QuorumSignResult, error) { + ret := _m.Called(quorumType, requestID, messageHash, quorumHash) + + var r0 *btcjson.QuorumSignResult + var r1 error + if rf, ok := ret.Get(0).(func(btcjson.LLMQType, bytes.HexBytes, bytes.HexBytes, bytes.HexBytes) (*btcjson.QuorumSignResult, error)); ok { + return rf(quorumType, requestID, messageHash, quorumHash) + } + if rf, ok := ret.Get(0).(func(btcjson.LLMQType, bytes.HexBytes, bytes.HexBytes, bytes.HexBytes) *btcjson.QuorumSignResult); ok { + r0 = rf(quorumType, requestID, messageHash, quorumHash) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*btcjson.QuorumSignResult) + } + } + + if rf, ok := ret.Get(1).(func(btcjson.LLMQType, bytes.HexBytes, bytes.HexBytes, bytes.HexBytes) error); ok { + r1 = rf(quorumType, requestID, messageHash, quorumHash) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// QuorumVerify provides a mock function with given fields: quorumType, requestID, messageHash, signature, quorumHash +func (_m *Client) QuorumVerify(quorumType btcjson.LLMQType, requestID bytes.HexBytes, messageHash bytes.HexBytes, signature bytes.HexBytes, quorumHash bytes.HexBytes) (bool, error) { + ret := _m.Called(quorumType, requestID, messageHash, signature, quorumHash) + + var r0 bool + var r1 error + if rf, ok := ret.Get(0).(func(btcjson.LLMQType, bytes.HexBytes, bytes.HexBytes, bytes.HexBytes, bytes.HexBytes) (bool, error)); ok { + return rf(quorumType, requestID, messageHash, signature, quorumHash) + } + if rf, ok := ret.Get(0).(func(btcjson.LLMQType, bytes.HexBytes, bytes.HexBytes, bytes.HexBytes, bytes.HexBytes) bool); ok { + r0 = rf(quorumType, requestID, messageHash, signature, quorumHash) + } else { + r0 = ret.Get(0).(bool) + } + + if rf, ok := ret.Get(1).(func(btcjson.LLMQType, bytes.HexBytes, bytes.HexBytes, bytes.HexBytes, bytes.HexBytes) error); ok { + r1 = rf(quorumType, requestID, messageHash, signature, quorumHash) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +type mockConstructorTestingTNewClient interface { + mock.TestingT + Cleanup(func()) +} + +// NewClient creates a new instance of Client. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewClient(t mockConstructorTestingTNewClient) *Client { + mock := &Client{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/go.mod b/go.mod index 0fcaebb7f4..2320440541 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce github.com/containerd/continuity v0.3.0 // indirect github.com/dashpay/bls-signatures/go-bindings v0.0.0-20230207105415-06df92693ac8 - github.com/dashpay/dashd-go v0.24.0 + github.com/dashpay/dashd-go v0.24.1 github.com/dashpay/dashd-go/btcec/v2 v2.1.0 // indirect github.com/fortytw2/leaktest v1.3.0 github.com/fxamacker/cbor/v2 v2.4.0 @@ -57,17 +57,25 @@ require ( ) require ( + github.com/aead/siphash v1.0.1 // 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/goleveldb v1.0.0 // indirect + github.com/btcsuite/snappy-go v1.0.0 // indirect github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792 // indirect + github.com/btcsuite/winsvc v1.0.0 // indirect github.com/dashpay/dashd-go/btcutil v1.2.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect + github.com/decred/dcrd/lru v1.0.0 // indirect github.com/didip/tollbooth/v6 v6.0.1 // indirect github.com/didip/tollbooth_chi v0.0.0-20200524181329-8b84cd7183d9 // indirect github.com/go-chi/render v1.0.1 // indirect github.com/go-pkgz/expirable-cache v0.0.3 // indirect github.com/go-pkgz/rest v1.5.0 // indirect github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect + github.com/jessevdk/go-flags v1.4.0 // indirect + github.com/jrick/logrotate v1.0.0 // indirect + github.com/kkdai/bstream v1.0.0 // indirect github.com/pelletier/go-toml/v2 v2.0.5 // indirect github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c // indirect diff --git a/go.sum b/go.sum index a8a10a935f..6693db9fe2 100644 --- a/go.sum +++ b/go.sum @@ -78,6 +78,7 @@ github.com/OpenPeeDeeP/depguard v1.1.0/go.mod h1:JtAMzWkmFEzDPyAd+W0NHl1lvpQKTvT github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= github.com/adlio/schema v1.3.3 h1:oBJn8I02PyTB466pZO1UZEn1TV5XLlifBSyMrmHl/1I= github.com/adlio/schema v1.3.3/go.mod h1:1EsRssiv9/Ce2CMzq5DoL7RiMshhuigQxrR4DMV9fHg= +github.com/aead/siphash v1.0.1 h1:FwHfE/T45KPKYuuSAKyyvE+oPWcaQ+CUmFW0bPlM+kg= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -127,9 +128,14 @@ github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce/go.mod h1:0DVlH 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 h1:Tvd0BfvqX9o823q1j2UZ/epQo09eJh6dTcRp79ilIN4= +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 h1:ZxaA6lo2EpxGddsA8JwWOcxlzRybb444sgmeJQMJGQE= +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 h1:J9B4L7e3oqhXOcm+2IuNApwzQec85lE+QaikUcCs+dk= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/bufbuild/buf v1.4.0 h1:GqE3a8CMmcFvWPzuY3Mahf9Kf3S9XgZ/ORpfYFzO+90= github.com/bufbuild/buf v1.4.0/go.mod h1:mwHG7klTHnX+rM/ym8LXGl7vYpVmnwT96xWoRB4H5QI= @@ -195,6 +201,10 @@ github.com/dashpay/bls-signatures/go-bindings v0.0.0-20230207105415-06df92693ac8 github.com/dashpay/bls-signatures/go-bindings v0.0.0-20230207105415-06df92693ac8/go.mod h1:auvGS60NBZ+a21aCCQh366PdsjDvHinsCvl28VrYPu4= github.com/dashpay/dashd-go v0.24.0 h1:doC8GW2/ygu5JPCvYHQLx6TNza0TPcCR5rXUUS9CxY8= github.com/dashpay/dashd-go v0.24.0/go.mod h1:4yuk/laGME2RnQRTdqTbw87PhT+42hE1anLCnpkgls8= +github.com/dashpay/dashd-go v0.24.1-0.20230712150728-6f8baed01ca5 h1:Pnde8NKgvO2Aq2dVQxHeUYHfkVje4HVPCv2x5LKQ1Dk= +github.com/dashpay/dashd-go v0.24.1-0.20230712150728-6f8baed01ca5/go.mod h1:4yuk/laGME2RnQRTdqTbw87PhT+42hE1anLCnpkgls8= +github.com/dashpay/dashd-go v0.24.1 h1:w+F5pDt+fqud4QQM/O9sAJihbQ3oswO8DKOmDS/pcNw= +github.com/dashpay/dashd-go v0.24.1/go.mod h1:4yuk/laGME2RnQRTdqTbw87PhT+42hE1anLCnpkgls8= github.com/dashpay/dashd-go/btcec/v2 v2.1.0 h1:fXwlLf5H+TtgHxjGMU74NesKzk6NisjKMPF04pBcygk= github.com/dashpay/dashd-go/btcec/v2 v2.1.0/go.mod h1:1i8XtxdOmvK6mYEUCneVXTzFbrCUw3wq1u91j8gvsns= github.com/dashpay/dashd-go/btcutil v1.2.0 h1:YMq7L0V0au5bbphIhpsBBc+nfOZqU+gJ4pkgRZB7Eiw= @@ -207,6 +217,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 h1:HbphB4TFFXpv7MNrT52FGrrgVXF1owhMVTHFZIlnvd4= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc= +github.com/decred/dcrd/lru v1.0.0 h1:Kbsb1SFDsIlaupWPwsPp+dkxiBY1frcS07PCPgotKz8= +github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= github.com/denis-tingaikin/go-header v0.4.3 h1:tEaZKAlqql6SKCY++utLmkPLd6K8IBM20Ha7UVm+mtU= github.com/denis-tingaikin/go-header v0.4.3/go.mod h1:0wOCWuN71D5qIgE2nz9KrKmuYBAC2Mra5RassOIQ2/c= github.com/denisenkom/go-mssqldb v0.12.0 h1:VtrkII767ttSPNRfFekePK3sctr+joXgO58stqQbtUA= @@ -514,6 +526,8 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt github.com/jdxcode/netrc v0.0.0-20210204082910-926c7f70242a h1:d4+I1YEKVmWZrgkt6jpXBnLgV2ZjO0YxEtLDdfIZfH4= github.com/jdxcode/netrc v0.0.0-20210204082910-926c7f70242a/go.mod h1:Zi/ZFkEqFHTm7qkjyNJjaWH4LQA9LQhGJyF0lTYGpxw= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jgautheron/goconst v1.5.1 h1:HxVbL1MhydKs8R8n/HE5NPvzfaYmQJA3o879lE4+WcM= github.com/jgautheron/goconst v1.5.1/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4= github.com/jhump/gopoet v0.0.0-20190322174617-17282ff210b3/go.mod h1:me9yfT6IJSlOL3FCfrg+L6yzUEZ+5jW6WHt4Sk+UPUI= @@ -540,6 +554,7 @@ github.com/jonboulle/clockwork v0.2.0/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUB github.com/jonboulle/clockwork v0.3.0 h1:9BSCMi8C+0qdApAp4auwX0RkLGUjs956h0EkuQymUhg= github.com/jonboulle/clockwork v0.3.0/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= +github.com/jrick/logrotate v1.0.0 h1:lQ1bL/n9mBNeIXoTUoYRlK4dHuNJVofX9oWqBtPnSzI= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= @@ -562,6 +577,8 @@ github.com/kisielk/errcheck v1.6.1/go.mod h1:nXw/i/MfnvRHqXa7XXmQMUB0oNFGuBrNI8d github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/kkdai/bstream v1.0.0 h1:Se5gHwgp2VT2uHfDrkbbgbgEvV9cimLELwrPJctSjg8= +github.com/kkdai/bstream v1.0.0/go.mod h1:FDnDOHt5Yx4p3FaHcioFT0QjDOtgUpvjeZqAs+NVZZA= github.com/klauspost/compress v1.15.10 h1:Ai8UzuomSCDw90e1qNMtb15msBXsNpH6gzkkENQNcJo= github.com/klauspost/compress v1.15.10/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE= @@ -701,6 +718,7 @@ github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/ginkgo/v2 v2.1.4 h1:GNapqRSid3zijZ9H77KrgVG4/8KqiyRsxcSxe+7ApXY= github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= +github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= @@ -1046,6 +1064,7 @@ golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2 golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.6.0 h1:b9gGHsz9/HhJ3HF5DHQytPpuwocVTChQJK3AvoLRD5I= golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= +golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= diff --git a/node/setup.go b/node/setup.go index aba51f7a8b..f61fb708af 100644 --- a/node/setup.go +++ b/node/setup.go @@ -537,6 +537,13 @@ func createPrivval(ctx context.Context, logger log.Logger, conf *config.Config, return nil, fmt.Errorf("failed to create Dash Core RPC client: %w", err) } + logger.Info("Waiting for Dash Core RPC Client to be ready") + err = dashcore.WaitForMNReady(dashCoreRPCClient, time.Second) + if err != nil { + return nil, fmt.Errorf("failed to wait for masternode status 'ready': %w", err) + } + logger.Info("Dash Core RPC Client is ready") + // If a local port is provided for Dash Core rpc into the service to sign. privValidator, err := createAndStartPrivValidatorDashCoreClient( genDoc.QuorumType, diff --git a/test/e2e/pkg/mockcoreserver/core_server.go b/test/e2e/pkg/mockcoreserver/core_server.go index ef26284e87..e7772c3bbd 100644 --- a/test/e2e/pkg/mockcoreserver/core_server.go +++ b/test/e2e/pkg/mockcoreserver/core_server.go @@ -170,6 +170,7 @@ func (c *MockCoreServer) MasternodeStatus(ctx context.Context, _ btcjson.Mastern } return btcjson.MasternodeStatusResult{ ProTxHash: proTxHash.String(), + State: btcjson.MNStatusStateReady, } }