Merge pull request #5822 from filecoin-project/epic/robust-message-management
Robust message management
This commit is contained in:
commit
8465a97c4b
@ -252,6 +252,13 @@ type FullNode interface {
|
||||
// MpoolBatchPushMessage batch pushes a unsigned message to mempool.
|
||||
MpoolBatchPushMessage(context.Context, []*types.Message, *MessageSendSpec) ([]*types.SignedMessage, error) //perm:sign
|
||||
|
||||
// MpoolCheckMessages performs logical checks on a batch of messages
|
||||
MpoolCheckMessages(context.Context, []*MessagePrototype) ([][]MessageCheckStatus, error) //perm:read
|
||||
// MpoolCheckPendingMessages performs logical checks for all pending messages from a given address
|
||||
MpoolCheckPendingMessages(context.Context, address.Address) ([][]MessageCheckStatus, error) //perm:read
|
||||
// MpoolCheckReplaceMessages performs logical checks on pending messages with replacement
|
||||
MpoolCheckReplaceMessages(context.Context, []*types.Message) ([][]MessageCheckStatus, error) //perm:read
|
||||
|
||||
// MpoolGetNonce gets next nonce for the specified sender.
|
||||
// Note that this method may not be atomic. Use MpoolPushMessage instead.
|
||||
MpoolGetNonce(context.Context, address.Address) (uint64, error) //perm:read
|
||||
@ -579,15 +586,16 @@ type FullNode interface {
|
||||
// MsigCreate creates a multisig wallet
|
||||
// It takes the following params: <required number of senders>, <approving addresses>, <unlock duration>
|
||||
//<initial balance>, <sender address of the create msg>, <gas price>
|
||||
MsigCreate(context.Context, uint64, []address.Address, abi.ChainEpoch, types.BigInt, address.Address, types.BigInt) (cid.Cid, error) //perm:sign
|
||||
MsigCreate(context.Context, uint64, []address.Address, abi.ChainEpoch, types.BigInt, address.Address, types.BigInt) (*MessagePrototype, error) //perm:sign
|
||||
|
||||
// MsigPropose proposes a multisig message
|
||||
// It takes the following params: <multisig address>, <recipient address>, <value to transfer>,
|
||||
// <sender address of the propose msg>, <method to call in the proposed message>, <params to include in the proposed message>
|
||||
MsigPropose(context.Context, address.Address, address.Address, types.BigInt, address.Address, uint64, []byte) (cid.Cid, error) //perm:sign
|
||||
MsigPropose(context.Context, address.Address, address.Address, types.BigInt, address.Address, uint64, []byte) (*MessagePrototype, error) //perm:sign
|
||||
|
||||
// MsigApprove approves a previously-proposed multisig message by transaction ID
|
||||
// It takes the following params: <multisig address>, <proposed transaction ID> <signer address>
|
||||
MsigApprove(context.Context, address.Address, uint64, address.Address) (cid.Cid, error) //perm:sign
|
||||
MsigApprove(context.Context, address.Address, uint64, address.Address) (*MessagePrototype, error) //perm:sign
|
||||
|
||||
// MsigApproveTxnHash approves a previously-proposed multisig message, specified
|
||||
// using both transaction ID and a hash of the parameters used in the
|
||||
@ -595,43 +603,49 @@ type FullNode interface {
|
||||
// exactly the transaction you think you are.
|
||||
// It takes the following params: <multisig address>, <proposed message ID>, <proposer address>, <recipient address>, <value to transfer>,
|
||||
// <sender address of the approve msg>, <method to call in the proposed message>, <params to include in the proposed message>
|
||||
MsigApproveTxnHash(context.Context, address.Address, uint64, address.Address, address.Address, types.BigInt, address.Address, uint64, []byte) (cid.Cid, error) //perm:sign
|
||||
MsigApproveTxnHash(context.Context, address.Address, uint64, address.Address, address.Address, types.BigInt, address.Address, uint64, []byte) (*MessagePrototype, error) //perm:sign
|
||||
|
||||
// MsigCancel cancels a previously-proposed multisig message
|
||||
// It takes the following params: <multisig address>, <proposed transaction ID>, <recipient address>, <value to transfer>,
|
||||
// <sender address of the cancel msg>, <method to call in the proposed message>, <params to include in the proposed message>
|
||||
MsigCancel(context.Context, address.Address, uint64, address.Address, types.BigInt, address.Address, uint64, []byte) (cid.Cid, error) //perm:sign
|
||||
MsigCancel(context.Context, address.Address, uint64, address.Address, types.BigInt, address.Address, uint64, []byte) (*MessagePrototype, error) //perm:sign
|
||||
|
||||
// MsigAddPropose proposes adding a signer in the multisig
|
||||
// It takes the following params: <multisig address>, <sender address of the propose msg>,
|
||||
// <new signer>, <whether the number of required signers should be increased>
|
||||
MsigAddPropose(context.Context, address.Address, address.Address, address.Address, bool) (cid.Cid, error) //perm:sign
|
||||
MsigAddPropose(context.Context, address.Address, address.Address, address.Address, bool) (*MessagePrototype, error) //perm:sign
|
||||
|
||||
// MsigAddApprove approves a previously proposed AddSigner message
|
||||
// It takes the following params: <multisig address>, <sender address of the approve msg>, <proposed message ID>,
|
||||
// <proposer address>, <new signer>, <whether the number of required signers should be increased>
|
||||
MsigAddApprove(context.Context, address.Address, address.Address, uint64, address.Address, address.Address, bool) (cid.Cid, error) //perm:sign
|
||||
MsigAddApprove(context.Context, address.Address, address.Address, uint64, address.Address, address.Address, bool) (*MessagePrototype, error) //perm:sign
|
||||
|
||||
// MsigAddCancel cancels a previously proposed AddSigner message
|
||||
// It takes the following params: <multisig address>, <sender address of the cancel msg>, <proposed message ID>,
|
||||
// <new signer>, <whether the number of required signers should be increased>
|
||||
MsigAddCancel(context.Context, address.Address, address.Address, uint64, address.Address, bool) (cid.Cid, error) //perm:sign
|
||||
MsigAddCancel(context.Context, address.Address, address.Address, uint64, address.Address, bool) (*MessagePrototype, error) //perm:sign
|
||||
|
||||
// MsigSwapPropose proposes swapping 2 signers in the multisig
|
||||
// It takes the following params: <multisig address>, <sender address of the propose msg>,
|
||||
// <old signer>, <new signer>
|
||||
MsigSwapPropose(context.Context, address.Address, address.Address, address.Address, address.Address) (cid.Cid, error) //perm:sign
|
||||
MsigSwapPropose(context.Context, address.Address, address.Address, address.Address, address.Address) (*MessagePrototype, error) //perm:sign
|
||||
|
||||
// MsigSwapApprove approves a previously proposed SwapSigner
|
||||
// It takes the following params: <multisig address>, <sender address of the approve msg>, <proposed message ID>,
|
||||
// <proposer address>, <old signer>, <new signer>
|
||||
MsigSwapApprove(context.Context, address.Address, address.Address, uint64, address.Address, address.Address, address.Address) (cid.Cid, error) //perm:sign
|
||||
MsigSwapApprove(context.Context, address.Address, address.Address, uint64, address.Address, address.Address, address.Address) (*MessagePrototype, error) //perm:sign
|
||||
|
||||
// MsigSwapCancel cancels a previously proposed SwapSigner message
|
||||
// It takes the following params: <multisig address>, <sender address of the cancel msg>, <proposed message ID>,
|
||||
// <old signer>, <new signer>
|
||||
MsigSwapCancel(context.Context, address.Address, address.Address, uint64, address.Address, address.Address) (cid.Cid, error) //perm:sign
|
||||
MsigSwapCancel(context.Context, address.Address, address.Address, uint64, address.Address, address.Address) (*MessagePrototype, error) //perm:sign
|
||||
|
||||
// MsigRemoveSigner proposes the removal of a signer from the multisig.
|
||||
// It accepts the multisig to make the change on, the proposer address to
|
||||
// send the message from, the address to be removed, and a boolean
|
||||
// indicating whether or not the signing threshold should be lowered by one
|
||||
// along with the address removal.
|
||||
MsigRemoveSigner(ctx context.Context, msig address.Address, proposer address.Address, toRemove address.Address, decrease bool) (cid.Cid, error) //perm:sign
|
||||
MsigRemoveSigner(ctx context.Context, msig address.Address, proposer address.Address, toRemove address.Address, decrease bool) (*MessagePrototype, error) //perm:sign
|
||||
|
||||
// MarketAddBalance adds funds to the market actor
|
||||
MarketAddBalance(ctx context.Context, wallet, addr address.Address, amt types.BigInt) (cid.Cid, error) //perm:sign
|
||||
@ -664,6 +678,11 @@ type FullNode interface {
|
||||
PaychVoucherList(context.Context, address.Address) ([]*paych.SignedVoucher, error) //perm:write
|
||||
PaychVoucherSubmit(context.Context, address.Address, *paych.SignedVoucher, []byte, []byte) (cid.Cid, error) //perm:sign
|
||||
|
||||
// MethodGroup: Node
|
||||
// These methods are general node management and status commands
|
||||
|
||||
NodeStatus(ctx context.Context, inclChainStatus bool) (NodeStatus, error) //perm:read
|
||||
|
||||
// CreateBackup creates node backup onder the specified file name. The
|
||||
// method requires that the lotus daemon is running with the
|
||||
// LOTUS_BACKUP_BASE_PATH environment variable set to some path, and that
|
||||
|
35
api/checkstatuscode_string.go
Normal file
35
api/checkstatuscode_string.go
Normal file
@ -0,0 +1,35 @@
|
||||
// Code generated by "stringer -type=CheckStatusCode -trimprefix=CheckStatus"; DO NOT EDIT.
|
||||
|
||||
package api
|
||||
|
||||
import "strconv"
|
||||
|
||||
func _() {
|
||||
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||
// Re-run the stringer command to generate them again.
|
||||
var x [1]struct{}
|
||||
_ = x[CheckStatusMessageSerialize-1]
|
||||
_ = x[CheckStatusMessageSize-2]
|
||||
_ = x[CheckStatusMessageValidity-3]
|
||||
_ = x[CheckStatusMessageMinGas-4]
|
||||
_ = x[CheckStatusMessageMinBaseFee-5]
|
||||
_ = x[CheckStatusMessageBaseFee-6]
|
||||
_ = x[CheckStatusMessageBaseFeeLowerBound-7]
|
||||
_ = x[CheckStatusMessageBaseFeeUpperBound-8]
|
||||
_ = x[CheckStatusMessageGetStateNonce-9]
|
||||
_ = x[CheckStatusMessageNonce-10]
|
||||
_ = x[CheckStatusMessageGetStateBalance-11]
|
||||
_ = x[CheckStatusMessageBalance-12]
|
||||
}
|
||||
|
||||
const _CheckStatusCode_name = "MessageSerializeMessageSizeMessageValidityMessageMinGasMessageMinBaseFeeMessageBaseFeeMessageBaseFeeLowerBoundMessageBaseFeeUpperBoundMessageGetStateNonceMessageNonceMessageGetStateBalanceMessageBalance"
|
||||
|
||||
var _CheckStatusCode_index = [...]uint8{0, 16, 27, 42, 55, 72, 86, 110, 134, 154, 166, 188, 202}
|
||||
|
||||
func (i CheckStatusCode) String() string {
|
||||
i -= 1
|
||||
if i < 0 || i >= CheckStatusCode(len(_CheckStatusCode_index)-1) {
|
||||
return "CheckStatusCode(" + strconv.FormatInt(int64(i+1), 10) + ")"
|
||||
}
|
||||
return _CheckStatusCode_name[_CheckStatusCode_index[i]:_CheckStatusCode_index[i+1]]
|
||||
}
|
@ -261,6 +261,9 @@ func init() {
|
||||
},
|
||||
"methods": []interface{}{}},
|
||||
)
|
||||
|
||||
addExample(api.CheckStatusCode(0))
|
||||
addExample(map[string]interface{}{"abc": 123})
|
||||
}
|
||||
|
||||
func GetAPIType(name, pkg string) (i interface{}, t, permStruct, commonPermStruct reflect.Type) {
|
||||
|
@ -1068,6 +1068,51 @@ func (mr *MockFullNodeMockRecorder) MpoolBatchPushUntrusted(arg0, arg1 interface
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolBatchPushUntrusted", reflect.TypeOf((*MockFullNode)(nil).MpoolBatchPushUntrusted), arg0, arg1)
|
||||
}
|
||||
|
||||
// MpoolCheckMessages mocks base method
|
||||
func (m *MockFullNode) MpoolCheckMessages(arg0 context.Context, arg1 []*api.MessagePrototype) ([][]api.MessageCheckStatus, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "MpoolCheckMessages", arg0, arg1)
|
||||
ret0, _ := ret[0].([][]api.MessageCheckStatus)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// MpoolCheckMessages indicates an expected call of MpoolCheckMessages
|
||||
func (mr *MockFullNodeMockRecorder) MpoolCheckMessages(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolCheckMessages", reflect.TypeOf((*MockFullNode)(nil).MpoolCheckMessages), arg0, arg1)
|
||||
}
|
||||
|
||||
// MpoolCheckPendingMessages mocks base method
|
||||
func (m *MockFullNode) MpoolCheckPendingMessages(arg0 context.Context, arg1 address.Address) ([][]api.MessageCheckStatus, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "MpoolCheckPendingMessages", arg0, arg1)
|
||||
ret0, _ := ret[0].([][]api.MessageCheckStatus)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// MpoolCheckPendingMessages indicates an expected call of MpoolCheckPendingMessages
|
||||
func (mr *MockFullNodeMockRecorder) MpoolCheckPendingMessages(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolCheckPendingMessages", reflect.TypeOf((*MockFullNode)(nil).MpoolCheckPendingMessages), arg0, arg1)
|
||||
}
|
||||
|
||||
// MpoolCheckReplaceMessages mocks base method
|
||||
func (m *MockFullNode) MpoolCheckReplaceMessages(arg0 context.Context, arg1 []*types.Message) ([][]api.MessageCheckStatus, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "MpoolCheckReplaceMessages", arg0, arg1)
|
||||
ret0, _ := ret[0].([][]api.MessageCheckStatus)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// MpoolCheckReplaceMessages indicates an expected call of MpoolCheckReplaceMessages
|
||||
func (mr *MockFullNodeMockRecorder) MpoolCheckReplaceMessages(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolCheckReplaceMessages", reflect.TypeOf((*MockFullNode)(nil).MpoolCheckReplaceMessages), arg0, arg1)
|
||||
}
|
||||
|
||||
// MpoolClear mocks base method
|
||||
func (m *MockFullNode) MpoolClear(arg0 context.Context, arg1 bool) error {
|
||||
m.ctrl.T.Helper()
|
||||
@ -1217,10 +1262,10 @@ func (mr *MockFullNodeMockRecorder) MpoolSub(arg0 interface{}) *gomock.Call {
|
||||
}
|
||||
|
||||
// MsigAddApprove mocks base method
|
||||
func (m *MockFullNode) MsigAddApprove(arg0 context.Context, arg1, arg2 address.Address, arg3 uint64, arg4, arg5 address.Address, arg6 bool) (cid.Cid, error) {
|
||||
func (m *MockFullNode) MsigAddApprove(arg0 context.Context, arg1, arg2 address.Address, arg3 uint64, arg4, arg5 address.Address, arg6 bool) (*api.MessagePrototype, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "MsigAddApprove", arg0, arg1, arg2, arg3, arg4, arg5, arg6)
|
||||
ret0, _ := ret[0].(cid.Cid)
|
||||
ret0, _ := ret[0].(*api.MessagePrototype)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
@ -1232,10 +1277,10 @@ func (mr *MockFullNodeMockRecorder) MsigAddApprove(arg0, arg1, arg2, arg3, arg4,
|
||||
}
|
||||
|
||||
// MsigAddCancel mocks base method
|
||||
func (m *MockFullNode) MsigAddCancel(arg0 context.Context, arg1, arg2 address.Address, arg3 uint64, arg4 address.Address, arg5 bool) (cid.Cid, error) {
|
||||
func (m *MockFullNode) MsigAddCancel(arg0 context.Context, arg1, arg2 address.Address, arg3 uint64, arg4 address.Address, arg5 bool) (*api.MessagePrototype, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "MsigAddCancel", arg0, arg1, arg2, arg3, arg4, arg5)
|
||||
ret0, _ := ret[0].(cid.Cid)
|
||||
ret0, _ := ret[0].(*api.MessagePrototype)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
@ -1247,10 +1292,10 @@ func (mr *MockFullNodeMockRecorder) MsigAddCancel(arg0, arg1, arg2, arg3, arg4,
|
||||
}
|
||||
|
||||
// MsigAddPropose mocks base method
|
||||
func (m *MockFullNode) MsigAddPropose(arg0 context.Context, arg1, arg2, arg3 address.Address, arg4 bool) (cid.Cid, error) {
|
||||
func (m *MockFullNode) MsigAddPropose(arg0 context.Context, arg1, arg2, arg3 address.Address, arg4 bool) (*api.MessagePrototype, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "MsigAddPropose", arg0, arg1, arg2, arg3, arg4)
|
||||
ret0, _ := ret[0].(cid.Cid)
|
||||
ret0, _ := ret[0].(*api.MessagePrototype)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
@ -1262,10 +1307,10 @@ func (mr *MockFullNodeMockRecorder) MsigAddPropose(arg0, arg1, arg2, arg3, arg4
|
||||
}
|
||||
|
||||
// MsigApprove mocks base method
|
||||
func (m *MockFullNode) MsigApprove(arg0 context.Context, arg1 address.Address, arg2 uint64, arg3 address.Address) (cid.Cid, error) {
|
||||
func (m *MockFullNode) MsigApprove(arg0 context.Context, arg1 address.Address, arg2 uint64, arg3 address.Address) (*api.MessagePrototype, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "MsigApprove", arg0, arg1, arg2, arg3)
|
||||
ret0, _ := ret[0].(cid.Cid)
|
||||
ret0, _ := ret[0].(*api.MessagePrototype)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
@ -1277,10 +1322,10 @@ func (mr *MockFullNodeMockRecorder) MsigApprove(arg0, arg1, arg2, arg3 interface
|
||||
}
|
||||
|
||||
// MsigApproveTxnHash mocks base method
|
||||
func (m *MockFullNode) MsigApproveTxnHash(arg0 context.Context, arg1 address.Address, arg2 uint64, arg3, arg4 address.Address, arg5 big.Int, arg6 address.Address, arg7 uint64, arg8 []byte) (cid.Cid, error) {
|
||||
func (m *MockFullNode) MsigApproveTxnHash(arg0 context.Context, arg1 address.Address, arg2 uint64, arg3, arg4 address.Address, arg5 big.Int, arg6 address.Address, arg7 uint64, arg8 []byte) (*api.MessagePrototype, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "MsigApproveTxnHash", arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
|
||||
ret0, _ := ret[0].(cid.Cid)
|
||||
ret0, _ := ret[0].(*api.MessagePrototype)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
@ -1292,10 +1337,10 @@ func (mr *MockFullNodeMockRecorder) MsigApproveTxnHash(arg0, arg1, arg2, arg3, a
|
||||
}
|
||||
|
||||
// MsigCancel mocks base method
|
||||
func (m *MockFullNode) MsigCancel(arg0 context.Context, arg1 address.Address, arg2 uint64, arg3 address.Address, arg4 big.Int, arg5 address.Address, arg6 uint64, arg7 []byte) (cid.Cid, error) {
|
||||
func (m *MockFullNode) MsigCancel(arg0 context.Context, arg1 address.Address, arg2 uint64, arg3 address.Address, arg4 big.Int, arg5 address.Address, arg6 uint64, arg7 []byte) (*api.MessagePrototype, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "MsigCancel", arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
|
||||
ret0, _ := ret[0].(cid.Cid)
|
||||
ret0, _ := ret[0].(*api.MessagePrototype)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
@ -1307,10 +1352,10 @@ func (mr *MockFullNodeMockRecorder) MsigCancel(arg0, arg1, arg2, arg3, arg4, arg
|
||||
}
|
||||
|
||||
// MsigCreate mocks base method
|
||||
func (m *MockFullNode) MsigCreate(arg0 context.Context, arg1 uint64, arg2 []address.Address, arg3 abi.ChainEpoch, arg4 big.Int, arg5 address.Address, arg6 big.Int) (cid.Cid, error) {
|
||||
func (m *MockFullNode) MsigCreate(arg0 context.Context, arg1 uint64, arg2 []address.Address, arg3 abi.ChainEpoch, arg4 big.Int, arg5 address.Address, arg6 big.Int) (*api.MessagePrototype, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "MsigCreate", arg0, arg1, arg2, arg3, arg4, arg5, arg6)
|
||||
ret0, _ := ret[0].(cid.Cid)
|
||||
ret0, _ := ret[0].(*api.MessagePrototype)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
@ -1382,10 +1427,10 @@ func (mr *MockFullNodeMockRecorder) MsigGetVestingSchedule(arg0, arg1, arg2 inte
|
||||
}
|
||||
|
||||
// MsigPropose mocks base method
|
||||
func (m *MockFullNode) MsigPropose(arg0 context.Context, arg1, arg2 address.Address, arg3 big.Int, arg4 address.Address, arg5 uint64, arg6 []byte) (cid.Cid, error) {
|
||||
func (m *MockFullNode) MsigPropose(arg0 context.Context, arg1, arg2 address.Address, arg3 big.Int, arg4 address.Address, arg5 uint64, arg6 []byte) (*api.MessagePrototype, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "MsigPropose", arg0, arg1, arg2, arg3, arg4, arg5, arg6)
|
||||
ret0, _ := ret[0].(cid.Cid)
|
||||
ret0, _ := ret[0].(*api.MessagePrototype)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
@ -1397,10 +1442,10 @@ func (mr *MockFullNodeMockRecorder) MsigPropose(arg0, arg1, arg2, arg3, arg4, ar
|
||||
}
|
||||
|
||||
// MsigRemoveSigner mocks base method
|
||||
func (m *MockFullNode) MsigRemoveSigner(arg0 context.Context, arg1, arg2, arg3 address.Address, arg4 bool) (cid.Cid, error) {
|
||||
func (m *MockFullNode) MsigRemoveSigner(arg0 context.Context, arg1, arg2, arg3 address.Address, arg4 bool) (*api.MessagePrototype, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "MsigRemoveSigner", arg0, arg1, arg2, arg3, arg4)
|
||||
ret0, _ := ret[0].(cid.Cid)
|
||||
ret0, _ := ret[0].(*api.MessagePrototype)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
@ -1412,10 +1457,10 @@ func (mr *MockFullNodeMockRecorder) MsigRemoveSigner(arg0, arg1, arg2, arg3, arg
|
||||
}
|
||||
|
||||
// MsigSwapApprove mocks base method
|
||||
func (m *MockFullNode) MsigSwapApprove(arg0 context.Context, arg1, arg2 address.Address, arg3 uint64, arg4, arg5, arg6 address.Address) (cid.Cid, error) {
|
||||
func (m *MockFullNode) MsigSwapApprove(arg0 context.Context, arg1, arg2 address.Address, arg3 uint64, arg4, arg5, arg6 address.Address) (*api.MessagePrototype, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "MsigSwapApprove", arg0, arg1, arg2, arg3, arg4, arg5, arg6)
|
||||
ret0, _ := ret[0].(cid.Cid)
|
||||
ret0, _ := ret[0].(*api.MessagePrototype)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
@ -1427,10 +1472,10 @@ func (mr *MockFullNodeMockRecorder) MsigSwapApprove(arg0, arg1, arg2, arg3, arg4
|
||||
}
|
||||
|
||||
// MsigSwapCancel mocks base method
|
||||
func (m *MockFullNode) MsigSwapCancel(arg0 context.Context, arg1, arg2 address.Address, arg3 uint64, arg4, arg5 address.Address) (cid.Cid, error) {
|
||||
func (m *MockFullNode) MsigSwapCancel(arg0 context.Context, arg1, arg2 address.Address, arg3 uint64, arg4, arg5 address.Address) (*api.MessagePrototype, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "MsigSwapCancel", arg0, arg1, arg2, arg3, arg4, arg5)
|
||||
ret0, _ := ret[0].(cid.Cid)
|
||||
ret0, _ := ret[0].(*api.MessagePrototype)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
@ -1442,10 +1487,10 @@ func (mr *MockFullNodeMockRecorder) MsigSwapCancel(arg0, arg1, arg2, arg3, arg4,
|
||||
}
|
||||
|
||||
// MsigSwapPropose mocks base method
|
||||
func (m *MockFullNode) MsigSwapPropose(arg0 context.Context, arg1, arg2, arg3, arg4 address.Address) (cid.Cid, error) {
|
||||
func (m *MockFullNode) MsigSwapPropose(arg0 context.Context, arg1, arg2, arg3, arg4 address.Address) (*api.MessagePrototype, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "MsigSwapPropose", arg0, arg1, arg2, arg3, arg4)
|
||||
ret0, _ := ret[0].(cid.Cid)
|
||||
ret0, _ := ret[0].(*api.MessagePrototype)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
@ -1692,6 +1737,21 @@ func (mr *MockFullNodeMockRecorder) NetPubsubScores(arg0 interface{}) *gomock.Ca
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetPubsubScores", reflect.TypeOf((*MockFullNode)(nil).NetPubsubScores), arg0)
|
||||
}
|
||||
|
||||
// NodeStatus mocks base method
|
||||
func (m *MockFullNode) NodeStatus(arg0 context.Context, arg1 bool) (api.NodeStatus, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "NodeStatus", arg0, arg1)
|
||||
ret0, _ := ret[0].(api.NodeStatus)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// NodeStatus indicates an expected call of NodeStatus
|
||||
func (mr *MockFullNodeMockRecorder) NodeStatus(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NodeStatus", reflect.TypeOf((*MockFullNode)(nil).NodeStatus), arg0, arg1)
|
||||
}
|
||||
|
||||
// PaychAllocateLane mocks base method
|
||||
func (m *MockFullNode) PaychAllocateLane(arg0 context.Context, arg1 address.Address) (uint64, error) {
|
||||
m.ctrl.T.Helper()
|
||||
|
136
api/proxy_gen.go
136
api/proxy_gen.go
@ -235,6 +235,12 @@ type FullNodeStruct struct {
|
||||
|
||||
MpoolBatchPushUntrusted func(p0 context.Context, p1 []*types.SignedMessage) ([]cid.Cid, error) `perm:"write"`
|
||||
|
||||
MpoolCheckMessages func(p0 context.Context, p1 []*MessagePrototype) ([][]MessageCheckStatus, error) `perm:"read"`
|
||||
|
||||
MpoolCheckPendingMessages func(p0 context.Context, p1 address.Address) ([][]MessageCheckStatus, error) `perm:"read"`
|
||||
|
||||
MpoolCheckReplaceMessages func(p0 context.Context, p1 []*types.Message) ([][]MessageCheckStatus, error) `perm:"read"`
|
||||
|
||||
MpoolClear func(p0 context.Context, p1 bool) error `perm:"write"`
|
||||
|
||||
MpoolGetConfig func(p0 context.Context) (*types.MpoolConfig, error) `perm:"read"`
|
||||
@ -255,19 +261,19 @@ type FullNodeStruct struct {
|
||||
|
||||
MpoolSub func(p0 context.Context) (<-chan MpoolUpdate, error) `perm:"read"`
|
||||
|
||||
MsigAddApprove func(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 bool) (cid.Cid, error) `perm:"sign"`
|
||||
MsigAddApprove func(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 bool) (*MessagePrototype, error) `perm:"sign"`
|
||||
|
||||
MsigAddCancel func(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 bool) (cid.Cid, error) `perm:"sign"`
|
||||
MsigAddCancel func(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 bool) (*MessagePrototype, error) `perm:"sign"`
|
||||
|
||||
MsigAddPropose func(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (cid.Cid, error) `perm:"sign"`
|
||||
MsigAddPropose func(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (*MessagePrototype, error) `perm:"sign"`
|
||||
|
||||
MsigApprove func(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address) (cid.Cid, error) `perm:"sign"`
|
||||
MsigApprove func(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address) (*MessagePrototype, error) `perm:"sign"`
|
||||
|
||||
MsigApproveTxnHash func(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 address.Address, p5 types.BigInt, p6 address.Address, p7 uint64, p8 []byte) (cid.Cid, error) `perm:"sign"`
|
||||
MsigApproveTxnHash func(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 address.Address, p5 types.BigInt, p6 address.Address, p7 uint64, p8 []byte) (*MessagePrototype, error) `perm:"sign"`
|
||||
|
||||
MsigCancel func(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 types.BigInt, p5 address.Address, p6 uint64, p7 []byte) (cid.Cid, error) `perm:"sign"`
|
||||
MsigCancel func(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 types.BigInt, p5 address.Address, p6 uint64, p7 []byte) (*MessagePrototype, error) `perm:"sign"`
|
||||
|
||||
MsigCreate func(p0 context.Context, p1 uint64, p2 []address.Address, p3 abi.ChainEpoch, p4 types.BigInt, p5 address.Address, p6 types.BigInt) (cid.Cid, error) `perm:"sign"`
|
||||
MsigCreate func(p0 context.Context, p1 uint64, p2 []address.Address, p3 abi.ChainEpoch, p4 types.BigInt, p5 address.Address, p6 types.BigInt) (*MessagePrototype, error) `perm:"sign"`
|
||||
|
||||
MsigGetAvailableBalance func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) `perm:"read"`
|
||||
|
||||
@ -277,15 +283,17 @@ type FullNodeStruct struct {
|
||||
|
||||
MsigGetVestingSchedule func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MsigVesting, error) `perm:"read"`
|
||||
|
||||
MsigPropose func(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt, p4 address.Address, p5 uint64, p6 []byte) (cid.Cid, error) `perm:"sign"`
|
||||
MsigPropose func(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt, p4 address.Address, p5 uint64, p6 []byte) (*MessagePrototype, error) `perm:"sign"`
|
||||
|
||||
MsigRemoveSigner func(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (cid.Cid, error) `perm:"sign"`
|
||||
MsigRemoveSigner func(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (*MessagePrototype, error) `perm:"sign"`
|
||||
|
||||
MsigSwapApprove func(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 address.Address) (cid.Cid, error) `perm:"sign"`
|
||||
MsigSwapApprove func(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 address.Address) (*MessagePrototype, error) `perm:"sign"`
|
||||
|
||||
MsigSwapCancel func(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address) (cid.Cid, error) `perm:"sign"`
|
||||
MsigSwapCancel func(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address) (*MessagePrototype, error) `perm:"sign"`
|
||||
|
||||
MsigSwapPropose func(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 address.Address) (cid.Cid, error) `perm:"sign"`
|
||||
MsigSwapPropose func(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 address.Address) (*MessagePrototype, error) `perm:"sign"`
|
||||
|
||||
NodeStatus func(p0 context.Context, p1 bool) (NodeStatus, error) `perm:"read"`
|
||||
|
||||
PaychAllocateLane func(p0 context.Context, p1 address.Address) (uint64, error) `perm:"sign"`
|
||||
|
||||
@ -1507,6 +1515,30 @@ func (s *FullNodeStub) MpoolBatchPushUntrusted(p0 context.Context, p1 []*types.S
|
||||
return *new([]cid.Cid), xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) MpoolCheckMessages(p0 context.Context, p1 []*MessagePrototype) ([][]MessageCheckStatus, error) {
|
||||
return s.Internal.MpoolCheckMessages(p0, p1)
|
||||
}
|
||||
|
||||
func (s *FullNodeStub) MpoolCheckMessages(p0 context.Context, p1 []*MessagePrototype) ([][]MessageCheckStatus, error) {
|
||||
return *new([][]MessageCheckStatus), xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) MpoolCheckPendingMessages(p0 context.Context, p1 address.Address) ([][]MessageCheckStatus, error) {
|
||||
return s.Internal.MpoolCheckPendingMessages(p0, p1)
|
||||
}
|
||||
|
||||
func (s *FullNodeStub) MpoolCheckPendingMessages(p0 context.Context, p1 address.Address) ([][]MessageCheckStatus, error) {
|
||||
return *new([][]MessageCheckStatus), xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) MpoolCheckReplaceMessages(p0 context.Context, p1 []*types.Message) ([][]MessageCheckStatus, error) {
|
||||
return s.Internal.MpoolCheckReplaceMessages(p0, p1)
|
||||
}
|
||||
|
||||
func (s *FullNodeStub) MpoolCheckReplaceMessages(p0 context.Context, p1 []*types.Message) ([][]MessageCheckStatus, error) {
|
||||
return *new([][]MessageCheckStatus), xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) MpoolClear(p0 context.Context, p1 bool) error {
|
||||
return s.Internal.MpoolClear(p0, p1)
|
||||
}
|
||||
@ -1587,60 +1619,60 @@ func (s *FullNodeStub) MpoolSub(p0 context.Context) (<-chan MpoolUpdate, error)
|
||||
return nil, xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) MsigAddApprove(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 bool) (cid.Cid, error) {
|
||||
func (s *FullNodeStruct) MsigAddApprove(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 bool) (*MessagePrototype, error) {
|
||||
return s.Internal.MsigAddApprove(p0, p1, p2, p3, p4, p5, p6)
|
||||
}
|
||||
|
||||
func (s *FullNodeStub) MsigAddApprove(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 bool) (cid.Cid, error) {
|
||||
return *new(cid.Cid), xerrors.New("method not supported")
|
||||
func (s *FullNodeStub) MsigAddApprove(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 bool) (*MessagePrototype, error) {
|
||||
return nil, xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) MsigAddCancel(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 bool) (cid.Cid, error) {
|
||||
func (s *FullNodeStruct) MsigAddCancel(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 bool) (*MessagePrototype, error) {
|
||||
return s.Internal.MsigAddCancel(p0, p1, p2, p3, p4, p5)
|
||||
}
|
||||
|
||||
func (s *FullNodeStub) MsigAddCancel(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 bool) (cid.Cid, error) {
|
||||
return *new(cid.Cid), xerrors.New("method not supported")
|
||||
func (s *FullNodeStub) MsigAddCancel(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 bool) (*MessagePrototype, error) {
|
||||
return nil, xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) MsigAddPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (cid.Cid, error) {
|
||||
func (s *FullNodeStruct) MsigAddPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (*MessagePrototype, error) {
|
||||
return s.Internal.MsigAddPropose(p0, p1, p2, p3, p4)
|
||||
}
|
||||
|
||||
func (s *FullNodeStub) MsigAddPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (cid.Cid, error) {
|
||||
return *new(cid.Cid), xerrors.New("method not supported")
|
||||
func (s *FullNodeStub) MsigAddPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (*MessagePrototype, error) {
|
||||
return nil, xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) MsigApprove(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address) (cid.Cid, error) {
|
||||
func (s *FullNodeStruct) MsigApprove(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address) (*MessagePrototype, error) {
|
||||
return s.Internal.MsigApprove(p0, p1, p2, p3)
|
||||
}
|
||||
|
||||
func (s *FullNodeStub) MsigApprove(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address) (cid.Cid, error) {
|
||||
return *new(cid.Cid), xerrors.New("method not supported")
|
||||
func (s *FullNodeStub) MsigApprove(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address) (*MessagePrototype, error) {
|
||||
return nil, xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) MsigApproveTxnHash(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 address.Address, p5 types.BigInt, p6 address.Address, p7 uint64, p8 []byte) (cid.Cid, error) {
|
||||
func (s *FullNodeStruct) MsigApproveTxnHash(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 address.Address, p5 types.BigInt, p6 address.Address, p7 uint64, p8 []byte) (*MessagePrototype, error) {
|
||||
return s.Internal.MsigApproveTxnHash(p0, p1, p2, p3, p4, p5, p6, p7, p8)
|
||||
}
|
||||
|
||||
func (s *FullNodeStub) MsigApproveTxnHash(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 address.Address, p5 types.BigInt, p6 address.Address, p7 uint64, p8 []byte) (cid.Cid, error) {
|
||||
return *new(cid.Cid), xerrors.New("method not supported")
|
||||
func (s *FullNodeStub) MsigApproveTxnHash(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 address.Address, p5 types.BigInt, p6 address.Address, p7 uint64, p8 []byte) (*MessagePrototype, error) {
|
||||
return nil, xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) MsigCancel(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 types.BigInt, p5 address.Address, p6 uint64, p7 []byte) (cid.Cid, error) {
|
||||
func (s *FullNodeStruct) MsigCancel(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 types.BigInt, p5 address.Address, p6 uint64, p7 []byte) (*MessagePrototype, error) {
|
||||
return s.Internal.MsigCancel(p0, p1, p2, p3, p4, p5, p6, p7)
|
||||
}
|
||||
|
||||
func (s *FullNodeStub) MsigCancel(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 types.BigInt, p5 address.Address, p6 uint64, p7 []byte) (cid.Cid, error) {
|
||||
return *new(cid.Cid), xerrors.New("method not supported")
|
||||
func (s *FullNodeStub) MsigCancel(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 types.BigInt, p5 address.Address, p6 uint64, p7 []byte) (*MessagePrototype, error) {
|
||||
return nil, xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) MsigCreate(p0 context.Context, p1 uint64, p2 []address.Address, p3 abi.ChainEpoch, p4 types.BigInt, p5 address.Address, p6 types.BigInt) (cid.Cid, error) {
|
||||
func (s *FullNodeStruct) MsigCreate(p0 context.Context, p1 uint64, p2 []address.Address, p3 abi.ChainEpoch, p4 types.BigInt, p5 address.Address, p6 types.BigInt) (*MessagePrototype, error) {
|
||||
return s.Internal.MsigCreate(p0, p1, p2, p3, p4, p5, p6)
|
||||
}
|
||||
|
||||
func (s *FullNodeStub) MsigCreate(p0 context.Context, p1 uint64, p2 []address.Address, p3 abi.ChainEpoch, p4 types.BigInt, p5 address.Address, p6 types.BigInt) (cid.Cid, error) {
|
||||
return *new(cid.Cid), xerrors.New("method not supported")
|
||||
func (s *FullNodeStub) MsigCreate(p0 context.Context, p1 uint64, p2 []address.Address, p3 abi.ChainEpoch, p4 types.BigInt, p5 address.Address, p6 types.BigInt) (*MessagePrototype, error) {
|
||||
return nil, xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) MsigGetAvailableBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) {
|
||||
@ -1675,44 +1707,52 @@ func (s *FullNodeStub) MsigGetVestingSchedule(p0 context.Context, p1 address.Add
|
||||
return *new(MsigVesting), xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) MsigPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt, p4 address.Address, p5 uint64, p6 []byte) (cid.Cid, error) {
|
||||
func (s *FullNodeStruct) MsigPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt, p4 address.Address, p5 uint64, p6 []byte) (*MessagePrototype, error) {
|
||||
return s.Internal.MsigPropose(p0, p1, p2, p3, p4, p5, p6)
|
||||
}
|
||||
|
||||
func (s *FullNodeStub) MsigPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt, p4 address.Address, p5 uint64, p6 []byte) (cid.Cid, error) {
|
||||
return *new(cid.Cid), xerrors.New("method not supported")
|
||||
func (s *FullNodeStub) MsigPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt, p4 address.Address, p5 uint64, p6 []byte) (*MessagePrototype, error) {
|
||||
return nil, xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) MsigRemoveSigner(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (cid.Cid, error) {
|
||||
func (s *FullNodeStruct) MsigRemoveSigner(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (*MessagePrototype, error) {
|
||||
return s.Internal.MsigRemoveSigner(p0, p1, p2, p3, p4)
|
||||
}
|
||||
|
||||
func (s *FullNodeStub) MsigRemoveSigner(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (cid.Cid, error) {
|
||||
return *new(cid.Cid), xerrors.New("method not supported")
|
||||
func (s *FullNodeStub) MsigRemoveSigner(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (*MessagePrototype, error) {
|
||||
return nil, xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) MsigSwapApprove(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 address.Address) (cid.Cid, error) {
|
||||
func (s *FullNodeStruct) MsigSwapApprove(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 address.Address) (*MessagePrototype, error) {
|
||||
return s.Internal.MsigSwapApprove(p0, p1, p2, p3, p4, p5, p6)
|
||||
}
|
||||
|
||||
func (s *FullNodeStub) MsigSwapApprove(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 address.Address) (cid.Cid, error) {
|
||||
return *new(cid.Cid), xerrors.New("method not supported")
|
||||
func (s *FullNodeStub) MsigSwapApprove(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 address.Address) (*MessagePrototype, error) {
|
||||
return nil, xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) MsigSwapCancel(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address) (cid.Cid, error) {
|
||||
func (s *FullNodeStruct) MsigSwapCancel(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address) (*MessagePrototype, error) {
|
||||
return s.Internal.MsigSwapCancel(p0, p1, p2, p3, p4, p5)
|
||||
}
|
||||
|
||||
func (s *FullNodeStub) MsigSwapCancel(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address) (cid.Cid, error) {
|
||||
return *new(cid.Cid), xerrors.New("method not supported")
|
||||
func (s *FullNodeStub) MsigSwapCancel(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address) (*MessagePrototype, error) {
|
||||
return nil, xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) MsigSwapPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 address.Address) (cid.Cid, error) {
|
||||
func (s *FullNodeStruct) MsigSwapPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 address.Address) (*MessagePrototype, error) {
|
||||
return s.Internal.MsigSwapPropose(p0, p1, p2, p3, p4)
|
||||
}
|
||||
|
||||
func (s *FullNodeStub) MsigSwapPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 address.Address) (cid.Cid, error) {
|
||||
return *new(cid.Cid), xerrors.New("method not supported")
|
||||
func (s *FullNodeStub) MsigSwapPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 address.Address) (*MessagePrototype, error) {
|
||||
return nil, xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) NodeStatus(p0 context.Context, p1 bool) (NodeStatus, error) {
|
||||
return s.Internal.NodeStatus(p0, p1)
|
||||
}
|
||||
|
||||
func (s *FullNodeStub) NodeStatus(p0 context.Context, p1 bool) (NodeStatus, error) {
|
||||
return *new(NodeStatus), xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) PaychAllocateLane(p0 context.Context, p1 address.Address) (uint64, error) {
|
||||
|
@ -29,7 +29,7 @@ func SendFunds(ctx context.Context, t *testing.T, sender TestNode, addr address.
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
res, err := sender.StateWaitMsg(ctx, sm.Cid(), 1, lapi.LookbackNoLimit, true)
|
||||
res, err := sender.StateWaitMsg(ctx, sm.Cid(), 3, lapi.LookbackNoLimit, true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
60
api/types.go
60
api/types.go
@ -5,6 +5,8 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
|
||||
datatransfer "github.com/filecoin-project/go-data-transfer"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/ipfs/go-cid"
|
||||
@ -116,3 +118,61 @@ type ConnMgrInfo struct {
|
||||
Tags map[string]int
|
||||
Conns map[string]time.Time
|
||||
}
|
||||
|
||||
type NodeStatus struct {
|
||||
SyncStatus NodeSyncStatus
|
||||
PeerStatus NodePeerStatus
|
||||
ChainStatus NodeChainStatus
|
||||
}
|
||||
|
||||
type NodeSyncStatus struct {
|
||||
Epoch uint64
|
||||
Behind uint64
|
||||
}
|
||||
|
||||
type NodePeerStatus struct {
|
||||
PeersToPublishMsgs int
|
||||
PeersToPublishBlocks int
|
||||
}
|
||||
|
||||
type NodeChainStatus struct {
|
||||
BlocksPerTipsetLast100 float64
|
||||
BlocksPerTipsetLastFinality float64
|
||||
}
|
||||
|
||||
type CheckStatusCode int
|
||||
|
||||
//go:generate go run golang.org/x/tools/cmd/stringer -type=CheckStatusCode -trimprefix=CheckStatus
|
||||
const (
|
||||
_ CheckStatusCode = iota
|
||||
// Message Checks
|
||||
CheckStatusMessageSerialize
|
||||
CheckStatusMessageSize
|
||||
CheckStatusMessageValidity
|
||||
CheckStatusMessageMinGas
|
||||
CheckStatusMessageMinBaseFee
|
||||
CheckStatusMessageBaseFee
|
||||
CheckStatusMessageBaseFeeLowerBound
|
||||
CheckStatusMessageBaseFeeUpperBound
|
||||
CheckStatusMessageGetStateNonce
|
||||
CheckStatusMessageNonce
|
||||
CheckStatusMessageGetStateBalance
|
||||
CheckStatusMessageBalance
|
||||
)
|
||||
|
||||
type CheckStatus struct {
|
||||
Code CheckStatusCode
|
||||
OK bool
|
||||
Err string
|
||||
Hint map[string]interface{}
|
||||
}
|
||||
|
||||
type MessageCheckStatus struct {
|
||||
Cid cid.Cid
|
||||
CheckStatus
|
||||
}
|
||||
|
||||
type MessagePrototype struct {
|
||||
Message types.Message
|
||||
ValidNonce bool
|
||||
}
|
||||
|
@ -3,7 +3,9 @@ package v0api
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
|
||||
@ -57,4 +59,129 @@ func (w *WrapperV1Full) Version(ctx context.Context) (api.APIVersion, error) {
|
||||
return ver, nil
|
||||
}
|
||||
|
||||
func (w *WrapperV1Full) executePrototype(ctx context.Context, p *api.MessagePrototype) (cid.Cid, error) {
|
||||
sm, err := w.FullNode.MpoolPushMessage(ctx, &p.Message, nil)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("pushing message: %w", err)
|
||||
}
|
||||
|
||||
return sm.Cid(), nil
|
||||
}
|
||||
func (w *WrapperV1Full) MsigCreate(ctx context.Context, req uint64, addrs []address.Address, duration abi.ChainEpoch, val types.BigInt, src address.Address, gp types.BigInt) (cid.Cid, error) {
|
||||
|
||||
p, err := w.FullNode.MsigCreate(ctx, req, addrs, duration, val, src, gp)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("creating prototype: %w", err)
|
||||
}
|
||||
|
||||
return w.executePrototype(ctx, p)
|
||||
}
|
||||
|
||||
func (w *WrapperV1Full) MsigPropose(ctx context.Context, msig address.Address, to address.Address, amt types.BigInt, src address.Address, method uint64, params []byte) (cid.Cid, error) {
|
||||
|
||||
p, err := w.FullNode.MsigPropose(ctx, msig, to, amt, src, method, params)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("creating prototype: %w", err)
|
||||
}
|
||||
|
||||
return w.executePrototype(ctx, p)
|
||||
}
|
||||
func (w *WrapperV1Full) MsigApprove(ctx context.Context, msig address.Address, txID uint64, src address.Address) (cid.Cid, error) {
|
||||
|
||||
p, err := w.FullNode.MsigApprove(ctx, msig, txID, src)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("creating prototype: %w", err)
|
||||
}
|
||||
|
||||
return w.executePrototype(ctx, p)
|
||||
}
|
||||
|
||||
func (w *WrapperV1Full) MsigApproveTxnHash(ctx context.Context, msig address.Address, txID uint64, proposer address.Address, to address.Address, amt types.BigInt, src address.Address, method uint64, params []byte) (cid.Cid, error) {
|
||||
p, err := w.FullNode.MsigApproveTxnHash(ctx, msig, txID, proposer, to, amt, src, method, params)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("creating prototype: %w", err)
|
||||
}
|
||||
|
||||
return w.executePrototype(ctx, p)
|
||||
}
|
||||
|
||||
func (w *WrapperV1Full) MsigCancel(ctx context.Context, msig address.Address, txID uint64, to address.Address, amt types.BigInt, src address.Address, method uint64, params []byte) (cid.Cid, error) {
|
||||
p, err := w.FullNode.MsigCancel(ctx, msig, txID, to, amt, src, method, params)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("creating prototype: %w", err)
|
||||
}
|
||||
|
||||
return w.executePrototype(ctx, p)
|
||||
}
|
||||
|
||||
func (w *WrapperV1Full) MsigAddPropose(ctx context.Context, msig address.Address, src address.Address, newAdd address.Address, inc bool) (cid.Cid, error) {
|
||||
|
||||
p, err := w.FullNode.MsigAddPropose(ctx, msig, src, newAdd, inc)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("creating prototype: %w", err)
|
||||
}
|
||||
|
||||
return w.executePrototype(ctx, p)
|
||||
}
|
||||
|
||||
func (w *WrapperV1Full) MsigAddApprove(ctx context.Context, msig address.Address, src address.Address, txID uint64, proposer address.Address, newAdd address.Address, inc bool) (cid.Cid, error) {
|
||||
|
||||
p, err := w.FullNode.MsigAddApprove(ctx, msig, src, txID, proposer, newAdd, inc)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("creating prototype: %w", err)
|
||||
}
|
||||
|
||||
return w.executePrototype(ctx, p)
|
||||
}
|
||||
|
||||
func (w *WrapperV1Full) MsigAddCancel(ctx context.Context, msig address.Address, src address.Address, txID uint64, newAdd address.Address, inc bool) (cid.Cid, error) {
|
||||
|
||||
p, err := w.FullNode.MsigAddCancel(ctx, msig, src, txID, newAdd, inc)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("creating prototype: %w", err)
|
||||
}
|
||||
|
||||
return w.executePrototype(ctx, p)
|
||||
}
|
||||
|
||||
func (w *WrapperV1Full) MsigSwapPropose(ctx context.Context, msig address.Address, src address.Address, oldAdd address.Address, newAdd address.Address) (cid.Cid, error) {
|
||||
|
||||
p, err := w.FullNode.MsigSwapPropose(ctx, msig, src, oldAdd, newAdd)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("creating prototype: %w", err)
|
||||
}
|
||||
|
||||
return w.executePrototype(ctx, p)
|
||||
}
|
||||
|
||||
func (w *WrapperV1Full) MsigSwapApprove(ctx context.Context, msig address.Address, src address.Address, txID uint64, proposer address.Address, oldAdd address.Address, newAdd address.Address) (cid.Cid, error) {
|
||||
|
||||
p, err := w.FullNode.MsigSwapApprove(ctx, msig, src, txID, proposer, oldAdd, newAdd)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("creating prototype: %w", err)
|
||||
}
|
||||
|
||||
return w.executePrototype(ctx, p)
|
||||
}
|
||||
|
||||
func (w *WrapperV1Full) MsigSwapCancel(ctx context.Context, msig address.Address, src address.Address, txID uint64, oldAdd address.Address, newAdd address.Address) (cid.Cid, error) {
|
||||
|
||||
p, err := w.FullNode.MsigSwapCancel(ctx, msig, src, txID, oldAdd, newAdd)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("creating prototype: %w", err)
|
||||
}
|
||||
|
||||
return w.executePrototype(ctx, p)
|
||||
}
|
||||
|
||||
func (w *WrapperV1Full) MsigRemoveSigner(ctx context.Context, msig address.Address, proposer address.Address, toRemove address.Address, decrease bool) (cid.Cid, error) {
|
||||
|
||||
p, err := w.FullNode.MsigRemoveSigner(ctx, msig, proposer, toRemove, decrease)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("creating prototype: %w", err)
|
||||
}
|
||||
|
||||
return w.executePrototype(ctx, p)
|
||||
}
|
||||
|
||||
var _ FullNode = &WrapperV1Full{}
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -6,4 +6,5 @@ import (
|
||||
_ "github.com/GeertJohan/go.rice/rice"
|
||||
_ "github.com/golang/mock/mockgen"
|
||||
_ "github.com/whyrusleeping/bencher"
|
||||
_ "golang.org/x/tools/cmd/stringer"
|
||||
)
|
||||
|
431
chain/messagepool/check.go
Normal file
431
chain/messagepool/check.go
Normal file
@ -0,0 +1,431 @@
|
||||
package messagepool
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
stdbig "math/big"
|
||||
"sort"
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/chain/vm"
|
||||
)
|
||||
|
||||
var baseFeeUpperBoundFactor = types.NewInt(10)
|
||||
|
||||
// CheckMessages performs a set of logic checks for a list of messages, prior to submitting it to the mpool
|
||||
func (mp *MessagePool) CheckMessages(protos []*api.MessagePrototype) ([][]api.MessageCheckStatus, error) {
|
||||
flex := make([]bool, len(protos))
|
||||
msgs := make([]*types.Message, len(protos))
|
||||
for i, p := range protos {
|
||||
flex[i] = !p.ValidNonce
|
||||
msgs[i] = &p.Message
|
||||
}
|
||||
return mp.checkMessages(msgs, false, flex)
|
||||
}
|
||||
|
||||
// CheckPendingMessages performs a set of logical sets for all messages pending from a given actor
|
||||
func (mp *MessagePool) CheckPendingMessages(from address.Address) ([][]api.MessageCheckStatus, error) {
|
||||
var msgs []*types.Message
|
||||
mp.lk.Lock()
|
||||
mset, ok := mp.pending[from]
|
||||
if ok {
|
||||
for _, sm := range mset.msgs {
|
||||
msgs = append(msgs, &sm.Message)
|
||||
}
|
||||
}
|
||||
mp.lk.Unlock()
|
||||
|
||||
if len(msgs) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
sort.Slice(msgs, func(i, j int) bool {
|
||||
return msgs[i].Nonce < msgs[j].Nonce
|
||||
})
|
||||
|
||||
return mp.checkMessages(msgs, true, nil)
|
||||
}
|
||||
|
||||
// CheckReplaceMessages performs a set of logical checks for related messages while performing a
|
||||
// replacement.
|
||||
func (mp *MessagePool) CheckReplaceMessages(replace []*types.Message) ([][]api.MessageCheckStatus, error) {
|
||||
msgMap := make(map[address.Address]map[uint64]*types.Message)
|
||||
count := 0
|
||||
|
||||
mp.lk.Lock()
|
||||
for _, m := range replace {
|
||||
mmap, ok := msgMap[m.From]
|
||||
if !ok {
|
||||
mmap = make(map[uint64]*types.Message)
|
||||
msgMap[m.From] = mmap
|
||||
mset, ok := mp.pending[m.From]
|
||||
if ok {
|
||||
count += len(mset.msgs)
|
||||
for _, sm := range mset.msgs {
|
||||
mmap[sm.Message.Nonce] = &sm.Message
|
||||
}
|
||||
} else {
|
||||
count++
|
||||
}
|
||||
}
|
||||
mmap[m.Nonce] = m
|
||||
}
|
||||
mp.lk.Unlock()
|
||||
|
||||
msgs := make([]*types.Message, 0, count)
|
||||
start := 0
|
||||
for _, mmap := range msgMap {
|
||||
end := start + len(mmap)
|
||||
|
||||
for _, m := range mmap {
|
||||
msgs = append(msgs, m)
|
||||
}
|
||||
|
||||
sort.Slice(msgs[start:end], func(i, j int) bool {
|
||||
return msgs[start+i].Nonce < msgs[start+j].Nonce
|
||||
})
|
||||
|
||||
start = end
|
||||
}
|
||||
|
||||
return mp.checkMessages(msgs, true, nil)
|
||||
}
|
||||
|
||||
// flexibleNonces should be either nil or of len(msgs), it signifies that message at given index
|
||||
// has non-determied nonce at this point
|
||||
func (mp *MessagePool) checkMessages(msgs []*types.Message, interned bool, flexibleNonces []bool) (result [][]api.MessageCheckStatus, err error) {
|
||||
if mp.api.IsLite() {
|
||||
return nil, nil
|
||||
}
|
||||
mp.curTsLk.Lock()
|
||||
curTs := mp.curTs
|
||||
mp.curTsLk.Unlock()
|
||||
|
||||
epoch := curTs.Height()
|
||||
|
||||
var baseFee big.Int
|
||||
if len(curTs.Blocks()) > 0 {
|
||||
baseFee = curTs.Blocks()[0].ParentBaseFee
|
||||
} else {
|
||||
baseFee, err = mp.api.ChainComputeBaseFee(context.Background(), curTs)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("error computing basefee: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
baseFeeLowerBound := getBaseFeeLowerBound(baseFee, baseFeeLowerBoundFactor)
|
||||
baseFeeUpperBound := types.BigMul(baseFee, baseFeeUpperBoundFactor)
|
||||
|
||||
type actorState struct {
|
||||
nextNonce uint64
|
||||
requiredFunds *stdbig.Int
|
||||
}
|
||||
|
||||
state := make(map[address.Address]*actorState)
|
||||
balances := make(map[address.Address]big.Int)
|
||||
|
||||
result = make([][]api.MessageCheckStatus, len(msgs))
|
||||
|
||||
for i, m := range msgs {
|
||||
// pre-check: actor nonce
|
||||
check := api.MessageCheckStatus{
|
||||
Cid: m.Cid(),
|
||||
CheckStatus: api.CheckStatus{
|
||||
Code: api.CheckStatusMessageGetStateNonce,
|
||||
},
|
||||
}
|
||||
|
||||
st, ok := state[m.From]
|
||||
if !ok {
|
||||
mp.lk.Lock()
|
||||
mset, ok := mp.pending[m.From]
|
||||
if ok && !interned {
|
||||
st = &actorState{nextNonce: mset.nextNonce, requiredFunds: mset.requiredFunds}
|
||||
for _, m := range mset.msgs {
|
||||
st.requiredFunds = new(stdbig.Int).Add(st.requiredFunds, m.Message.Value.Int)
|
||||
}
|
||||
state[m.From] = st
|
||||
mp.lk.Unlock()
|
||||
|
||||
check.OK = true
|
||||
check.Hint = map[string]interface{}{
|
||||
"nonce": st.nextNonce,
|
||||
}
|
||||
} else {
|
||||
mp.lk.Unlock()
|
||||
|
||||
stateNonce, err := mp.getStateNonce(m.From, curTs)
|
||||
if err != nil {
|
||||
check.OK = false
|
||||
check.Err = fmt.Sprintf("error retrieving state nonce: %s", err.Error())
|
||||
} else {
|
||||
check.OK = true
|
||||
check.Hint = map[string]interface{}{
|
||||
"nonce": stateNonce,
|
||||
}
|
||||
}
|
||||
|
||||
st = &actorState{nextNonce: stateNonce, requiredFunds: new(stdbig.Int)}
|
||||
state[m.From] = st
|
||||
}
|
||||
} else {
|
||||
check.OK = true
|
||||
}
|
||||
|
||||
result[i] = append(result[i], check)
|
||||
if !check.OK {
|
||||
continue
|
||||
}
|
||||
|
||||
// pre-check: actor balance
|
||||
check = api.MessageCheckStatus{
|
||||
Cid: m.Cid(),
|
||||
CheckStatus: api.CheckStatus{
|
||||
Code: api.CheckStatusMessageGetStateBalance,
|
||||
},
|
||||
}
|
||||
|
||||
balance, ok := balances[m.From]
|
||||
if !ok {
|
||||
balance, err = mp.getStateBalance(m.From, curTs)
|
||||
if err != nil {
|
||||
check.OK = false
|
||||
check.Err = fmt.Sprintf("error retrieving state balance: %s", err)
|
||||
} else {
|
||||
check.OK = true
|
||||
check.Hint = map[string]interface{}{
|
||||
"balance": balance,
|
||||
}
|
||||
}
|
||||
|
||||
balances[m.From] = balance
|
||||
} else {
|
||||
check.OK = true
|
||||
check.Hint = map[string]interface{}{
|
||||
"balance": balance,
|
||||
}
|
||||
}
|
||||
|
||||
result[i] = append(result[i], check)
|
||||
if !check.OK {
|
||||
continue
|
||||
}
|
||||
|
||||
// 1. Serialization
|
||||
check = api.MessageCheckStatus{
|
||||
Cid: m.Cid(),
|
||||
CheckStatus: api.CheckStatus{
|
||||
Code: api.CheckStatusMessageSerialize,
|
||||
},
|
||||
}
|
||||
|
||||
bytes, err := m.Serialize()
|
||||
if err != nil {
|
||||
check.OK = false
|
||||
check.Err = err.Error()
|
||||
} else {
|
||||
check.OK = true
|
||||
}
|
||||
|
||||
result[i] = append(result[i], check)
|
||||
|
||||
// 2. Message size
|
||||
check = api.MessageCheckStatus{
|
||||
Cid: m.Cid(),
|
||||
CheckStatus: api.CheckStatus{
|
||||
Code: api.CheckStatusMessageSize,
|
||||
},
|
||||
}
|
||||
|
||||
if len(bytes) > 32*1024-128 { // 128 bytes to account for signature size
|
||||
check.OK = false
|
||||
check.Err = "message too big"
|
||||
} else {
|
||||
check.OK = true
|
||||
}
|
||||
|
||||
result[i] = append(result[i], check)
|
||||
|
||||
// 3. Syntactic validation
|
||||
check = api.MessageCheckStatus{
|
||||
Cid: m.Cid(),
|
||||
CheckStatus: api.CheckStatus{
|
||||
Code: api.CheckStatusMessageValidity,
|
||||
},
|
||||
}
|
||||
|
||||
if err := m.ValidForBlockInclusion(0, build.NewestNetworkVersion); err != nil {
|
||||
check.OK = false
|
||||
check.Err = fmt.Sprintf("syntactically invalid message: %s", err.Error())
|
||||
} else {
|
||||
check.OK = true
|
||||
}
|
||||
|
||||
result[i] = append(result[i], check)
|
||||
if !check.OK {
|
||||
// skip remaining checks if it is a syntatically invalid message
|
||||
continue
|
||||
}
|
||||
|
||||
// gas checks
|
||||
|
||||
// 4. Min Gas
|
||||
minGas := vm.PricelistByEpoch(epoch).OnChainMessage(m.ChainLength())
|
||||
|
||||
check = api.MessageCheckStatus{
|
||||
Cid: m.Cid(),
|
||||
CheckStatus: api.CheckStatus{
|
||||
Code: api.CheckStatusMessageMinGas,
|
||||
Hint: map[string]interface{}{
|
||||
"minGas": minGas,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if m.GasLimit < minGas.Total() {
|
||||
check.OK = false
|
||||
check.Err = "GasLimit less than epoch minimum gas"
|
||||
} else {
|
||||
check.OK = true
|
||||
}
|
||||
|
||||
result[i] = append(result[i], check)
|
||||
|
||||
// 5. Min Base Fee
|
||||
check = api.MessageCheckStatus{
|
||||
Cid: m.Cid(),
|
||||
CheckStatus: api.CheckStatus{
|
||||
Code: api.CheckStatusMessageMinBaseFee,
|
||||
},
|
||||
}
|
||||
|
||||
if m.GasFeeCap.LessThan(minimumBaseFee) {
|
||||
check.OK = false
|
||||
check.Err = "GasFeeCap less than minimum base fee"
|
||||
} else {
|
||||
check.OK = true
|
||||
}
|
||||
|
||||
result[i] = append(result[i], check)
|
||||
if !check.OK {
|
||||
goto checkState
|
||||
}
|
||||
|
||||
// 6. Base Fee
|
||||
check = api.MessageCheckStatus{
|
||||
Cid: m.Cid(),
|
||||
CheckStatus: api.CheckStatus{
|
||||
Code: api.CheckStatusMessageBaseFee,
|
||||
Hint: map[string]interface{}{
|
||||
"baseFee": baseFee,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if m.GasFeeCap.LessThan(baseFee) {
|
||||
check.OK = false
|
||||
check.Err = "GasFeeCap less than current base fee"
|
||||
} else {
|
||||
check.OK = true
|
||||
}
|
||||
|
||||
result[i] = append(result[i], check)
|
||||
|
||||
// 7. Base Fee lower bound
|
||||
check = api.MessageCheckStatus{
|
||||
Cid: m.Cid(),
|
||||
CheckStatus: api.CheckStatus{
|
||||
Code: api.CheckStatusMessageBaseFeeLowerBound,
|
||||
Hint: map[string]interface{}{
|
||||
"baseFeeLowerBound": baseFeeLowerBound,
|
||||
"baseFee": baseFee,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if m.GasFeeCap.LessThan(baseFeeLowerBound) {
|
||||
check.OK = false
|
||||
check.Err = "GasFeeCap less than base fee lower bound for inclusion in next 20 epochs"
|
||||
} else {
|
||||
check.OK = true
|
||||
}
|
||||
|
||||
result[i] = append(result[i], check)
|
||||
|
||||
// 8. Base Fee upper bound
|
||||
check = api.MessageCheckStatus{
|
||||
Cid: m.Cid(),
|
||||
CheckStatus: api.CheckStatus{
|
||||
Code: api.CheckStatusMessageBaseFeeUpperBound,
|
||||
Hint: map[string]interface{}{
|
||||
"baseFeeUpperBound": baseFeeUpperBound,
|
||||
"baseFee": baseFee,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if m.GasFeeCap.LessThan(baseFeeUpperBound) {
|
||||
check.OK = true // on purpose, the checks is more of a warning
|
||||
check.Err = "GasFeeCap less than base fee upper bound for inclusion in next 20 epochs"
|
||||
} else {
|
||||
check.OK = true
|
||||
}
|
||||
|
||||
result[i] = append(result[i], check)
|
||||
|
||||
// stateful checks
|
||||
checkState:
|
||||
// 9. Message Nonce
|
||||
check = api.MessageCheckStatus{
|
||||
Cid: m.Cid(),
|
||||
CheckStatus: api.CheckStatus{
|
||||
Code: api.CheckStatusMessageNonce,
|
||||
Hint: map[string]interface{}{
|
||||
"nextNonce": st.nextNonce,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if (flexibleNonces == nil || !flexibleNonces[i]) && st.nextNonce != m.Nonce {
|
||||
check.OK = false
|
||||
check.Err = fmt.Sprintf("message nonce doesn't match next nonce (%d)", st.nextNonce)
|
||||
} else {
|
||||
check.OK = true
|
||||
st.nextNonce++
|
||||
}
|
||||
|
||||
result[i] = append(result[i], check)
|
||||
|
||||
// check required funds -vs- balance
|
||||
st.requiredFunds = new(stdbig.Int).Add(st.requiredFunds, m.RequiredFunds().Int)
|
||||
st.requiredFunds.Add(st.requiredFunds, m.Value.Int)
|
||||
|
||||
// 10. Balance
|
||||
check = api.MessageCheckStatus{
|
||||
Cid: m.Cid(),
|
||||
CheckStatus: api.CheckStatus{
|
||||
Code: api.CheckStatusMessageBalance,
|
||||
Hint: map[string]interface{}{
|
||||
"requiredFunds": big.Int{Int: stdbig.NewInt(0).Set(st.requiredFunds)},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if balance.Int.Cmp(st.requiredFunds) < 0 {
|
||||
check.OK = false
|
||||
check.Err = "insufficient balance"
|
||||
} else {
|
||||
check.OK = true
|
||||
}
|
||||
|
||||
result[i] = append(result[i], check)
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
@ -805,6 +805,13 @@ func (mp *MessagePool) GetNonce(_ context.Context, addr address.Address, _ types
|
||||
return mp.getNonceLocked(addr, mp.curTs)
|
||||
}
|
||||
|
||||
// GetActor should not be used. It is only here to satisfy interface mess caused by lite node handling
|
||||
func (mp *MessagePool) GetActor(_ context.Context, addr address.Address, _ types.TipSetKey) (*types.Actor, error) {
|
||||
mp.curTsLk.Lock()
|
||||
defer mp.curTsLk.Unlock()
|
||||
return mp.api.GetActorAfter(addr, mp.curTs)
|
||||
}
|
||||
|
||||
func (mp *MessagePool) getNonceLocked(addr address.Address, curTs *types.TipSet) (uint64, error) {
|
||||
stateNonce, err := mp.getStateNonce(addr, curTs) // sanity check
|
||||
if err != nil {
|
||||
@ -825,8 +832,8 @@ func (mp *MessagePool) getNonceLocked(addr address.Address, curTs *types.TipSet)
|
||||
return stateNonce, nil
|
||||
}
|
||||
|
||||
func (mp *MessagePool) getStateNonce(addr address.Address, curTs *types.TipSet) (uint64, error) {
|
||||
act, err := mp.api.GetActorAfter(addr, curTs)
|
||||
func (mp *MessagePool) getStateNonce(addr address.Address, ts *types.TipSet) (uint64, error) {
|
||||
act, err := mp.api.GetActorAfter(addr, ts)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
@ -103,6 +103,9 @@ func (tma *testMpoolAPI) SubscribeHeadChanges(cb func(rev, app []*types.TipSet)
|
||||
func (tma *testMpoolAPI) PutMessage(m types.ChainMsg) (cid.Cid, error) {
|
||||
return cid.Undef, nil
|
||||
}
|
||||
func (tma *testMpoolAPI) IsLite() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (tma *testMpoolAPI) PubSubPublish(string, []byte) error {
|
||||
tma.published++
|
||||
|
@ -9,6 +9,7 @@ import (
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/lotus/chain/messagesigner"
|
||||
"github.com/filecoin-project/lotus/chain/stmgr"
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
@ -30,17 +31,28 @@ type Provider interface {
|
||||
MessagesForTipset(*types.TipSet) ([]types.ChainMsg, error)
|
||||
LoadTipSet(tsk types.TipSetKey) (*types.TipSet, error)
|
||||
ChainComputeBaseFee(ctx context.Context, ts *types.TipSet) (types.BigInt, error)
|
||||
IsLite() bool
|
||||
}
|
||||
|
||||
type mpoolProvider struct {
|
||||
sm *stmgr.StateManager
|
||||
ps *pubsub.PubSub
|
||||
|
||||
lite messagesigner.MpoolNonceAPI
|
||||
}
|
||||
|
||||
func NewProvider(sm *stmgr.StateManager, ps *pubsub.PubSub) Provider {
|
||||
return &mpoolProvider{sm: sm, ps: ps}
|
||||
}
|
||||
|
||||
func NewProviderLite(sm *stmgr.StateManager, ps *pubsub.PubSub, noncer messagesigner.MpoolNonceAPI) Provider {
|
||||
return &mpoolProvider{sm: sm, ps: ps, lite: noncer}
|
||||
}
|
||||
|
||||
func (mpp *mpoolProvider) IsLite() bool {
|
||||
return mpp.lite != nil
|
||||
}
|
||||
|
||||
func (mpp *mpoolProvider) SubscribeHeadChanges(cb func(rev, app []*types.TipSet) error) *types.TipSet {
|
||||
mpp.sm.ChainStore().SubscribeHeadChanges(
|
||||
store.WrapHeadChangeCoalescer(
|
||||
@ -61,6 +73,19 @@ func (mpp *mpoolProvider) PubSubPublish(k string, v []byte) error {
|
||||
}
|
||||
|
||||
func (mpp *mpoolProvider) GetActorAfter(addr address.Address, ts *types.TipSet) (*types.Actor, error) {
|
||||
if mpp.IsLite() {
|
||||
n, err := mpp.lite.GetNonce(context.TODO(), addr, ts.Key())
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("getting nonce over lite: %w", err)
|
||||
}
|
||||
a, err := mpp.lite.GetActor(context.TODO(), addr, ts.Key())
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("getting actor over lite: %w", err)
|
||||
}
|
||||
a.Nonce = n
|
||||
return a, nil
|
||||
}
|
||||
|
||||
stcid, _, err := mpp.sm.TipSetState(context.TODO(), ts)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("computing tipset state for GetActor: %w", err)
|
||||
|
@ -24,6 +24,7 @@ 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)
|
||||
}
|
||||
|
||||
// MessageSigner keeps track of nonces per address, and increments the nonce
|
||||
|
@ -41,6 +41,9 @@ func (mp *mockMpool) GetNonce(_ context.Context, addr address.Address, _ types.T
|
||||
|
||||
return mp.nonces[addr], nil
|
||||
}
|
||||
func (mp *mockMpool) GetActor(_ context.Context, addr address.Address, _ types.TipSetKey) (*types.Actor, error) {
|
||||
panic("don't use it")
|
||||
}
|
||||
|
||||
func TestMessageSignerSignMessage(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
@ -46,6 +46,15 @@ func (f FIL) Short() string {
|
||||
return strings.TrimRight(strings.TrimRight(r.FloatString(3), "0"), ".") + " " + prefix + "FIL"
|
||||
}
|
||||
|
||||
func (f FIL) Nano() string {
|
||||
r := new(big.Rat).SetFrac(f.Int, big.NewInt(int64(1e9)))
|
||||
if r.Sign() == 0 {
|
||||
return "0"
|
||||
}
|
||||
|
||||
return strings.TrimRight(strings.TrimRight(r.FloatString(9), "0"), ".") + " nFIL"
|
||||
}
|
||||
|
||||
func (f FIL) Format(s fmt.State, ch rune) {
|
||||
switch ch {
|
||||
case 's', 'v':
|
||||
|
31
cli/chain.go
31
cli/chain.go
@ -31,6 +31,7 @@ import (
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
lapi "github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/api/v0api"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
@ -1116,11 +1117,13 @@ var SlashConsensusFault = &cli.Command{
|
||||
},
|
||||
},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
api, closer, err := GetFullNodeAPI(cctx)
|
||||
srv, err := GetFullNodeServices(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
defer srv.Close() //nolint:errcheck
|
||||
|
||||
a := srv.FullNodeAPI()
|
||||
ctx := ReqContext(cctx)
|
||||
|
||||
c1, err := cid.Parse(cctx.Args().Get(0))
|
||||
@ -1128,7 +1131,7 @@ var SlashConsensusFault = &cli.Command{
|
||||
return xerrors.Errorf("parsing cid 1: %w", err)
|
||||
}
|
||||
|
||||
b1, err := api.ChainGetBlock(ctx, c1)
|
||||
b1, err := a.ChainGetBlock(ctx, c1)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting block 1: %w", err)
|
||||
}
|
||||
@ -1138,7 +1141,7 @@ var SlashConsensusFault = &cli.Command{
|
||||
return xerrors.Errorf("parsing cid 2: %w", err)
|
||||
}
|
||||
|
||||
b2, err := api.ChainGetBlock(ctx, c2)
|
||||
b2, err := a.ChainGetBlock(ctx, c2)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting block 2: %w", err)
|
||||
}
|
||||
@ -1149,7 +1152,7 @@ var SlashConsensusFault = &cli.Command{
|
||||
|
||||
var fromAddr address.Address
|
||||
if from := cctx.String("from"); from == "" {
|
||||
defaddr, err := api.WalletDefaultAddress(ctx)
|
||||
defaddr, err := a.WalletDefaultAddress(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -1185,7 +1188,7 @@ var SlashConsensusFault = &cli.Command{
|
||||
return xerrors.Errorf("parsing cid extra: %w", err)
|
||||
}
|
||||
|
||||
bExtra, err := api.ChainGetBlock(ctx, cExtra)
|
||||
bExtra, err := a.ChainGetBlock(ctx, cExtra)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting block extra: %w", err)
|
||||
}
|
||||
@ -1203,15 +1206,17 @@ var SlashConsensusFault = &cli.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
msg := &types.Message{
|
||||
To: b2.Miner,
|
||||
From: fromAddr,
|
||||
Value: types.NewInt(0),
|
||||
Method: builtin.MethodsMiner.ReportConsensusFault,
|
||||
Params: enc,
|
||||
proto := &api.MessagePrototype{
|
||||
Message: types.Message{
|
||||
To: b2.Miner,
|
||||
From: fromAddr,
|
||||
Value: types.NewInt(0),
|
||||
Method: builtin.MethodsMiner.ReportConsensusFault,
|
||||
Params: enc,
|
||||
},
|
||||
}
|
||||
|
||||
smsg, err := api.MpoolPushMessage(ctx, msg, nil)
|
||||
smsg, err := InteractiveSend(ctx, cctx, srv, proto)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ func GetFullNodeServices(ctx *cli.Context) (ServicesAPI, error) {
|
||||
return tn.(ServicesAPI), nil
|
||||
}
|
||||
|
||||
api, c, err := GetFullNodeAPI(ctx)
|
||||
api, c, err := GetFullNodeAPIV1(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -81,6 +81,7 @@ var Commands = []*cli.Command{
|
||||
WithCategory("developer", FetchParamCmd),
|
||||
WithCategory("network", NetCmd),
|
||||
WithCategory("network", SyncCmd),
|
||||
WithCategory("status", StatusCmd),
|
||||
PprofCmd,
|
||||
VersionCmd,
|
||||
}
|
||||
|
9
cli/init_test.go
Normal file
9
cli/init_test.go
Normal file
@ -0,0 +1,9 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
logging "github.com/ipfs/go-log/v2"
|
||||
)
|
||||
|
||||
func init() {
|
||||
logging.SetLogLevel("watchdog", "ERROR")
|
||||
}
|
@ -34,6 +34,7 @@ var MpoolCmd = &cli.Command{
|
||||
MpoolFindCmd,
|
||||
MpoolConfig,
|
||||
MpoolGasPerfCmd,
|
||||
mpoolManage,
|
||||
},
|
||||
}
|
||||
|
||||
|
360
cli/mpool_manage.go
Normal file
360
cli/mpool_manage.go
Normal file
@ -0,0 +1,360 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
"github.com/Kubuxu/imtui"
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
"github.com/filecoin-project/lotus/chain/messagepool"
|
||||
types "github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/gdamore/tcell/v2"
|
||||
cid "github.com/ipfs/go-cid"
|
||||
"github.com/urfave/cli/v2"
|
||||
"golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var mpoolManage = &cli.Command{
|
||||
Name: "manage",
|
||||
Action: func(cctx *cli.Context) error {
|
||||
srv, err := GetFullNodeServices(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer srv.Close() //nolint:errcheck
|
||||
|
||||
ctx := ReqContext(cctx)
|
||||
|
||||
_, localAddr, err := srv.LocalAddresses(ctx)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting local addresses: %w", err)
|
||||
}
|
||||
|
||||
msgs, err := srv.MpoolPendingFilter(ctx, func(sm *types.SignedMessage) bool {
|
||||
if sm.Message.From.Empty() {
|
||||
return false
|
||||
}
|
||||
for _, a := range localAddr {
|
||||
if a == sm.Message.From {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}, types.EmptyTSK)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t, err := imtui.NewTui()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
mm := &mmUI{
|
||||
ctx: ctx,
|
||||
srv: srv,
|
||||
addrs: localAddr,
|
||||
messages: msgs,
|
||||
}
|
||||
sort.Slice(mm.addrs, func(i, j int) bool {
|
||||
return mm.addrs[i].String() < mm.addrs[j].String()
|
||||
})
|
||||
t.PushScene(mm.addrSelect())
|
||||
|
||||
err = t.Run()
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
type mmUI struct {
|
||||
ctx context.Context
|
||||
srv ServicesAPI
|
||||
addrs []address.Address
|
||||
messages []*types.SignedMessage
|
||||
}
|
||||
|
||||
func (mm *mmUI) addrSelect() func(*imtui.Tui) error {
|
||||
rows := [][]string{{"Address", "No. Messages"}}
|
||||
mCount := map[address.Address]int{}
|
||||
for _, sm := range mm.messages {
|
||||
mCount[sm.Message.From]++
|
||||
}
|
||||
for _, a := range mm.addrs {
|
||||
rows = append(rows, []string{a.String(), fmt.Sprintf("%d", mCount[a])})
|
||||
}
|
||||
|
||||
flex := []int{4, 1}
|
||||
sel := 0
|
||||
scroll := 0
|
||||
return func(t *imtui.Tui) error {
|
||||
if t.CurrentKey != nil && t.CurrentKey.Key() == tcell.KeyEnter {
|
||||
if sel > 0 {
|
||||
t.ReplaceScene(mm.messageLising(mm.addrs[sel-1]))
|
||||
}
|
||||
}
|
||||
t.FlexTable(0, 0, 0, &sel, &scroll, rows, flex, true)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func errUI(err error) func(*imtui.Tui) error {
|
||||
return func(t *imtui.Tui) error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
type msgInfo struct {
|
||||
sm *types.SignedMessage
|
||||
checks []api.MessageCheckStatus
|
||||
}
|
||||
|
||||
func (mi *msgInfo) Row() []string {
|
||||
cidStr := mi.sm.Cid().String()
|
||||
failedChecks := 0
|
||||
for _, c := range mi.checks {
|
||||
if !c.OK {
|
||||
failedChecks++
|
||||
}
|
||||
}
|
||||
shortAddr := mi.sm.Message.To.String()
|
||||
if len(shortAddr) > 16 {
|
||||
shortAddr = "…" + shortAddr[len(shortAddr)-16:]
|
||||
}
|
||||
var fCk string
|
||||
if failedChecks == 0 {
|
||||
fCk = "[:green:]OK"
|
||||
} else {
|
||||
fCk = "[:orange:]" + fmt.Sprintf("%d", failedChecks)
|
||||
}
|
||||
return []string{"…" + cidStr[len(cidStr)-32:], shortAddr,
|
||||
fmt.Sprintf("%d", mi.sm.Message.Nonce), types.FIL(mi.sm.Message.Value).String(),
|
||||
fmt.Sprintf("%d", mi.sm.Message.Method), fCk}
|
||||
|
||||
}
|
||||
|
||||
func (mm *mmUI) messageLising(a address.Address) func(*imtui.Tui) error {
|
||||
genMsgInfos := func() ([]msgInfo, error) {
|
||||
msgs, err := mm.srv.MpoolPendingFilter(mm.ctx, func(sm *types.SignedMessage) bool {
|
||||
if sm.Message.From.Empty() {
|
||||
return false
|
||||
}
|
||||
if a == sm.Message.From {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}, types.EmptyTSK)
|
||||
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("getting pending: %w", err)
|
||||
}
|
||||
|
||||
msgIdx := map[cid.Cid]*types.SignedMessage{}
|
||||
for _, sm := range msgs {
|
||||
if sm.Message.From == a {
|
||||
msgIdx[sm.Message.Cid()] = sm
|
||||
msgIdx[sm.Cid()] = sm
|
||||
}
|
||||
}
|
||||
|
||||
checks, err := mm.srv.MpoolCheckPendingMessages(mm.ctx, a)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("checking pending: %w", err)
|
||||
}
|
||||
msgInfos := make([]msgInfo, 0, len(checks))
|
||||
for _, msgChecks := range checks {
|
||||
failingChecks := []api.MessageCheckStatus{}
|
||||
for _, c := range msgChecks {
|
||||
if !c.OK {
|
||||
failingChecks = append(failingChecks, c)
|
||||
}
|
||||
}
|
||||
msgInfos = append(msgInfos, msgInfo{
|
||||
sm: msgIdx[msgChecks[0].Cid],
|
||||
checks: failingChecks,
|
||||
})
|
||||
}
|
||||
return msgInfos, nil
|
||||
}
|
||||
|
||||
sel := 0
|
||||
scroll := 0
|
||||
|
||||
var msgInfos []msgInfo
|
||||
var rows [][]string
|
||||
flex := []int{3, 2, 1, 1, 1, 1}
|
||||
refresh := true
|
||||
|
||||
return func(t *imtui.Tui) error {
|
||||
if refresh {
|
||||
var err error
|
||||
msgInfos, err = genMsgInfos()
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting msgInfos: %w", err)
|
||||
}
|
||||
|
||||
rows = [][]string{{"Message Cid", "To", "Nonce", "Value", "Method", "Checks"}}
|
||||
for _, mi := range msgInfos {
|
||||
rows = append(rows, mi.Row())
|
||||
}
|
||||
refresh = false
|
||||
}
|
||||
|
||||
if t.CurrentKey != nil && t.CurrentKey.Key() == tcell.KeyEnter {
|
||||
if sel > 0 {
|
||||
t.PushScene(mm.messageDetail(msgInfos[sel-1]))
|
||||
refresh = true
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
t.Label(0, 0, fmt.Sprintf("Address: %s", a), tcell.StyleDefault)
|
||||
t.FlexTable(1, 0, 0, &sel, &scroll, rows, flex, true)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (mm *mmUI) messageDetail(mi msgInfo) func(*imtui.Tui) error {
|
||||
baseFee, err := mm.srv.GetBaseFee(mm.ctx)
|
||||
if err != nil {
|
||||
return errUI(err)
|
||||
}
|
||||
_ = baseFee
|
||||
|
||||
m := mi.sm.Message
|
||||
maxFee := big.Mul(m.GasFeeCap, big.NewInt(m.GasLimit))
|
||||
|
||||
issues := [][]string{}
|
||||
for _, c := range mi.checks {
|
||||
issues = append(issues, []string{c.Code.String(), c.Err})
|
||||
}
|
||||
issuesFlex := []int{1, 3}
|
||||
var sel, scroll int
|
||||
|
||||
executeReprice := false
|
||||
executeNoop := false
|
||||
return func(t *imtui.Tui) error {
|
||||
if executeReprice {
|
||||
m.GasFeeCap = big.Div(maxFee, big.NewInt(m.GasLimit))
|
||||
m.GasPremium = messagepool.ComputeMinRBF(m.GasPremium)
|
||||
m.GasFeeCap = big.Max(m.GasFeeCap, m.GasPremium)
|
||||
|
||||
_, _, err := mm.srv.PublishMessage(mm.ctx, &api.MessagePrototype{
|
||||
Message: m,
|
||||
ValidNonce: true,
|
||||
}, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
t.PopScene()
|
||||
return nil
|
||||
}
|
||||
if executeNoop {
|
||||
nop := types.Message{
|
||||
To: builtin.BurntFundsActorAddr,
|
||||
From: m.From,
|
||||
|
||||
Nonce: m.Nonce,
|
||||
Value: big.Zero(),
|
||||
}
|
||||
|
||||
nop.GasPremium = messagepool.ComputeMinRBF(m.GasPremium)
|
||||
|
||||
_, _, err := mm.srv.PublishMessage(mm.ctx, &api.MessagePrototype{
|
||||
Message: nop,
|
||||
ValidNonce: true,
|
||||
}, true)
|
||||
|
||||
if err != nil {
|
||||
return xerrors.Errorf("publishing noop message: %w", err)
|
||||
}
|
||||
|
||||
t.PopScene()
|
||||
return nil
|
||||
}
|
||||
|
||||
if t.CurrentKey != nil {
|
||||
if t.CurrentKey.Key() == tcell.KeyLeft {
|
||||
t.PopScene()
|
||||
return nil
|
||||
}
|
||||
if t.CurrentKey.Key() == tcell.KeyRune {
|
||||
switch t.CurrentKey.Rune() {
|
||||
case 'R', 'r':
|
||||
t.PushScene(feeUI(baseFee, m.GasLimit, &maxFee, &executeReprice))
|
||||
return nil
|
||||
case 'N', 'n':
|
||||
t.PushScene(confirmationScene(
|
||||
&executeNoop,
|
||||
"Are you sure you want to cancel the message by",
|
||||
"replacing it with a message with no effects?"))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
row := 0
|
||||
defS := tcell.StyleDefault
|
||||
display := func(f string, args ...interface{}) {
|
||||
t.Label(0, row, fmt.Sprintf(f, args...), defS)
|
||||
row++
|
||||
}
|
||||
|
||||
display("Message CID: %s", m.Cid())
|
||||
display("Signed Message CID: %s", mi.sm.Cid())
|
||||
row++
|
||||
display("From: %s", m.From)
|
||||
display("To: %s", m.To)
|
||||
row++
|
||||
display("Nonce: %d", m.Nonce)
|
||||
display("Value: %s", types.FIL(m.Value))
|
||||
row++
|
||||
display("GasLimit: %d", m.GasLimit)
|
||||
display("GasPremium: %s", types.FIL(m.GasPremium).Short())
|
||||
display("GasFeeCap %s", types.FIL(m.GasFeeCap).Short())
|
||||
row++
|
||||
display("Press R to reprice this message")
|
||||
display("Press N to replace this message with no-operation message")
|
||||
row++
|
||||
|
||||
t.FlexTable(row, 0, 0, &sel, &scroll, issues, issuesFlex, false)
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func confirmationScene(yes *bool, ask ...string) func(*imtui.Tui) error {
|
||||
return func(t *imtui.Tui) error {
|
||||
row := 0
|
||||
defS := tcell.StyleDefault
|
||||
display := func(f string, args ...interface{}) {
|
||||
t.Label(0, row, fmt.Sprintf(f, args...), defS)
|
||||
row++
|
||||
}
|
||||
|
||||
for _, a := range ask {
|
||||
display(a)
|
||||
}
|
||||
row++
|
||||
display("Enter to confirm")
|
||||
display("Esc to cancel")
|
||||
|
||||
if t.CurrentKey != nil {
|
||||
if t.CurrentKey.Key() == tcell.KeyEnter {
|
||||
*yes = true
|
||||
t.PopScene()
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
247
cli/multisig.go
247
cli/multisig.go
@ -95,11 +95,13 @@ var msigCreateCmd = &cli.Command{
|
||||
return ShowHelp(cctx, fmt.Errorf("multisigs must have at least one signer"))
|
||||
}
|
||||
|
||||
api, closer, err := GetFullNodeAPI(cctx)
|
||||
srv, err := GetFullNodeServices(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
defer srv.Close() //nolint:errcheck
|
||||
|
||||
api := srv.FullNodeAPI()
|
||||
ctx := ReqContext(cctx)
|
||||
|
||||
var addrs []address.Address
|
||||
@ -146,13 +148,20 @@ var msigCreateCmd = &cli.Command{
|
||||
|
||||
gp := types.NewInt(1)
|
||||
|
||||
msgCid, err := api.MsigCreate(ctx, required, addrs, d, intVal, sendAddr, gp)
|
||||
proto, err := api.MsigCreate(ctx, required, addrs, d, intVal, sendAddr, gp)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sm, err := InteractiveSend(ctx, cctx, srv, proto)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msgCid := sm.Cid()
|
||||
|
||||
// wait for it to get mined into a block
|
||||
wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence")))
|
||||
wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence")), build.Finality, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -364,11 +373,13 @@ var msigProposeCmd = &cli.Command{
|
||||
return ShowHelp(cctx, fmt.Errorf("must either pass three or five arguments"))
|
||||
}
|
||||
|
||||
api, closer, err := GetFullNodeAPI(cctx)
|
||||
srv, err := GetFullNodeServices(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
defer srv.Close() //nolint:errcheck
|
||||
|
||||
api := srv.FullNodeAPI()
|
||||
ctx := ReqContext(cctx)
|
||||
|
||||
msig, err := address.NewFromString(cctx.Args().Get(0))
|
||||
@ -426,14 +437,21 @@ var msigProposeCmd = &cli.Command{
|
||||
return fmt.Errorf("actor %s is not a multisig actor", msig)
|
||||
}
|
||||
|
||||
msgCid, err := api.MsigPropose(ctx, msig, dest, types.BigInt(value), from, method, params)
|
||||
proto, err := api.MsigPropose(ctx, msig, dest, types.BigInt(value), from, method, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sm, err := InteractiveSend(ctx, cctx, srv, proto)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msgCid := sm.Cid()
|
||||
|
||||
fmt.Println("send proposal in message: ", msgCid)
|
||||
|
||||
wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence")))
|
||||
wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence")), build.Finality, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -481,11 +499,13 @@ var msigApproveCmd = &cli.Command{
|
||||
return ShowHelp(cctx, fmt.Errorf("usage: msig approve <msig addr> <message ID> <proposer address> <desination> <value> [ <method> <params> ]"))
|
||||
}
|
||||
|
||||
api, closer, err := GetFullNodeAPI(cctx)
|
||||
srv, err := GetFullNodeServices(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
defer srv.Close() //nolint:errcheck
|
||||
|
||||
api := srv.FullNodeAPI()
|
||||
ctx := ReqContext(cctx)
|
||||
|
||||
msig, err := address.NewFromString(cctx.Args().Get(0))
|
||||
@ -515,10 +535,17 @@ var msigApproveCmd = &cli.Command{
|
||||
|
||||
var msgCid cid.Cid
|
||||
if cctx.Args().Len() == 2 {
|
||||
msgCid, err = api.MsigApprove(ctx, msig, txid, from)
|
||||
proto, err := api.MsigApprove(ctx, msig, txid, from)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sm, err := InteractiveSend(ctx, cctx, srv, proto)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msgCid = sm.Cid()
|
||||
} else {
|
||||
proposer, err := address.NewFromString(cctx.Args().Get(2))
|
||||
if err != nil {
|
||||
@ -558,15 +585,22 @@ var msigApproveCmd = &cli.Command{
|
||||
params = p
|
||||
}
|
||||
|
||||
msgCid, err = api.MsigApproveTxnHash(ctx, msig, txid, proposer, dest, types.BigInt(value), from, method, params)
|
||||
proto, err := api.MsigApproveTxnHash(ctx, msig, txid, proposer, dest, types.BigInt(value), from, method, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sm, err := InteractiveSend(ctx, cctx, srv, proto)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msgCid = sm.Cid()
|
||||
}
|
||||
|
||||
fmt.Println("sent approval in message: ", msgCid)
|
||||
|
||||
wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence")))
|
||||
wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence")), build.Finality, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -598,11 +632,13 @@ var msigRemoveProposeCmd = &cli.Command{
|
||||
return ShowHelp(cctx, fmt.Errorf("must pass multisig address and signer address"))
|
||||
}
|
||||
|
||||
api, closer, err := GetFullNodeAPI(cctx)
|
||||
srv, err := GetFullNodeServices(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
defer srv.Close() //nolint:errcheck
|
||||
|
||||
api := srv.FullNodeAPI()
|
||||
ctx := ReqContext(cctx)
|
||||
|
||||
msig, err := address.NewFromString(cctx.Args().Get(0))
|
||||
@ -630,14 +666,21 @@ var msigRemoveProposeCmd = &cli.Command{
|
||||
from = defaddr
|
||||
}
|
||||
|
||||
msgCid, err := api.MsigRemoveSigner(ctx, msig, from, addr, cctx.Bool("decrease-threshold"))
|
||||
proto, err := api.MsigRemoveSigner(ctx, msig, from, addr, cctx.Bool("decrease-threshold"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sm, err := InteractiveSend(ctx, cctx, srv, proto)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msgCid := sm.Cid()
|
||||
|
||||
fmt.Println("sent remove proposal in message: ", msgCid)
|
||||
|
||||
wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence")))
|
||||
wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence")), build.Finality, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -676,11 +719,13 @@ var msigAddProposeCmd = &cli.Command{
|
||||
return ShowHelp(cctx, fmt.Errorf("must pass multisig address and signer address"))
|
||||
}
|
||||
|
||||
api, closer, err := GetFullNodeAPI(cctx)
|
||||
srv, err := GetFullNodeServices(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
defer srv.Close() //nolint:errcheck
|
||||
|
||||
api := srv.FullNodeAPI()
|
||||
ctx := ReqContext(cctx)
|
||||
|
||||
msig, err := address.NewFromString(cctx.Args().Get(0))
|
||||
@ -708,14 +753,21 @@ var msigAddProposeCmd = &cli.Command{
|
||||
from = defaddr
|
||||
}
|
||||
|
||||
msgCid, err := api.MsigAddPropose(ctx, msig, from, addr, cctx.Bool("increase-threshold"))
|
||||
proto, err := api.MsigAddPropose(ctx, msig, from, addr, cctx.Bool("increase-threshold"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sm, err := InteractiveSend(ctx, cctx, srv, proto)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msgCid := sm.Cid()
|
||||
|
||||
fmt.Fprintln(cctx.App.Writer, "sent add proposal in message: ", msgCid)
|
||||
|
||||
wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence")))
|
||||
wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence")), build.Finality, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -743,11 +795,13 @@ var msigAddApproveCmd = &cli.Command{
|
||||
return ShowHelp(cctx, fmt.Errorf("must pass multisig address, proposer address, transaction id, new signer address, whether to increase threshold"))
|
||||
}
|
||||
|
||||
api, closer, err := GetFullNodeAPI(cctx)
|
||||
srv, err := GetFullNodeServices(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
defer srv.Close() //nolint:errcheck
|
||||
|
||||
api := srv.FullNodeAPI()
|
||||
ctx := ReqContext(cctx)
|
||||
|
||||
msig, err := address.NewFromString(cctx.Args().Get(0))
|
||||
@ -790,14 +844,21 @@ var msigAddApproveCmd = &cli.Command{
|
||||
from = defaddr
|
||||
}
|
||||
|
||||
msgCid, err := api.MsigAddApprove(ctx, msig, from, txid, prop, newAdd, inc)
|
||||
proto, err := api.MsigAddApprove(ctx, msig, from, txid, prop, newAdd, inc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sm, err := InteractiveSend(ctx, cctx, srv, proto)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msgCid := sm.Cid()
|
||||
|
||||
fmt.Println("sent add approval in message: ", msgCid)
|
||||
|
||||
wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence")))
|
||||
wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence")), build.Finality, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -825,11 +886,13 @@ var msigAddCancelCmd = &cli.Command{
|
||||
return ShowHelp(cctx, fmt.Errorf("must pass multisig address, transaction id, new signer address, whether to increase threshold"))
|
||||
}
|
||||
|
||||
api, closer, err := GetFullNodeAPI(cctx)
|
||||
srv, err := GetFullNodeServices(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
defer srv.Close() //nolint:errcheck
|
||||
|
||||
api := srv.FullNodeAPI()
|
||||
ctx := ReqContext(cctx)
|
||||
|
||||
msig, err := address.NewFromString(cctx.Args().Get(0))
|
||||
@ -867,14 +930,21 @@ var msigAddCancelCmd = &cli.Command{
|
||||
from = defaddr
|
||||
}
|
||||
|
||||
msgCid, err := api.MsigAddCancel(ctx, msig, from, txid, newAdd, inc)
|
||||
proto, err := api.MsigAddCancel(ctx, msig, from, txid, newAdd, inc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sm, err := InteractiveSend(ctx, cctx, srv, proto)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msgCid := sm.Cid()
|
||||
|
||||
fmt.Println("sent add cancellation in message: ", msgCid)
|
||||
|
||||
wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence")))
|
||||
wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence")), build.Finality, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -902,11 +972,13 @@ var msigSwapProposeCmd = &cli.Command{
|
||||
return ShowHelp(cctx, fmt.Errorf("must pass multisig address, old signer address, new signer address"))
|
||||
}
|
||||
|
||||
api, closer, err := GetFullNodeAPI(cctx)
|
||||
srv, err := GetFullNodeServices(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
defer srv.Close() //nolint:errcheck
|
||||
|
||||
api := srv.FullNodeAPI()
|
||||
ctx := ReqContext(cctx)
|
||||
|
||||
msig, err := address.NewFromString(cctx.Args().Get(0))
|
||||
@ -939,14 +1011,21 @@ var msigSwapProposeCmd = &cli.Command{
|
||||
from = defaddr
|
||||
}
|
||||
|
||||
msgCid, err := api.MsigSwapPropose(ctx, msig, from, oldAdd, newAdd)
|
||||
proto, err := api.MsigSwapPropose(ctx, msig, from, oldAdd, newAdd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sm, err := InteractiveSend(ctx, cctx, srv, proto)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msgCid := sm.Cid()
|
||||
|
||||
fmt.Println("sent swap proposal in message: ", msgCid)
|
||||
|
||||
wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence")))
|
||||
wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence")), build.Finality, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -974,11 +1053,13 @@ var msigSwapApproveCmd = &cli.Command{
|
||||
return ShowHelp(cctx, fmt.Errorf("must pass multisig address, proposer address, transaction id, old signer address, new signer address"))
|
||||
}
|
||||
|
||||
api, closer, err := GetFullNodeAPI(cctx)
|
||||
srv, err := GetFullNodeServices(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
defer srv.Close() //nolint:errcheck
|
||||
|
||||
api := srv.FullNodeAPI()
|
||||
ctx := ReqContext(cctx)
|
||||
|
||||
msig, err := address.NewFromString(cctx.Args().Get(0))
|
||||
@ -1021,14 +1102,21 @@ var msigSwapApproveCmd = &cli.Command{
|
||||
from = defaddr
|
||||
}
|
||||
|
||||
msgCid, err := api.MsigSwapApprove(ctx, msig, from, txid, prop, oldAdd, newAdd)
|
||||
proto, err := api.MsigSwapApprove(ctx, msig, from, txid, prop, oldAdd, newAdd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sm, err := InteractiveSend(ctx, cctx, srv, proto)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msgCid := sm.Cid()
|
||||
|
||||
fmt.Println("sent swap approval in message: ", msgCid)
|
||||
|
||||
wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence")))
|
||||
wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence")), build.Finality, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -1056,11 +1144,13 @@ var msigSwapCancelCmd = &cli.Command{
|
||||
return ShowHelp(cctx, fmt.Errorf("must pass multisig address, transaction id, old signer address, new signer address"))
|
||||
}
|
||||
|
||||
api, closer, err := GetFullNodeAPI(cctx)
|
||||
srv, err := GetFullNodeServices(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
defer srv.Close() //nolint:errcheck
|
||||
|
||||
api := srv.FullNodeAPI()
|
||||
ctx := ReqContext(cctx)
|
||||
|
||||
msig, err := address.NewFromString(cctx.Args().Get(0))
|
||||
@ -1098,14 +1188,21 @@ var msigSwapCancelCmd = &cli.Command{
|
||||
from = defaddr
|
||||
}
|
||||
|
||||
msgCid, err := api.MsigSwapCancel(ctx, msig, from, txid, oldAdd, newAdd)
|
||||
proto, err := api.MsigSwapCancel(ctx, msig, from, txid, oldAdd, newAdd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sm, err := InteractiveSend(ctx, cctx, srv, proto)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msgCid := sm.Cid()
|
||||
|
||||
fmt.Println("sent swap cancellation in message: ", msgCid)
|
||||
|
||||
wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence")))
|
||||
wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence")), build.Finality, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -1133,11 +1230,13 @@ var msigLockProposeCmd = &cli.Command{
|
||||
return ShowHelp(cctx, fmt.Errorf("must pass multisig address, start epoch, unlock duration, and amount"))
|
||||
}
|
||||
|
||||
api, closer, err := GetFullNodeAPI(cctx)
|
||||
srv, err := GetFullNodeServices(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
defer srv.Close() //nolint:errcheck
|
||||
|
||||
api := srv.FullNodeAPI()
|
||||
ctx := ReqContext(cctx)
|
||||
|
||||
msig, err := address.NewFromString(cctx.Args().Get(0))
|
||||
@ -1185,14 +1284,21 @@ var msigLockProposeCmd = &cli.Command{
|
||||
return actErr
|
||||
}
|
||||
|
||||
msgCid, err := api.MsigPropose(ctx, msig, msig, big.Zero(), from, uint64(multisig.Methods.LockBalance), params)
|
||||
proto, err := api.MsigPropose(ctx, msig, msig, big.Zero(), from, uint64(multisig.Methods.LockBalance), params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sm, err := InteractiveSend(ctx, cctx, srv, proto)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msgCid := sm.Cid()
|
||||
|
||||
fmt.Println("sent lock proposal in message: ", msgCid)
|
||||
|
||||
wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence")))
|
||||
wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence")), build.Finality, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -1220,11 +1326,13 @@ var msigLockApproveCmd = &cli.Command{
|
||||
return ShowHelp(cctx, fmt.Errorf("must pass multisig address, proposer address, tx id, start epoch, unlock duration, and amount"))
|
||||
}
|
||||
|
||||
api, closer, err := GetFullNodeAPI(cctx)
|
||||
srv, err := GetFullNodeServices(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
defer srv.Close() //nolint:errcheck
|
||||
|
||||
api := srv.FullNodeAPI()
|
||||
ctx := ReqContext(cctx)
|
||||
|
||||
msig, err := address.NewFromString(cctx.Args().Get(0))
|
||||
@ -1282,14 +1390,21 @@ var msigLockApproveCmd = &cli.Command{
|
||||
return actErr
|
||||
}
|
||||
|
||||
msgCid, err := api.MsigApproveTxnHash(ctx, msig, txid, prop, msig, big.Zero(), from, uint64(multisig.Methods.LockBalance), params)
|
||||
proto, err := api.MsigApproveTxnHash(ctx, msig, txid, prop, msig, big.Zero(), from, uint64(multisig.Methods.LockBalance), params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sm, err := InteractiveSend(ctx, cctx, srv, proto)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msgCid := sm.Cid()
|
||||
|
||||
fmt.Println("sent lock approval in message: ", msgCid)
|
||||
|
||||
wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence")))
|
||||
wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence")), build.Finality, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -1317,11 +1432,13 @@ var msigLockCancelCmd = &cli.Command{
|
||||
return ShowHelp(cctx, fmt.Errorf("must pass multisig address, tx id, start epoch, unlock duration, and amount"))
|
||||
}
|
||||
|
||||
api, closer, err := GetFullNodeAPI(cctx)
|
||||
srv, err := GetFullNodeServices(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
defer srv.Close() //nolint:errcheck
|
||||
|
||||
api := srv.FullNodeAPI()
|
||||
ctx := ReqContext(cctx)
|
||||
|
||||
msig, err := address.NewFromString(cctx.Args().Get(0))
|
||||
@ -1374,14 +1491,21 @@ var msigLockCancelCmd = &cli.Command{
|
||||
return actErr
|
||||
}
|
||||
|
||||
msgCid, err := api.MsigCancel(ctx, msig, txid, msig, big.Zero(), from, uint64(multisig.Methods.LockBalance), params)
|
||||
proto, err := api.MsigCancel(ctx, msig, txid, msig, big.Zero(), from, uint64(multisig.Methods.LockBalance), params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sm, err := InteractiveSend(ctx, cctx, srv, proto)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msgCid := sm.Cid()
|
||||
|
||||
fmt.Println("sent lock cancellation in message: ", msgCid)
|
||||
|
||||
wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence")))
|
||||
wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence")), build.Finality, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -1471,11 +1595,13 @@ var msigProposeThresholdCmd = &cli.Command{
|
||||
return ShowHelp(cctx, fmt.Errorf("must pass multisig address and new threshold value"))
|
||||
}
|
||||
|
||||
api, closer, err := GetFullNodeAPI(cctx)
|
||||
srv, err := GetFullNodeServices(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
defer srv.Close() //nolint:errcheck
|
||||
|
||||
api := srv.FullNodeAPI()
|
||||
ctx := ReqContext(cctx)
|
||||
|
||||
msig, err := address.NewFromString(cctx.Args().Get(0))
|
||||
@ -1511,14 +1637,21 @@ var msigProposeThresholdCmd = &cli.Command{
|
||||
return actErr
|
||||
}
|
||||
|
||||
msgCid, err := api.MsigPropose(ctx, msig, msig, types.NewInt(0), from, uint64(multisig.Methods.ChangeNumApprovalsThreshold), params)
|
||||
proto, err := api.MsigPropose(ctx, msig, msig, types.NewInt(0), from, uint64(multisig.Methods.ChangeNumApprovalsThreshold), params)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to propose change of threshold: %w", err)
|
||||
}
|
||||
|
||||
sm, err := InteractiveSend(ctx, cctx, srv, proto)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msgCid := sm.Cid()
|
||||
|
||||
fmt.Println("sent change threshold proposal in message: ", msgCid)
|
||||
|
||||
wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence")))
|
||||
wait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence")), build.Finality, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
24
cli/send.go
24
cli/send.go
@ -2,7 +2,6 @@ package cli
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
@ -59,10 +58,14 @@ var sendCmd = &cli.Command{
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "force",
|
||||
Usage: "must be specified for the action to take effect if maybe SysErrInsufficientFunds etc",
|
||||
Usage: "Deprecated: use global 'force-send'",
|
||||
},
|
||||
},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
if cctx.IsSet("force") {
|
||||
fmt.Println("'force' flag is deprecated, use global flag 'force-send'")
|
||||
}
|
||||
|
||||
if cctx.Args().Len() != 2 {
|
||||
return ShowHelp(cctx, fmt.Errorf("'send' expects two arguments, target and amount"))
|
||||
}
|
||||
@ -137,23 +140,22 @@ var sendCmd = &cli.Command{
|
||||
params.Params = decparams
|
||||
}
|
||||
|
||||
params.Force = cctx.Bool("force")
|
||||
|
||||
if cctx.IsSet("nonce") {
|
||||
n := cctx.Uint64("nonce")
|
||||
params.Nonce = &n
|
||||
}
|
||||
|
||||
msgCid, err := srv.Send(ctx, params)
|
||||
|
||||
proto, err := srv.MessageForSend(ctx, params)
|
||||
if err != nil {
|
||||
if errors.Is(err, ErrSendBalanceTooLow) {
|
||||
return fmt.Errorf("--force must be specified for this action to have an effect; you have been warned: %w", err)
|
||||
}
|
||||
return xerrors.Errorf("executing send: %w", err)
|
||||
return xerrors.Errorf("creating message prototype: %w", err)
|
||||
}
|
||||
|
||||
fmt.Fprintf(cctx.App.Writer, "%s\n", msgCid)
|
||||
sm, err := InteractiveSend(ctx, cctx, srv, proto)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Fprintf(cctx.App.Writer, "%s\n", sm.Cid())
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
@ -2,24 +2,17 @@ package cli
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
types "github.com/filecoin-project/lotus/chain/types"
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
cid "github.com/ipfs/go-cid"
|
||||
"github.com/stretchr/testify/assert"
|
||||
ucli "github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var arbtCid = (&types.Message{
|
||||
From: mustAddr(address.NewIDAddress(2)),
|
||||
To: mustAddr(address.NewIDAddress(1)),
|
||||
Value: types.NewInt(1000),
|
||||
}).Cid()
|
||||
|
||||
func mustAddr(a address.Address, err error) address.Address {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@ -49,80 +42,26 @@ func TestSendCLI(t *testing.T) {
|
||||
app, mockSrvcs, buf, done := newMockApp(t, sendCmd)
|
||||
defer done()
|
||||
|
||||
gomock.InOrder(
|
||||
mockSrvcs.EXPECT().Send(gomock.Any(), SendParams{
|
||||
To: mustAddr(address.NewIDAddress(1)),
|
||||
Val: oneFil,
|
||||
}).Return(arbtCid, nil),
|
||||
mockSrvcs.EXPECT().Close(),
|
||||
)
|
||||
err := app.Run([]string{"lotus", "send", "t01", "1"})
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, arbtCid.String()+"\n", buf.String())
|
||||
})
|
||||
t.Run("ErrSendBalanceTooLow", func(t *testing.T) {
|
||||
app, mockSrvcs, _, done := newMockApp(t, sendCmd)
|
||||
defer done()
|
||||
|
||||
gomock.InOrder(
|
||||
mockSrvcs.EXPECT().Send(gomock.Any(), SendParams{
|
||||
To: mustAddr(address.NewIDAddress(1)),
|
||||
Val: oneFil,
|
||||
}).Return(cid.Undef, ErrSendBalanceTooLow),
|
||||
mockSrvcs.EXPECT().Close(),
|
||||
)
|
||||
err := app.Run([]string{"lotus", "send", "t01", "1"})
|
||||
assert.ErrorIs(t, err, ErrSendBalanceTooLow)
|
||||
})
|
||||
t.Run("generic-err-is-forwarded", func(t *testing.T) {
|
||||
app, mockSrvcs, _, done := newMockApp(t, sendCmd)
|
||||
defer done()
|
||||
|
||||
errMark := errors.New("something")
|
||||
gomock.InOrder(
|
||||
mockSrvcs.EXPECT().Send(gomock.Any(), SendParams{
|
||||
To: mustAddr(address.NewIDAddress(1)),
|
||||
Val: oneFil,
|
||||
}).Return(cid.Undef, errMark),
|
||||
mockSrvcs.EXPECT().Close(),
|
||||
)
|
||||
err := app.Run([]string{"lotus", "send", "t01", "1"})
|
||||
assert.ErrorIs(t, err, errMark)
|
||||
})
|
||||
|
||||
t.Run("from-specific", func(t *testing.T) {
|
||||
app, mockSrvcs, buf, done := newMockApp(t, sendCmd)
|
||||
defer done()
|
||||
|
||||
gomock.InOrder(
|
||||
mockSrvcs.EXPECT().Send(gomock.Any(), SendParams{
|
||||
To: mustAddr(address.NewIDAddress(1)),
|
||||
From: mustAddr(address.NewIDAddress(2)),
|
||||
Val: oneFil,
|
||||
}).Return(arbtCid, nil),
|
||||
mockSrvcs.EXPECT().Close(),
|
||||
)
|
||||
err := app.Run([]string{"lotus", "send", "--from=t02", "t01", "1"})
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, arbtCid.String()+"\n", buf.String())
|
||||
})
|
||||
|
||||
t.Run("nonce-specific", func(t *testing.T) {
|
||||
app, mockSrvcs, buf, done := newMockApp(t, sendCmd)
|
||||
defer done()
|
||||
zero := uint64(0)
|
||||
|
||||
gomock.InOrder(
|
||||
mockSrvcs.EXPECT().Send(gomock.Any(), SendParams{
|
||||
arbtProto := &api.MessagePrototype{
|
||||
Message: types.Message{
|
||||
From: mustAddr(address.NewIDAddress(1)),
|
||||
To: mustAddr(address.NewIDAddress(1)),
|
||||
Nonce: &zero,
|
||||
Val: oneFil,
|
||||
}).Return(arbtCid, nil),
|
||||
Value: oneFil,
|
||||
},
|
||||
}
|
||||
sigMsg := fakeSign(&arbtProto.Message)
|
||||
|
||||
gomock.InOrder(
|
||||
mockSrvcs.EXPECT().MessageForSend(gomock.Any(), SendParams{
|
||||
To: mustAddr(address.NewIDAddress(1)),
|
||||
Val: oneFil,
|
||||
}).Return(arbtProto, nil),
|
||||
mockSrvcs.EXPECT().PublishMessage(gomock.Any(), arbtProto, false).
|
||||
Return(sigMsg, nil, nil),
|
||||
mockSrvcs.EXPECT().Close(),
|
||||
)
|
||||
err := app.Run([]string{"lotus", "send", "--nonce=0", "t01", "1"})
|
||||
err := app.Run([]string{"lotus", "send", "t01", "1"})
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, arbtCid.String()+"\n", buf.String())
|
||||
assert.EqualValues(t, sigMsg.Cid().String()+"\n", buf.String())
|
||||
})
|
||||
|
||||
}
|
||||
|
264
cli/sending_ui.go
Normal file
264
cli/sending_ui.go
Normal file
@ -0,0 +1,264 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"github.com/Kubuxu/imtui"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
types "github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/gdamore/tcell/v2"
|
||||
cid "github.com/ipfs/go-cid"
|
||||
"github.com/urfave/cli/v2"
|
||||
"golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
func InteractiveSend(ctx context.Context, cctx *cli.Context, srv ServicesAPI,
|
||||
proto *api.MessagePrototype) (*types.SignedMessage, error) {
|
||||
|
||||
msg, checks, err := srv.PublishMessage(ctx, proto, cctx.Bool("force") || cctx.Bool("force-send"))
|
||||
printer := cctx.App.Writer
|
||||
if xerrors.Is(err, ErrCheckFailed) {
|
||||
if !cctx.Bool("interactive") {
|
||||
fmt.Fprintf(printer, "Following checks have failed:\n")
|
||||
printChecks(printer, checks, proto.Message.Cid())
|
||||
} else {
|
||||
proto, err = resolveChecks(ctx, srv, cctx.App.Writer, proto, checks)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("from UI: %w", err)
|
||||
}
|
||||
|
||||
msg, _, err = srv.PublishMessage(ctx, proto, true)
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("publishing message: %w", err)
|
||||
}
|
||||
|
||||
return msg, nil
|
||||
}
|
||||
|
||||
var interactiveSolves = map[api.CheckStatusCode]bool{
|
||||
api.CheckStatusMessageMinBaseFee: true,
|
||||
api.CheckStatusMessageBaseFee: true,
|
||||
api.CheckStatusMessageBaseFeeLowerBound: true,
|
||||
api.CheckStatusMessageBaseFeeUpperBound: true,
|
||||
}
|
||||
|
||||
func baseFeeFromHints(hint map[string]interface{}) big.Int {
|
||||
bHint, ok := hint["baseFee"]
|
||||
if !ok {
|
||||
return big.Zero()
|
||||
}
|
||||
bHintS, ok := bHint.(string)
|
||||
if !ok {
|
||||
return big.Zero()
|
||||
}
|
||||
|
||||
var err error
|
||||
baseFee, err := big.FromString(bHintS)
|
||||
if err != nil {
|
||||
return big.Zero()
|
||||
}
|
||||
return baseFee
|
||||
}
|
||||
|
||||
func resolveChecks(ctx context.Context, s ServicesAPI, printer io.Writer,
|
||||
proto *api.MessagePrototype, checkGroups [][]api.MessageCheckStatus,
|
||||
) (*api.MessagePrototype, error) {
|
||||
|
||||
fmt.Fprintf(printer, "Following checks have failed:\n")
|
||||
printChecks(printer, checkGroups, proto.Message.Cid())
|
||||
|
||||
if feeCapBad, baseFee := isFeeCapProblem(checkGroups, proto.Message.Cid()); feeCapBad {
|
||||
fmt.Fprintf(printer, "Fee of the message can be adjusted\n")
|
||||
if askUser(printer, "Do you wish to do that? [Yes/no]: ", true) {
|
||||
var err error
|
||||
proto, err = runFeeCapAdjustmentUI(proto, baseFee)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
checks, err := s.RunChecksForPrototype(ctx, proto)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fmt.Fprintf(printer, "Following checks still failed:\n")
|
||||
printChecks(printer, checks, proto.Message.Cid())
|
||||
}
|
||||
|
||||
if !askUser(printer, "Do you wish to send this message? [yes/No]: ", false) {
|
||||
return nil, ErrAbortedByUser
|
||||
}
|
||||
return proto, nil
|
||||
}
|
||||
|
||||
var ErrAbortedByUser = errors.New("aborted by user")
|
||||
|
||||
func printChecks(printer io.Writer, checkGroups [][]api.MessageCheckStatus, protoCid cid.Cid) {
|
||||
for _, checks := range checkGroups {
|
||||
for _, c := range checks {
|
||||
if c.OK {
|
||||
continue
|
||||
}
|
||||
aboutProto := c.Cid.Equals(protoCid)
|
||||
msgName := "current"
|
||||
if !aboutProto {
|
||||
msgName = c.Cid.String()
|
||||
}
|
||||
fmt.Fprintf(printer, "%s message failed a check %s: %s\n", msgName, c.Code, c.Err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func askUser(printer io.Writer, q string, def bool) bool {
|
||||
var resp string
|
||||
fmt.Fprint(printer, q)
|
||||
fmt.Scanln(&resp)
|
||||
resp = strings.ToLower(resp)
|
||||
if len(resp) == 0 {
|
||||
return def
|
||||
}
|
||||
return resp[0] == 'y'
|
||||
}
|
||||
|
||||
func isFeeCapProblem(checkGroups [][]api.MessageCheckStatus, protoCid cid.Cid) (bool, big.Int) {
|
||||
baseFee := big.Zero()
|
||||
yes := false
|
||||
for _, checks := range checkGroups {
|
||||
for _, c := range checks {
|
||||
if c.OK {
|
||||
continue
|
||||
}
|
||||
aboutProto := c.Cid.Equals(protoCid)
|
||||
if aboutProto && interactiveSolves[c.Code] {
|
||||
yes = true
|
||||
if baseFee.IsZero() {
|
||||
baseFee = baseFeeFromHints(c.Hint)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if baseFee.IsZero() {
|
||||
// this will only be the case if failing check is: MessageMinBaseFee
|
||||
baseFee = big.NewInt(build.MinimumBaseFee)
|
||||
}
|
||||
|
||||
return yes, baseFee
|
||||
}
|
||||
|
||||
func runFeeCapAdjustmentUI(proto *api.MessagePrototype, baseFee abi.TokenAmount) (*api.MessagePrototype, error) {
|
||||
t, err := imtui.NewTui()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
maxFee := big.Mul(proto.Message.GasFeeCap, big.NewInt(proto.Message.GasLimit))
|
||||
send := false
|
||||
t.PushScene(feeUI(baseFee, proto.Message.GasLimit, &maxFee, &send))
|
||||
|
||||
err = t.Run()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !send {
|
||||
return nil, fmt.Errorf("aborted by user")
|
||||
}
|
||||
|
||||
proto.Message.GasFeeCap = big.Div(maxFee, big.NewInt(proto.Message.GasLimit))
|
||||
|
||||
return proto, nil
|
||||
}
|
||||
|
||||
func feeUI(baseFee abi.TokenAmount, gasLimit int64, maxFee *abi.TokenAmount, send *bool) func(*imtui.Tui) error {
|
||||
orignalMaxFee := *maxFee
|
||||
required := big.Mul(baseFee, big.NewInt(gasLimit))
|
||||
safe := big.Mul(required, big.NewInt(10))
|
||||
|
||||
price := fmt.Sprintf("%s", types.FIL(*maxFee).Unitless())
|
||||
|
||||
return func(t *imtui.Tui) error {
|
||||
if t.CurrentKey != nil {
|
||||
if t.CurrentKey.Key() == tcell.KeyRune {
|
||||
pF, err := types.ParseFIL(price)
|
||||
switch t.CurrentKey.Rune() {
|
||||
case 's', 'S':
|
||||
price = types.FIL(safe).Unitless()
|
||||
case '+':
|
||||
if err == nil {
|
||||
p := big.Mul(big.Int(pF), types.NewInt(11))
|
||||
p = big.Div(p, types.NewInt(10))
|
||||
price = fmt.Sprintf("%s", types.FIL(p).Unitless())
|
||||
}
|
||||
case '-':
|
||||
if err == nil {
|
||||
p := big.Mul(big.Int(pF), types.NewInt(10))
|
||||
p = big.Div(p, types.NewInt(11))
|
||||
price = fmt.Sprintf("%s", types.FIL(p).Unitless())
|
||||
}
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
if t.CurrentKey.Key() == tcell.KeyEnter {
|
||||
*send = true
|
||||
t.PopScene()
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
defS := tcell.StyleDefault
|
||||
|
||||
row := 0
|
||||
t.Label(0, row, "Fee of the message is too low.", defS)
|
||||
row++
|
||||
|
||||
t.Label(0, row, fmt.Sprintf("Your configured maximum fee is: %s FIL",
|
||||
types.FIL(orignalMaxFee).Unitless()), defS)
|
||||
row++
|
||||
t.Label(0, row, fmt.Sprintf("Required maximum fee for the message: %s FIL",
|
||||
types.FIL(required).Unitless()), defS)
|
||||
row++
|
||||
w := t.Label(0, row, fmt.Sprintf("Safe maximum fee for the message: %s FIL",
|
||||
types.FIL(safe).Unitless()), defS)
|
||||
t.Label(w, row, " Press S to use it", defS)
|
||||
row++
|
||||
|
||||
w = t.Label(0, row, "Current Maximum Fee: ", defS)
|
||||
|
||||
w += t.EditFieldFiltered(w, row, 14, &price, imtui.FilterDecimal, defS.Foreground(tcell.ColorWhite).Background(tcell.ColorBlack))
|
||||
|
||||
w += t.Label(w, row, " FIL", defS)
|
||||
|
||||
pF, err := types.ParseFIL(price)
|
||||
*maxFee = abi.TokenAmount(pF)
|
||||
if err != nil {
|
||||
w += t.Label(w, row, " invalid price", defS.Foreground(tcell.ColorMaroon).Bold(true))
|
||||
} else if maxFee.GreaterThanEqual(safe) {
|
||||
w += t.Label(w, row, " SAFE", defS.Foreground(tcell.ColorDarkGreen).Bold(true))
|
||||
} else if maxFee.GreaterThanEqual(required) {
|
||||
w += t.Label(w, row, " low", defS.Foreground(tcell.ColorYellow).Bold(true))
|
||||
over := big.Div(big.Mul(*maxFee, big.NewInt(100)), required)
|
||||
w += t.Label(w, row,
|
||||
fmt.Sprintf(" %.1fx over the minimum", float64(over.Int64())/100.0), defS)
|
||||
} else {
|
||||
w += t.Label(w, row, " too low", defS.Foreground(tcell.ColorRed).Bold(true))
|
||||
}
|
||||
row += 2
|
||||
|
||||
t.Label(0, row, fmt.Sprintf("Current Base Fee is: %s", types.FIL(baseFee).Nano()), defS)
|
||||
row++
|
||||
t.Label(0, row, fmt.Sprintf("Resulting FeeCap is: %s",
|
||||
types.FIL(big.Div(*maxFee, big.NewInt(gasLimit))).Nano()), defS)
|
||||
row++
|
||||
t.Label(0, row, "You can use '+' and '-' to adjust the fee.", defS)
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
204
cli/services.go
204
cli/services.go
@ -4,14 +4,14 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-jsonrpc"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/lotus/api/v0api"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/chain/stmgr"
|
||||
types "github.com/filecoin-project/lotus/chain/types"
|
||||
cid "github.com/ipfs/go-cid"
|
||||
@ -22,12 +22,30 @@ import (
|
||||
//go:generate go run github.com/golang/mock/mockgen -destination=servicesmock_test.go -package=cli -self_package github.com/filecoin-project/lotus/cli . ServicesAPI
|
||||
|
||||
type ServicesAPI interface {
|
||||
// Sends executes a send given SendParams
|
||||
Send(ctx context.Context, params SendParams) (cid.Cid, error)
|
||||
FullNodeAPI() api.FullNode
|
||||
|
||||
GetBaseFee(ctx context.Context) (abi.TokenAmount, error)
|
||||
|
||||
// MessageForSend creates a prototype of a message based on SendParams
|
||||
MessageForSend(ctx context.Context, params SendParams) (*api.MessagePrototype, error)
|
||||
|
||||
// DecodeTypedParamsFromJSON takes in information needed to identify a method and converts JSON
|
||||
// parameters to bytes of their CBOR encoding
|
||||
DecodeTypedParamsFromJSON(ctx context.Context, to address.Address, method abi.MethodNum, paramstr string) ([]byte, error)
|
||||
|
||||
RunChecksForPrototype(ctx context.Context, prototype *api.MessagePrototype) ([][]api.MessageCheckStatus, error)
|
||||
|
||||
// PublishMessage takes in a message prototype and publishes it
|
||||
// before publishing the message, it runs checks on the node, message and mpool to verify that
|
||||
// message is valid and won't be stuck.
|
||||
// if `force` is true, it skips the checks
|
||||
PublishMessage(ctx context.Context, prototype *api.MessagePrototype, force bool) (*types.SignedMessage, [][]api.MessageCheckStatus, error)
|
||||
|
||||
LocalAddresses(ctx context.Context) (address.Address, []address.Address, error)
|
||||
|
||||
MpoolPendingFilter(ctx context.Context, filter func(*types.SignedMessage) bool, tsk types.TipSetKey) ([]*types.SignedMessage, error)
|
||||
MpoolCheckPendingMessages(ctx context.Context, a address.Address) ([][]api.MessageCheckStatus, error)
|
||||
|
||||
// Close ends the session of services and disconnects from RPC, using Services after Close is called
|
||||
// most likely will result in an error
|
||||
// Should not be called concurrently
|
||||
@ -35,10 +53,14 @@ type ServicesAPI interface {
|
||||
}
|
||||
|
||||
type ServicesImpl struct {
|
||||
api v0api.FullNode
|
||||
api api.FullNode
|
||||
closer jsonrpc.ClientCloser
|
||||
}
|
||||
|
||||
func (s *ServicesImpl) FullNodeAPI() api.FullNode {
|
||||
return s.api
|
||||
}
|
||||
|
||||
func (s *ServicesImpl) Close() error {
|
||||
if s.closer == nil {
|
||||
return xerrors.Errorf("Services already closed")
|
||||
@ -48,6 +70,16 @@ func (s *ServicesImpl) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *ServicesImpl) GetBaseFee(ctx context.Context) (abi.TokenAmount, error) {
|
||||
// not used but useful
|
||||
|
||||
ts, err := s.api.ChainHead(ctx)
|
||||
if err != nil {
|
||||
return big.Zero(), xerrors.Errorf("getting head: %w", err)
|
||||
}
|
||||
return ts.MinTicketBlock().ParentBaseFee, nil
|
||||
}
|
||||
|
||||
func (s *ServicesImpl) DecodeTypedParamsFromJSON(ctx context.Context, to address.Address, method abi.MethodNum, paramstr string) ([]byte, error) {
|
||||
act, err := s.api.StateGetActor(ctx, to, types.EmptyTSK)
|
||||
if err != nil {
|
||||
@ -72,6 +104,79 @@ func (s *ServicesImpl) DecodeTypedParamsFromJSON(ctx context.Context, to address
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
type CheckInfo struct {
|
||||
MessageTie cid.Cid
|
||||
CurrentMessageTie bool
|
||||
|
||||
Check api.MessageCheckStatus
|
||||
}
|
||||
|
||||
var ErrCheckFailed = fmt.Errorf("check has failed")
|
||||
|
||||
func (s *ServicesImpl) RunChecksForPrototype(ctx context.Context, prototype *api.MessagePrototype) ([][]api.MessageCheckStatus, error) {
|
||||
var outChecks [][]api.MessageCheckStatus
|
||||
checks, err := s.api.MpoolCheckMessages(ctx, []*api.MessagePrototype{prototype})
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("message check: %w", err)
|
||||
}
|
||||
outChecks = append(outChecks, checks...)
|
||||
|
||||
checks, err = s.api.MpoolCheckPendingMessages(ctx, prototype.Message.From)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("pending mpool check: %w", err)
|
||||
}
|
||||
outChecks = append(outChecks, checks...)
|
||||
|
||||
return outChecks, nil
|
||||
}
|
||||
|
||||
// PublishMessage modifies prototype to include gas estimation
|
||||
// Errors with ErrCheckFailed if any of the checks fail
|
||||
// First group of checks is related to the message prototype
|
||||
func (s *ServicesImpl) PublishMessage(ctx context.Context,
|
||||
prototype *api.MessagePrototype, force bool) (*types.SignedMessage, [][]api.MessageCheckStatus, error) {
|
||||
|
||||
gasedMsg, err := s.api.GasEstimateMessageGas(ctx, &prototype.Message, nil, types.EmptyTSK)
|
||||
if err != nil {
|
||||
return nil, nil, xerrors.Errorf("estimating gas: %w", err)
|
||||
}
|
||||
prototype.Message = *gasedMsg
|
||||
|
||||
if !force {
|
||||
checks, err := s.RunChecksForPrototype(ctx, prototype)
|
||||
if err != nil {
|
||||
return nil, nil, xerrors.Errorf("running checks: %w", err)
|
||||
}
|
||||
for _, chks := range checks {
|
||||
for _, c := range chks {
|
||||
if !c.OK {
|
||||
return nil, checks, ErrCheckFailed
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if prototype.ValidNonce {
|
||||
sm, err := s.api.WalletSignMessage(ctx, prototype.Message.From, &prototype.Message)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
_, err = s.api.MpoolPush(ctx, sm)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return sm, nil, nil
|
||||
}
|
||||
|
||||
sm, err := s.api.MpoolPushMessage(ctx, &prototype.Message, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return sm, nil, nil
|
||||
}
|
||||
|
||||
type SendParams struct {
|
||||
To address.Address
|
||||
From address.Address
|
||||
@ -84,26 +189,18 @@ type SendParams struct {
|
||||
Nonce *uint64
|
||||
Method abi.MethodNum
|
||||
Params []byte
|
||||
|
||||
Force bool
|
||||
}
|
||||
|
||||
// This is specialised Send for Send command
|
||||
// There might be room for generic Send that other commands can use to send their messages
|
||||
// We will see
|
||||
|
||||
var ErrSendBalanceTooLow = errors.New("balance too low")
|
||||
|
||||
func (s *ServicesImpl) Send(ctx context.Context, params SendParams) (cid.Cid, error) {
|
||||
func (s *ServicesImpl) MessageForSend(ctx context.Context, params SendParams) (*api.MessagePrototype, error) {
|
||||
if params.From == address.Undef {
|
||||
defaddr, err := s.api.WalletDefaultAddress(ctx)
|
||||
if err != nil {
|
||||
return cid.Undef, err
|
||||
return nil, err
|
||||
}
|
||||
params.From = defaddr
|
||||
}
|
||||
|
||||
msg := &types.Message{
|
||||
msg := types.Message{
|
||||
From: params.From,
|
||||
To: params.To,
|
||||
Value: params.Val,
|
||||
@ -127,40 +224,53 @@ func (s *ServicesImpl) Send(ctx context.Context, params SendParams) (cid.Cid, er
|
||||
} else {
|
||||
msg.GasLimit = 0
|
||||
}
|
||||
|
||||
if !params.Force {
|
||||
// Funds insufficient check
|
||||
fromBalance, err := s.api.WalletBalance(ctx, msg.From)
|
||||
if err != nil {
|
||||
return cid.Undef, err
|
||||
}
|
||||
totalCost := types.BigAdd(types.BigMul(msg.GasFeeCap, types.NewInt(uint64(msg.GasLimit))), msg.Value)
|
||||
|
||||
if fromBalance.LessThan(totalCost) {
|
||||
return cid.Undef, xerrors.Errorf("From balance %s less than total cost %s: %w", types.FIL(fromBalance), types.FIL(totalCost), ErrSendBalanceTooLow)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
validNonce := false
|
||||
if params.Nonce != nil {
|
||||
msg.Nonce = *params.Nonce
|
||||
sm, err := s.api.WalletSignMessage(ctx, params.From, msg)
|
||||
if err != nil {
|
||||
return cid.Undef, err
|
||||
}
|
||||
|
||||
_, err = s.api.MpoolPush(ctx, sm)
|
||||
if err != nil {
|
||||
return cid.Undef, err
|
||||
}
|
||||
|
||||
return sm.Cid(), nil
|
||||
validNonce = true
|
||||
}
|
||||
|
||||
sm, err := s.api.MpoolPushMessage(ctx, msg, nil)
|
||||
if err != nil {
|
||||
return cid.Undef, err
|
||||
prototype := &api.MessagePrototype{
|
||||
Message: msg,
|
||||
ValidNonce: validNonce,
|
||||
}
|
||||
|
||||
return sm.Cid(), nil
|
||||
return prototype, nil
|
||||
}
|
||||
|
||||
func (s *ServicesImpl) MpoolPendingFilter(ctx context.Context, filter func(*types.SignedMessage) bool,
|
||||
tsk types.TipSetKey) ([]*types.SignedMessage, error) {
|
||||
msgs, err := s.api.MpoolPending(ctx, types.EmptyTSK)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("getting pending messages: %w", err)
|
||||
}
|
||||
out := []*types.SignedMessage{}
|
||||
for _, sm := range msgs {
|
||||
if filter(sm) {
|
||||
out = append(out, sm)
|
||||
}
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (s *ServicesImpl) LocalAddresses(ctx context.Context) (address.Address, []address.Address, error) {
|
||||
def, err := s.api.WalletDefaultAddress(ctx)
|
||||
if err != nil {
|
||||
return address.Undef, nil, xerrors.Errorf("getting default addr: %w", err)
|
||||
}
|
||||
|
||||
all, err := s.api.WalletList(ctx)
|
||||
if err != nil {
|
||||
return address.Undef, nil, xerrors.Errorf("getting list of addrs: %w", err)
|
||||
}
|
||||
|
||||
return def, all, nil
|
||||
}
|
||||
|
||||
func (s *ServicesImpl) MpoolCheckPendingMessages(ctx context.Context, a address.Address) ([][]api.MessageCheckStatus, error) {
|
||||
checks, err := s.api.MpoolCheckPendingMessages(ctx, a)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("pending mpool check: %w", err)
|
||||
}
|
||||
return checks, nil
|
||||
}
|
||||
|
@ -9,10 +9,9 @@ import (
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
mocks "github.com/filecoin-project/lotus/api/v0api/v0mocks"
|
||||
mocks "github.com/filecoin-project/lotus/api/mocks"
|
||||
types "github.com/filecoin-project/lotus/chain/types"
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
cid "github.com/ipfs/go-cid"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
@ -61,6 +60,7 @@ func setupMockSrvcs(t *testing.T) (*ServicesImpl, *mocks.MockFullNode) {
|
||||
return srvcs, mockApi
|
||||
}
|
||||
|
||||
// linter doesn't like dead code, so these are commented out.
|
||||
func fakeSign(msg *types.Message) *types.SignedMessage {
|
||||
return &types.SignedMessage{
|
||||
Message: *msg,
|
||||
@ -68,15 +68,15 @@ func fakeSign(msg *types.Message) *types.SignedMessage {
|
||||
}
|
||||
}
|
||||
|
||||
func makeMessageSigner() (*cid.Cid, interface{}) {
|
||||
smCid := cid.Undef
|
||||
return &smCid,
|
||||
func(_ context.Context, msg *types.Message, _ *api.MessageSendSpec) (*types.SignedMessage, error) {
|
||||
sm := fakeSign(msg)
|
||||
smCid = sm.Cid()
|
||||
return sm, nil
|
||||
}
|
||||
}
|
||||
//func makeMessageSigner() (*cid.Cid, interface{}) {
|
||||
//smCid := cid.Undef
|
||||
//return &smCid,
|
||||
//func(_ context.Context, msg *types.Message, _ *api.MessageSendSpec) (*types.SignedMessage, error) {
|
||||
//sm := fakeSign(msg)
|
||||
//smCid = sm.Cid()
|
||||
//return sm, nil
|
||||
//}
|
||||
//}
|
||||
|
||||
type MessageMatcher SendParams
|
||||
|
||||
@ -84,11 +84,13 @@ var _ gomock.Matcher = MessageMatcher{}
|
||||
|
||||
// Matches returns whether x is a match.
|
||||
func (mm MessageMatcher) Matches(x interface{}) bool {
|
||||
m, ok := x.(*types.Message)
|
||||
proto, ok := x.(*api.MessagePrototype)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
m := &proto.Message
|
||||
|
||||
if mm.From != address.Undef && mm.From != m.From {
|
||||
return false
|
||||
}
|
||||
@ -151,47 +153,12 @@ func TestSendService(t *testing.T) {
|
||||
|
||||
t.Run("happy", func(t *testing.T) {
|
||||
params := params
|
||||
srvcs, mockApi := setupMockSrvcs(t)
|
||||
srvcs, _ := setupMockSrvcs(t)
|
||||
defer srvcs.Close() //nolint:errcheck
|
||||
msgCid, sign := makeMessageSigner()
|
||||
gomock.InOrder(
|
||||
mockApi.EXPECT().WalletBalance(ctxM, params.From).Return(types.NewInt(balance), nil),
|
||||
mockApi.EXPECT().MpoolPushMessage(ctxM, MessageMatcher(params), nil).DoAndReturn(sign),
|
||||
)
|
||||
|
||||
c, err := srvcs.Send(ctx, params)
|
||||
proto, err := srvcs.MessageForSend(ctx, params)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, *msgCid, c)
|
||||
})
|
||||
|
||||
t.Run("balance-too-low", func(t *testing.T) {
|
||||
params := params
|
||||
srvcs, mockApi := setupMockSrvcs(t)
|
||||
defer srvcs.Close() //nolint:errcheck
|
||||
gomock.InOrder(
|
||||
mockApi.EXPECT().WalletBalance(ctxM, a1).Return(types.NewInt(balance-200), nil),
|
||||
// no MpoolPushMessage
|
||||
)
|
||||
|
||||
c, err := srvcs.Send(ctx, params)
|
||||
assert.Equal(t, c, cid.Undef)
|
||||
assert.ErrorIs(t, err, ErrSendBalanceTooLow)
|
||||
})
|
||||
|
||||
t.Run("force", func(t *testing.T) {
|
||||
params := params
|
||||
params.Force = true
|
||||
srvcs, mockApi := setupMockSrvcs(t)
|
||||
defer srvcs.Close() //nolint:errcheck
|
||||
msgCid, sign := makeMessageSigner()
|
||||
gomock.InOrder(
|
||||
mockApi.EXPECT().WalletBalance(ctxM, a1).Return(types.NewInt(balance-200), nil).AnyTimes(),
|
||||
mockApi.EXPECT().MpoolPushMessage(ctxM, MessageMatcher(params), nil).DoAndReturn(sign),
|
||||
)
|
||||
|
||||
c, err := srvcs.Send(ctx, params)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, *msgCid, c)
|
||||
assert.True(t, MessageMatcher(params).Matches(proto))
|
||||
})
|
||||
|
||||
t.Run("default-from", func(t *testing.T) {
|
||||
@ -202,16 +169,14 @@ func TestSendService(t *testing.T) {
|
||||
|
||||
srvcs, mockApi := setupMockSrvcs(t)
|
||||
defer srvcs.Close() //nolint:errcheck
|
||||
msgCid, sign := makeMessageSigner()
|
||||
|
||||
gomock.InOrder(
|
||||
mockApi.EXPECT().WalletDefaultAddress(ctxM).Return(a1, nil),
|
||||
mockApi.EXPECT().WalletBalance(ctxM, a1).Return(types.NewInt(balance), nil),
|
||||
mockApi.EXPECT().MpoolPushMessage(ctxM, mm, nil).DoAndReturn(sign),
|
||||
)
|
||||
|
||||
c, err := srvcs.Send(ctx, params)
|
||||
proto, err := srvcs.MessageForSend(ctx, params)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, *msgCid, c)
|
||||
assert.True(t, mm.Matches(proto))
|
||||
})
|
||||
|
||||
t.Run("set-nonce", func(t *testing.T) {
|
||||
@ -220,26 +185,12 @@ func TestSendService(t *testing.T) {
|
||||
params.Nonce = &n
|
||||
mm := MessageMatcher(params)
|
||||
|
||||
srvcs, mockApi := setupMockSrvcs(t)
|
||||
srvcs, _ := setupMockSrvcs(t)
|
||||
defer srvcs.Close() //nolint:errcheck
|
||||
_, _ = mm, mockApi
|
||||
|
||||
var sm *types.SignedMessage
|
||||
gomock.InOrder(
|
||||
mockApi.EXPECT().WalletBalance(ctxM, a1).Return(types.NewInt(balance), nil),
|
||||
mockApi.EXPECT().WalletSignMessage(ctxM, a1, mm).DoAndReturn(
|
||||
func(_ context.Context, _ address.Address, msg *types.Message) (*types.SignedMessage, error) {
|
||||
sm = fakeSign(msg)
|
||||
|
||||
// now we expect MpoolPush with that SignedMessage
|
||||
mockApi.EXPECT().MpoolPush(ctxM, sm).Return(sm.Cid(), nil)
|
||||
return sm, nil
|
||||
}),
|
||||
)
|
||||
|
||||
c, err := srvcs.Send(ctx, params)
|
||||
proto, err := srvcs.MessageForSend(ctx, params)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, sm.Cid(), c)
|
||||
assert.True(t, mm.Matches(proto))
|
||||
})
|
||||
|
||||
t.Run("gas-params", func(t *testing.T) {
|
||||
@ -251,16 +202,14 @@ func TestSendService(t *testing.T) {
|
||||
gp := big.NewInt(10)
|
||||
params.GasPremium = &gp
|
||||
|
||||
srvcs, mockApi := setupMockSrvcs(t)
|
||||
defer srvcs.Close() //nolint:errcheck
|
||||
msgCid, sign := makeMessageSigner()
|
||||
gomock.InOrder(
|
||||
mockApi.EXPECT().WalletBalance(ctxM, params.From).Return(types.NewInt(balance), nil),
|
||||
mockApi.EXPECT().MpoolPushMessage(ctxM, MessageMatcher(params), nil).DoAndReturn(sign),
|
||||
)
|
||||
mm := MessageMatcher(params)
|
||||
|
||||
c, err := srvcs.Send(ctx, params)
|
||||
srvcs, _ := setupMockSrvcs(t)
|
||||
defer srvcs.Close() //nolint:errcheck
|
||||
|
||||
proto, err := srvcs.MessageForSend(ctx, params)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, *msgCid, c)
|
||||
assert.True(t, mm.Matches(proto))
|
||||
|
||||
})
|
||||
}
|
||||
|
@ -8,8 +8,10 @@ import (
|
||||
context "context"
|
||||
go_address "github.com/filecoin-project/go-address"
|
||||
abi "github.com/filecoin-project/go-state-types/abi"
|
||||
big "github.com/filecoin-project/go-state-types/big"
|
||||
api "github.com/filecoin-project/lotus/api"
|
||||
types "github.com/filecoin-project/lotus/chain/types"
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
go_cid "github.com/ipfs/go-cid"
|
||||
reflect "reflect"
|
||||
)
|
||||
|
||||
@ -65,17 +67,123 @@ func (mr *MockServicesAPIMockRecorder) DecodeTypedParamsFromJSON(arg0, arg1, arg
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DecodeTypedParamsFromJSON", reflect.TypeOf((*MockServicesAPI)(nil).DecodeTypedParamsFromJSON), arg0, arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
// Send mocks base method
|
||||
func (m *MockServicesAPI) Send(arg0 context.Context, arg1 SendParams) (go_cid.Cid, error) {
|
||||
// FullNodeAPI mocks base method
|
||||
func (m *MockServicesAPI) FullNodeAPI() api.FullNode {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Send", arg0, arg1)
|
||||
ret0, _ := ret[0].(go_cid.Cid)
|
||||
ret := m.ctrl.Call(m, "FullNodeAPI")
|
||||
ret0, _ := ret[0].(api.FullNode)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// FullNodeAPI indicates an expected call of FullNodeAPI
|
||||
func (mr *MockServicesAPIMockRecorder) FullNodeAPI() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FullNodeAPI", reflect.TypeOf((*MockServicesAPI)(nil).FullNodeAPI))
|
||||
}
|
||||
|
||||
// GetBaseFee mocks base method
|
||||
func (m *MockServicesAPI) GetBaseFee(arg0 context.Context) (big.Int, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetBaseFee", arg0)
|
||||
ret0, _ := ret[0].(big.Int)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Send indicates an expected call of Send
|
||||
func (mr *MockServicesAPIMockRecorder) Send(arg0, arg1 interface{}) *gomock.Call {
|
||||
// GetBaseFee indicates an expected call of GetBaseFee
|
||||
func (mr *MockServicesAPIMockRecorder) GetBaseFee(arg0 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Send", reflect.TypeOf((*MockServicesAPI)(nil).Send), arg0, arg1)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBaseFee", reflect.TypeOf((*MockServicesAPI)(nil).GetBaseFee), arg0)
|
||||
}
|
||||
|
||||
// LocalAddresses mocks base method
|
||||
func (m *MockServicesAPI) LocalAddresses(arg0 context.Context) (go_address.Address, []go_address.Address, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "LocalAddresses", arg0)
|
||||
ret0, _ := ret[0].(go_address.Address)
|
||||
ret1, _ := ret[1].([]go_address.Address)
|
||||
ret2, _ := ret[2].(error)
|
||||
return ret0, ret1, ret2
|
||||
}
|
||||
|
||||
// LocalAddresses indicates an expected call of LocalAddresses
|
||||
func (mr *MockServicesAPIMockRecorder) LocalAddresses(arg0 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LocalAddresses", reflect.TypeOf((*MockServicesAPI)(nil).LocalAddresses), arg0)
|
||||
}
|
||||
|
||||
// MessageForSend mocks base method
|
||||
func (m *MockServicesAPI) MessageForSend(arg0 context.Context, arg1 SendParams) (*api.MessagePrototype, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "MessageForSend", arg0, arg1)
|
||||
ret0, _ := ret[0].(*api.MessagePrototype)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// MessageForSend indicates an expected call of MessageForSend
|
||||
func (mr *MockServicesAPIMockRecorder) MessageForSend(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MessageForSend", reflect.TypeOf((*MockServicesAPI)(nil).MessageForSend), arg0, arg1)
|
||||
}
|
||||
|
||||
// MpoolCheckPendingMessages mocks base method
|
||||
func (m *MockServicesAPI) MpoolCheckPendingMessages(arg0 context.Context, arg1 go_address.Address) ([][]api.MessageCheckStatus, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "MpoolCheckPendingMessages", arg0, arg1)
|
||||
ret0, _ := ret[0].([][]api.MessageCheckStatus)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// MpoolCheckPendingMessages indicates an expected call of MpoolCheckPendingMessages
|
||||
func (mr *MockServicesAPIMockRecorder) MpoolCheckPendingMessages(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolCheckPendingMessages", reflect.TypeOf((*MockServicesAPI)(nil).MpoolCheckPendingMessages), arg0, arg1)
|
||||
}
|
||||
|
||||
// MpoolPendingFilter mocks base method
|
||||
func (m *MockServicesAPI) MpoolPendingFilter(arg0 context.Context, arg1 func(*types.SignedMessage) bool, arg2 types.TipSetKey) ([]*types.SignedMessage, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "MpoolPendingFilter", arg0, arg1, arg2)
|
||||
ret0, _ := ret[0].([]*types.SignedMessage)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// MpoolPendingFilter indicates an expected call of MpoolPendingFilter
|
||||
func (mr *MockServicesAPIMockRecorder) MpoolPendingFilter(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MpoolPendingFilter", reflect.TypeOf((*MockServicesAPI)(nil).MpoolPendingFilter), arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// PublishMessage mocks base method
|
||||
func (m *MockServicesAPI) PublishMessage(arg0 context.Context, arg1 *api.MessagePrototype, arg2 bool) (*types.SignedMessage, [][]api.MessageCheckStatus, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "PublishMessage", arg0, arg1, arg2)
|
||||
ret0, _ := ret[0].(*types.SignedMessage)
|
||||
ret1, _ := ret[1].([][]api.MessageCheckStatus)
|
||||
ret2, _ := ret[2].(error)
|
||||
return ret0, ret1, ret2
|
||||
}
|
||||
|
||||
// PublishMessage indicates an expected call of PublishMessage
|
||||
func (mr *MockServicesAPIMockRecorder) PublishMessage(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PublishMessage", reflect.TypeOf((*MockServicesAPI)(nil).PublishMessage), arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// RunChecksForPrototype mocks base method
|
||||
func (m *MockServicesAPI) RunChecksForPrototype(arg0 context.Context, arg1 *api.MessagePrototype) ([][]api.MessageCheckStatus, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "RunChecksForPrototype", arg0, arg1)
|
||||
ret0, _ := ret[0].([][]api.MessageCheckStatus)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// RunChecksForPrototype indicates an expected call of RunChecksForPrototype
|
||||
func (mr *MockServicesAPIMockRecorder) RunChecksForPrototype(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RunChecksForPrototype", reflect.TypeOf((*MockServicesAPI)(nil).RunChecksForPrototype), arg0, arg1)
|
||||
}
|
||||
|
60
cli/status.go
Normal file
60
cli/status.go
Normal file
@ -0,0 +1,60 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
)
|
||||
|
||||
var StatusCmd = &cli.Command{
|
||||
Name: "status",
|
||||
Usage: "Check node status",
|
||||
Flags: []cli.Flag{
|
||||
&cli.BoolFlag{
|
||||
Name: "chain",
|
||||
Usage: "include chain health status",
|
||||
},
|
||||
},
|
||||
|
||||
Action: func(cctx *cli.Context) error {
|
||||
apic, closer, err := GetFullNodeAPIV1(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
ctx := ReqContext(cctx)
|
||||
|
||||
inclChainStatus := cctx.Bool("chain")
|
||||
|
||||
status, err := apic.NodeStatus(ctx, inclChainStatus)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("Sync Epoch: %d\n", status.SyncStatus.Epoch)
|
||||
fmt.Printf("Epochs Behind: %d\n", status.SyncStatus.Behind)
|
||||
fmt.Printf("Peers to Publish Messages: %d\n", status.PeerStatus.PeersToPublishMsgs)
|
||||
fmt.Printf("Peers to Publish Blocks: %d\n", status.PeerStatus.PeersToPublishBlocks)
|
||||
|
||||
if inclChainStatus && status.SyncStatus.Epoch > uint64(build.Finality) {
|
||||
var ok100, okFin string
|
||||
if status.ChainStatus.BlocksPerTipsetLast100 >= 4.75 {
|
||||
ok100 = "[OK]"
|
||||
} else {
|
||||
ok100 = "[UNHEALTHY]"
|
||||
}
|
||||
if status.ChainStatus.BlocksPerTipsetLastFinality >= 4.75 {
|
||||
okFin = "[OK]"
|
||||
} else {
|
||||
okFin = "[UNHEALTHY]"
|
||||
}
|
||||
|
||||
fmt.Printf("Blocks per TipSet in last 100 epochs: %f %s\n", status.ChainStatus.BlocksPerTipsetLast100, ok100)
|
||||
fmt.Printf("Blocks per TipSet in last finality: %f %s\n", status.ChainStatus.BlocksPerTipsetLastFinality, okFin)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
@ -56,7 +56,7 @@ type MockCLIClient struct {
|
||||
|
||||
func (c *MockCLIClient) RunCmd(input ...string) string {
|
||||
out, err := c.RunCmdRaw(input...)
|
||||
require.NoError(c.t, err)
|
||||
require.NoError(c.t, err, "output:\n%s", out)
|
||||
|
||||
return out
|
||||
}
|
||||
|
@ -9,4 +9,6 @@ func QuietMiningLogs() {
|
||||
_ = log.SetLogLevel("sub", "ERROR")
|
||||
_ = log.SetLogLevel("storageminer", "ERROR")
|
||||
_ = log.SetLogLevel("pubsub", "ERROR")
|
||||
_ = log.SetLogLevel("gen", "ERROR")
|
||||
_ = log.SetLogLevel("dht/RtRefreshManager", "ERROR")
|
||||
}
|
||||
|
@ -18,6 +18,8 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-jsonrpc"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
@ -102,7 +104,28 @@ func TestWalletMsig(t *testing.T) {
|
||||
// Create an msig with three of the addresses and threshold of two sigs
|
||||
msigAddrs := walletAddrs[:3]
|
||||
amt := types.NewInt(1000)
|
||||
addProposal, err := lite.MsigCreate(ctx, 2, msigAddrs, abi.ChainEpoch(50), amt, liteWalletAddr, types.NewInt(0))
|
||||
proto, err := lite.MsigCreate(ctx, 2, msigAddrs, abi.ChainEpoch(50), amt, liteWalletAddr, types.NewInt(0))
|
||||
require.NoError(t, err)
|
||||
|
||||
doSend := func(proto *api.MessagePrototype) (cid.Cid, error) {
|
||||
if proto.ValidNonce {
|
||||
sm, err := lite.WalletSignMessage(ctx, proto.Message.From, &proto.Message)
|
||||
if err != nil {
|
||||
return cid.Undef, err
|
||||
}
|
||||
|
||||
return lite.MpoolPush(ctx, sm)
|
||||
}
|
||||
|
||||
sm, err := lite.MpoolPushMessage(ctx, &proto.Message, nil)
|
||||
if err != nil {
|
||||
return cid.Undef, err
|
||||
}
|
||||
|
||||
return sm.Cid(), nil
|
||||
}
|
||||
|
||||
addProposal, err := doSend(proto)
|
||||
require.NoError(t, err)
|
||||
|
||||
res, err := lite.StateWaitMsg(ctx, addProposal, 1, api.LookbackNoLimit, true)
|
||||
@ -122,7 +145,10 @@ func TestWalletMsig(t *testing.T) {
|
||||
require.Less(t, msigBalance.Int64(), amt.Int64())
|
||||
|
||||
// Propose to add a new address to the msig
|
||||
addProposal, err = lite.MsigAddPropose(ctx, msig, walletAddrs[0], walletAddrs[3], false)
|
||||
proto, err = lite.MsigAddPropose(ctx, msig, walletAddrs[0], walletAddrs[3], false)
|
||||
require.NoError(t, err)
|
||||
|
||||
addProposal, err = doSend(proto)
|
||||
require.NoError(t, err)
|
||||
|
||||
res, err = lite.StateWaitMsg(ctx, addProposal, 1, api.LookbackNoLimit, true)
|
||||
@ -136,7 +162,10 @@ func TestWalletMsig(t *testing.T) {
|
||||
// Approve proposal (proposer is first (implicit) signer, approver is
|
||||
// second signer
|
||||
txnID := uint64(proposeReturn.TxnID)
|
||||
approval1, err := lite.MsigAddApprove(ctx, msig, walletAddrs[1], txnID, walletAddrs[0], walletAddrs[3], false)
|
||||
proto, err = lite.MsigAddApprove(ctx, msig, walletAddrs[1], txnID, walletAddrs[0], walletAddrs[3], false)
|
||||
require.NoError(t, err)
|
||||
|
||||
approval1, err := doSend(proto)
|
||||
require.NoError(t, err)
|
||||
|
||||
res, err = lite.StateWaitMsg(ctx, approval1, 1, api.LookbackNoLimit, true)
|
||||
@ -304,7 +333,7 @@ func sendFunds(ctx context.Context, fromNode test.TestNode, fromAddr address.Add
|
||||
return err
|
||||
}
|
||||
|
||||
res, err := fromNode.StateWaitMsg(ctx, sm.Cid(), 1, api.LookbackNoLimit, true)
|
||||
res, err := fromNode.StateWaitMsg(ctx, sm.Cid(), 3, api.LookbackNoLimit, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -67,11 +67,13 @@ var verifRegAddVerifierCmd = &cli.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
api, closer, err := lcli.GetFullNodeAPI(cctx)
|
||||
srv, err := lcli.GetFullNodeServices(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
defer srv.Close() //nolint:errcheck
|
||||
|
||||
api := srv.FullNodeAPI()
|
||||
ctx := lcli.ReqContext(cctx)
|
||||
|
||||
vrk, err := api.StateVerifiedRegistryRootKey(ctx, types.EmptyTSK)
|
||||
@ -79,14 +81,21 @@ var verifRegAddVerifierCmd = &cli.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
smsg, err := api.MsigPropose(ctx, vrk, verifreg.Address, big.Zero(), sender, uint64(verifreg.Methods.AddVerifier), params)
|
||||
proto, err := api.MsigPropose(ctx, vrk, verifreg.Address, big.Zero(), sender, uint64(verifreg.Methods.AddVerifier), params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("message sent, now waiting on cid: %s\n", smsg)
|
||||
sm, _, err := srv.PublishMessage(ctx, proto, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mwait, err := api.StateWaitMsg(ctx, smsg, build.MessageConfidence)
|
||||
msgCid := sm.Cid()
|
||||
|
||||
fmt.Printf("message sent, now waiting on cid: %s\n", msgCid)
|
||||
|
||||
mwait, err := api.StateWaitMsg(ctx, msgCid, uint64(cctx.Int("confidence")), build.Finality, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -2,7 +2,9 @@ package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
|
||||
"github.com/mattn/go-isatty"
|
||||
"github.com/urfave/cli/v2"
|
||||
"go.opencensus.io/trace"
|
||||
|
||||
@ -52,6 +54,8 @@ func main() {
|
||||
ctx, span := trace.StartSpan(context.Background(), "/cli")
|
||||
defer span.End()
|
||||
|
||||
interactiveDef := isatty.IsTerminal(os.Stdout.Fd()) || isatty.IsCygwinTerminal(os.Stdout.Fd())
|
||||
|
||||
app := &cli.App{
|
||||
Name: "lotus",
|
||||
Usage: "Filecoin decentralized storage network client",
|
||||
@ -64,10 +68,20 @@ func main() {
|
||||
Hidden: true,
|
||||
Value: "~/.lotus", // TODO: Consider XDG_DATA_HOME
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "interactive",
|
||||
Usage: "setting to false will disable interactive functionality of commands",
|
||||
Value: interactiveDef,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "force-send",
|
||||
Usage: "if true, will ignore pre-send checks",
|
||||
},
|
||||
},
|
||||
|
||||
Commands: append(local, lcli.Commands...),
|
||||
}
|
||||
|
||||
app.Setup()
|
||||
app.Metadata["traceContext"] = ctx
|
||||
app.Metadata["repoType"] = repo.FullNode
|
||||
|
@ -82,6 +82,9 @@
|
||||
* [MpoolBatchPush](#MpoolBatchPush)
|
||||
* [MpoolBatchPushMessage](#MpoolBatchPushMessage)
|
||||
* [MpoolBatchPushUntrusted](#MpoolBatchPushUntrusted)
|
||||
* [MpoolCheckMessages](#MpoolCheckMessages)
|
||||
* [MpoolCheckPendingMessages](#MpoolCheckPendingMessages)
|
||||
* [MpoolCheckReplaceMessages](#MpoolCheckReplaceMessages)
|
||||
* [MpoolClear](#MpoolClear)
|
||||
* [MpoolGetConfig](#MpoolGetConfig)
|
||||
* [MpoolGetNonce](#MpoolGetNonce)
|
||||
@ -126,6 +129,8 @@
|
||||
* [NetPeerInfo](#NetPeerInfo)
|
||||
* [NetPeers](#NetPeers)
|
||||
* [NetPubsubScores](#NetPubsubScores)
|
||||
* [Node](#Node)
|
||||
* [NodeStatus](#NodeStatus)
|
||||
* [Paych](#Paych)
|
||||
* [PaychAllocateLane](#PaychAllocateLane)
|
||||
* [PaychAvailableFunds](#PaychAvailableFunds)
|
||||
@ -1991,6 +1996,51 @@ Inputs:
|
||||
|
||||
Response: `null`
|
||||
|
||||
### MpoolCheckMessages
|
||||
MpoolCheckMessages performs logical checks on a batch of messages
|
||||
|
||||
|
||||
Perms: read
|
||||
|
||||
Inputs:
|
||||
```json
|
||||
[
|
||||
null
|
||||
]
|
||||
```
|
||||
|
||||
Response: `null`
|
||||
|
||||
### MpoolCheckPendingMessages
|
||||
MpoolCheckPendingMessages performs logical checks for all pending messages from a given address
|
||||
|
||||
|
||||
Perms: read
|
||||
|
||||
Inputs:
|
||||
```json
|
||||
[
|
||||
"f01234"
|
||||
]
|
||||
```
|
||||
|
||||
Response: `null`
|
||||
|
||||
### MpoolCheckReplaceMessages
|
||||
MpoolCheckReplaceMessages performs logical checks on pending messages with replacement
|
||||
|
||||
|
||||
Perms: read
|
||||
|
||||
Inputs:
|
||||
```json
|
||||
[
|
||||
null
|
||||
]
|
||||
```
|
||||
|
||||
Response: `null`
|
||||
|
||||
### MpoolClear
|
||||
MpoolClear clears pending messages from the mpool
|
||||
|
||||
@ -2324,7 +2374,22 @@ Inputs:
|
||||
Response:
|
||||
```json
|
||||
{
|
||||
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
|
||||
"Message": {
|
||||
"Version": 42,
|
||||
"To": "f01234",
|
||||
"From": "f01234",
|
||||
"Nonce": 42,
|
||||
"Value": "0",
|
||||
"GasLimit": 9,
|
||||
"GasFeeCap": "0",
|
||||
"GasPremium": "0",
|
||||
"Method": 1,
|
||||
"Params": "Ynl0ZSBhcnJheQ==",
|
||||
"CID": {
|
||||
"/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s"
|
||||
}
|
||||
},
|
||||
"ValidNonce": true
|
||||
}
|
||||
```
|
||||
|
||||
@ -2350,7 +2415,22 @@ Inputs:
|
||||
Response:
|
||||
```json
|
||||
{
|
||||
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
|
||||
"Message": {
|
||||
"Version": 42,
|
||||
"To": "f01234",
|
||||
"From": "f01234",
|
||||
"Nonce": 42,
|
||||
"Value": "0",
|
||||
"GasLimit": 9,
|
||||
"GasFeeCap": "0",
|
||||
"GasPremium": "0",
|
||||
"Method": 1,
|
||||
"Params": "Ynl0ZSBhcnJheQ==",
|
||||
"CID": {
|
||||
"/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s"
|
||||
}
|
||||
},
|
||||
"ValidNonce": true
|
||||
}
|
||||
```
|
||||
|
||||
@ -2375,7 +2455,22 @@ Inputs:
|
||||
Response:
|
||||
```json
|
||||
{
|
||||
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
|
||||
"Message": {
|
||||
"Version": 42,
|
||||
"To": "f01234",
|
||||
"From": "f01234",
|
||||
"Nonce": 42,
|
||||
"Value": "0",
|
||||
"GasLimit": 9,
|
||||
"GasFeeCap": "0",
|
||||
"GasPremium": "0",
|
||||
"Method": 1,
|
||||
"Params": "Ynl0ZSBhcnJheQ==",
|
||||
"CID": {
|
||||
"/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s"
|
||||
}
|
||||
},
|
||||
"ValidNonce": true
|
||||
}
|
||||
```
|
||||
|
||||
@ -2398,7 +2493,22 @@ Inputs:
|
||||
Response:
|
||||
```json
|
||||
{
|
||||
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
|
||||
"Message": {
|
||||
"Version": 42,
|
||||
"To": "f01234",
|
||||
"From": "f01234",
|
||||
"Nonce": 42,
|
||||
"Value": "0",
|
||||
"GasLimit": 9,
|
||||
"GasFeeCap": "0",
|
||||
"GasPremium": "0",
|
||||
"Method": 1,
|
||||
"Params": "Ynl0ZSBhcnJheQ==",
|
||||
"CID": {
|
||||
"/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s"
|
||||
}
|
||||
},
|
||||
"ValidNonce": true
|
||||
}
|
||||
```
|
||||
|
||||
@ -2430,7 +2540,22 @@ Inputs:
|
||||
Response:
|
||||
```json
|
||||
{
|
||||
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
|
||||
"Message": {
|
||||
"Version": 42,
|
||||
"To": "f01234",
|
||||
"From": "f01234",
|
||||
"Nonce": 42,
|
||||
"Value": "0",
|
||||
"GasLimit": 9,
|
||||
"GasFeeCap": "0",
|
||||
"GasPremium": "0",
|
||||
"Method": 1,
|
||||
"Params": "Ynl0ZSBhcnJheQ==",
|
||||
"CID": {
|
||||
"/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s"
|
||||
}
|
||||
},
|
||||
"ValidNonce": true
|
||||
}
|
||||
```
|
||||
|
||||
@ -2458,7 +2583,22 @@ Inputs:
|
||||
Response:
|
||||
```json
|
||||
{
|
||||
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
|
||||
"Message": {
|
||||
"Version": 42,
|
||||
"To": "f01234",
|
||||
"From": "f01234",
|
||||
"Nonce": 42,
|
||||
"Value": "0",
|
||||
"GasLimit": 9,
|
||||
"GasFeeCap": "0",
|
||||
"GasPremium": "0",
|
||||
"Method": 1,
|
||||
"Params": "Ynl0ZSBhcnJheQ==",
|
||||
"CID": {
|
||||
"/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s"
|
||||
}
|
||||
},
|
||||
"ValidNonce": true
|
||||
}
|
||||
```
|
||||
|
||||
@ -2485,7 +2625,22 @@ Inputs:
|
||||
Response:
|
||||
```json
|
||||
{
|
||||
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
|
||||
"Message": {
|
||||
"Version": 42,
|
||||
"To": "f01234",
|
||||
"From": "f01234",
|
||||
"Nonce": 42,
|
||||
"Value": "0",
|
||||
"GasLimit": 9,
|
||||
"GasFeeCap": "0",
|
||||
"GasPremium": "0",
|
||||
"Method": 1,
|
||||
"Params": "Ynl0ZSBhcnJheQ==",
|
||||
"CID": {
|
||||
"/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s"
|
||||
}
|
||||
},
|
||||
"ValidNonce": true
|
||||
}
|
||||
```
|
||||
|
||||
@ -2622,7 +2777,22 @@ Inputs:
|
||||
Response:
|
||||
```json
|
||||
{
|
||||
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
|
||||
"Message": {
|
||||
"Version": 42,
|
||||
"To": "f01234",
|
||||
"From": "f01234",
|
||||
"Nonce": 42,
|
||||
"Value": "0",
|
||||
"GasLimit": 9,
|
||||
"GasFeeCap": "0",
|
||||
"GasPremium": "0",
|
||||
"Method": 1,
|
||||
"Params": "Ynl0ZSBhcnJheQ==",
|
||||
"CID": {
|
||||
"/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s"
|
||||
}
|
||||
},
|
||||
"ValidNonce": true
|
||||
}
|
||||
```
|
||||
|
||||
@ -2649,7 +2819,22 @@ Inputs:
|
||||
Response:
|
||||
```json
|
||||
{
|
||||
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
|
||||
"Message": {
|
||||
"Version": 42,
|
||||
"To": "f01234",
|
||||
"From": "f01234",
|
||||
"Nonce": 42,
|
||||
"Value": "0",
|
||||
"GasLimit": 9,
|
||||
"GasFeeCap": "0",
|
||||
"GasPremium": "0",
|
||||
"Method": 1,
|
||||
"Params": "Ynl0ZSBhcnJheQ==",
|
||||
"CID": {
|
||||
"/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s"
|
||||
}
|
||||
},
|
||||
"ValidNonce": true
|
||||
}
|
||||
```
|
||||
|
||||
@ -2676,7 +2861,22 @@ Inputs:
|
||||
Response:
|
||||
```json
|
||||
{
|
||||
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
|
||||
"Message": {
|
||||
"Version": 42,
|
||||
"To": "f01234",
|
||||
"From": "f01234",
|
||||
"Nonce": 42,
|
||||
"Value": "0",
|
||||
"GasLimit": 9,
|
||||
"GasFeeCap": "0",
|
||||
"GasPremium": "0",
|
||||
"Method": 1,
|
||||
"Params": "Ynl0ZSBhcnJheQ==",
|
||||
"CID": {
|
||||
"/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s"
|
||||
}
|
||||
},
|
||||
"ValidNonce": true
|
||||
}
|
||||
```
|
||||
|
||||
@ -2702,7 +2902,22 @@ Inputs:
|
||||
Response:
|
||||
```json
|
||||
{
|
||||
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
|
||||
"Message": {
|
||||
"Version": 42,
|
||||
"To": "f01234",
|
||||
"From": "f01234",
|
||||
"Nonce": 42,
|
||||
"Value": "0",
|
||||
"GasLimit": 9,
|
||||
"GasFeeCap": "0",
|
||||
"GasPremium": "0",
|
||||
"Method": 1,
|
||||
"Params": "Ynl0ZSBhcnJheQ==",
|
||||
"CID": {
|
||||
"/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s"
|
||||
}
|
||||
},
|
||||
"ValidNonce": true
|
||||
}
|
||||
```
|
||||
|
||||
@ -2727,7 +2942,22 @@ Inputs:
|
||||
Response:
|
||||
```json
|
||||
{
|
||||
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
|
||||
"Message": {
|
||||
"Version": 42,
|
||||
"To": "f01234",
|
||||
"From": "f01234",
|
||||
"Nonce": 42,
|
||||
"Value": "0",
|
||||
"GasLimit": 9,
|
||||
"GasFeeCap": "0",
|
||||
"GasPremium": "0",
|
||||
"Method": 1,
|
||||
"Params": "Ynl0ZSBhcnJheQ==",
|
||||
"CID": {
|
||||
"/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s"
|
||||
}
|
||||
},
|
||||
"ValidNonce": true
|
||||
}
|
||||
```
|
||||
|
||||
@ -3000,6 +3230,40 @@ Inputs: `null`
|
||||
|
||||
Response: `null`
|
||||
|
||||
## Node
|
||||
These methods are general node management and status commands
|
||||
|
||||
|
||||
### NodeStatus
|
||||
There are not yet any comments for this method.
|
||||
|
||||
Perms: read
|
||||
|
||||
Inputs:
|
||||
```json
|
||||
[
|
||||
true
|
||||
]
|
||||
```
|
||||
|
||||
Response:
|
||||
```json
|
||||
{
|
||||
"SyncStatus": {
|
||||
"Epoch": 42,
|
||||
"Behind": 42
|
||||
},
|
||||
"PeerStatus": {
|
||||
"PeersToPublishMsgs": 123,
|
||||
"PeersToPublishBlocks": 123
|
||||
},
|
||||
"ChainStatus": {
|
||||
"BlocksPerTipsetLast100": 12.3,
|
||||
"BlocksPerTipsetLastFinality": 12.3
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Paych
|
||||
The Paych methods are for interacting with and managing payment channels
|
||||
|
||||
|
@ -31,8 +31,12 @@ COMMANDS:
|
||||
NETWORK:
|
||||
net Manage P2P Network
|
||||
sync Inspect or interact with the chain syncer
|
||||
STATUS:
|
||||
status Check node status
|
||||
|
||||
GLOBAL OPTIONS:
|
||||
--interactive setting to false will disable interactive functionality of commands (default: false)
|
||||
--force-send if true, will ignore pre-send checks (default: false)
|
||||
--help, -h show help (default: false)
|
||||
--version, -v print the version (default: false)
|
||||
```
|
||||
@ -136,7 +140,7 @@ OPTIONS:
|
||||
--method value specify method to invoke (default: 0)
|
||||
--params-json value specify invocation parameters in json
|
||||
--params-hex value specify invocation parameters in hex
|
||||
--force must be specified for the action to take effect if maybe SysErrInsufficientFunds etc (default: false)
|
||||
--force Deprecated: use global 'force-send' (default: false)
|
||||
--help, -h show help (default: false)
|
||||
|
||||
```
|
||||
@ -1299,6 +1303,7 @@ COMMANDS:
|
||||
find find a message in the mempool
|
||||
config get or set current mpool configuration
|
||||
gas-perf Check gas performance of messages in mempool
|
||||
manage
|
||||
help, h Shows a list of commands or help for one command
|
||||
|
||||
OPTIONS:
|
||||
@ -1412,6 +1417,9 @@ OPTIONS:
|
||||
--help, -h show help (default: false)
|
||||
|
||||
```
|
||||
# nage
|
||||
```
|
||||
```
|
||||
|
||||
## lotus state
|
||||
```
|
||||
@ -2671,3 +2679,20 @@ OPTIONS:
|
||||
--help, -h show help (default: false)
|
||||
|
||||
```
|
||||
|
||||
## lotus status
|
||||
```
|
||||
NAME:
|
||||
lotus status - Check node status
|
||||
|
||||
USAGE:
|
||||
lotus status [command options] [arguments...]
|
||||
|
||||
CATEGORY:
|
||||
STATUS
|
||||
|
||||
OPTIONS:
|
||||
--chain include chain health status (default: false)
|
||||
--help, -h show help (default: false)
|
||||
|
||||
```
|
||||
|
6
go.mod
6
go.mod
@ -8,6 +8,7 @@ require (
|
||||
github.com/BurntSushi/toml v0.3.1
|
||||
github.com/GeertJohan/go.rice v1.0.0
|
||||
github.com/Gurpartap/async v0.0.0-20180927173644-4f7f499dd9ee
|
||||
github.com/Kubuxu/imtui v0.0.0-20210401140320-41663d68d0fa
|
||||
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect
|
||||
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d
|
||||
github.com/alecthomas/jsonschema v0.0.0-20200530073317-71f438968921
|
||||
@ -50,6 +51,7 @@ require (
|
||||
github.com/filecoin-project/specs-storage v0.1.1-0.20201105051918-5188d9774506
|
||||
github.com/filecoin-project/test-vectors/schema v0.0.5
|
||||
github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1
|
||||
github.com/gdamore/tcell/v2 v2.2.0
|
||||
github.com/go-kit/kit v0.10.0
|
||||
github.com/go-ole/go-ole v1.2.4 // indirect
|
||||
github.com/golang/mock v1.4.4
|
||||
@ -86,7 +88,7 @@ require (
|
||||
github.com/ipfs/go-ipfs-util v0.0.2
|
||||
github.com/ipfs/go-ipld-cbor v0.0.5
|
||||
github.com/ipfs/go-ipld-format v0.2.0
|
||||
github.com/ipfs/go-log/v2 v2.1.2-0.20200626104915-0016c0b4b3e4
|
||||
github.com/ipfs/go-log/v2 v2.1.2
|
||||
github.com/ipfs/go-merkledag v0.3.2
|
||||
github.com/ipfs/go-metrics-interface v0.0.1
|
||||
github.com/ipfs/go-metrics-prometheus v0.0.2
|
||||
@ -116,6 +118,7 @@ require (
|
||||
github.com/libp2p/go-libp2p-yamux v0.4.1
|
||||
github.com/libp2p/go-maddr-filter v0.1.0
|
||||
github.com/mattn/go-colorable v0.1.6 // indirect
|
||||
github.com/mattn/go-isatty v0.0.12
|
||||
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1
|
||||
github.com/mitchellh/go-homedir v1.1.0
|
||||
github.com/multiformats/go-base32 v0.0.3
|
||||
@ -150,6 +153,7 @@ require (
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0
|
||||
golang.org/x/tools v0.0.0-20201112185108-eeaa07dd7696
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.28
|
||||
|
18
go.sum
18
go.sum
@ -42,6 +42,8 @@ github.com/Gurpartap/async v0.0.0-20180927173644-4f7f499dd9ee h1:8doiS7ib3zi6/K1
|
||||
github.com/Gurpartap/async v0.0.0-20180927173644-4f7f499dd9ee/go.mod h1:W0GbEAA4uFNYOGG2cJpmFJ04E6SD1NLELPYZB57/7AY=
|
||||
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
|
||||
github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y=
|
||||
github.com/Kubuxu/imtui v0.0.0-20210401140320-41663d68d0fa h1:1PPxEyGdIGVkX/kqMvLJ95a1dGS1Sz7tpNEgehEYYt0=
|
||||
github.com/Kubuxu/imtui v0.0.0-20210401140320-41663d68d0fa/go.mod h1:WUmMvh9wMtqj1Xhf1hf3kp9RvL+y6odtdYxpyZjb90U=
|
||||
github.com/Masterminds/glide v0.13.2/go.mod h1:STyF5vcenH/rUqTEv+/hBXlSTo7KYwg2oc2f4tzPWic=
|
||||
github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
|
||||
github.com/Masterminds/vcs v1.13.0/go.mod h1:N09YCmOQr6RLxC6UNHzuVwAdodYbbnycGHSmwVJjcKA=
|
||||
@ -330,6 +332,10 @@ github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWo
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1 h1:EzDjxMg43q1tA2c0MV3tNbaontnHLplHyFF6M5KiVP0=
|
||||
github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1/go.mod h1:0eHX/BVySxPc6SE2mZRoppGq7qcEagxdmQnA3dzork8=
|
||||
github.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko=
|
||||
github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg=
|
||||
github.com/gdamore/tcell/v2 v2.2.0 h1:vSyEgKwraXPSOkvCk7IwOSyX+Pv3V2cV9CikJMXg4U4=
|
||||
github.com/gdamore/tcell/v2 v2.2.0/go.mod h1:cTTuF84Dlj/RqmaCIV5p4w8uG1zWdk0SF6oBpwHp4fU=
|
||||
github.com/getsentry/raven-go v0.2.0 h1:no+xWJRb5ZI7eE8TWgIq1jLulQiIoLG0IfYxv5JYMGs=
|
||||
github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ=
|
||||
github.com/ghemawat/stream v0.0.0-20171120220530-696b145b53b9/go.mod h1:106OIgooyS7OzLDOpUGgm9fA3bQENb/cFSyyBmMoJDs=
|
||||
@ -672,8 +678,9 @@ github.com/ipfs/go-log/v2 v2.0.3/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBW
|
||||
github.com/ipfs/go-log/v2 v2.0.5/go.mod h1:eZs4Xt4ZUJQFM3DlanGhy7TkwwawCZcSByscwkWG+dw=
|
||||
github.com/ipfs/go-log/v2 v2.0.8/go.mod h1:eZs4Xt4ZUJQFM3DlanGhy7TkwwawCZcSByscwkWG+dw=
|
||||
github.com/ipfs/go-log/v2 v2.1.1/go.mod h1:2v2nsGfZsvvAJz13SyFzf9ObaqwHiHxsPLEHntrv9KM=
|
||||
github.com/ipfs/go-log/v2 v2.1.2-0.20200626104915-0016c0b4b3e4 h1:3bijxqzQ1O9yg7gd7Aqk80oaEvsJ+uXw0zSvi2qR3Jw=
|
||||
github.com/ipfs/go-log/v2 v2.1.2-0.20200626104915-0016c0b4b3e4/go.mod h1:2v2nsGfZsvvAJz13SyFzf9ObaqwHiHxsPLEHntrv9KM=
|
||||
github.com/ipfs/go-log/v2 v2.1.2 h1:a0dRiL098zY23vay1h3dimx6y94XchEUyt5h0l4VvQU=
|
||||
github.com/ipfs/go-log/v2 v2.1.2/go.mod h1:2v2nsGfZsvvAJz13SyFzf9ObaqwHiHxsPLEHntrv9KM=
|
||||
github.com/ipfs/go-merkledag v0.0.3/go.mod h1:Oc5kIXLHokkE1hWGMBHw+oxehkAaTOqtEb7Zbh6BhLA=
|
||||
github.com/ipfs/go-merkledag v0.0.6/go.mod h1:QYPdnlvkOg7GnQRofu9XZimC5ZW5Wi3bKys/4GQQfto=
|
||||
github.com/ipfs/go-merkledag v0.2.3/go.mod h1:SQiXrtSts3KGNmgOzMICy5c0POOpUNQLvB3ClKnBAlk=
|
||||
@ -1110,6 +1117,8 @@ github.com/lucas-clemente/quic-go v0.11.2/go.mod h1:PpMmPfPKO9nKJ/psF49ESTAGQSdf
|
||||
github.com/lucas-clemente/quic-go v0.16.0/go.mod h1:I0+fcNTdb9eS1ZcjQZbDVPGchJ86chcIxPALn9lEJqE=
|
||||
github.com/lucas-clemente/quic-go v0.18.1 h1:DMR7guC0NtVS8zNZR3IO7NARZvZygkSC56GGtC6cyys=
|
||||
github.com/lucas-clemente/quic-go v0.18.1/go.mod h1:yXttHsSNxQi8AWijC/vLP+OJczXqzHSOcJrM5ITUlCg=
|
||||
github.com/lucasb-eyer/go-colorful v1.0.3 h1:QIbQXiugsb+q10B+MI+7DI1oQLdmnep86tWFlaaUAac=
|
||||
github.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
|
||||
github.com/lufia/iostat v1.1.0/go.mod h1:rEPNA0xXgjHQjuI5Cy05sLlS2oRcSlWHRLrvh/AQ+Pg=
|
||||
github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=
|
||||
github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
|
||||
@ -1143,8 +1152,9 @@ github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOA
|
||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-runewidth v0.0.7 h1:Ei8KR0497xHyKJPAv59M1dkC+rOZCMBJ+t3fZ+twI54=
|
||||
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-runewidth v0.0.10 h1:CoZ3S2P7pvtP45xOtBw+/mDL2z0RKI576gSkzRRpdGg=
|
||||
github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
|
||||
github.com/mattn/go-xmlrpc v0.0.3/go.mod h1:mqc2dz7tP5x5BKlCahN/n+hs7OSZKJkS9JsHNBRlrxA=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
@ -1369,6 +1379,8 @@ github.com/raulk/go-watchdog v1.0.1/go.mod h1:lzSbAl5sh4rtI8tYHU01BWIDzgzqaQLj6R
|
||||
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/rivo/uniseg v0.1.0 h1:+2KBaVoUmb9XzDsrx/Ct0W/EYOSFf/nWTauy++DprtY=
|
||||
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
@ -1814,6 +1826,8 @@ golang.org/x/sys v0.0.0-20200926100807-9d91bd62050c/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 h1:nxC68pudNYkKU6jWhgrqdreuFiOQWj1Fs7T3VrH4Pjw=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf h1:MZ2shdL+ZM/XzY3ZGOnh4Nlpnxz5GSOhOmtHo3iPU6M=
|
||||
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
|
@ -333,6 +333,7 @@ var ChainNode = Options(
|
||||
|
||||
// Lite node API
|
||||
ApplyIf(isLiteNode,
|
||||
Override(new(messagepool.Provider), messagepool.NewProviderLite),
|
||||
Override(new(messagesigner.MpoolNonceAPI), From(new(modules.MpoolNonceAPI))),
|
||||
Override(new(full.ChainModuleAPI), From(new(api.Gateway))),
|
||||
Override(new(full.GasModuleAPI), From(new(api.Gateway))),
|
||||
@ -343,6 +344,7 @@ var ChainNode = Options(
|
||||
|
||||
// Full node API / service startup
|
||||
ApplyIf(isFullNode,
|
||||
Override(new(messagepool.Provider), messagepool.NewProvider),
|
||||
Override(new(messagesigner.MpoolNonceAPI), From(new(*messagepool.MessagePool))),
|
||||
Override(new(full.ChainModuleAPI), From(new(full.ChainModule))),
|
||||
Override(new(full.GasModuleAPI), From(new(full.GasModule))),
|
||||
|
@ -2,16 +2,21 @@ package impl
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
|
||||
logging "github.com/ipfs/go-log/v2"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/node/impl/client"
|
||||
"github.com/filecoin-project/lotus/node/impl/common"
|
||||
"github.com/filecoin-project/lotus/node/impl/full"
|
||||
"github.com/filecoin-project/lotus/node/impl/market"
|
||||
"github.com/filecoin-project/lotus/node/impl/paych"
|
||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||
"github.com/filecoin-project/lotus/node/modules/lp2p"
|
||||
)
|
||||
|
||||
var log = logging.Logger("node")
|
||||
@ -30,11 +35,86 @@ type FullNodeAPI struct {
|
||||
full.SyncAPI
|
||||
full.BeaconAPI
|
||||
|
||||
DS dtypes.MetadataDS
|
||||
DS dtypes.MetadataDS
|
||||
NetworkName dtypes.NetworkName
|
||||
}
|
||||
|
||||
func (n *FullNodeAPI) CreateBackup(ctx context.Context, fpath string) error {
|
||||
return backup(n.DS, fpath)
|
||||
}
|
||||
|
||||
func (n *FullNodeAPI) NodeStatus(ctx context.Context, inclChainStatus bool) (status api.NodeStatus, err error) {
|
||||
curTs, err := n.ChainHead(ctx)
|
||||
if err != nil {
|
||||
return status, err
|
||||
}
|
||||
|
||||
status.SyncStatus.Epoch = uint64(curTs.Height())
|
||||
timestamp := time.Unix(int64(curTs.MinTimestamp()), 0)
|
||||
delta := time.Since(timestamp).Seconds()
|
||||
status.SyncStatus.Behind = uint64(delta / 30)
|
||||
|
||||
// get peers in the messages and blocks topics
|
||||
peersMsgs := make(map[peer.ID]struct{})
|
||||
peersBlocks := make(map[peer.ID]struct{})
|
||||
|
||||
for _, p := range n.PubSub.ListPeers(build.MessagesTopic(n.NetworkName)) {
|
||||
peersMsgs[p] = struct{}{}
|
||||
}
|
||||
|
||||
for _, p := range n.PubSub.ListPeers(build.BlocksTopic(n.NetworkName)) {
|
||||
peersBlocks[p] = struct{}{}
|
||||
}
|
||||
|
||||
// get scores for all connected and recent peers
|
||||
scores, err := n.NetPubsubScores(ctx)
|
||||
if err != nil {
|
||||
return status, err
|
||||
}
|
||||
|
||||
for _, score := range scores {
|
||||
if score.Score.Score > lp2p.PublishScoreThreshold {
|
||||
_, inMsgs := peersMsgs[score.ID]
|
||||
if inMsgs {
|
||||
status.PeerStatus.PeersToPublishMsgs++
|
||||
}
|
||||
|
||||
_, inBlocks := peersBlocks[score.ID]
|
||||
if inBlocks {
|
||||
status.PeerStatus.PeersToPublishBlocks++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if inclChainStatus && status.SyncStatus.Epoch > uint64(build.Finality) {
|
||||
blockCnt := 0
|
||||
ts := curTs
|
||||
|
||||
for i := 0; i < 100; i++ {
|
||||
blockCnt += len(ts.Blocks())
|
||||
tsk := ts.Parents()
|
||||
ts, err = n.ChainGetTipSet(ctx, tsk)
|
||||
if err != nil {
|
||||
return status, err
|
||||
}
|
||||
}
|
||||
|
||||
status.ChainStatus.BlocksPerTipsetLast100 = float64(blockCnt) / 100
|
||||
|
||||
for i := 100; i < int(build.Finality); i++ {
|
||||
blockCnt += len(ts.Blocks())
|
||||
tsk := ts.Parents()
|
||||
ts, err = n.ChainGetTipSet(ctx, tsk)
|
||||
if err != nil {
|
||||
return status, err
|
||||
}
|
||||
}
|
||||
|
||||
status.ChainStatus.BlocksPerTipsetLastFinality = float64(blockCnt) / float64(build.Finality)
|
||||
|
||||
}
|
||||
|
||||
return status, nil
|
||||
}
|
||||
|
||||
var _ api.FullNode = &FullNodeAPI{}
|
||||
|
@ -225,6 +225,18 @@ func (a *MpoolAPI) MpoolBatchPushMessage(ctx context.Context, msgs []*types.Mess
|
||||
return smsgs, nil
|
||||
}
|
||||
|
||||
func (a *MpoolAPI) MpoolCheckMessages(ctx context.Context, protos []*api.MessagePrototype) ([][]api.MessageCheckStatus, error) {
|
||||
return a.Mpool.CheckMessages(protos)
|
||||
}
|
||||
|
||||
func (a *MpoolAPI) MpoolCheckPendingMessages(ctx context.Context, from address.Address) ([][]api.MessageCheckStatus, error) {
|
||||
return a.Mpool.CheckPendingMessages(from)
|
||||
}
|
||||
|
||||
func (a *MpoolAPI) MpoolCheckReplaceMessages(ctx context.Context, msgs []*types.Message) ([][]api.MessageCheckStatus, error) {
|
||||
return a.Mpool.CheckReplaceMessages(msgs)
|
||||
}
|
||||
|
||||
func (a *MpoolAPI) MpoolGetNonce(ctx context.Context, addr address.Address) (uint64, error) {
|
||||
return a.Mpool.GetNonce(ctx, addr, types.EmptyTSK)
|
||||
}
|
||||
|
@ -14,7 +14,6 @@ import (
|
||||
|
||||
multisig2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/multisig"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
"go.uber.org/fx"
|
||||
"golang.org/x/xerrors"
|
||||
)
|
||||
@ -37,134 +36,129 @@ func (a *MsigAPI) messageBuilder(ctx context.Context, from address.Address) (mul
|
||||
|
||||
// TODO: remove gp (gasPrice) from arguments
|
||||
// TODO: Add "vesting start" to arguments.
|
||||
func (a *MsigAPI) MsigCreate(ctx context.Context, req uint64, addrs []address.Address, duration abi.ChainEpoch, val types.BigInt, src address.Address, gp types.BigInt) (cid.Cid, error) {
|
||||
func (a *MsigAPI) MsigCreate(ctx context.Context, req uint64, addrs []address.Address, duration abi.ChainEpoch, val types.BigInt, src address.Address, gp types.BigInt) (*api.MessagePrototype, error) {
|
||||
|
||||
mb, err := a.messageBuilder(ctx, src)
|
||||
if err != nil {
|
||||
return cid.Undef, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
msg, err := mb.Create(addrs, req, 0, duration, val)
|
||||
if err != nil {
|
||||
return cid.Undef, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// send the message out to the network
|
||||
smsg, err := a.MpoolAPI.MpoolPushMessage(ctx, msg, nil)
|
||||
if err != nil {
|
||||
return cid.Undef, err
|
||||
}
|
||||
|
||||
return smsg.Cid(), nil
|
||||
return &api.MessagePrototype{
|
||||
Message: *msg,
|
||||
ValidNonce: false,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (a *MsigAPI) MsigPropose(ctx context.Context, msig address.Address, to address.Address, amt types.BigInt, src address.Address, method uint64, params []byte) (cid.Cid, error) {
|
||||
func (a *MsigAPI) MsigPropose(ctx context.Context, msig address.Address, to address.Address, amt types.BigInt, src address.Address, method uint64, params []byte) (*api.MessagePrototype, error) {
|
||||
|
||||
mb, err := a.messageBuilder(ctx, src)
|
||||
if err != nil {
|
||||
return cid.Undef, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
msg, err := mb.Propose(msig, to, amt, abi.MethodNum(method), params)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to create proposal: %w", err)
|
||||
return nil, xerrors.Errorf("failed to create proposal: %w", err)
|
||||
}
|
||||
|
||||
smsg, err := a.MpoolAPI.MpoolPushMessage(ctx, msg, nil)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to push message: %w", err)
|
||||
}
|
||||
|
||||
return smsg.Cid(), nil
|
||||
return &api.MessagePrototype{
|
||||
Message: *msg,
|
||||
ValidNonce: false,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (a *MsigAPI) MsigAddPropose(ctx context.Context, msig address.Address, src address.Address, newAdd address.Address, inc bool) (cid.Cid, error) {
|
||||
func (a *MsigAPI) MsigAddPropose(ctx context.Context, msig address.Address, src address.Address, newAdd address.Address, inc bool) (*api.MessagePrototype, error) {
|
||||
enc, actErr := serializeAddParams(newAdd, inc)
|
||||
if actErr != nil {
|
||||
return cid.Undef, actErr
|
||||
return nil, actErr
|
||||
}
|
||||
|
||||
return a.MsigPropose(ctx, msig, msig, big.Zero(), src, uint64(multisig.Methods.AddSigner), enc)
|
||||
}
|
||||
|
||||
func (a *MsigAPI) MsigAddApprove(ctx context.Context, msig address.Address, src address.Address, txID uint64, proposer address.Address, newAdd address.Address, inc bool) (cid.Cid, error) {
|
||||
func (a *MsigAPI) MsigAddApprove(ctx context.Context, msig address.Address, src address.Address, txID uint64, proposer address.Address, newAdd address.Address, inc bool) (*api.MessagePrototype, error) {
|
||||
enc, actErr := serializeAddParams(newAdd, inc)
|
||||
if actErr != nil {
|
||||
return cid.Undef, actErr
|
||||
return nil, actErr
|
||||
}
|
||||
|
||||
return a.MsigApproveTxnHash(ctx, msig, txID, proposer, msig, big.Zero(), src, uint64(multisig.Methods.AddSigner), enc)
|
||||
}
|
||||
|
||||
func (a *MsigAPI) MsigAddCancel(ctx context.Context, msig address.Address, src address.Address, txID uint64, newAdd address.Address, inc bool) (cid.Cid, error) {
|
||||
func (a *MsigAPI) MsigAddCancel(ctx context.Context, msig address.Address, src address.Address, txID uint64, newAdd address.Address, inc bool) (*api.MessagePrototype, error) {
|
||||
enc, actErr := serializeAddParams(newAdd, inc)
|
||||
if actErr != nil {
|
||||
return cid.Undef, actErr
|
||||
return nil, actErr
|
||||
}
|
||||
|
||||
return a.MsigCancel(ctx, msig, txID, msig, big.Zero(), src, uint64(multisig.Methods.AddSigner), enc)
|
||||
}
|
||||
|
||||
func (a *MsigAPI) MsigSwapPropose(ctx context.Context, msig address.Address, src address.Address, oldAdd address.Address, newAdd address.Address) (cid.Cid, error) {
|
||||
func (a *MsigAPI) MsigSwapPropose(ctx context.Context, msig address.Address, src address.Address, oldAdd address.Address, newAdd address.Address) (*api.MessagePrototype, error) {
|
||||
enc, actErr := serializeSwapParams(oldAdd, newAdd)
|
||||
if actErr != nil {
|
||||
return cid.Undef, actErr
|
||||
return nil, actErr
|
||||
}
|
||||
|
||||
return a.MsigPropose(ctx, msig, msig, big.Zero(), src, uint64(multisig.Methods.SwapSigner), enc)
|
||||
}
|
||||
|
||||
func (a *MsigAPI) MsigSwapApprove(ctx context.Context, msig address.Address, src address.Address, txID uint64, proposer address.Address, oldAdd address.Address, newAdd address.Address) (cid.Cid, error) {
|
||||
func (a *MsigAPI) MsigSwapApprove(ctx context.Context, msig address.Address, src address.Address, txID uint64, proposer address.Address, oldAdd address.Address, newAdd address.Address) (*api.MessagePrototype, error) {
|
||||
enc, actErr := serializeSwapParams(oldAdd, newAdd)
|
||||
if actErr != nil {
|
||||
return cid.Undef, actErr
|
||||
return nil, actErr
|
||||
}
|
||||
|
||||
return a.MsigApproveTxnHash(ctx, msig, txID, proposer, msig, big.Zero(), src, uint64(multisig.Methods.SwapSigner), enc)
|
||||
}
|
||||
|
||||
func (a *MsigAPI) MsigSwapCancel(ctx context.Context, msig address.Address, src address.Address, txID uint64, oldAdd address.Address, newAdd address.Address) (cid.Cid, error) {
|
||||
func (a *MsigAPI) MsigSwapCancel(ctx context.Context, msig address.Address, src address.Address, txID uint64, oldAdd address.Address, newAdd address.Address) (*api.MessagePrototype, error) {
|
||||
enc, actErr := serializeSwapParams(oldAdd, newAdd)
|
||||
if actErr != nil {
|
||||
return cid.Undef, actErr
|
||||
return nil, actErr
|
||||
}
|
||||
|
||||
return a.MsigCancel(ctx, msig, txID, msig, big.Zero(), src, uint64(multisig.Methods.SwapSigner), enc)
|
||||
}
|
||||
|
||||
func (a *MsigAPI) MsigApprove(ctx context.Context, msig address.Address, txID uint64, src address.Address) (cid.Cid, error) {
|
||||
func (a *MsigAPI) MsigApprove(ctx context.Context, msig address.Address, txID uint64, src address.Address) (*api.MessagePrototype, error) {
|
||||
return a.msigApproveOrCancelSimple(ctx, api.MsigApprove, msig, txID, src)
|
||||
}
|
||||
|
||||
func (a *MsigAPI) MsigApproveTxnHash(ctx context.Context, msig address.Address, txID uint64, proposer address.Address, to address.Address, amt types.BigInt, src address.Address, method uint64, params []byte) (cid.Cid, error) {
|
||||
func (a *MsigAPI) MsigApproveTxnHash(ctx context.Context, msig address.Address, txID uint64, proposer address.Address, to address.Address, amt types.BigInt, src address.Address, method uint64, params []byte) (*api.MessagePrototype, error) {
|
||||
return a.msigApproveOrCancelTxnHash(ctx, api.MsigApprove, msig, txID, proposer, to, amt, src, method, params)
|
||||
}
|
||||
|
||||
func (a *MsigAPI) MsigCancel(ctx context.Context, msig address.Address, txID uint64, to address.Address, amt types.BigInt, src address.Address, method uint64, params []byte) (cid.Cid, error) {
|
||||
func (a *MsigAPI) MsigCancel(ctx context.Context, msig address.Address, txID uint64, to address.Address, amt types.BigInt, src address.Address, method uint64, params []byte) (*api.MessagePrototype, error) {
|
||||
return a.msigApproveOrCancelTxnHash(ctx, api.MsigCancel, msig, txID, src, to, amt, src, method, params)
|
||||
}
|
||||
|
||||
func (a *MsigAPI) MsigRemoveSigner(ctx context.Context, msig address.Address, proposer address.Address, toRemove address.Address, decrease bool) (cid.Cid, error) {
|
||||
func (a *MsigAPI) MsigRemoveSigner(ctx context.Context, msig address.Address, proposer address.Address, toRemove address.Address, decrease bool) (*api.MessagePrototype, error) {
|
||||
enc, actErr := serializeRemoveParams(toRemove, decrease)
|
||||
if actErr != nil {
|
||||
return cid.Undef, actErr
|
||||
return nil, actErr
|
||||
}
|
||||
|
||||
return a.MsigPropose(ctx, msig, msig, types.NewInt(0), proposer, uint64(multisig.Methods.RemoveSigner), enc)
|
||||
}
|
||||
|
||||
func (a *MsigAPI) msigApproveOrCancelSimple(ctx context.Context, operation api.MsigProposeResponse, msig address.Address, txID uint64, src address.Address) (cid.Cid, error) {
|
||||
func (a *MsigAPI) msigApproveOrCancelSimple(ctx context.Context, operation api.MsigProposeResponse, msig address.Address, txID uint64, src address.Address) (*api.MessagePrototype, error) {
|
||||
if msig == address.Undef {
|
||||
return cid.Undef, xerrors.Errorf("must provide multisig address")
|
||||
return nil, xerrors.Errorf("must provide multisig address")
|
||||
}
|
||||
|
||||
if src == address.Undef {
|
||||
return cid.Undef, xerrors.Errorf("must provide source address")
|
||||
return nil, xerrors.Errorf("must provide source address")
|
||||
}
|
||||
|
||||
mb, err := a.messageBuilder(ctx, src)
|
||||
if err != nil {
|
||||
return cid.Undef, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var msg *types.Message
|
||||
@ -174,34 +168,31 @@ func (a *MsigAPI) msigApproveOrCancelSimple(ctx context.Context, operation api.M
|
||||
case api.MsigCancel:
|
||||
msg, err = mb.Cancel(msig, txID, nil)
|
||||
default:
|
||||
return cid.Undef, xerrors.Errorf("Invalid operation for msigApproveOrCancel")
|
||||
return nil, xerrors.Errorf("Invalid operation for msigApproveOrCancel")
|
||||
}
|
||||
if err != nil {
|
||||
return cid.Undef, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
smsg, err := a.MpoolAPI.MpoolPushMessage(ctx, msg, nil)
|
||||
if err != nil {
|
||||
return cid.Undef, err
|
||||
}
|
||||
|
||||
return smsg.Cid(), nil
|
||||
|
||||
return &api.MessagePrototype{
|
||||
Message: *msg,
|
||||
ValidNonce: false,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (a *MsigAPI) msigApproveOrCancelTxnHash(ctx context.Context, operation api.MsigProposeResponse, msig address.Address, txID uint64, proposer address.Address, to address.Address, amt types.BigInt, src address.Address, method uint64, params []byte) (cid.Cid, error) {
|
||||
func (a *MsigAPI) msigApproveOrCancelTxnHash(ctx context.Context, operation api.MsigProposeResponse, msig address.Address, txID uint64, proposer address.Address, to address.Address, amt types.BigInt, src address.Address, method uint64, params []byte) (*api.MessagePrototype, error) {
|
||||
if msig == address.Undef {
|
||||
return cid.Undef, xerrors.Errorf("must provide multisig address")
|
||||
return nil, xerrors.Errorf("must provide multisig address")
|
||||
}
|
||||
|
||||
if src == address.Undef {
|
||||
return cid.Undef, xerrors.Errorf("must provide source address")
|
||||
return nil, xerrors.Errorf("must provide source address")
|
||||
}
|
||||
|
||||
if proposer.Protocol() != address.ID {
|
||||
proposerID, err := a.StateAPI.StateLookupID(ctx, proposer, types.EmptyTSK)
|
||||
if err != nil {
|
||||
return cid.Undef, err
|
||||
return nil, err
|
||||
}
|
||||
proposer = proposerID
|
||||
}
|
||||
@ -216,7 +207,7 @@ func (a *MsigAPI) msigApproveOrCancelTxnHash(ctx context.Context, operation api.
|
||||
|
||||
mb, err := a.messageBuilder(ctx, src)
|
||||
if err != nil {
|
||||
return cid.Undef, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var msg *types.Message
|
||||
@ -226,18 +217,16 @@ func (a *MsigAPI) msigApproveOrCancelTxnHash(ctx context.Context, operation api.
|
||||
case api.MsigCancel:
|
||||
msg, err = mb.Cancel(msig, txID, &p)
|
||||
default:
|
||||
return cid.Undef, xerrors.Errorf("Invalid operation for msigApproveOrCancel")
|
||||
return nil, xerrors.Errorf("Invalid operation for msigApproveOrCancel")
|
||||
}
|
||||
if err != nil {
|
||||
return cid.Undef, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
smsg, err := a.MpoolAPI.MpoolPushMessage(ctx, msg, nil)
|
||||
if err != nil {
|
||||
return cid.Undef, err
|
||||
}
|
||||
|
||||
return smsg.Cid(), nil
|
||||
return &api.MessagePrototype{
|
||||
Message: *msg,
|
||||
ValidNonce: false,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func serializeAddParams(new address.Address, inc bool) ([]byte, error) {
|
||||
|
@ -426,7 +426,7 @@ func (a *StateAPI) StateReplay(ctx context.Context, tsk types.TipSetKey, mc cid.
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (m *StateModule) StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error) {
|
||||
func (m *StateModule) StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (a *types.Actor, err error) {
|
||||
ts, err := m.Chain.GetTipSetFromKey(tsk)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
|
||||
|
@ -9,7 +9,6 @@ import (
|
||||
"github.com/ipfs/go-blockservice"
|
||||
"github.com/libp2p/go-libp2p-core/host"
|
||||
"github.com/libp2p/go-libp2p-core/routing"
|
||||
pubsub "github.com/libp2p/go-libp2p-pubsub"
|
||||
"go.uber.org/fx"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
@ -59,8 +58,7 @@ func ChainBlockService(bs dtypes.ExposedBlockstore, rem dtypes.ChainBitswap) dty
|
||||
return blockservice.New(bs, rem)
|
||||
}
|
||||
|
||||
func MessagePool(lc fx.Lifecycle, sm *stmgr.StateManager, ps *pubsub.PubSub, ds dtypes.MetadataDS, nn dtypes.NetworkName, j journal.Journal) (*messagepool.MessagePool, error) {
|
||||
mpp := messagepool.NewProvider(sm, ps)
|
||||
func MessagePool(lc fx.Lifecycle, mpp messagepool.Provider, ds dtypes.MetadataDS, nn dtypes.NetworkName, j journal.Journal) (*messagepool.MessagePool, error) {
|
||||
mp, err := messagepool.New(mpp, ds, nn, j)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("constructing mpool: %w", err)
|
||||
|
@ -36,6 +36,15 @@ func init() {
|
||||
pubsub.GossipSubHistoryLength = 10
|
||||
pubsub.GossipSubGossipFactor = 0.1
|
||||
}
|
||||
|
||||
const (
|
||||
GossipScoreThreshold = -500
|
||||
PublishScoreThreshold = -1000
|
||||
GraylistScoreThreshold = -2500
|
||||
AcceptPXScoreThreshold = 1000
|
||||
OpportunisticGraftScoreThreshold = 3.5
|
||||
)
|
||||
|
||||
func ScoreKeeper() *dtypes.ScoreKeeper {
|
||||
return new(dtypes.ScoreKeeper)
|
||||
}
|
||||
@ -256,11 +265,11 @@ func GossipSub(in GossipIn) (service *pubsub.PubSub, err error) {
|
||||
Topics: topicParams,
|
||||
},
|
||||
&pubsub.PeerScoreThresholds{
|
||||
GossipThreshold: -500,
|
||||
PublishThreshold: -1000,
|
||||
GraylistThreshold: -2500,
|
||||
AcceptPXThreshold: 1000,
|
||||
OpportunisticGraftThreshold: 3.5,
|
||||
GossipThreshold: GossipScoreThreshold,
|
||||
PublishThreshold: PublishScoreThreshold,
|
||||
GraylistThreshold: GraylistScoreThreshold,
|
||||
AcceptPXThreshold: AcceptPXScoreThreshold,
|
||||
OpportunisticGraftThreshold: OpportunisticGraftScoreThreshold,
|
||||
},
|
||||
),
|
||||
pubsub.WithPeerScoreInspect(in.Sk.Update, 10*time.Second),
|
||||
|
@ -63,7 +63,7 @@ func (a *MpoolNonceAPI) GetNonce(ctx context.Context, addr address.Address, tsk
|
||||
act, err := a.StateModule.StateGetActor(ctx, keyAddr, ts.Key())
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), types.ErrActorNotFound.Error()) {
|
||||
return 0, types.ErrActorNotFound
|
||||
return 0, xerrors.Errorf("getting actor converted: %w", types.ErrActorNotFound)
|
||||
}
|
||||
return 0, xerrors.Errorf("getting actor: %w", err)
|
||||
}
|
||||
@ -96,4 +96,13 @@ func (a *MpoolNonceAPI) GetNonce(ctx context.Context, addr address.Address, tsk
|
||||
return highestNonce, nil
|
||||
}
|
||||
|
||||
func (a *MpoolNonceAPI) GetActor(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*types.Actor, error) {
|
||||
act, err := a.StateModule.StateGetActor(ctx, addr, tsk)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("calling StateGetActor: %w", err)
|
||||
}
|
||||
|
||||
return act, nil
|
||||
}
|
||||
|
||||
var _ messagesigner.MpoolNonceAPI = (*MpoolNonceAPI)(nil)
|
||||
|
Loading…
Reference in New Issue
Block a user