Add Mpool ref to raft state and rearrange some APIs
This commit is contained in:
parent
570f61438a
commit
f89a682d98
@ -29,7 +29,6 @@ import (
|
|||||||
lminer "github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
lminer "github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
||||||
"github.com/filecoin-project/lotus/chain/actors/builtin/power"
|
"github.com/filecoin-project/lotus/chain/actors/builtin/power"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
consensus2 "github.com/filecoin-project/lotus/lib/consensus/raft"
|
|
||||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||||
"github.com/filecoin-project/lotus/node/repo/imports"
|
"github.com/filecoin-project/lotus/node/repo/imports"
|
||||||
)
|
)
|
||||||
@ -753,7 +752,7 @@ type FullNode interface {
|
|||||||
// the path specified when calling CreateBackup is within the base path
|
// the path specified when calling CreateBackup is within the base path
|
||||||
CreateBackup(ctx context.Context, fpath string) error //perm:admin
|
CreateBackup(ctx context.Context, fpath string) error //perm:admin
|
||||||
|
|
||||||
RaftState(ctx context.Context) (*consensus2.RaftState, error) //perm:read
|
RaftState(ctx context.Context) (*RaftStateData, error) //perm:read
|
||||||
RaftLeader(ctx context.Context) (peer.ID, error) //perm:read
|
RaftLeader(ctx context.Context) (peer.ID, error) //perm:read
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,7 +40,6 @@ import (
|
|||||||
"github.com/filecoin-project/lotus/api/v0api"
|
"github.com/filecoin-project/lotus/api/v0api"
|
||||||
"github.com/filecoin-project/lotus/build"
|
"github.com/filecoin-project/lotus/build"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
consensus "github.com/filecoin-project/lotus/lib/consensus/raft"
|
|
||||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||||
"github.com/filecoin-project/lotus/node/repo/imports"
|
"github.com/filecoin-project/lotus/node/repo/imports"
|
||||||
sealing "github.com/filecoin-project/lotus/storage/pipeline"
|
sealing "github.com/filecoin-project/lotus/storage/pipeline"
|
||||||
@ -341,7 +340,7 @@ func init() {
|
|||||||
addExample(map[string]bitfield.BitField{
|
addExample(map[string]bitfield.BitField{
|
||||||
"": bitfield.NewFromSet([]uint64{5, 6, 7, 10}),
|
"": bitfield.NewFromSet([]uint64{5, 6, 7, 10}),
|
||||||
})
|
})
|
||||||
addExample(&consensus.RaftState{
|
addExample(&api.RaftStateData{
|
||||||
NonceMap: make(map[address.Address]uint64),
|
NonceMap: make(map[address.Address]uint64),
|
||||||
MsgUuids: make(map[uuid.UUID]*types.SignedMessage),
|
MsgUuids: make(map[uuid.UUID]*types.SignedMessage),
|
||||||
})
|
})
|
||||||
@ -357,6 +356,7 @@ func init() {
|
|||||||
Headers: nil,
|
Headers: nil,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetAPIType(name, pkg string) (i interface{}, t reflect.Type, permStruct []reflect.Type) {
|
func GetAPIType(name, pkg string) (i interface{}, t reflect.Type, permStruct []reflect.Type) {
|
||||||
|
@ -37,7 +37,6 @@ import (
|
|||||||
miner0 "github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
miner0 "github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
||||||
types "github.com/filecoin-project/lotus/chain/types"
|
types "github.com/filecoin-project/lotus/chain/types"
|
||||||
alerting "github.com/filecoin-project/lotus/journal/alerting"
|
alerting "github.com/filecoin-project/lotus/journal/alerting"
|
||||||
consensus "github.com/filecoin-project/lotus/lib/consensus/raft"
|
|
||||||
dtypes "github.com/filecoin-project/lotus/node/modules/dtypes"
|
dtypes "github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||||
imports "github.com/filecoin-project/lotus/node/repo/imports"
|
imports "github.com/filecoin-project/lotus/node/repo/imports"
|
||||||
)
|
)
|
||||||
@ -2260,10 +2259,10 @@ func (mr *MockFullNodeMockRecorder) RaftLeader(arg0 interface{}) *gomock.Call {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// RaftState mocks base method.
|
// RaftState mocks base method.
|
||||||
func (m *MockFullNode) RaftState(arg0 context.Context) (*consensus.RaftState, error) {
|
func (m *MockFullNode) RaftState(arg0 context.Context) (*api.RaftStateData, error) {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "RaftState", arg0)
|
ret := m.ctrl.Call(m, "RaftState", arg0)
|
||||||
ret0, _ := ret[0].(*consensus.RaftState)
|
ret0, _ := ret[0].(*api.RaftStateData)
|
||||||
ret1, _ := ret[1].(error)
|
ret1, _ := ret[1].(error)
|
||||||
return ret0, ret1
|
return ret0, ret1
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,6 @@ import (
|
|||||||
lminer "github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
lminer "github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
"github.com/filecoin-project/lotus/journal/alerting"
|
"github.com/filecoin-project/lotus/journal/alerting"
|
||||||
consensus2 "github.com/filecoin-project/lotus/lib/consensus/raft"
|
|
||||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||||
"github.com/filecoin-project/lotus/node/repo/imports"
|
"github.com/filecoin-project/lotus/node/repo/imports"
|
||||||
"github.com/filecoin-project/lotus/storage/pipeline/sealiface"
|
"github.com/filecoin-project/lotus/storage/pipeline/sealiface"
|
||||||
@ -342,7 +341,7 @@ type FullNodeStruct struct {
|
|||||||
|
|
||||||
RaftLeader func(p0 context.Context) (peer.ID, error) `perm:"read"`
|
RaftLeader func(p0 context.Context) (peer.ID, error) `perm:"read"`
|
||||||
|
|
||||||
RaftState func(p0 context.Context) (*consensus2.RaftState, error) `perm:"read"`
|
RaftState func(p0 context.Context) (*RaftStateData, error) `perm:"read"`
|
||||||
|
|
||||||
StateAccountKey func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) `perm:"read"`
|
StateAccountKey func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) `perm:"read"`
|
||||||
|
|
||||||
@ -2465,14 +2464,14 @@ func (s *FullNodeStub) RaftLeader(p0 context.Context) (peer.ID, error) {
|
|||||||
return *new(peer.ID), ErrNotSupported
|
return *new(peer.ID), ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *FullNodeStruct) RaftState(p0 context.Context) (*consensus2.RaftState, error) {
|
func (s *FullNodeStruct) RaftState(p0 context.Context) (*RaftStateData, error) {
|
||||||
if s.Internal.RaftState == nil {
|
if s.Internal.RaftState == nil {
|
||||||
return nil, ErrNotSupported
|
return nil, ErrNotSupported
|
||||||
}
|
}
|
||||||
return s.Internal.RaftState(p0)
|
return s.Internal.RaftState(p0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *FullNodeStub) RaftState(p0 context.Context) (*consensus2.RaftState, error) {
|
func (s *FullNodeStub) RaftState(p0 context.Context) (*RaftStateData, error) {
|
||||||
return nil, ErrNotSupported
|
return nil, ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
|
58
api/types.go
58
api/types.go
@ -337,3 +337,61 @@ type ForkUpgradeParams struct {
|
|||||||
UpgradeChocolateHeight abi.ChainEpoch
|
UpgradeChocolateHeight abi.ChainEpoch
|
||||||
UpgradeOhSnapHeight abi.ChainEpoch
|
UpgradeOhSnapHeight abi.ChainEpoch
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type NonceMapType map[address.Address]uint64
|
||||||
|
type MsgUuidMapType map[uuid.UUID]*types.SignedMessage
|
||||||
|
|
||||||
|
type RaftStateData struct {
|
||||||
|
NonceMap NonceMapType
|
||||||
|
MsgUuids MsgUuidMapType
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *NonceMapType) MarshalJSON() ([]byte, error) {
|
||||||
|
marshalled := make(map[string]uint64)
|
||||||
|
for a, n := range *n {
|
||||||
|
marshalled[a.String()] = n
|
||||||
|
}
|
||||||
|
return json.Marshal(marshalled)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *NonceMapType) UnmarshalJSON(b []byte) error {
|
||||||
|
unmarshalled := make(map[string]uint64)
|
||||||
|
err := json.Unmarshal(b, &unmarshalled)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*n = make(map[address.Address]uint64)
|
||||||
|
for saddr, nonce := range unmarshalled {
|
||||||
|
a, err := address.NewFromString(saddr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
(*n)[a] = nonce
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MsgUuidMapType) MarshalJSON() ([]byte, error) {
|
||||||
|
marshalled := make(map[string]*types.SignedMessage)
|
||||||
|
for u, msg := range *m {
|
||||||
|
marshalled[u.String()] = msg
|
||||||
|
}
|
||||||
|
return json.Marshal(marshalled)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MsgUuidMapType) UnmarshalJSON(b []byte) error {
|
||||||
|
unmarshalled := make(map[string]*types.SignedMessage)
|
||||||
|
err := json.Unmarshal(b, &unmarshalled)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*m = make(map[uuid.UUID]*types.SignedMessage)
|
||||||
|
for suid, msg := range unmarshalled {
|
||||||
|
u, err := uuid.Parse(suid)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
(*m)[u] = msg
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1583,3 +1583,8 @@ func getBaseFeeLowerBound(baseFee, factor types.BigInt) types.BigInt {
|
|||||||
|
|
||||||
return baseFeeLowerBound
|
return baseFeeLowerBound
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type MpoolNonceAPI interface {
|
||||||
|
GetNonce(context.Context, address.Address, types.TipSetKey) (uint64, error)
|
||||||
|
GetActor(context.Context, address.Address, types.TipSetKey) (*types.Actor, error)
|
||||||
|
}
|
||||||
|
@ -10,7 +10,7 @@ import (
|
|||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/messagesigner"
|
//"github.com/filecoin-project/lotus/chain/messagesigner"
|
||||||
"github.com/filecoin-project/lotus/chain/stmgr"
|
"github.com/filecoin-project/lotus/chain/stmgr"
|
||||||
"github.com/filecoin-project/lotus/chain/store"
|
"github.com/filecoin-project/lotus/chain/store"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
@ -39,7 +39,7 @@ type mpoolProvider struct {
|
|||||||
sm *stmgr.StateManager
|
sm *stmgr.StateManager
|
||||||
ps *pubsub.PubSub
|
ps *pubsub.PubSub
|
||||||
|
|
||||||
lite messagesigner.MpoolNonceAPI
|
lite MpoolNonceAPI
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ Provider = (*mpoolProvider)(nil)
|
var _ Provider = (*mpoolProvider)(nil)
|
||||||
@ -48,7 +48,7 @@ func NewProvider(sm *stmgr.StateManager, ps *pubsub.PubSub) Provider {
|
|||||||
return &mpoolProvider{sm: sm, ps: ps}
|
return &mpoolProvider{sm: sm, ps: ps}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewProviderLite(sm *stmgr.StateManager, ps *pubsub.PubSub, noncer messagesigner.MpoolNonceAPI) Provider {
|
func NewProviderLite(sm *stmgr.StateManager, ps *pubsub.PubSub, noncer MpoolNonceAPI) Provider {
|
||||||
return &mpoolProvider{sm: sm, ps: ps, lite: noncer}
|
return &mpoolProvider{sm: sm, ps: ps, lite: noncer}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ import (
|
|||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/api"
|
"github.com/filecoin-project/lotus/api"
|
||||||
|
"github.com/filecoin-project/lotus/chain/messagepool"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||||
)
|
)
|
||||||
@ -24,11 +25,6 @@ const dsKeyMsgUUIDSet = "MsgUuidSet"
|
|||||||
|
|
||||||
var log = logging.Logger("messagesigner")
|
var log = logging.Logger("messagesigner")
|
||||||
|
|
||||||
type MpoolNonceAPI interface {
|
|
||||||
GetNonce(context.Context, address.Address, types.TipSetKey) (uint64, error)
|
|
||||||
GetActor(context.Context, address.Address, types.TipSetKey) (*types.Actor, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type MsgSigner interface {
|
type MsgSigner interface {
|
||||||
SignMessage(ctx context.Context, msg *types.Message, spec *api.MessageSendSpec, cb func(*types.SignedMessage) error) (*types.SignedMessage, error)
|
SignMessage(ctx context.Context, msg *types.Message, spec *api.MessageSendSpec, cb func(*types.SignedMessage) error) (*types.SignedMessage, error)
|
||||||
GetSignedMessage(ctx context.Context, uuid uuid.UUID) (*types.SignedMessage, error)
|
GetSignedMessage(ctx context.Context, uuid uuid.UUID) (*types.SignedMessage, error)
|
||||||
@ -47,13 +43,13 @@ type MsgSigner interface {
|
|||||||
type MessageSigner struct {
|
type MessageSigner struct {
|
||||||
wallet api.Wallet
|
wallet api.Wallet
|
||||||
lk sync.Mutex
|
lk sync.Mutex
|
||||||
mpool MpoolNonceAPI
|
mpool messagepool.MpoolNonceAPI
|
||||||
ds datastore.Batching
|
ds datastore.Batching
|
||||||
}
|
}
|
||||||
|
|
||||||
//var _ full.MsgSigner = &MessageSigner{}
|
//var _ full.MsgSigner = &MessageSigner{}
|
||||||
|
|
||||||
func NewMessageSigner(wallet api.Wallet, mpool MpoolNonceAPI, ds dtypes.MetadataDS) *MessageSigner {
|
func NewMessageSigner(wallet api.Wallet, mpool messagepool.MpoolNonceAPI, ds dtypes.MetadataDS) *MessageSigner {
|
||||||
ds = namespace.Wrap(ds, datastore.NewKey("/message-signer/"))
|
ds = namespace.Wrap(ds, datastore.NewKey("/message-signer/"))
|
||||||
return &MessageSigner{
|
return &MessageSigner{
|
||||||
wallet: wallet,
|
wallet: wallet,
|
||||||
|
@ -10,6 +10,7 @@ import (
|
|||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/api"
|
"github.com/filecoin-project/lotus/api"
|
||||||
|
"github.com/filecoin-project/lotus/chain/messagepool"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
consensus "github.com/filecoin-project/lotus/lib/consensus/raft"
|
consensus "github.com/filecoin-project/lotus/lib/consensus/raft"
|
||||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||||
@ -22,7 +23,7 @@ type MessageSignerConsensus struct {
|
|||||||
|
|
||||||
func NewMessageSignerConsensus(
|
func NewMessageSignerConsensus(
|
||||||
wallet api.Wallet,
|
wallet api.Wallet,
|
||||||
mpool MpoolNonceAPI,
|
mpool messagepool.MpoolNonceAPI,
|
||||||
ds dtypes.MetadataDS,
|
ds dtypes.MetadataDS,
|
||||||
consensus *consensus.Consensus) *MessageSignerConsensus {
|
consensus *consensus.Consensus) *MessageSignerConsensus {
|
||||||
|
|
||||||
|
@ -4,8 +4,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/filecoin-project/lotus/lib/retry"
|
|
||||||
"go.uber.org/atomic"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
@ -17,6 +15,7 @@ import (
|
|||||||
|
|
||||||
"github.com/mitchellh/go-homedir"
|
"github.com/mitchellh/go-homedir"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
|
"go.uber.org/atomic"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-jsonrpc"
|
"github.com/filecoin-project/go-jsonrpc"
|
||||||
@ -25,6 +24,7 @@ import (
|
|||||||
"github.com/filecoin-project/lotus/api/client"
|
"github.com/filecoin-project/lotus/api/client"
|
||||||
"github.com/filecoin-project/lotus/api/v0api"
|
"github.com/filecoin-project/lotus/api/v0api"
|
||||||
"github.com/filecoin-project/lotus/api/v1api"
|
"github.com/filecoin-project/lotus/api/v1api"
|
||||||
|
"github.com/filecoin-project/lotus/lib/retry"
|
||||||
"github.com/filecoin-project/lotus/node/repo"
|
"github.com/filecoin-project/lotus/node/repo"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -0,0 +1,302 @@
|
|||||||
|
[API]
|
||||||
|
# Binding address for the Lotus API
|
||||||
|
#
|
||||||
|
# type: string
|
||||||
|
# env var: LOTUS_API_LISTENADDRESS
|
||||||
|
#ListenAddress = "/ip4/127.0.0.1/tcp/1234/http"
|
||||||
|
|
||||||
|
# type: string
|
||||||
|
# env var: LOTUS_API_REMOTELISTENADDRESS
|
||||||
|
#RemoteListenAddress = ""
|
||||||
|
|
||||||
|
# type: Duration
|
||||||
|
# env var: LOTUS_API_TIMEOUT
|
||||||
|
#Timeout = "30s"
|
||||||
|
|
||||||
|
|
||||||
|
[Backup]
|
||||||
|
# When set to true disables metadata log (.lotus/kvlog). This can save disk
|
||||||
|
# space by reducing metadata redundancy.
|
||||||
|
#
|
||||||
|
# Note that in case of metadata corruption it might be much harder to recover
|
||||||
|
# your node if metadata log is disabled
|
||||||
|
#
|
||||||
|
# type: bool
|
||||||
|
# env var: LOTUS_BACKUP_DISABLEMETADATALOG
|
||||||
|
#DisableMetadataLog = true
|
||||||
|
|
||||||
|
|
||||||
|
[Logging]
|
||||||
|
[Logging.SubsystemLevels]
|
||||||
|
# env var: LOTUS_LOGGING_SUBSYSTEMLEVELS_EXAMPLE-SUBSYSTEM
|
||||||
|
#example-subsystem = "INFO"
|
||||||
|
|
||||||
|
|
||||||
|
[Libp2p]
|
||||||
|
# Binding address for the libp2p host - 0 means random port.
|
||||||
|
# Format: multiaddress; see https://multiformats.io/multiaddr/
|
||||||
|
#
|
||||||
|
# type: []string
|
||||||
|
# env var: LOTUS_LIBP2P_LISTENADDRESSES
|
||||||
|
#ListenAddresses = ["/ip4/0.0.0.0/tcp/0", "/ip6/::/tcp/0"]
|
||||||
|
|
||||||
|
# Addresses to explicitally announce to other peers. If not specified,
|
||||||
|
# all interface addresses are announced
|
||||||
|
# Format: multiaddress
|
||||||
|
#
|
||||||
|
# type: []string
|
||||||
|
# env var: LOTUS_LIBP2P_ANNOUNCEADDRESSES
|
||||||
|
#AnnounceAddresses = []
|
||||||
|
|
||||||
|
# Addresses to not announce
|
||||||
|
# Format: multiaddress
|
||||||
|
#
|
||||||
|
# type: []string
|
||||||
|
# env var: LOTUS_LIBP2P_NOANNOUNCEADDRESSES
|
||||||
|
#NoAnnounceAddresses = []
|
||||||
|
|
||||||
|
# When not disabled (default), lotus asks NAT devices (e.g., routers), to
|
||||||
|
# open up an external port and forward it to the port lotus is running on.
|
||||||
|
# When this works (i.e., when your router supports NAT port forwarding),
|
||||||
|
# it makes the local lotus node accessible from the public internet
|
||||||
|
#
|
||||||
|
# type: bool
|
||||||
|
# env var: LOTUS_LIBP2P_DISABLENATPORTMAP
|
||||||
|
#DisableNatPortMap = false
|
||||||
|
|
||||||
|
# ConnMgrLow is the number of connections that the basic connection manager
|
||||||
|
# will trim down to.
|
||||||
|
#
|
||||||
|
# type: uint
|
||||||
|
# env var: LOTUS_LIBP2P_CONNMGRLOW
|
||||||
|
#ConnMgrLow = 150
|
||||||
|
|
||||||
|
# ConnMgrHigh is the number of connections that, when exceeded, will trigger
|
||||||
|
# a connection GC operation. Note: protected/recently formed connections don't
|
||||||
|
# count towards this limit.
|
||||||
|
#
|
||||||
|
# type: uint
|
||||||
|
# env var: LOTUS_LIBP2P_CONNMGRHIGH
|
||||||
|
#ConnMgrHigh = 180
|
||||||
|
|
||||||
|
# ConnMgrGrace is a time duration that new connections are immune from being
|
||||||
|
# closed by the connection manager.
|
||||||
|
#
|
||||||
|
# type: Duration
|
||||||
|
# env var: LOTUS_LIBP2P_CONNMGRGRACE
|
||||||
|
#ConnMgrGrace = "20s"
|
||||||
|
|
||||||
|
|
||||||
|
[Pubsub]
|
||||||
|
# Run the node in bootstrap-node mode
|
||||||
|
#
|
||||||
|
# type: bool
|
||||||
|
# env var: LOTUS_PUBSUB_BOOTSTRAPPER
|
||||||
|
#Bootstrapper = false
|
||||||
|
|
||||||
|
# type: string
|
||||||
|
# env var: LOTUS_PUBSUB_REMOTETRACER
|
||||||
|
#RemoteTracer = ""
|
||||||
|
|
||||||
|
|
||||||
|
[Client]
|
||||||
|
# type: bool
|
||||||
|
# env var: LOTUS_CLIENT_USEIPFS
|
||||||
|
#UseIpfs = false
|
||||||
|
|
||||||
|
# type: bool
|
||||||
|
# env var: LOTUS_CLIENT_IPFSONLINEMODE
|
||||||
|
#IpfsOnlineMode = false
|
||||||
|
|
||||||
|
# type: string
|
||||||
|
# env var: LOTUS_CLIENT_IPFSMADDR
|
||||||
|
#IpfsMAddr = ""
|
||||||
|
|
||||||
|
# type: bool
|
||||||
|
# env var: LOTUS_CLIENT_IPFSUSEFORRETRIEVAL
|
||||||
|
#IpfsUseForRetrieval = false
|
||||||
|
|
||||||
|
# The maximum number of simultaneous data transfers between the client
|
||||||
|
# and storage providers for storage deals
|
||||||
|
#
|
||||||
|
# type: uint64
|
||||||
|
# env var: LOTUS_CLIENT_SIMULTANEOUSTRANSFERSFORSTORAGE
|
||||||
|
#SimultaneousTransfersForStorage = 20
|
||||||
|
|
||||||
|
# The maximum number of simultaneous data transfers between the client
|
||||||
|
# and storage providers for retrieval deals
|
||||||
|
#
|
||||||
|
# type: uint64
|
||||||
|
# env var: LOTUS_CLIENT_SIMULTANEOUSTRANSFERSFORRETRIEVAL
|
||||||
|
#SimultaneousTransfersForRetrieval = 20
|
||||||
|
|
||||||
|
# Require that retrievals perform no on-chain operations. Paid retrievals
|
||||||
|
# without existing payment channels with available funds will fail instead
|
||||||
|
# of automatically performing on-chain operations.
|
||||||
|
#
|
||||||
|
# type: bool
|
||||||
|
# env var: LOTUS_CLIENT_OFFCHAINRETRIEVAL
|
||||||
|
#OffChainRetrieval = false
|
||||||
|
|
||||||
|
|
||||||
|
[Wallet]
|
||||||
|
# type: string
|
||||||
|
# env var: LOTUS_WALLET_REMOTEBACKEND
|
||||||
|
#RemoteBackend = ""
|
||||||
|
|
||||||
|
# type: bool
|
||||||
|
# env var: LOTUS_WALLET_ENABLELEDGER
|
||||||
|
#EnableLedger = false
|
||||||
|
|
||||||
|
# type: bool
|
||||||
|
# env var: LOTUS_WALLET_DISABLELOCAL
|
||||||
|
#DisableLocal = false
|
||||||
|
|
||||||
|
|
||||||
|
[Fees]
|
||||||
|
# type: types.FIL
|
||||||
|
# env var: LOTUS_FEES_DEFAULTMAXFEE
|
||||||
|
#DefaultMaxFee = "0.07 FIL"
|
||||||
|
|
||||||
|
|
||||||
|
[Chainstore]
|
||||||
|
# type: bool
|
||||||
|
# env var: LOTUS_CHAINSTORE_ENABLESPLITSTORE
|
||||||
|
#EnableSplitstore = false
|
||||||
|
|
||||||
|
[Chainstore.Splitstore]
|
||||||
|
# ColdStoreType specifies the type of the coldstore.
|
||||||
|
# It can be "universal" (default) or "discard" for discarding cold blocks.
|
||||||
|
#
|
||||||
|
# type: string
|
||||||
|
# env var: LOTUS_CHAINSTORE_SPLITSTORE_COLDSTORETYPE
|
||||||
|
#ColdStoreType = "universal"
|
||||||
|
|
||||||
|
# HotStoreType specifies the type of the hotstore.
|
||||||
|
# Only currently supported value is "badger".
|
||||||
|
#
|
||||||
|
# type: string
|
||||||
|
# env var: LOTUS_CHAINSTORE_SPLITSTORE_HOTSTORETYPE
|
||||||
|
#HotStoreType = "badger"
|
||||||
|
|
||||||
|
# MarkSetType specifies the type of the markset.
|
||||||
|
# It can be "map" for in memory marking or "badger" (default) for on-disk marking.
|
||||||
|
#
|
||||||
|
# type: string
|
||||||
|
# env var: LOTUS_CHAINSTORE_SPLITSTORE_MARKSETTYPE
|
||||||
|
#MarkSetType = "badger"
|
||||||
|
|
||||||
|
# HotStoreMessageRetention specifies the retention policy for messages, in finalities beyond
|
||||||
|
# the compaction boundary; default is 0.
|
||||||
|
#
|
||||||
|
# type: uint64
|
||||||
|
# env var: LOTUS_CHAINSTORE_SPLITSTORE_HOTSTOREMESSAGERETENTION
|
||||||
|
#HotStoreMessageRetention = 0
|
||||||
|
|
||||||
|
# HotStoreFullGCFrequency specifies how often to perform a full (moving) GC on the hotstore.
|
||||||
|
# A value of 0 disables, while a value 1 will do full GC in every compaction.
|
||||||
|
# Default is 20 (about once a week).
|
||||||
|
#
|
||||||
|
# type: uint64
|
||||||
|
# env var: LOTUS_CHAINSTORE_SPLITSTORE_HOTSTOREFULLGCFREQUENCY
|
||||||
|
#HotStoreFullGCFrequency = 20
|
||||||
|
|
||||||
|
# EnableColdStoreAutoPrune turns on compaction of the cold store i.e. pruning
|
||||||
|
# where hotstore compaction occurs every finality epochs pruning happens every 3 finalities
|
||||||
|
# Default is false
|
||||||
|
#
|
||||||
|
# type: bool
|
||||||
|
# env var: LOTUS_CHAINSTORE_SPLITSTORE_ENABLECOLDSTOREAUTOPRUNE
|
||||||
|
#EnableColdStoreAutoPrune = false
|
||||||
|
|
||||||
|
# ColdStoreFullGCFrequency specifies how often to performa a full (moving) GC on the coldstore.
|
||||||
|
# Only applies if auto prune is enabled. A value of 0 disables while a value of 1 will do
|
||||||
|
# full GC in every prune.
|
||||||
|
# Default is 7 (about once every a week)
|
||||||
|
#
|
||||||
|
# type: uint64
|
||||||
|
# env var: LOTUS_CHAINSTORE_SPLITSTORE_COLDSTOREFULLGCFREQUENCY
|
||||||
|
#ColdStoreFullGCFrequency = 7
|
||||||
|
|
||||||
|
# ColdStoreRetention specifies the retention policy for data reachable from the chain, in
|
||||||
|
# finalities beyond the compaction boundary, default is 0, -1 retains everything
|
||||||
|
#
|
||||||
|
# type: int64
|
||||||
|
# env var: LOTUS_CHAINSTORE_SPLITSTORE_COLDSTORERETENTION
|
||||||
|
#ColdStoreRetention = 0
|
||||||
|
|
||||||
|
|
||||||
|
[Raft]
|
||||||
|
# config to enabled node cluster with raft consensus
|
||||||
|
#
|
||||||
|
# type: bool
|
||||||
|
# env var: LOTUS_RAFT_CLUSTERMODEENABLED
|
||||||
|
#ClusterModeEnabled = false
|
||||||
|
|
||||||
|
# will shutdown libp2p host on shutdown. Useful for testing
|
||||||
|
#
|
||||||
|
# type: bool
|
||||||
|
# env var: LOTUS_RAFT_HOSTSHUTDOWN
|
||||||
|
#HostShutdown = false
|
||||||
|
|
||||||
|
# A folder to store Raft's data.
|
||||||
|
#
|
||||||
|
# type: string
|
||||||
|
# env var: LOTUS_RAFT_DATAFOLDER
|
||||||
|
#DataFolder = ""
|
||||||
|
|
||||||
|
# InitPeerset provides the list of initial cluster peers for new Raft
|
||||||
|
# peers (with no prior state). It is ignored when Raft was already
|
||||||
|
# initialized or when starting in staging mode.
|
||||||
|
#
|
||||||
|
# type: []peer.ID
|
||||||
|
# env var: LOTUS_RAFT_INITPEERSET
|
||||||
|
#InitPeerset = []
|
||||||
|
|
||||||
|
# LeaderTimeout specifies how long to wait for a leader before
|
||||||
|
# failing an operation.
|
||||||
|
#
|
||||||
|
# type: Duration
|
||||||
|
# env var: LOTUS_RAFT_WAITFORLEADERTIMEOUT
|
||||||
|
#WaitForLeaderTimeout = "15s"
|
||||||
|
|
||||||
|
# NetworkTimeout specifies how long before a Raft network
|
||||||
|
# operation is timed out
|
||||||
|
#
|
||||||
|
# type: Duration
|
||||||
|
# env var: LOTUS_RAFT_NETWORKTIMEOUT
|
||||||
|
#NetworkTimeout = "1m40s"
|
||||||
|
|
||||||
|
# CommitRetries specifies how many times we retry a failed commit until
|
||||||
|
# we give up.
|
||||||
|
#
|
||||||
|
# type: int
|
||||||
|
# env var: LOTUS_RAFT_COMMITRETRIES
|
||||||
|
#CommitRetries = 1
|
||||||
|
|
||||||
|
# How long to wait between retries
|
||||||
|
#
|
||||||
|
# type: Duration
|
||||||
|
# env var: LOTUS_RAFT_COMMITRETRYDELAY
|
||||||
|
#CommitRetryDelay = "200ms"
|
||||||
|
|
||||||
|
# BackupsRotate specifies the maximum number of Raft's DataFolder
|
||||||
|
# copies that we keep as backups (renaming) after cleanup.
|
||||||
|
#
|
||||||
|
# type: int
|
||||||
|
# env var: LOTUS_RAFT_BACKUPSROTATE
|
||||||
|
#BackupsRotate = 6
|
||||||
|
|
||||||
|
# Namespace to use when writing keys to the datastore
|
||||||
|
#
|
||||||
|
# type: string
|
||||||
|
# env var: LOTUS_RAFT_DATASTORENAMESPACE
|
||||||
|
#DatastoreNamespace = "/raft"
|
||||||
|
|
||||||
|
# Tracing enables propagation of contexts across binary boundaries.
|
||||||
|
#
|
||||||
|
# type: bool
|
||||||
|
# env var: LOTUS_RAFT_TRACING
|
||||||
|
#Tracing = false
|
||||||
|
|
||||||
|
|
@ -42,7 +42,7 @@ func generatePrivKey() (*kit.Libp2p, error) {
|
|||||||
return &kit.Libp2p{PeerID: peerId, PrivKey: privkey}, nil
|
return &kit.Libp2p{PeerID: peerId, PrivKey: privkey}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getRaftState(ctx context.Context, t *testing.T, node *kit.TestFullNode) *consensus.RaftState {
|
func getRaftState(ctx context.Context, t *testing.T, node *kit.TestFullNode) *api.RaftStateData {
|
||||||
raftState, err := node.RaftState(ctx)
|
raftState, err := node.RaftState(ctx)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
//rstate := raftState.(*consensus.RaftState)
|
//rstate := raftState.(*consensus.RaftState)
|
||||||
@ -51,7 +51,7 @@ func getRaftState(ctx context.Context, t *testing.T, node *kit.TestFullNode) *co
|
|||||||
|
|
||||||
func setup(ctx context.Context, t *testing.T, node0 *kit.TestFullNode, node1 *kit.TestFullNode, node2 *kit.TestFullNode, miner *kit.TestMiner) *kit.Ensemble {
|
func setup(ctx context.Context, t *testing.T, node0 *kit.TestFullNode, node1 *kit.TestFullNode, node2 *kit.TestFullNode, miner *kit.TestMiner) *kit.Ensemble {
|
||||||
|
|
||||||
//blockTime := 1000 * time.Millisecond
|
blockTime := 1 * time.Second
|
||||||
|
|
||||||
pkey0, _ := generatePrivKey()
|
pkey0, _ := generatePrivKey()
|
||||||
pkey1, _ := generatePrivKey()
|
pkey1, _ := generatePrivKey()
|
||||||
@ -61,8 +61,8 @@ func setup(ctx context.Context, t *testing.T, node0 *kit.TestFullNode, node1 *ki
|
|||||||
|
|
||||||
raftOps := kit.ConstructorOpts(
|
raftOps := kit.ConstructorOpts(
|
||||||
node.Override(new(*gorpc.Client), modules.NewRPCClient),
|
node.Override(new(*gorpc.Client), modules.NewRPCClient),
|
||||||
node.Override(new(*config.ClusterRaftConfig), func() *config.ClusterRaftConfig {
|
node.Override(new(*consensus.ClusterRaftConfig), func() *consensus.ClusterRaftConfig {
|
||||||
cfg := config.DefaultClusterRaftConfig()
|
cfg := consensus.DefaultClusterRaftConfig()
|
||||||
cfg.InitPeerset = initPeerSet
|
cfg.InitPeerset = initPeerSet
|
||||||
return cfg
|
return cfg
|
||||||
}),
|
}),
|
||||||
@ -304,35 +304,11 @@ func TestRaftStateLeaderDisconnectsMiner(t *testing.T) {
|
|||||||
peerToNode[n.Pkey.PeerID] = n
|
peerToNode[n.Pkey.PeerID] = n
|
||||||
}
|
}
|
||||||
|
|
||||||
//bal, err := node0.WalletBalance(ctx, node0.DefaultKey.Address)
|
leader, err := node0.RaftLeader(ctx)
|
||||||
//require.NoError(t, err)
|
|
||||||
|
|
||||||
//msgHalfBal := &types.Message{
|
|
||||||
// From: miner.OwnerKey.Address,
|
|
||||||
// To: node0.DefaultKey.Address,
|
|
||||||
// Value: big.Div(bal, big.NewInt(2)),
|
|
||||||
//}
|
|
||||||
//mu := uuid.New()
|
|
||||||
//smHalfBal, err := miner.FullNode.MpoolPushMessage(ctx, msgHalfBal, &api.MessageSendSpec{
|
|
||||||
// MsgUuid: mu,
|
|
||||||
//})
|
|
||||||
//require.NoError(t, err)
|
|
||||||
//mLookup, err := node0.StateWaitMsg(ctx, smHalfBal.Cid(), 3, api.LookbackNoLimit, true)
|
|
||||||
//require.NoError(t, err)
|
|
||||||
//require.Equal(t, exitcode.Ok, mLookup.Receipt.ExitCode)
|
|
||||||
//
|
|
||||||
//rstate0 := getRaftState(ctx, t, &node0)
|
|
||||||
//rstate1 := getRaftState(ctx, t, &node1)
|
|
||||||
//rstate2 := getRaftState(ctx, t, &node2)
|
|
||||||
//
|
|
||||||
//require.True(t, reflect.DeepEqual(rstate0, rstate1))
|
|
||||||
//require.True(t, reflect.DeepEqual(rstate0, rstate2))
|
|
||||||
|
|
||||||
// Take leader node down
|
|
||||||
leader, err := node1.RaftLeader(ctx)
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
leaderNode := peerToNode[leader]
|
leaderNode := peerToNode[leader]
|
||||||
|
|
||||||
|
// Take leader node down
|
||||||
err = leaderNode.Stop(ctx)
|
err = leaderNode.Stop(ctx)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
oldLeaderNode := leaderNode
|
oldLeaderNode := leaderNode
|
||||||
@ -351,11 +327,6 @@ func TestRaftStateLeaderDisconnectsMiner(t *testing.T) {
|
|||||||
require.NotEqual(t, newLeader, leader)
|
require.NotEqual(t, newLeader, leader)
|
||||||
leaderNode = peerToNode[newLeader]
|
leaderNode = peerToNode[newLeader]
|
||||||
|
|
||||||
fmt.Println("New leader: ", newLeader)
|
|
||||||
|
|
||||||
//err = node0.Stop(ctx)
|
|
||||||
//require.NoError(t, err)
|
|
||||||
|
|
||||||
msg2 := &types.Message{
|
msg2 := &types.Message{
|
||||||
From: miner.OwnerKey.Address,
|
From: miner.OwnerKey.Address,
|
||||||
To: node0.DefaultKey.Address,
|
To: node0.DefaultKey.Address,
|
||||||
@ -373,8 +344,6 @@ func TestRaftStateLeaderDisconnectsMiner(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, exitcode.Ok, mLookup.Receipt.ExitCode)
|
require.Equal(t, exitcode.Ok, mLookup.Receipt.ExitCode)
|
||||||
|
|
||||||
fmt.Println("!!!!!!!!!!!!!!!!TEST FINISHED!!!!!!!!!!!!!!!!!!!")
|
|
||||||
|
|
||||||
rstate := getRaftState(ctx, t, leaderNode)
|
rstate := getRaftState(ctx, t, leaderNode)
|
||||||
|
|
||||||
for _, n := range nodes {
|
for _, n := range nodes {
|
||||||
@ -420,24 +389,16 @@ func TestLeaderDisconnectsCheckMsgStateOnNewLeader(t *testing.T) {
|
|||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
//
|
leader, err := node0.RaftLeader(ctx)
|
||||||
//rstate0 := getRaftState(ctx, t, &node0)
|
|
||||||
//rstate1 := getRaftState(ctx, t, &node1)
|
|
||||||
//rstate2 := getRaftState(ctx, t, &node2)
|
|
||||||
//
|
|
||||||
//require.True(t, reflect.DeepEqual(rstate0, rstate1))
|
|
||||||
//require.True(t, reflect.DeepEqual(rstate0, rstate2))
|
|
||||||
|
|
||||||
// Take leader node down
|
|
||||||
leader, err := node1.RaftLeader(ctx)
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
leaderNode := peerToNode[leader]
|
leaderNode := peerToNode[leader]
|
||||||
|
|
||||||
|
// Take leader node down
|
||||||
err = leaderNode.Stop(ctx)
|
err = leaderNode.Stop(ctx)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
oldLeaderNode := leaderNode
|
oldLeaderNode := leaderNode
|
||||||
|
|
||||||
//time.Sleep(5 * time.Second)
|
time.Sleep(5 * time.Second)
|
||||||
|
|
||||||
newLeader := leader
|
newLeader := leader
|
||||||
for _, n := range nodes {
|
for _, n := range nodes {
|
||||||
@ -451,17 +412,10 @@ func TestLeaderDisconnectsCheckMsgStateOnNewLeader(t *testing.T) {
|
|||||||
require.NotEqual(t, newLeader, leader)
|
require.NotEqual(t, newLeader, leader)
|
||||||
leaderNode = peerToNode[newLeader]
|
leaderNode = peerToNode[newLeader]
|
||||||
|
|
||||||
fmt.Println("New leader: ", newLeader)
|
|
||||||
|
|
||||||
mLookup, err := leaderNode.StateWaitMsg(ctx, smHalfBal.Cid(), 3, api.LookbackNoLimit, true)
|
mLookup, err := leaderNode.StateWaitMsg(ctx, smHalfBal.Cid(), 3, api.LookbackNoLimit, true)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, exitcode.Ok, mLookup.Receipt.ExitCode)
|
require.Equal(t, exitcode.Ok, mLookup.Receipt.ExitCode)
|
||||||
|
|
||||||
//err = node0.Stop(ctx)
|
|
||||||
//require.NoError(t, err)
|
|
||||||
|
|
||||||
fmt.Println("!!!!!!!!!!!!!!!!TEST FINISHED!!!!!!!!!!!!!!!!!!!")
|
|
||||||
|
|
||||||
rstate := getRaftState(ctx, t, leaderNode)
|
rstate := getRaftState(ctx, t, leaderNode)
|
||||||
|
|
||||||
for _, n := range nodes {
|
for _, n := range nodes {
|
||||||
@ -471,3 +425,53 @@ func TestLeaderDisconnectsCheckMsgStateOnNewLeader(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestChainStoreSync(t *testing.T) {
|
||||||
|
|
||||||
|
kit.QuietMiningLogs()
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
var (
|
||||||
|
node0 kit.TestFullNode
|
||||||
|
node1 kit.TestFullNode
|
||||||
|
node2 kit.TestFullNode
|
||||||
|
miner kit.TestMiner
|
||||||
|
)
|
||||||
|
|
||||||
|
nodes := []*kit.TestFullNode{&node0, &node1, &node2}
|
||||||
|
|
||||||
|
setup(ctx, t, &node0, &node1, &node2, &miner)
|
||||||
|
|
||||||
|
peerToNode := make(map[peer.ID]*kit.TestFullNode)
|
||||||
|
for _, n := range nodes {
|
||||||
|
peerToNode[n.Pkey.PeerID] = n
|
||||||
|
}
|
||||||
|
|
||||||
|
bal, err := node0.WalletBalance(ctx, node0.DefaultKey.Address)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
leader, err := node0.RaftLeader(ctx)
|
||||||
|
require.NoError(t, err)
|
||||||
|
leaderNode := peerToNode[leader]
|
||||||
|
|
||||||
|
msgHalfBal := &types.Message{
|
||||||
|
From: miner.OwnerKey.Address,
|
||||||
|
To: node0.DefaultKey.Address,
|
||||||
|
Value: big.Div(bal, big.NewInt(2)),
|
||||||
|
}
|
||||||
|
mu := uuid.New()
|
||||||
|
smHalfBal, err := miner.FullNode.MpoolPushMessage(ctx, msgHalfBal, &api.MessageSendSpec{
|
||||||
|
MsgUuid: mu,
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
for _, n := range nodes {
|
||||||
|
fmt.Println(n != leaderNode)
|
||||||
|
if n != leaderNode {
|
||||||
|
mLookup, err := n.StateWaitMsg(ctx, smHalfBal.Cid(), 3, api.LookbackNoLimit, true)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, exitcode.Ok, mLookup.Receipt.ExitCode)
|
||||||
|
//break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
package consensus
|
package consensus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"io/ioutil"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
hraft "github.com/hashicorp/raft"
|
hraft "github.com/hashicorp/raft"
|
||||||
|
"github.com/libp2p/go-libp2p/core/peer"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/node/config"
|
"github.com/filecoin-project/lotus/node/config"
|
||||||
@ -25,45 +27,88 @@ var (
|
|||||||
DefaultDatastoreNamespace = "/r" // from "/raft"
|
DefaultDatastoreNamespace = "/r" // from "/raft"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Config allows to configure the Raft Consensus component for ipfs-cluster.
|
// ClusterRaftConfig allows to configure the Raft Consensus component for the node cluster.
|
||||||
// The component's configuration section is represented by ConfigJSON.
|
type ClusterRaftConfig struct {
|
||||||
// Config implements the ComponentConfig interface.
|
// config to enabled node cluster with raft consensus
|
||||||
//type Config struct {
|
ClusterModeEnabled bool
|
||||||
// //config.Saver
|
// will shutdown libp2p host on shutdown. Useful for testing
|
||||||
// //
|
HostShutdown bool
|
||||||
// //// will shutdown libp2p host on shutdown. Useful for testing
|
// A folder to store Raft's data.
|
||||||
// hostShutdown bool
|
DataFolder string
|
||||||
//
|
// InitPeerset provides the list of initial cluster peers for new Raft
|
||||||
// // A folder to store Raft's data.
|
// peers (with no prior state). It is ignored when Raft was already
|
||||||
// DataFolder string
|
// initialized or when starting in staging mode.
|
||||||
//
|
InitPeerset []peer.ID
|
||||||
// // InitPeerset provides the list of initial cluster peers for new Raft
|
// LeaderTimeout specifies how long to wait for a leader before
|
||||||
// // peers (with no prior state). It is ignored when Raft was already
|
// failing an operation.
|
||||||
// // initialized or when starting in staging mode.
|
WaitForLeaderTimeout time.Duration
|
||||||
// InitPeerset []peer.ID
|
// NetworkTimeout specifies how long before a Raft network
|
||||||
// // LeaderTimeout specifies how long to wait for a leader before
|
// operation is timed out
|
||||||
// // failing an operation.
|
NetworkTimeout time.Duration
|
||||||
// WaitForLeaderTimeout time.Duration
|
// CommitRetries specifies how many times we retry a failed commit until
|
||||||
// // NetworkTimeout specifies how long before a Raft network
|
// we give up.
|
||||||
// // operation is timed out
|
CommitRetries int
|
||||||
// NetworkTimeout time.Duration
|
// How long to wait between retries
|
||||||
// // CommitRetries specifies how many times we retry a failed commit until
|
CommitRetryDelay time.Duration
|
||||||
// // we give up.
|
// BackupsRotate specifies the maximum number of Raft's DataFolder
|
||||||
// CommitRetries int
|
// copies that we keep as backups (renaming) after cleanup.
|
||||||
// // How long to wait between retries
|
BackupsRotate int
|
||||||
// CommitRetryDelay time.Duration
|
// Namespace to use when writing keys to the datastore
|
||||||
// // BackupsRotate specifies the maximum number of Raft's DataFolder
|
DatastoreNamespace string
|
||||||
// // copies that we keep as backups (renaming) after cleanup.
|
|
||||||
// BackupsRotate int
|
// A Hashicorp Raft's configuration object.
|
||||||
// // Namespace to use when writing keys to the datastore
|
RaftConfig *hraft.Config
|
||||||
// DatastoreNamespace string
|
|
||||||
//
|
// Tracing enables propagation of contexts across binary boundaries.
|
||||||
// // A Hashicorp Raft's configuration object.
|
Tracing bool
|
||||||
// RaftConfig *hraft.Config
|
}
|
||||||
//
|
|
||||||
// // Tracing enables propagation of contexts across binary boundaries.
|
func DefaultClusterRaftConfig() *ClusterRaftConfig {
|
||||||
// Tracing bool
|
var cfg ClusterRaftConfig
|
||||||
//}
|
cfg.DataFolder = "" // empty so it gets omitted
|
||||||
|
cfg.InitPeerset = []peer.ID{}
|
||||||
|
cfg.WaitForLeaderTimeout = DefaultWaitForLeaderTimeout
|
||||||
|
cfg.NetworkTimeout = DefaultNetworkTimeout
|
||||||
|
cfg.CommitRetries = DefaultCommitRetries
|
||||||
|
cfg.CommitRetryDelay = DefaultCommitRetryDelay
|
||||||
|
cfg.BackupsRotate = DefaultBackupsRotate
|
||||||
|
cfg.DatastoreNamespace = DefaultDatastoreNamespace
|
||||||
|
cfg.RaftConfig = hraft.DefaultConfig()
|
||||||
|
|
||||||
|
// These options are imposed over any Default Raft Config.
|
||||||
|
cfg.RaftConfig.ShutdownOnRemove = false
|
||||||
|
cfg.RaftConfig.LocalID = "will_be_set_automatically"
|
||||||
|
|
||||||
|
// Set up logging
|
||||||
|
cfg.RaftConfig.LogOutput = ioutil.Discard
|
||||||
|
//cfg.RaftConfig.Logger = &hcLogToLogger{}
|
||||||
|
return &cfg
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewClusterRaftConfig(userRaftConfig *config.UserRaftConfig) *ClusterRaftConfig {
|
||||||
|
var cfg ClusterRaftConfig
|
||||||
|
cfg.DataFolder = userRaftConfig.DataFolder
|
||||||
|
cfg.InitPeerset = userRaftConfig.InitPeerset
|
||||||
|
cfg.WaitForLeaderTimeout = time.Duration(userRaftConfig.WaitForLeaderTimeout)
|
||||||
|
cfg.NetworkTimeout = time.Duration(userRaftConfig.NetworkTimeout)
|
||||||
|
cfg.CommitRetries = userRaftConfig.CommitRetries
|
||||||
|
cfg.CommitRetryDelay = time.Duration(userRaftConfig.CommitRetryDelay)
|
||||||
|
cfg.BackupsRotate = userRaftConfig.BackupsRotate
|
||||||
|
cfg.DatastoreNamespace = userRaftConfig.DatastoreNamespace
|
||||||
|
|
||||||
|
// Keep this to be default hraft config for now
|
||||||
|
cfg.RaftConfig = hraft.DefaultConfig()
|
||||||
|
|
||||||
|
// These options are imposed over any Default Raft Config.
|
||||||
|
cfg.RaftConfig.ShutdownOnRemove = false
|
||||||
|
cfg.RaftConfig.LocalID = "will_be_set_automatically"
|
||||||
|
|
||||||
|
// Set up logging
|
||||||
|
cfg.RaftConfig.LogOutput = ioutil.Discard
|
||||||
|
//cfg.RaftConfig.Logger = &hcLogToLogger{}
|
||||||
|
return &cfg
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// ConfigJSON represents a human-friendly Config
|
// ConfigJSON represents a human-friendly Config
|
||||||
// object which can be saved to JSON. Most configuration keys are converted
|
// object which can be saved to JSON. Most configuration keys are converted
|
||||||
@ -145,7 +190,7 @@ var (
|
|||||||
|
|
||||||
//// Validate checks that this configuration has working values,
|
//// Validate checks that this configuration has working values,
|
||||||
//// at least in appearance.
|
//// at least in appearance.
|
||||||
func ValidateConfig(cfg *config.ClusterRaftConfig) error {
|
func ValidateConfig(cfg *ClusterRaftConfig) error {
|
||||||
if cfg.RaftConfig == nil {
|
if cfg.RaftConfig == nil {
|
||||||
return xerrors.Errorf("no hashicorp/raft.Config")
|
return xerrors.Errorf("no hashicorp/raft.Config")
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@ package consensus
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"sort"
|
"sort"
|
||||||
@ -15,8 +14,9 @@ import (
|
|||||||
|
|
||||||
addr "github.com/filecoin-project/go-address"
|
addr "github.com/filecoin-project/go-address"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/api"
|
||||||
|
"github.com/filecoin-project/lotus/chain/messagepool"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
"github.com/filecoin-project/lotus/node/config"
|
|
||||||
|
|
||||||
//ds "github.com/ipfs/go-datastore"
|
//ds "github.com/ipfs/go-datastore"
|
||||||
logging "github.com/ipfs/go-log/v2"
|
logging "github.com/ipfs/go-log/v2"
|
||||||
@ -29,67 +29,21 @@ import (
|
|||||||
|
|
||||||
var logger = logging.Logger("raft")
|
var logger = logging.Logger("raft")
|
||||||
|
|
||||||
type NonceMapType map[addr.Address]uint64
|
//type NonceMapType map[addr.Address]uint64
|
||||||
type MsgUuidMapType map[uuid.UUID]*types.SignedMessage
|
//type MsgUuidMapType map[uuid.UUID]*types.SignedMessage
|
||||||
|
|
||||||
type RaftState struct {
|
type RaftState struct {
|
||||||
NonceMap NonceMapType
|
NonceMap api.NonceMapType
|
||||||
MsgUuids MsgUuidMapType
|
MsgUuids api.MsgUuidMapType
|
||||||
|
Mpool *messagepool.MessagePool
|
||||||
}
|
}
|
||||||
|
|
||||||
func newRaftState() *RaftState {
|
func newRaftState(mpool *messagepool.MessagePool) *RaftState {
|
||||||
return &RaftState{NonceMap: make(map[addr.Address]uint64),
|
return &RaftState{
|
||||||
MsgUuids: make(map[uuid.UUID]*types.SignedMessage)}
|
NonceMap: make(map[addr.Address]uint64),
|
||||||
}
|
MsgUuids: make(map[uuid.UUID]*types.SignedMessage),
|
||||||
|
Mpool: mpool,
|
||||||
func (n *NonceMapType) MarshalJSON() ([]byte, error) {
|
|
||||||
marshalled := make(map[string]uint64)
|
|
||||||
for a, n := range *n {
|
|
||||||
marshalled[a.String()] = n
|
|
||||||
}
|
}
|
||||||
return json.Marshal(marshalled)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *NonceMapType) UnmarshalJSON(b []byte) error {
|
|
||||||
unmarshalled := make(map[string]uint64)
|
|
||||||
err := json.Unmarshal(b, &unmarshalled)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
*n = make(map[addr.Address]uint64)
|
|
||||||
for saddr, nonce := range unmarshalled {
|
|
||||||
a, err := addr.NewFromString(saddr)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
(*n)[a] = nonce
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MsgUuidMapType) MarshalJSON() ([]byte, error) {
|
|
||||||
marshalled := make(map[string]*types.SignedMessage)
|
|
||||||
for u, msg := range *m {
|
|
||||||
marshalled[u.String()] = msg
|
|
||||||
}
|
|
||||||
return json.Marshal(marshalled)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MsgUuidMapType) UnmarshalJSON(b []byte) error {
|
|
||||||
unmarshalled := make(map[string]*types.SignedMessage)
|
|
||||||
err := json.Unmarshal(b, &unmarshalled)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
*m = make(map[uuid.UUID]*types.SignedMessage)
|
|
||||||
for suid, msg := range unmarshalled {
|
|
||||||
u, err := uuid.Parse(suid)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
(*m)[u] = msg
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type ConsensusOp struct {
|
type ConsensusOp struct {
|
||||||
@ -103,6 +57,7 @@ func (c ConsensusOp) ApplyTo(state consensus.State) (consensus.State, error) {
|
|||||||
s := state.(*RaftState)
|
s := state.(*RaftState)
|
||||||
s.NonceMap[c.Addr] = c.Nonce
|
s.NonceMap[c.Addr] = c.Nonce
|
||||||
s.MsgUuids[c.Uuid] = c.SignedMsg
|
s.MsgUuids[c.Uuid] = c.SignedMsg
|
||||||
|
s.Mpool.Add(context.TODO(), c.SignedMsg)
|
||||||
return s, nil
|
return s, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,7 +69,7 @@ var _ consensus.Op = &ConsensusOp{}
|
|||||||
type Consensus struct {
|
type Consensus struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
cancel func()
|
cancel func()
|
||||||
config *config.ClusterRaftConfig
|
config *ClusterRaftConfig
|
||||||
|
|
||||||
host host.Host
|
host host.Host
|
||||||
|
|
||||||
@ -141,7 +96,7 @@ type Consensus struct {
|
|||||||
//
|
//
|
||||||
// The staging parameter controls if the Raft peer should start in
|
// The staging parameter controls if the Raft peer should start in
|
||||||
// staging mode (used when joining a new Raft peerset with other peers).
|
// staging mode (used when joining a new Raft peerset with other peers).
|
||||||
func NewConsensus(host host.Host, cfg *config.ClusterRaftConfig, staging bool) (*Consensus, error) {
|
func NewConsensus(host host.Host, cfg *ClusterRaftConfig, mpool *messagepool.MessagePool, staging bool) (*Consensus, error) {
|
||||||
err := ValidateConfig(cfg)
|
err := ValidateConfig(cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -150,7 +105,7 @@ func NewConsensus(host host.Host, cfg *config.ClusterRaftConfig, staging bool) (
|
|||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
|
||||||
logger.Debug("starting Consensus and waiting for a leader...")
|
logger.Debug("starting Consensus and waiting for a leader...")
|
||||||
state := newRaftState()
|
state := newRaftState(mpool)
|
||||||
|
|
||||||
consensus := libp2praft.NewOpLog(state, &ConsensusOp{})
|
consensus := libp2praft.NewOpLog(state, &ConsensusOp{})
|
||||||
|
|
||||||
@ -183,12 +138,13 @@ func NewConsensus(host host.Host, cfg *config.ClusterRaftConfig, staging bool) (
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewConsensusWithRPCClient(staging bool) func(host host.Host,
|
func NewConsensusWithRPCClient(staging bool) func(host host.Host,
|
||||||
cfg *config.ClusterRaftConfig,
|
cfg *ClusterRaftConfig,
|
||||||
rpcClient *rpc.Client,
|
rpcClient *rpc.Client,
|
||||||
|
mpool *messagepool.MessagePool,
|
||||||
) (*Consensus, error) {
|
) (*Consensus, error) {
|
||||||
|
|
||||||
return func(host host.Host, cfg *config.ClusterRaftConfig, rpcClient *rpc.Client) (*Consensus, error) {
|
return func(host host.Host, cfg *ClusterRaftConfig, rpcClient *rpc.Client, mpool *messagepool.MessagePool) (*Consensus, error) {
|
||||||
cc, err := NewConsensus(host, cfg, staging)
|
cc, err := NewConsensus(host, cfg, mpool, staging)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -506,7 +462,7 @@ func (cc *Consensus) State(ctx context.Context) (*RaftState, error) {
|
|||||||
|
|
||||||
st, err := cc.consensus.GetLogHead()
|
st, err := cc.consensus.GetLogHead()
|
||||||
if err == libp2praft.ErrNoState {
|
if err == libp2praft.ErrNoState {
|
||||||
return newRaftState(), nil
|
return newRaftState(nil), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -12,8 +12,6 @@ import (
|
|||||||
p2praft "github.com/libp2p/go-libp2p-raft"
|
p2praft "github.com/libp2p/go-libp2p-raft"
|
||||||
host "github.com/libp2p/go-libp2p/core/host"
|
host "github.com/libp2p/go-libp2p/core/host"
|
||||||
peer "github.com/libp2p/go-libp2p/core/peer"
|
peer "github.com/libp2p/go-libp2p/core/peer"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/node/config"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ErrWaitingForSelf is returned when we are waiting for ourselves to depart
|
// ErrWaitingForSelf is returned when we are waiting for ourselves to depart
|
||||||
@ -44,7 +42,7 @@ type raftWrapper struct {
|
|||||||
ctx context.Context
|
ctx context.Context
|
||||||
cancel context.CancelFunc
|
cancel context.CancelFunc
|
||||||
raft *hraft.Raft
|
raft *hraft.Raft
|
||||||
config *config.ClusterRaftConfig
|
config *ClusterRaftConfig
|
||||||
host host.Host
|
host host.Host
|
||||||
serverConfig hraft.Configuration
|
serverConfig hraft.Configuration
|
||||||
transport *hraft.NetworkTransport
|
transport *hraft.NetworkTransport
|
||||||
@ -60,7 +58,7 @@ type raftWrapper struct {
|
|||||||
// to make sure the raft instance is usable.
|
// to make sure the raft instance is usable.
|
||||||
func newRaftWrapper(
|
func newRaftWrapper(
|
||||||
host host.Host,
|
host host.Host,
|
||||||
cfg *config.ClusterRaftConfig,
|
cfg *ClusterRaftConfig,
|
||||||
fsm hraft.FSM,
|
fsm hraft.FSM,
|
||||||
staging bool,
|
staging bool,
|
||||||
) (*raftWrapper, error) {
|
) (*raftWrapper, error) {
|
||||||
|
@ -143,7 +143,7 @@ var ChainNode = Options(
|
|||||||
// Lite node API
|
// Lite node API
|
||||||
ApplyIf(isLiteNode,
|
ApplyIf(isLiteNode,
|
||||||
Override(new(messagepool.Provider), messagepool.NewProviderLite),
|
Override(new(messagepool.Provider), messagepool.NewProviderLite),
|
||||||
Override(new(messagesigner.MpoolNonceAPI), From(new(modules.MpoolNonceAPI))),
|
Override(new(messagepool.MpoolNonceAPI), From(new(modules.MpoolNonceAPI))),
|
||||||
Override(new(full.ChainModuleAPI), From(new(api.Gateway))),
|
Override(new(full.ChainModuleAPI), From(new(api.Gateway))),
|
||||||
Override(new(full.GasModuleAPI), From(new(api.Gateway))),
|
Override(new(full.GasModuleAPI), From(new(api.Gateway))),
|
||||||
Override(new(full.MpoolModuleAPI), From(new(api.Gateway))),
|
Override(new(full.MpoolModuleAPI), From(new(api.Gateway))),
|
||||||
@ -154,7 +154,7 @@ var ChainNode = Options(
|
|||||||
// Full node API / service startup
|
// Full node API / service startup
|
||||||
ApplyIf(isFullNode,
|
ApplyIf(isFullNode,
|
||||||
Override(new(messagepool.Provider), messagepool.NewProvider),
|
Override(new(messagepool.Provider), messagepool.NewProvider),
|
||||||
Override(new(messagesigner.MpoolNonceAPI), From(new(*messagepool.MessagePool))),
|
Override(new(messagepool.MpoolNonceAPI), From(new(*messagepool.MessagePool))),
|
||||||
Override(new(full.ChainModuleAPI), From(new(full.ChainModule))),
|
Override(new(full.ChainModuleAPI), From(new(full.ChainModule))),
|
||||||
Override(new(full.GasModuleAPI), From(new(full.GasModule))),
|
Override(new(full.GasModuleAPI), From(new(full.GasModule))),
|
||||||
Override(new(full.MpoolModuleAPI), From(new(full.MpoolModule))),
|
Override(new(full.MpoolModuleAPI), From(new(full.MpoolModule))),
|
||||||
|
@ -2,12 +2,10 @@ package config
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding"
|
"encoding"
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
hraft "github.com/hashicorp/raft"
|
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
"github.com/libp2p/go-libp2p/core/peer"
|
"github.com/libp2p/go-libp2p/core/peer"
|
||||||
|
|
||||||
@ -102,7 +100,7 @@ func DefaultFullNode() *FullNode {
|
|||||||
ColdStoreFullGCFrequency: 7,
|
ColdStoreFullGCFrequency: 7,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Raft: *DefaultClusterRaftConfig(),
|
Raft: *DefaultUserRaftConfig(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -290,8 +288,30 @@ var (
|
|||||||
DefaultDatastoreNamespace = "/raft"
|
DefaultDatastoreNamespace = "/raft"
|
||||||
)
|
)
|
||||||
|
|
||||||
func DefaultClusterRaftConfig() *ClusterRaftConfig {
|
//func DefaultClusterRaftConfig() *ClusterRaftConfig {
|
||||||
var cfg ClusterRaftConfig
|
// var cfg ClusterRaftConfig
|
||||||
|
// cfg.DataFolder = "" // empty so it gets omitted
|
||||||
|
// cfg.InitPeerset = []peer.ID{}
|
||||||
|
// cfg.WaitForLeaderTimeout = Duration(DefaultWaitForLeaderTimeout)
|
||||||
|
// cfg.NetworkTimeout = Duration(DefaultNetworkTimeout)
|
||||||
|
// cfg.CommitRetries = DefaultCommitRetries
|
||||||
|
// cfg.CommitRetryDelay = Duration(DefaultCommitRetryDelay)
|
||||||
|
// cfg.BackupsRotate = DefaultBackupsRotate
|
||||||
|
// cfg.DatastoreNamespace = DefaultDatastoreNamespace
|
||||||
|
// cfg.RaftConfig = hraft.DefaultConfig()
|
||||||
|
//
|
||||||
|
// // These options are imposed over any Default Raft Config.
|
||||||
|
// cfg.RaftConfig.ShutdownOnRemove = false
|
||||||
|
// cfg.RaftConfig.LocalID = "will_be_set_automatically"
|
||||||
|
//
|
||||||
|
// // Set up logging
|
||||||
|
// cfg.RaftConfig.LogOutput = ioutil.Discard
|
||||||
|
// //cfg.RaftConfig.Logger = &hcLogToLogger{}
|
||||||
|
// return &cfg
|
||||||
|
//}
|
||||||
|
|
||||||
|
func DefaultUserRaftConfig() *UserRaftConfig {
|
||||||
|
var cfg UserRaftConfig
|
||||||
cfg.DataFolder = "" // empty so it gets omitted
|
cfg.DataFolder = "" // empty so it gets omitted
|
||||||
cfg.InitPeerset = []peer.ID{}
|
cfg.InitPeerset = []peer.ID{}
|
||||||
cfg.WaitForLeaderTimeout = Duration(DefaultWaitForLeaderTimeout)
|
cfg.WaitForLeaderTimeout = Duration(DefaultWaitForLeaderTimeout)
|
||||||
@ -300,14 +320,6 @@ func DefaultClusterRaftConfig() *ClusterRaftConfig {
|
|||||||
cfg.CommitRetryDelay = Duration(DefaultCommitRetryDelay)
|
cfg.CommitRetryDelay = Duration(DefaultCommitRetryDelay)
|
||||||
cfg.BackupsRotate = DefaultBackupsRotate
|
cfg.BackupsRotate = DefaultBackupsRotate
|
||||||
cfg.DatastoreNamespace = DefaultDatastoreNamespace
|
cfg.DatastoreNamespace = DefaultDatastoreNamespace
|
||||||
cfg.RaftConfig = hraft.DefaultConfig()
|
|
||||||
|
|
||||||
// These options are imposed over any Default Raft Config.
|
|
||||||
cfg.RaftConfig.ShutdownOnRemove = false
|
|
||||||
cfg.RaftConfig.LocalID = "will_be_set_automatically"
|
|
||||||
|
|
||||||
// Set up logging
|
|
||||||
cfg.RaftConfig.LogOutput = ioutil.Discard
|
|
||||||
//cfg.RaftConfig.Logger = &hcLogToLogger{}
|
|
||||||
return &cfg
|
return &cfg
|
||||||
}
|
}
|
||||||
|
@ -117,86 +117,6 @@ without existing payment channels with available funds will fail instead
|
|||||||
of automatically performing on-chain operations.`,
|
of automatically performing on-chain operations.`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"ClusterRaftConfig": []DocField{
|
|
||||||
{
|
|
||||||
Name: "ClusterModeEnabled",
|
|
||||||
Type: "bool",
|
|
||||||
|
|
||||||
Comment: `config to enabled node cluster with raft consensus`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "HostShutdown",
|
|
||||||
Type: "bool",
|
|
||||||
|
|
||||||
Comment: `will shutdown libp2p host on shutdown. Useful for testing`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "DataFolder",
|
|
||||||
Type: "string",
|
|
||||||
|
|
||||||
Comment: `A folder to store Raft's data.`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "InitPeerset",
|
|
||||||
Type: "[]peer.ID",
|
|
||||||
|
|
||||||
Comment: `InitPeerset provides the list of initial cluster peers for new Raft
|
|
||||||
peers (with no prior state). It is ignored when Raft was already
|
|
||||||
initialized or when starting in staging mode.`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "WaitForLeaderTimeout",
|
|
||||||
Type: "Duration",
|
|
||||||
|
|
||||||
Comment: `LeaderTimeout specifies how long to wait for a leader before
|
|
||||||
failing an operation.`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "NetworkTimeout",
|
|
||||||
Type: "Duration",
|
|
||||||
|
|
||||||
Comment: `NetworkTimeout specifies how long before a Raft network
|
|
||||||
operation is timed out`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "CommitRetries",
|
|
||||||
Type: "int",
|
|
||||||
|
|
||||||
Comment: `CommitRetries specifies how many times we retry a failed commit until
|
|
||||||
we give up.`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "CommitRetryDelay",
|
|
||||||
Type: "Duration",
|
|
||||||
|
|
||||||
Comment: `How long to wait between retries`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "BackupsRotate",
|
|
||||||
Type: "int",
|
|
||||||
|
|
||||||
Comment: `BackupsRotate specifies the maximum number of Raft's DataFolder
|
|
||||||
copies that we keep as backups (renaming) after cleanup.`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "DatastoreNamespace",
|
|
||||||
Type: "string",
|
|
||||||
|
|
||||||
Comment: `Namespace to use when writing keys to the datastore`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "RaftConfig",
|
|
||||||
Type: "*hraft.Config",
|
|
||||||
|
|
||||||
Comment: `A Hashicorp Raft's configuration object.`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "Tracing",
|
|
||||||
Type: "bool",
|
|
||||||
|
|
||||||
Comment: `Tracing enables propagation of contexts across binary boundaries.`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"Common": []DocField{
|
"Common": []DocField{
|
||||||
{
|
{
|
||||||
Name: "API",
|
Name: "API",
|
||||||
@ -456,7 +376,7 @@ see https://lotus.filecoin.io/storage-providers/advanced-configurations/market/#
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "Raft",
|
Name: "Raft",
|
||||||
Type: "ClusterRaftConfig",
|
Type: "UserRaftConfig",
|
||||||
|
|
||||||
Comment: ``,
|
Comment: ``,
|
||||||
},
|
},
|
||||||
@ -1303,6 +1223,80 @@ finalities beyond the compaction boundary, default is 0, -1 retains everything`,
|
|||||||
Comment: ``,
|
Comment: ``,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"UserRaftConfig": []DocField{
|
||||||
|
{
|
||||||
|
Name: "ClusterModeEnabled",
|
||||||
|
Type: "bool",
|
||||||
|
|
||||||
|
Comment: `config to enabled node cluster with raft consensus`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "HostShutdown",
|
||||||
|
Type: "bool",
|
||||||
|
|
||||||
|
Comment: `will shutdown libp2p host on shutdown. Useful for testing`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "DataFolder",
|
||||||
|
Type: "string",
|
||||||
|
|
||||||
|
Comment: `A folder to store Raft's data.`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "InitPeerset",
|
||||||
|
Type: "[]peer.ID",
|
||||||
|
|
||||||
|
Comment: `InitPeerset provides the list of initial cluster peers for new Raft
|
||||||
|
peers (with no prior state). It is ignored when Raft was already
|
||||||
|
initialized or when starting in staging mode.`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "WaitForLeaderTimeout",
|
||||||
|
Type: "Duration",
|
||||||
|
|
||||||
|
Comment: `LeaderTimeout specifies how long to wait for a leader before
|
||||||
|
failing an operation.`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "NetworkTimeout",
|
||||||
|
Type: "Duration",
|
||||||
|
|
||||||
|
Comment: `NetworkTimeout specifies how long before a Raft network
|
||||||
|
operation is timed out`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "CommitRetries",
|
||||||
|
Type: "int",
|
||||||
|
|
||||||
|
Comment: `CommitRetries specifies how many times we retry a failed commit until
|
||||||
|
we give up.`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "CommitRetryDelay",
|
||||||
|
Type: "Duration",
|
||||||
|
|
||||||
|
Comment: `How long to wait between retries`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "BackupsRotate",
|
||||||
|
Type: "int",
|
||||||
|
|
||||||
|
Comment: `BackupsRotate specifies the maximum number of Raft's DataFolder
|
||||||
|
copies that we keep as backups (renaming) after cleanup.`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "DatastoreNamespace",
|
||||||
|
Type: "string",
|
||||||
|
|
||||||
|
Comment: `Namespace to use when writing keys to the datastore`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "Tracing",
|
||||||
|
Type: "bool",
|
||||||
|
|
||||||
|
Comment: `Tracing enables propagation of contexts across binary boundaries.`,
|
||||||
|
},
|
||||||
|
},
|
||||||
"Wallet": []DocField{
|
"Wallet": []DocField{
|
||||||
{
|
{
|
||||||
Name: "RemoteBackend",
|
Name: "RemoteBackend",
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
hraft "github.com/hashicorp/raft"
|
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
"github.com/libp2p/go-libp2p/core/peer"
|
"github.com/libp2p/go-libp2p/core/peer"
|
||||||
|
|
||||||
@ -29,7 +28,7 @@ type FullNode struct {
|
|||||||
Wallet Wallet
|
Wallet Wallet
|
||||||
Fees FeeConfig
|
Fees FeeConfig
|
||||||
Chainstore Chainstore
|
Chainstore Chainstore
|
||||||
Raft ClusterRaftConfig
|
Raft UserRaftConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
// // Common
|
// // Common
|
||||||
@ -612,8 +611,43 @@ type FeeConfig struct {
|
|||||||
DefaultMaxFee types.FIL
|
DefaultMaxFee types.FIL
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClusterRaftConfig allows to configure the Raft Consensus component for the node cluster.
|
//// ClusterRaftConfig allows to configure the Raft Consensus component for the node cluster.
|
||||||
type ClusterRaftConfig struct {
|
//type ClusterRaftConfig struct {
|
||||||
|
// // config to enabled node cluster with raft consensus
|
||||||
|
// ClusterModeEnabled bool
|
||||||
|
// // will shutdown libp2p host on shutdown. Useful for testing
|
||||||
|
// HostShutdown bool
|
||||||
|
// // A folder to store Raft's data.
|
||||||
|
// DataFolder string
|
||||||
|
// // InitPeerset provides the list of initial cluster peers for new Raft
|
||||||
|
// // peers (with no prior state). It is ignored when Raft was already
|
||||||
|
// // initialized or when starting in staging mode.
|
||||||
|
// InitPeerset []peer.ID
|
||||||
|
// // LeaderTimeout specifies how long to wait for a leader before
|
||||||
|
// // failing an operation.
|
||||||
|
// WaitForLeaderTimeout Duration
|
||||||
|
// // NetworkTimeout specifies how long before a Raft network
|
||||||
|
// // operation is timed out
|
||||||
|
// NetworkTimeout Duration
|
||||||
|
// // CommitRetries specifies how many times we retry a failed commit until
|
||||||
|
// // we give up.
|
||||||
|
// CommitRetries int
|
||||||
|
// // How long to wait between retries
|
||||||
|
// CommitRetryDelay Duration
|
||||||
|
// // BackupsRotate specifies the maximum number of Raft's DataFolder
|
||||||
|
// // copies that we keep as backups (renaming) after cleanup.
|
||||||
|
// BackupsRotate int
|
||||||
|
// // Namespace to use when writing keys to the datastore
|
||||||
|
// DatastoreNamespace string
|
||||||
|
//
|
||||||
|
// // A Hashicorp Raft's configuration object.
|
||||||
|
// RaftConfig *hraft.Config
|
||||||
|
//
|
||||||
|
// // Tracing enables propagation of contexts across binary boundaries.
|
||||||
|
// Tracing bool
|
||||||
|
//}
|
||||||
|
|
||||||
|
type UserRaftConfig struct {
|
||||||
// config to enabled node cluster with raft consensus
|
// config to enabled node cluster with raft consensus
|
||||||
ClusterModeEnabled bool
|
ClusterModeEnabled bool
|
||||||
// will shutdown libp2p host on shutdown. Useful for testing
|
// will shutdown libp2p host on shutdown. Useful for testing
|
||||||
@ -642,7 +676,7 @@ type ClusterRaftConfig struct {
|
|||||||
DatastoreNamespace string
|
DatastoreNamespace string
|
||||||
|
|
||||||
// A Hashicorp Raft's configuration object.
|
// A Hashicorp Raft's configuration object.
|
||||||
RaftConfig *hraft.Config
|
//RaftConfig *hraft.Config
|
||||||
|
|
||||||
// Tracing enables propagation of contexts across binary boundaries.
|
// Tracing enables propagation of contexts across binary boundaries.
|
||||||
Tracing bool
|
Tracing bool
|
||||||
|
@ -9,7 +9,8 @@ import (
|
|||||||
|
|
||||||
"github.com/filecoin-project/lotus/api"
|
"github.com/filecoin-project/lotus/api"
|
||||||
"github.com/filecoin-project/lotus/build"
|
"github.com/filecoin-project/lotus/build"
|
||||||
consensus2 "github.com/filecoin-project/lotus/lib/consensus/raft"
|
|
||||||
|
//consensus2 "github.com/filecoin-project/lotus/lib/consensus/raft"
|
||||||
"github.com/filecoin-project/lotus/node/impl/client"
|
"github.com/filecoin-project/lotus/node/impl/client"
|
||||||
"github.com/filecoin-project/lotus/node/impl/common"
|
"github.com/filecoin-project/lotus/node/impl/common"
|
||||||
"github.com/filecoin-project/lotus/node/impl/full"
|
"github.com/filecoin-project/lotus/node/impl/full"
|
||||||
@ -119,7 +120,7 @@ func (n *FullNodeAPI) NodeStatus(ctx context.Context, inclChainStatus bool) (sta
|
|||||||
return status, nil
|
return status, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *FullNodeAPI) RaftState(ctx context.Context) (*consensus2.RaftState, error) {
|
func (n *FullNodeAPI) RaftState(ctx context.Context) (*api.RaftStateData, error) {
|
||||||
return n.RaftAPI.GetRaftState(ctx)
|
return n.RaftAPI.GetRaftState(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,12 +2,13 @@ package full
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/libp2p/go-libp2p/core/peer"
|
"github.com/libp2p/go-libp2p/core/peer"
|
||||||
"go.uber.org/fx"
|
"go.uber.org/fx"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/api"
|
||||||
"github.com/filecoin-project/lotus/chain/messagesigner"
|
"github.com/filecoin-project/lotus/chain/messagesigner"
|
||||||
consensus "github.com/filecoin-project/lotus/lib/consensus/raft"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type RaftAPI struct {
|
type RaftAPI struct {
|
||||||
@ -16,11 +17,15 @@ type RaftAPI struct {
|
|||||||
MessageSigner *messagesigner.MessageSignerConsensus `optional:"true"`
|
MessageSigner *messagesigner.MessageSignerConsensus `optional:"true"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RaftAPI) GetRaftState(ctx context.Context) (*consensus.RaftState, error) {
|
func (r *RaftAPI) GetRaftState(ctx context.Context) (*api.RaftStateData, error) {
|
||||||
if r.MessageSigner == nil {
|
if r.MessageSigner == nil {
|
||||||
return nil, xerrors.Errorf("Raft consensus not enabled. Please check your configuration")
|
return nil, xerrors.Errorf("Raft consensus not enabled. Please check your configuration")
|
||||||
}
|
}
|
||||||
return r.MessageSigner.GetRaftState(ctx)
|
raftState, err := r.MessageSigner.GetRaftState(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &api.RaftStateData{NonceMap: raftState.NonceMap, MsgUuids: raftState.MsgUuids}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RaftAPI) Leader(ctx context.Context) (peer.ID, error) {
|
func (r *RaftAPI) Leader(ctx context.Context) (peer.ID, error) {
|
||||||
|
@ -9,7 +9,7 @@ import (
|
|||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/messagesigner"
|
"github.com/filecoin-project/lotus/chain/messagepool"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
"github.com/filecoin-project/lotus/node/impl/full"
|
"github.com/filecoin-project/lotus/node/impl/full"
|
||||||
)
|
)
|
||||||
@ -104,4 +104,4 @@ func (a *MpoolNonceAPI) GetActor(ctx context.Context, addr address.Address, tsk
|
|||||||
return act, nil
|
return act, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ messagesigner.MpoolNonceAPI = (*MpoolNonceAPI)(nil)
|
var _ messagepool.MpoolNonceAPI = (*MpoolNonceAPI)(nil)
|
||||||
|
Loading…
Reference in New Issue
Block a user