2022-09-08 18:20:05 +00:00
|
|
|
package messagesigner
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
|
|
|
|
"github.com/google/uuid"
|
|
|
|
"github.com/ipfs/go-datastore"
|
|
|
|
"github.com/ipfs/go-datastore/namespace"
|
|
|
|
"github.com/libp2p/go-libp2p/core/peer"
|
|
|
|
"golang.org/x/xerrors"
|
|
|
|
|
|
|
|
"github.com/filecoin-project/lotus/api"
|
|
|
|
"github.com/filecoin-project/lotus/chain/types"
|
|
|
|
consensus "github.com/filecoin-project/lotus/lib/consensus/raft"
|
|
|
|
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
|
|
|
)
|
|
|
|
|
|
|
|
type MessageSignerConsensus struct {
|
|
|
|
MsgSigner
|
|
|
|
consensus *consensus.Consensus
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewMessageSignerConsensus(
|
|
|
|
wallet api.Wallet,
|
|
|
|
mpool MpoolNonceAPI,
|
|
|
|
ds dtypes.MetadataDS,
|
|
|
|
consensus *consensus.Consensus) *MessageSignerConsensus {
|
|
|
|
|
|
|
|
ds = namespace.Wrap(ds, datastore.NewKey("/message-signer-consensus/"))
|
|
|
|
return &MessageSignerConsensus{
|
|
|
|
MsgSigner: &MessageSigner{
|
|
|
|
wallet: wallet,
|
|
|
|
mpool: mpool,
|
|
|
|
ds: ds,
|
|
|
|
},
|
|
|
|
consensus: consensus,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (ms *MessageSignerConsensus) IsLeader(ctx context.Context) bool {
|
|
|
|
return ms.consensus.IsLeader(ctx)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (ms *MessageSignerConsensus) RedirectToLeader(ctx context.Context, method string, arg interface{}, ret interface{}) (bool, error) {
|
|
|
|
ok, err := ms.consensus.RedirectToLeader(method, arg, ret.(*types.SignedMessage))
|
|
|
|
if err != nil {
|
|
|
|
return ok, err
|
|
|
|
}
|
|
|
|
return ok, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (ms *MessageSignerConsensus) SignMessage(
|
|
|
|
ctx context.Context,
|
|
|
|
msg *types.Message,
|
|
|
|
spec *api.MessageSendSpec,
|
|
|
|
cb func(*types.SignedMessage) error) (*types.SignedMessage, error) {
|
|
|
|
|
|
|
|
signedMsg, err := ms.MsgSigner.SignMessage(ctx, msg, spec, cb)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// We can't have an empty/default uuid as part of the consensus state so generate a new uuid if spec is empty
|
|
|
|
u := uuid.New()
|
|
|
|
if spec != nil {
|
|
|
|
u = spec.MsgUuid
|
|
|
|
}
|
|
|
|
|
|
|
|
op := &consensus.ConsensusOp{signedMsg.Message.Nonce, u, signedMsg.Message.From, signedMsg}
|
|
|
|
err = ms.consensus.Commit(ctx, op)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return signedMsg, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (ms *MessageSignerConsensus) GetSignedMessage(ctx context.Context, uuid uuid.UUID) (*types.SignedMessage, error) {
|
2022-09-27 16:08:04 +00:00
|
|
|
cstate, err := ms.consensus.State(ctx)
|
2022-09-08 18:20:05 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2022-09-27 16:08:04 +00:00
|
|
|
//cstate := state.(consensus.RaftState)
|
2022-09-08 18:20:05 +00:00
|
|
|
msg, ok := cstate.MsgUuids[uuid]
|
|
|
|
if !ok {
|
|
|
|
return nil, xerrors.Errorf("Msg with Uuid %s not available", uuid)
|
|
|
|
}
|
|
|
|
return msg, nil
|
|
|
|
}
|
|
|
|
|
2022-09-27 16:08:04 +00:00
|
|
|
func (ms *MessageSignerConsensus) GetRaftState(ctx context.Context) (*consensus.RaftState, error) {
|
2022-09-08 18:20:05 +00:00
|
|
|
return ms.consensus.State(ctx)
|
|
|
|
}
|
|
|
|
|
2022-09-22 20:27:15 +00:00
|
|
|
func (ms *MessageSignerConsensus) Leader(ctx context.Context) (peer.ID, error) {
|
2022-09-08 18:20:05 +00:00
|
|
|
return ms.consensus.Leader(ctx)
|
|
|
|
}
|