Merge remote-tracking branch 'origin/master' into feat/stateless-offline-dealflow
This commit is contained in:
commit
d54ed1b0c6
10
Makefile
10
Makefile
@ -333,6 +333,10 @@ type-gen: api-gen
|
||||
method-gen: api-gen
|
||||
(cd ./lotuspond/front/src/chain && go run ./methodgen.go)
|
||||
|
||||
actors-gen:
|
||||
go run ./chain/actors/agen
|
||||
go fmt ./...
|
||||
|
||||
api-gen:
|
||||
go run ./gen/api
|
||||
goimports -w api
|
||||
@ -341,9 +345,9 @@ api-gen:
|
||||
|
||||
docsgen: docsgen-md docsgen-openrpc
|
||||
|
||||
docsgen-md-bin: api-gen
|
||||
docsgen-md-bin: api-gen actors-gen
|
||||
go build $(GOFLAGS) -o docgen-md ./api/docgen/cmd
|
||||
docsgen-openrpc-bin: api-gen
|
||||
docsgen-openrpc-bin: api-gen actors-gen
|
||||
go build $(GOFLAGS) -o docgen-openrpc ./api/docgen-openrpc/cmd
|
||||
|
||||
docsgen-md: docsgen-md-full docsgen-md-storage docsgen-md-worker
|
||||
@ -367,7 +371,7 @@ docsgen-openrpc-worker: docsgen-openrpc-bin
|
||||
|
||||
.PHONY: docsgen docsgen-md-bin docsgen-openrpc-bin
|
||||
|
||||
gen: type-gen method-gen docsgen api-gen
|
||||
gen: actors-gen type-gen method-gen docsgen api-gen
|
||||
@echo ">>> IF YOU'VE MODIFIED THE CLI, REMEMBER TO ALSO MAKE docsgen-cli"
|
||||
.PHONY: gen
|
||||
|
||||
|
@ -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
|
||||
@ -581,15 +588,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
|
||||
@ -597,43 +605,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
|
||||
@ -666,6 +680,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) {
|
||||
|
@ -1083,6 +1083,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()
|
||||
@ -1232,10 +1277,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
|
||||
}
|
||||
@ -1247,10 +1292,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
|
||||
}
|
||||
@ -1262,10 +1307,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
|
||||
}
|
||||
@ -1277,10 +1322,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
|
||||
}
|
||||
@ -1292,10 +1337,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
|
||||
}
|
||||
@ -1307,10 +1352,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
|
||||
}
|
||||
@ -1322,10 +1367,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
|
||||
}
|
||||
@ -1397,10 +1442,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
|
||||
}
|
||||
@ -1412,10 +1457,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
|
||||
}
|
||||
@ -1427,10 +1472,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
|
||||
}
|
||||
@ -1442,10 +1487,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
|
||||
}
|
||||
@ -1457,10 +1502,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
|
||||
}
|
||||
@ -1707,6 +1752,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
@ -237,6 +237,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"`
|
||||
@ -257,19 +263,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"`
|
||||
|
||||
@ -279,15 +285,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"`
|
||||
|
||||
@ -1517,6 +1525,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)
|
||||
}
|
||||
@ -1597,60 +1629,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) {
|
||||
@ -1685,44 +1717,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) {
|
||||
|
@ -31,7 +31,7 @@ func TestCCUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
||||
|
||||
func testCCUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration, upgradeHeight abi.ChainEpoch) {
|
||||
ctx := context.Background()
|
||||
n, sn := b(t, []FullNodeOpts{FullNodeWithActorsV4At(upgradeHeight)}, OneMiner)
|
||||
n, sn := b(t, []FullNodeOpts{FullNodeWithLatestActorsAt(upgradeHeight)}, OneMiner)
|
||||
client := n[0].FullNode.(*impl.FullNodeAPI)
|
||||
miner := sn[0]
|
||||
|
||||
|
@ -63,7 +63,7 @@ func TestDeadlineToggling(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
n, sn := b(t, []FullNodeOpts{FullNodeWithActorsV4At(upgradeH)}, OneMiner)
|
||||
n, sn := b(t, []FullNodeOpts{FullNodeWithLatestActorsAt(upgradeH)}, OneMiner)
|
||||
|
||||
client := n[0].FullNode.(*impl.FullNodeAPI)
|
||||
minerA := sn[0]
|
||||
|
@ -206,7 +206,7 @@ func TestDealMining(t *testing.T, b APIBuilder, blocktime time.Duration, carExpo
|
||||
func (ts *testSuite) testNonGenesisMiner(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
n, sn := ts.makeNodes(t, []FullNodeOpts{
|
||||
FullNodeWithActorsV4At(-1),
|
||||
FullNodeWithLatestActorsAt(-1),
|
||||
}, []StorageMiner{
|
||||
{Full: 0, Preseal: PresealGenesis},
|
||||
})
|
||||
|
@ -121,7 +121,7 @@ var OneMiner = []StorageMiner{{Full: 0, Preseal: PresealGenesis}}
|
||||
var OneFull = DefaultFullOpts(1)
|
||||
var TwoFull = DefaultFullOpts(2)
|
||||
|
||||
var FullNodeWithActorsV4At = func(upgradeHeight abi.ChainEpoch) FullNodeOpts {
|
||||
var FullNodeWithLatestActorsAt = func(upgradeHeight abi.ChainEpoch) FullNodeOpts {
|
||||
if upgradeHeight == -1 {
|
||||
upgradeHeight = 3
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -223,7 +223,7 @@ func testWindowPostUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration,
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
n, sn := b(t, []FullNodeOpts{FullNodeWithActorsV4At(upgradeHeight)}, OneMiner)
|
||||
n, sn := b(t, []FullNodeOpts{FullNodeWithLatestActorsAt(upgradeHeight)}, OneMiner)
|
||||
|
||||
client := n[0].FullNode.(*impl.FullNodeAPI)
|
||||
miner := sn[0]
|
||||
@ -442,7 +442,7 @@ func TestTerminate(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
||||
|
||||
nSectors := uint64(2)
|
||||
|
||||
n, sn := b(t, []FullNodeOpts{FullNodeWithActorsV4At(-1)}, []StorageMiner{{Full: 0, Preseal: int(nSectors)}})
|
||||
n, sn := b(t, []FullNodeOpts{FullNodeWithLatestActorsAt(-1)}, []StorageMiner{{Full: 0, Preseal: int(nSectors)}})
|
||||
|
||||
client := n[0].FullNode.(*impl.FullNodeAPI)
|
||||
miner := sn[0]
|
||||
@ -617,7 +617,7 @@ func TestWindowPostDispute(t *testing.T, b APIBuilder, blocktime time.Duration)
|
||||
///
|
||||
// Then we're going to manually submit bad proofs.
|
||||
n, sn := b(t, []FullNodeOpts{
|
||||
FullNodeWithActorsV4At(-1),
|
||||
FullNodeWithLatestActorsAt(-1),
|
||||
}, []StorageMiner{
|
||||
{Full: 0, Preseal: PresealGenesis},
|
||||
{Full: 0},
|
||||
@ -900,7 +900,7 @@ func TestWindowPostDisputeFails(t *testing.T, b APIBuilder, blocktime time.Durat
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
n, sn := b(t, []FullNodeOpts{FullNodeWithActorsV4At(-1)}, OneMiner)
|
||||
n, sn := b(t, []FullNodeOpts{FullNodeWithLatestActorsAt(-1)}, OneMiner)
|
||||
|
||||
client := n[0].FullNode.(*impl.FullNodeAPI)
|
||||
miner := sn[0]
|
||||
|
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"
|
||||
)
|
||||
|
218
chain/actors/agen/main.go
Normal file
218
chain/actors/agen/main.go
Normal file
@ -0,0 +1,218 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"text/template"
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var latestVersion = 4
|
||||
|
||||
var versions = []int{0, 2, 3, latestVersion}
|
||||
|
||||
var versionImports = map[int]string{
|
||||
0: "/",
|
||||
2: "/v2/",
|
||||
3: "/v3/",
|
||||
latestVersion: "/v4/",
|
||||
}
|
||||
|
||||
var actors = map[string][]int{
|
||||
"account": versions,
|
||||
"cron": versions,
|
||||
"init": versions,
|
||||
"market": versions,
|
||||
"miner": versions,
|
||||
"multisig": versions,
|
||||
"paych": versions,
|
||||
"power": versions,
|
||||
"reward": versions,
|
||||
"verifreg": versions,
|
||||
}
|
||||
|
||||
func main() {
|
||||
if err := generateAdapters(); err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := generatePolicy("chain/actors/policy/policy.go"); err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := generateBuiltin("chain/actors/builtin/builtin.go"); err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func generateAdapters() error {
|
||||
for act, versions := range actors {
|
||||
actDir := filepath.Join("chain/actors/builtin", act)
|
||||
|
||||
if err := generateState(actDir); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := generateMessages(actDir); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
{
|
||||
af, err := ioutil.ReadFile(filepath.Join(actDir, "actor.go.template"))
|
||||
if err != nil {
|
||||
return xerrors.Errorf("loading actor template: %w", err)
|
||||
}
|
||||
|
||||
tpl := template.Must(template.New("").Funcs(template.FuncMap{
|
||||
"import": func(v int) string { return versionImports[v] },
|
||||
}).Parse(string(af)))
|
||||
|
||||
var b bytes.Buffer
|
||||
|
||||
err = tpl.Execute(&b, map[string]interface{}{
|
||||
"versions": versions,
|
||||
"latestVersion": latestVersion,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := ioutil.WriteFile(filepath.Join(actDir, fmt.Sprintf("%s.go", act)), b.Bytes(), 0666); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func generateState(actDir string) error {
|
||||
af, err := ioutil.ReadFile(filepath.Join(actDir, "state.go.template"))
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil // skip
|
||||
}
|
||||
|
||||
return xerrors.Errorf("loading state adapter template: %w", err)
|
||||
}
|
||||
|
||||
for _, version := range versions {
|
||||
tpl := template.Must(template.New("").Funcs(template.FuncMap{}).Parse(string(af)))
|
||||
|
||||
var b bytes.Buffer
|
||||
|
||||
err := tpl.Execute(&b, map[string]interface{}{
|
||||
"v": version,
|
||||
"import": versionImports[version],
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := ioutil.WriteFile(filepath.Join(actDir, fmt.Sprintf("v%d.go", version)), b.Bytes(), 0666); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func generateMessages(actDir string) error {
|
||||
af, err := ioutil.ReadFile(filepath.Join(actDir, "message.go.template"))
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil // skip
|
||||
}
|
||||
|
||||
return xerrors.Errorf("loading message adapter template: %w", err)
|
||||
}
|
||||
|
||||
for _, version := range versions {
|
||||
tpl := template.Must(template.New("").Funcs(template.FuncMap{}).Parse(string(af)))
|
||||
|
||||
var b bytes.Buffer
|
||||
|
||||
err := tpl.Execute(&b, map[string]interface{}{
|
||||
"v": version,
|
||||
"import": versionImports[version],
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := ioutil.WriteFile(filepath.Join(actDir, fmt.Sprintf("message%d.go", version)), b.Bytes(), 0666); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func generatePolicy(policyPath string) error {
|
||||
|
||||
pf, err := ioutil.ReadFile(policyPath + ".template")
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil // skip
|
||||
}
|
||||
|
||||
return xerrors.Errorf("loading policy template file: %w", err)
|
||||
}
|
||||
|
||||
tpl := template.Must(template.New("").Funcs(template.FuncMap{
|
||||
"import": func(v int) string { return versionImports[v] },
|
||||
}).Parse(string(pf)))
|
||||
var b bytes.Buffer
|
||||
|
||||
err = tpl.Execute(&b, map[string]interface{}{
|
||||
"versions": versions,
|
||||
"latestVersion": latestVersion,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := ioutil.WriteFile(policyPath, b.Bytes(), 0666); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func generateBuiltin(builtinPath string) error {
|
||||
|
||||
bf, err := ioutil.ReadFile(builtinPath + ".template")
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil // skip
|
||||
}
|
||||
|
||||
return xerrors.Errorf("loading builtin template file: %w", err)
|
||||
}
|
||||
|
||||
tpl := template.Must(template.New("").Funcs(template.FuncMap{
|
||||
"import": func(v int) string { return versionImports[v] },
|
||||
}).Parse(string(bf)))
|
||||
var b bytes.Buffer
|
||||
|
||||
err = tpl.Execute(&b, map[string]interface{}{
|
||||
"versions": versions,
|
||||
"latestVersion": latestVersion,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := ioutil.WriteFile(builtinPath, b.Bytes(), 0666); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
@ -12,21 +12,28 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
|
||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
|
||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||
|
||||
builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin"
|
||||
|
||||
builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
||||
builtin.RegisterActorState(builtin0.AccountActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||
return load0(store, root)
|
||||
})
|
||||
|
||||
builtin.RegisterActorState(builtin2.AccountActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||
return load2(store, root)
|
||||
})
|
||||
|
||||
builtin.RegisterActorState(builtin3.AccountActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||
return load3(store, root)
|
||||
})
|
||||
|
||||
builtin.RegisterActorState(builtin4.AccountActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||
return load4(store, root)
|
||||
})
|
||||
@ -36,14 +43,19 @@ var Methods = builtin4.MethodsAccount
|
||||
|
||||
func Load(store adt.Store, act *types.Actor) (State, error) {
|
||||
switch act.Code {
|
||||
|
||||
case builtin0.AccountActorCodeID:
|
||||
return load0(store, act.Head)
|
||||
|
||||
case builtin2.AccountActorCodeID:
|
||||
return load2(store, act.Head)
|
||||
|
||||
case builtin3.AccountActorCodeID:
|
||||
return load3(store, act.Head)
|
||||
|
||||
case builtin4.AccountActorCodeID:
|
||||
return load4(store, act.Head)
|
||||
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||
}
|
||||
|
41
chain/actors/builtin/account/actor.go.template
Normal file
41
chain/actors/builtin/account/actor.go.template
Normal file
@ -0,0 +1,41 @@
|
||||
package account
|
||||
|
||||
import (
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/cbor"
|
||||
"github.com/ipfs/go-cid"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
{{range .versions}}
|
||||
builtin{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin"
|
||||
{{end}}
|
||||
)
|
||||
|
||||
func init() {
|
||||
{{range .versions}}
|
||||
builtin.RegisterActorState(builtin{{.}}.AccountActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||
return load{{.}}(store, root)
|
||||
})
|
||||
{{end}}}
|
||||
|
||||
var Methods = builtin4.MethodsAccount
|
||||
|
||||
func Load(store adt.Store, act *types.Actor) (State, error) {
|
||||
switch act.Code {
|
||||
{{range .versions}}
|
||||
case builtin{{.}}.AccountActorCodeID:
|
||||
return load{{.}}(store, act.Head)
|
||||
{{end}}
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||
}
|
||||
|
||||
type State interface {
|
||||
cbor.Marshaler
|
||||
|
||||
PubkeyAddress() (address.Address, error)
|
||||
}
|
30
chain/actors/builtin/account/state.go.template
Normal file
30
chain/actors/builtin/account/state.go.template
Normal file
@ -0,0 +1,30 @@
|
||||
package account
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/ipfs/go-cid"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
|
||||
account{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/account"
|
||||
)
|
||||
|
||||
var _ State = (*state{{.v}})(nil)
|
||||
|
||||
func load{{.v}}(store adt.Store, root cid.Cid) (State, error) {
|
||||
out := state{{.v}}{store: store}
|
||||
err := store.Get(store.Context(), root, &out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
type state{{.v}} struct {
|
||||
account{{.v}}.State
|
||||
store adt.Store
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) PubkeyAddress() (address.Address, error) {
|
||||
return s.Address, nil
|
||||
}
|
@ -6,9 +6,16 @@ import (
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
smoothing0 "github.com/filecoin-project/specs-actors/actors/util/smoothing"
|
||||
|
||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||
smoothing2 "github.com/filecoin-project/specs-actors/v2/actors/util/smoothing"
|
||||
|
||||
builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin"
|
||||
smoothing3 "github.com/filecoin-project/specs-actors/v3/actors/util/smoothing"
|
||||
|
||||
builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin"
|
||||
smoothing4 "github.com/filecoin-project/specs-actors/v4/actors/util/smoothing"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/cbor"
|
||||
@ -16,30 +23,25 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
|
||||
smoothing0 "github.com/filecoin-project/specs-actors/actors/util/smoothing"
|
||||
smoothing2 "github.com/filecoin-project/specs-actors/v2/actors/util/smoothing"
|
||||
smoothing3 "github.com/filecoin-project/specs-actors/v3/actors/util/smoothing"
|
||||
smoothing4 "github.com/filecoin-project/specs-actors/v4/actors/util/smoothing"
|
||||
|
||||
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
proof0 "github.com/filecoin-project/specs-actors/actors/runtime/proof"
|
||||
miner4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/miner"
|
||||
proof4 "github.com/filecoin-project/specs-actors/v4/actors/runtime/proof"
|
||||
)
|
||||
|
||||
var SystemActorAddr = builtin0.SystemActorAddr
|
||||
var BurntFundsActorAddr = builtin0.BurntFundsActorAddr
|
||||
var CronActorAddr = builtin0.CronActorAddr
|
||||
var SystemActorAddr = builtin4.SystemActorAddr
|
||||
var BurntFundsActorAddr = builtin4.BurntFundsActorAddr
|
||||
var CronActorAddr = builtin4.CronActorAddr
|
||||
var SaftAddress = makeAddress("t0122")
|
||||
var ReserveAddress = makeAddress("t090")
|
||||
var RootVerifierAddress = makeAddress("t080")
|
||||
|
||||
var (
|
||||
ExpectedLeadersPerEpoch = builtin0.ExpectedLeadersPerEpoch
|
||||
ExpectedLeadersPerEpoch = builtin4.ExpectedLeadersPerEpoch
|
||||
)
|
||||
|
||||
const (
|
||||
EpochDurationSeconds = builtin0.EpochDurationSeconds
|
||||
EpochsInDay = builtin0.EpochsInDay
|
||||
SecondsInDay = builtin0.SecondsInDay
|
||||
EpochDurationSeconds = builtin4.EpochDurationSeconds
|
||||
EpochsInDay = builtin4.EpochsInDay
|
||||
SecondsInDay = builtin4.SecondsInDay
|
||||
)
|
||||
|
||||
const (
|
||||
@ -47,31 +49,38 @@ const (
|
||||
MethodConstructor = builtin4.MethodConstructor
|
||||
)
|
||||
|
||||
// These are all just type aliases across actor versions 0, 2, & 3. In the future, that might change
|
||||
// These are all just type aliases across actor versions. In the future, that might change
|
||||
// and we might need to do something fancier.
|
||||
type SectorInfo = proof0.SectorInfo
|
||||
type PoStProof = proof0.PoStProof
|
||||
type SectorInfo = proof4.SectorInfo
|
||||
type PoStProof = proof4.PoStProof
|
||||
type FilterEstimate = smoothing0.FilterEstimate
|
||||
|
||||
func FromV0FilterEstimate(v0 smoothing0.FilterEstimate) FilterEstimate {
|
||||
return (FilterEstimate)(v0) //nolint:unconvert
|
||||
func QAPowerForWeight(size abi.SectorSize, duration abi.ChainEpoch, dealWeight, verifiedWeight abi.DealWeight) abi.StoragePower {
|
||||
return miner4.QAPowerForWeight(size, duration, dealWeight, verifiedWeight)
|
||||
}
|
||||
|
||||
// Doesn't change between actors v0, v2, and v3.
|
||||
func QAPowerForWeight(size abi.SectorSize, duration abi.ChainEpoch, dealWeight, verifiedWeight abi.DealWeight) abi.StoragePower {
|
||||
return miner0.QAPowerForWeight(size, duration, dealWeight, verifiedWeight)
|
||||
func FromV0FilterEstimate(v0 smoothing0.FilterEstimate) FilterEstimate {
|
||||
|
||||
return (FilterEstimate)(v0) //nolint:unconvert
|
||||
|
||||
}
|
||||
|
||||
func FromV2FilterEstimate(v2 smoothing2.FilterEstimate) FilterEstimate {
|
||||
|
||||
return (FilterEstimate)(v2)
|
||||
|
||||
}
|
||||
|
||||
func FromV3FilterEstimate(v3 smoothing3.FilterEstimate) FilterEstimate {
|
||||
|
||||
return (FilterEstimate)(v3)
|
||||
|
||||
}
|
||||
|
||||
func FromV4FilterEstimate(v4 smoothing4.FilterEstimate) FilterEstimate {
|
||||
|
||||
return (FilterEstimate)(v4)
|
||||
|
||||
}
|
||||
|
||||
type ActorStateLoader func(store adt.Store, root cid.Cid) (cbor.Marshaler, error)
|
||||
@ -92,52 +101,127 @@ func Load(store adt.Store, act *types.Actor) (cbor.Marshaler, error) {
|
||||
|
||||
func ActorNameByCode(c cid.Cid) string {
|
||||
switch {
|
||||
|
||||
case builtin0.IsBuiltinActor(c):
|
||||
return builtin0.ActorNameByCode(c)
|
||||
|
||||
case builtin2.IsBuiltinActor(c):
|
||||
return builtin2.ActorNameByCode(c)
|
||||
|
||||
case builtin3.IsBuiltinActor(c):
|
||||
return builtin3.ActorNameByCode(c)
|
||||
|
||||
case builtin4.IsBuiltinActor(c):
|
||||
return builtin4.ActorNameByCode(c)
|
||||
|
||||
default:
|
||||
return "<unknown>"
|
||||
}
|
||||
}
|
||||
|
||||
func IsBuiltinActor(c cid.Cid) bool {
|
||||
return builtin0.IsBuiltinActor(c) ||
|
||||
builtin2.IsBuiltinActor(c) ||
|
||||
builtin3.IsBuiltinActor(c) ||
|
||||
builtin4.IsBuiltinActor(c)
|
||||
|
||||
if builtin0.IsBuiltinActor(c) {
|
||||
return true
|
||||
}
|
||||
|
||||
if builtin2.IsBuiltinActor(c) {
|
||||
return true
|
||||
}
|
||||
|
||||
if builtin3.IsBuiltinActor(c) {
|
||||
return true
|
||||
}
|
||||
|
||||
if builtin4.IsBuiltinActor(c) {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func IsAccountActor(c cid.Cid) bool {
|
||||
return c == builtin0.AccountActorCodeID ||
|
||||
c == builtin2.AccountActorCodeID ||
|
||||
c == builtin3.AccountActorCodeID ||
|
||||
c == builtin4.AccountActorCodeID
|
||||
|
||||
if c == builtin0.AccountActorCodeID {
|
||||
return true
|
||||
}
|
||||
|
||||
if c == builtin2.AccountActorCodeID {
|
||||
return true
|
||||
}
|
||||
|
||||
if c == builtin3.AccountActorCodeID {
|
||||
return true
|
||||
}
|
||||
|
||||
if c == builtin4.AccountActorCodeID {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func IsStorageMinerActor(c cid.Cid) bool {
|
||||
return c == builtin0.StorageMinerActorCodeID ||
|
||||
c == builtin2.StorageMinerActorCodeID ||
|
||||
c == builtin3.StorageMinerActorCodeID ||
|
||||
c == builtin4.StorageMinerActorCodeID
|
||||
|
||||
if c == builtin0.StorageMinerActorCodeID {
|
||||
return true
|
||||
}
|
||||
|
||||
if c == builtin2.StorageMinerActorCodeID {
|
||||
return true
|
||||
}
|
||||
|
||||
if c == builtin3.StorageMinerActorCodeID {
|
||||
return true
|
||||
}
|
||||
|
||||
if c == builtin4.StorageMinerActorCodeID {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func IsMultisigActor(c cid.Cid) bool {
|
||||
return c == builtin0.MultisigActorCodeID ||
|
||||
c == builtin2.MultisigActorCodeID ||
|
||||
c == builtin3.MultisigActorCodeID ||
|
||||
c == builtin4.MultisigActorCodeID
|
||||
|
||||
if c == builtin0.MultisigActorCodeID {
|
||||
return true
|
||||
}
|
||||
|
||||
if c == builtin2.MultisigActorCodeID {
|
||||
return true
|
||||
}
|
||||
|
||||
if c == builtin3.MultisigActorCodeID {
|
||||
return true
|
||||
}
|
||||
|
||||
if c == builtin4.MultisigActorCodeID {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func IsPaymentChannelActor(c cid.Cid) bool {
|
||||
return c == builtin0.PaymentChannelActorCodeID ||
|
||||
c == builtin2.PaymentChannelActorCodeID ||
|
||||
c == builtin3.PaymentChannelActorCodeID ||
|
||||
c == builtin4.PaymentChannelActorCodeID
|
||||
|
||||
if c == builtin0.PaymentChannelActorCodeID {
|
||||
return true
|
||||
}
|
||||
|
||||
if c == builtin2.PaymentChannelActorCodeID {
|
||||
return true
|
||||
}
|
||||
|
||||
if c == builtin3.PaymentChannelActorCodeID {
|
||||
return true
|
||||
}
|
||||
|
||||
if c == builtin4.PaymentChannelActorCodeID {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func makeAddress(addr string) address.Address {
|
||||
|
144
chain/actors/builtin/builtin.go.template
Normal file
144
chain/actors/builtin/builtin.go.template
Normal file
@ -0,0 +1,144 @@
|
||||
package builtin
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/ipfs/go-cid"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
{{range .versions}}
|
||||
builtin{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin"
|
||||
smoothing{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/util/smoothing"
|
||||
{{end}}
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/cbor"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
|
||||
miner{{.latestVersion}} "github.com/filecoin-project/specs-actors{{import .latestVersion}}actors/builtin/miner"
|
||||
proof{{.latestVersion}} "github.com/filecoin-project/specs-actors{{import .latestVersion}}actors/runtime/proof"
|
||||
)
|
||||
|
||||
var SystemActorAddr = builtin{{.latestVersion}}.SystemActorAddr
|
||||
var BurntFundsActorAddr = builtin{{.latestVersion}}.BurntFundsActorAddr
|
||||
var CronActorAddr = builtin{{.latestVersion}}.CronActorAddr
|
||||
var SaftAddress = makeAddress("t0122")
|
||||
var ReserveAddress = makeAddress("t090")
|
||||
var RootVerifierAddress = makeAddress("t080")
|
||||
|
||||
var (
|
||||
ExpectedLeadersPerEpoch = builtin{{.latestVersion}}.ExpectedLeadersPerEpoch
|
||||
)
|
||||
|
||||
const (
|
||||
EpochDurationSeconds = builtin{{.latestVersion}}.EpochDurationSeconds
|
||||
EpochsInDay = builtin{{.latestVersion}}.EpochsInDay
|
||||
SecondsInDay = builtin{{.latestVersion}}.SecondsInDay
|
||||
)
|
||||
|
||||
const (
|
||||
MethodSend = builtin{{.latestVersion}}.MethodSend
|
||||
MethodConstructor = builtin{{.latestVersion}}.MethodConstructor
|
||||
)
|
||||
|
||||
// These are all just type aliases across actor versions. In the future, that might change
|
||||
// and we might need to do something fancier.
|
||||
type SectorInfo = proof{{.latestVersion}}.SectorInfo
|
||||
type PoStProof = proof{{.latestVersion}}.PoStProof
|
||||
type FilterEstimate = smoothing0.FilterEstimate
|
||||
|
||||
func QAPowerForWeight(size abi.SectorSize, duration abi.ChainEpoch, dealWeight, verifiedWeight abi.DealWeight) abi.StoragePower {
|
||||
return miner{{.latestVersion}}.QAPowerForWeight(size, duration, dealWeight, verifiedWeight)
|
||||
}
|
||||
|
||||
{{range .versions}}
|
||||
func FromV{{.}}FilterEstimate(v{{.}} smoothing{{.}}.FilterEstimate) FilterEstimate {
|
||||
{{if (eq . 0)}}
|
||||
return (FilterEstimate)(v{{.}}) //nolint:unconvert
|
||||
{{else}}
|
||||
return (FilterEstimate)(v{{.}})
|
||||
{{end}}
|
||||
}
|
||||
{{end}}
|
||||
|
||||
type ActorStateLoader func(store adt.Store, root cid.Cid) (cbor.Marshaler, error)
|
||||
|
||||
var ActorStateLoaders = make(map[cid.Cid]ActorStateLoader)
|
||||
|
||||
func RegisterActorState(code cid.Cid, loader ActorStateLoader) {
|
||||
ActorStateLoaders[code] = loader
|
||||
}
|
||||
|
||||
func Load(store adt.Store, act *types.Actor) (cbor.Marshaler, error) {
|
||||
loader, found := ActorStateLoaders[act.Code]
|
||||
if !found {
|
||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||
}
|
||||
return loader(store, act.Head)
|
||||
}
|
||||
|
||||
func ActorNameByCode(c cid.Cid) string {
|
||||
switch {
|
||||
{{range .versions}}
|
||||
case builtin{{.}}.IsBuiltinActor(c):
|
||||
return builtin{{.}}.ActorNameByCode(c)
|
||||
{{end}}
|
||||
default:
|
||||
return "<unknown>"
|
||||
}
|
||||
}
|
||||
|
||||
func IsBuiltinActor(c cid.Cid) bool {
|
||||
{{range .versions}}
|
||||
if builtin{{.}}.IsBuiltinActor(c) {
|
||||
return true
|
||||
}
|
||||
{{end}}
|
||||
return false
|
||||
}
|
||||
|
||||
func IsAccountActor(c cid.Cid) bool {
|
||||
{{range .versions}}
|
||||
if c == builtin{{.}}.AccountActorCodeID {
|
||||
return true
|
||||
}
|
||||
{{end}}
|
||||
return false
|
||||
}
|
||||
|
||||
func IsStorageMinerActor(c cid.Cid) bool {
|
||||
{{range .versions}}
|
||||
if c == builtin{{.}}.StorageMinerActorCodeID {
|
||||
return true
|
||||
}
|
||||
{{end}}
|
||||
return false
|
||||
}
|
||||
|
||||
func IsMultisigActor(c cid.Cid) bool {
|
||||
{{range .versions}}
|
||||
if c == builtin{{.}}.MultisigActorCodeID {
|
||||
return true
|
||||
}
|
||||
{{end}}
|
||||
return false
|
||||
}
|
||||
|
||||
func IsPaymentChannelActor(c cid.Cid) bool {
|
||||
{{range .versions}}
|
||||
if c == builtin{{.}}.PaymentChannelActorCodeID {
|
||||
return true
|
||||
}
|
||||
{{end}}
|
||||
return false
|
||||
}
|
||||
|
||||
func makeAddress(addr string) address.Address {
|
||||
ret, err := address.NewFromString(addr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
10
chain/actors/builtin/cron/actor.go.template
Normal file
10
chain/actors/builtin/cron/actor.go.template
Normal file
@ -0,0 +1,10 @@
|
||||
package cron
|
||||
|
||||
import (
|
||||
builtin{{.latestVersion}} "github.com/filecoin-project/specs-actors{{import .latestVersion}}actors/builtin"
|
||||
)
|
||||
|
||||
var (
|
||||
Address = builtin{{.latestVersion}}.CronActorAddr
|
||||
Methods = builtin{{.latestVersion}}.MethodsCron
|
||||
)
|
60
chain/actors/builtin/init/actor.go.template
Normal file
60
chain/actors/builtin/init/actor.go.template
Normal file
@ -0,0 +1,60 @@
|
||||
package init
|
||||
|
||||
import (
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/cbor"
|
||||
"github.com/ipfs/go-cid"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||
{{range .versions}}
|
||||
builtin{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin"
|
||||
{{end}}
|
||||
)
|
||||
|
||||
func init() {
|
||||
{{range .versions}}
|
||||
builtin.RegisterActorState(builtin{{.}}.InitActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||
return load{{.}}(store, root)
|
||||
})
|
||||
{{end}}}
|
||||
|
||||
var (
|
||||
Address = builtin{{.latestVersion}}.InitActorAddr
|
||||
Methods = builtin{{.latestVersion}}.MethodsInit
|
||||
)
|
||||
|
||||
func Load(store adt.Store, act *types.Actor) (State, error) {
|
||||
switch act.Code {
|
||||
{{range .versions}}
|
||||
case builtin{{.}}.InitActorCodeID:
|
||||
return load{{.}}(store, act.Head)
|
||||
{{end}}
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||
}
|
||||
|
||||
type State interface {
|
||||
cbor.Marshaler
|
||||
|
||||
ResolveAddress(address address.Address) (address.Address, bool, error)
|
||||
MapAddressToNewID(address address.Address) (address.Address, error)
|
||||
NetworkName() (dtypes.NetworkName, error)
|
||||
|
||||
ForEachActor(func(id abi.ActorID, address address.Address) error) error
|
||||
|
||||
// Remove exists to support tooling that manipulates state for testing.
|
||||
// It should not be used in production code, as init actor entries are
|
||||
// immutable.
|
||||
Remove(addrs ...address.Address) error
|
||||
|
||||
// Sets the network's name. This should only be used on upgrade/fork.
|
||||
SetNetworkName(name string) error
|
||||
|
||||
addressMap() (adt.Map, error)
|
||||
}
|
@ -14,21 +14,28 @@ import (
|
||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||
|
||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
|
||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||
|
||||
builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin"
|
||||
|
||||
builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
||||
builtin.RegisterActorState(builtin0.InitActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||
return load0(store, root)
|
||||
})
|
||||
|
||||
builtin.RegisterActorState(builtin2.InitActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||
return load2(store, root)
|
||||
})
|
||||
|
||||
builtin.RegisterActorState(builtin3.InitActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||
return load3(store, root)
|
||||
})
|
||||
|
||||
builtin.RegisterActorState(builtin4.InitActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||
return load4(store, root)
|
||||
})
|
||||
@ -41,14 +48,19 @@ var (
|
||||
|
||||
func Load(store adt.Store, act *types.Actor) (State, error) {
|
||||
switch act.Code {
|
||||
|
||||
case builtin0.InitActorCodeID:
|
||||
return load0(store, act.Head)
|
||||
|
||||
case builtin2.InitActorCodeID:
|
||||
return load2(store, act.Head)
|
||||
|
||||
case builtin3.InitActorCodeID:
|
||||
return load3(store, act.Head)
|
||||
|
||||
case builtin4.InitActorCodeID:
|
||||
return load4(store, act.Head)
|
||||
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||
}
|
||||
|
89
chain/actors/builtin/init/state.go.template
Normal file
89
chain/actors/builtin/init/state.go.template
Normal file
@ -0,0 +1,89 @@
|
||||
package init
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/ipfs/go-cid"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||
|
||||
{{if (ge .v 3)}}
|
||||
builtin{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin"
|
||||
{{end}}
|
||||
|
||||
init{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/init"
|
||||
adt{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/util/adt"
|
||||
)
|
||||
|
||||
var _ State = (*state{{.v}})(nil)
|
||||
|
||||
func load{{.v}}(store adt.Store, root cid.Cid) (State, error) {
|
||||
out := state{{.v}}{store: store}
|
||||
err := store.Get(store.Context(), root, &out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
type state{{.v}} struct {
|
||||
init{{.v}}.State
|
||||
store adt.Store
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) ResolveAddress(address address.Address) (address.Address, bool, error) {
|
||||
return s.State.ResolveAddress(s.store, address)
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) MapAddressToNewID(address address.Address) (address.Address, error) {
|
||||
return s.State.MapAddressToNewID(s.store, address)
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) ForEachActor(cb func(id abi.ActorID, address address.Address) error) error {
|
||||
addrs, err := adt{{.v}}.AsMap(s.store, s.State.AddressMap{{if (ge .v 3)}}, builtin{{.v}}.DefaultHamtBitwidth{{end}})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var actorID cbg.CborInt
|
||||
return addrs.ForEach(&actorID, func(key string) error {
|
||||
addr, err := address.NewFromBytes([]byte(key))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return cb(abi.ActorID(actorID), addr)
|
||||
})
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) NetworkName() (dtypes.NetworkName, error) {
|
||||
return dtypes.NetworkName(s.State.NetworkName), nil
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) SetNetworkName(name string) error {
|
||||
s.State.NetworkName = name
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) Remove(addrs ...address.Address) (err error) {
|
||||
m, err := adt{{.v}}.AsMap(s.store, s.State.AddressMap{{if (ge .v 3)}}, builtin{{.v}}.DefaultHamtBitwidth{{end}})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, addr := range addrs {
|
||||
if err = m.Delete(abi.AddrKey(addr)); err != nil {
|
||||
return xerrors.Errorf("failed to delete entry for address: %s; err: %w", addr, err)
|
||||
}
|
||||
}
|
||||
amr, err := m.Root()
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to get address map root: %w", err)
|
||||
}
|
||||
s.State.AddressMap = amr
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) addressMap() (adt.Map, error) {
|
||||
return adt{{.v}}.AsMap(s.store, s.AddressMap{{if (ge .v 3)}}, builtin{{.v}}.DefaultHamtBitwidth{{end}})
|
||||
}
|
@ -3,7 +3,6 @@ package init
|
||||
import (
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin"
|
||||
"github.com/ipfs/go-cid"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
"golang.org/x/xerrors"
|
||||
@ -11,6 +10,8 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||
|
||||
builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin"
|
||||
|
||||
init3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/init"
|
||||
adt3 "github.com/filecoin-project/specs-actors/v3/actors/util/adt"
|
||||
)
|
||||
|
@ -3,7 +3,6 @@ package init
|
||||
import (
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin"
|
||||
"github.com/ipfs/go-cid"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
"golang.org/x/xerrors"
|
||||
@ -11,6 +10,8 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||
|
||||
builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin"
|
||||
|
||||
init4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/init"
|
||||
adt4 "github.com/filecoin-project/specs-actors/v4/actors/util/adt"
|
||||
)
|
||||
|
159
chain/actors/builtin/market/actor.go.template
Normal file
159
chain/actors/builtin/market/actor.go.template
Normal file
@ -0,0 +1,159 @@
|
||||
package market
|
||||
|
||||
import (
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/go-state-types/cbor"
|
||||
"github.com/ipfs/go-cid"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
|
||||
market0 "github.com/filecoin-project/specs-actors/actors/builtin/market"
|
||||
{{range .versions}}
|
||||
builtin{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin"
|
||||
{{end}}
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
func init() {
|
||||
{{range .versions}}
|
||||
builtin.RegisterActorState(builtin{{.}}.StorageMarketActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||
return load{{.}}(store, root)
|
||||
})
|
||||
{{end}}}
|
||||
|
||||
var (
|
||||
Address = builtin{{.latestVersion}}.StorageMarketActorAddr
|
||||
Methods = builtin{{.latestVersion}}.MethodsMarket
|
||||
)
|
||||
|
||||
func Load(store adt.Store, act *types.Actor) (State, error) {
|
||||
switch act.Code {
|
||||
{{range .versions}}
|
||||
case builtin{{.}}.StorageMarketActorCodeID:
|
||||
return load{{.}}(store, act.Head)
|
||||
{{end}}
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||
}
|
||||
|
||||
type State interface {
|
||||
cbor.Marshaler
|
||||
BalancesChanged(State) (bool, error)
|
||||
EscrowTable() (BalanceTable, error)
|
||||
LockedTable() (BalanceTable, error)
|
||||
TotalLocked() (abi.TokenAmount, error)
|
||||
StatesChanged(State) (bool, error)
|
||||
States() (DealStates, error)
|
||||
ProposalsChanged(State) (bool, error)
|
||||
Proposals() (DealProposals, error)
|
||||
VerifyDealsForActivation(
|
||||
minerAddr address.Address, deals []abi.DealID, currEpoch, sectorExpiry abi.ChainEpoch,
|
||||
) (weight, verifiedWeight abi.DealWeight, err error)
|
||||
NextID() (abi.DealID, error)
|
||||
}
|
||||
|
||||
type BalanceTable interface {
|
||||
ForEach(cb func(address.Address, abi.TokenAmount) error) error
|
||||
Get(key address.Address) (abi.TokenAmount, error)
|
||||
}
|
||||
|
||||
type DealStates interface {
|
||||
ForEach(cb func(id abi.DealID, ds DealState) error) error
|
||||
Get(id abi.DealID) (*DealState, bool, error)
|
||||
|
||||
array() adt.Array
|
||||
decode(*cbg.Deferred) (*DealState, error)
|
||||
}
|
||||
|
||||
type DealProposals interface {
|
||||
ForEach(cb func(id abi.DealID, dp DealProposal) error) error
|
||||
Get(id abi.DealID) (*DealProposal, bool, error)
|
||||
|
||||
array() adt.Array
|
||||
decode(*cbg.Deferred) (*DealProposal, error)
|
||||
}
|
||||
|
||||
type PublishStorageDealsParams = market0.PublishStorageDealsParams
|
||||
type PublishStorageDealsReturn = market0.PublishStorageDealsReturn
|
||||
type VerifyDealsForActivationParams = market0.VerifyDealsForActivationParams
|
||||
type WithdrawBalanceParams = market0.WithdrawBalanceParams
|
||||
|
||||
type ClientDealProposal = market0.ClientDealProposal
|
||||
|
||||
type DealState struct {
|
||||
SectorStartEpoch abi.ChainEpoch // -1 if not yet included in proven sector
|
||||
LastUpdatedEpoch abi.ChainEpoch // -1 if deal state never updated
|
||||
SlashEpoch abi.ChainEpoch // -1 if deal never slashed
|
||||
}
|
||||
|
||||
type DealProposal struct {
|
||||
PieceCID cid.Cid
|
||||
PieceSize abi.PaddedPieceSize
|
||||
VerifiedDeal bool
|
||||
Client address.Address
|
||||
Provider address.Address
|
||||
Label string
|
||||
StartEpoch abi.ChainEpoch
|
||||
EndEpoch abi.ChainEpoch
|
||||
StoragePricePerEpoch abi.TokenAmount
|
||||
ProviderCollateral abi.TokenAmount
|
||||
ClientCollateral abi.TokenAmount
|
||||
}
|
||||
|
||||
type DealStateChanges struct {
|
||||
Added []DealIDState
|
||||
Modified []DealStateChange
|
||||
Removed []DealIDState
|
||||
}
|
||||
|
||||
type DealIDState struct {
|
||||
ID abi.DealID
|
||||
Deal DealState
|
||||
}
|
||||
|
||||
// DealStateChange is a change in deal state from -> to
|
||||
type DealStateChange struct {
|
||||
ID abi.DealID
|
||||
From *DealState
|
||||
To *DealState
|
||||
}
|
||||
|
||||
type DealProposalChanges struct {
|
||||
Added []ProposalIDState
|
||||
Removed []ProposalIDState
|
||||
}
|
||||
|
||||
type ProposalIDState struct {
|
||||
ID abi.DealID
|
||||
Proposal DealProposal
|
||||
}
|
||||
|
||||
func EmptyDealState() *DealState {
|
||||
return &DealState{
|
||||
SectorStartEpoch: -1,
|
||||
SlashEpoch: -1,
|
||||
LastUpdatedEpoch: -1,
|
||||
}
|
||||
}
|
||||
|
||||
// returns the earned fees and pending fees for a given deal
|
||||
func (deal DealProposal) GetDealFees(height abi.ChainEpoch) (abi.TokenAmount, abi.TokenAmount) {
|
||||
tf := big.Mul(deal.StoragePricePerEpoch, big.NewInt(int64(deal.EndEpoch-deal.StartEpoch)))
|
||||
|
||||
ef := big.Mul(deal.StoragePricePerEpoch, big.NewInt(int64(height-deal.StartEpoch)))
|
||||
if ef.LessThan(big.Zero()) {
|
||||
ef = big.Zero()
|
||||
}
|
||||
|
||||
if ef.GreaterThan(tf) {
|
||||
ef = tf
|
||||
}
|
||||
|
||||
return ef, big.Sub(tf, ef)
|
||||
}
|
@ -1,19 +1,23 @@
|
||||
package market
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/go-state-types/cbor"
|
||||
"github.com/ipfs/go-cid"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
|
||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
market0 "github.com/filecoin-project/specs-actors/actors/builtin/market"
|
||||
|
||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
|
||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||
|
||||
builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin"
|
||||
|
||||
builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
@ -22,15 +26,19 @@ import (
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
||||
builtin.RegisterActorState(builtin0.StorageMarketActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||
return load0(store, root)
|
||||
})
|
||||
|
||||
builtin.RegisterActorState(builtin2.StorageMarketActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||
return load2(store, root)
|
||||
})
|
||||
|
||||
builtin.RegisterActorState(builtin3.StorageMarketActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||
return load3(store, root)
|
||||
})
|
||||
|
||||
builtin.RegisterActorState(builtin4.StorageMarketActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||
return load4(store, root)
|
||||
})
|
||||
@ -41,16 +49,21 @@ var (
|
||||
Methods = builtin4.MethodsMarket
|
||||
)
|
||||
|
||||
func Load(store adt.Store, act *types.Actor) (st State, err error) {
|
||||
func Load(store adt.Store, act *types.Actor) (State, error) {
|
||||
switch act.Code {
|
||||
|
||||
case builtin0.StorageMarketActorCodeID:
|
||||
return load0(store, act.Head)
|
||||
|
||||
case builtin2.StorageMarketActorCodeID:
|
||||
return load2(store, act.Head)
|
||||
|
||||
case builtin3.StorageMarketActorCodeID:
|
||||
return load3(store, act.Head)
|
||||
|
||||
case builtin4.StorageMarketActorCodeID:
|
||||
return load4(store, act.Head)
|
||||
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||
}
|
||||
|
209
chain/actors/builtin/market/state.go.template
Normal file
209
chain/actors/builtin/market/state.go.template
Normal file
@ -0,0 +1,209 @@
|
||||
package market
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/ipfs/go-cid"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
|
||||
market{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/market"
|
||||
adt{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/util/adt"
|
||||
)
|
||||
|
||||
var _ State = (*state{{.v}})(nil)
|
||||
|
||||
func load{{.v}}(store adt.Store, root cid.Cid) (State, error) {
|
||||
out := state{{.v}}{store: store}
|
||||
err := store.Get(store.Context(), root, &out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
type state{{.v}} struct {
|
||||
market{{.v}}.State
|
||||
store adt.Store
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) TotalLocked() (abi.TokenAmount, error) {
|
||||
fml := types.BigAdd(s.TotalClientLockedCollateral, s.TotalProviderLockedCollateral)
|
||||
fml = types.BigAdd(fml, s.TotalClientStorageFee)
|
||||
return fml, nil
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) BalancesChanged(otherState State) (bool, error) {
|
||||
otherState{{.v}}, ok := otherState.(*state{{.v}})
|
||||
if !ok {
|
||||
// there's no way to compare different versions of the state, so let's
|
||||
// just say that means the state of balances has changed
|
||||
return true, nil
|
||||
}
|
||||
return !s.State.EscrowTable.Equals(otherState{{.v}}.State.EscrowTable) || !s.State.LockedTable.Equals(otherState{{.v}}.State.LockedTable), nil
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) StatesChanged(otherState State) (bool, error) {
|
||||
otherState{{.v}}, ok := otherState.(*state{{.v}})
|
||||
if !ok {
|
||||
// there's no way to compare different versions of the state, so let's
|
||||
// just say that means the state of balances has changed
|
||||
return true, nil
|
||||
}
|
||||
return !s.State.States.Equals(otherState{{.v}}.State.States), nil
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) States() (DealStates, error) {
|
||||
stateArray, err := adt{{.v}}.AsArray(s.store, s.State.States{{if (ge .v 3)}}, market{{.v}}.StatesAmtBitwidth{{end}})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &dealStates{{.v}}{stateArray}, nil
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) ProposalsChanged(otherState State) (bool, error) {
|
||||
otherState{{.v}}, ok := otherState.(*state{{.v}})
|
||||
if !ok {
|
||||
// there's no way to compare different versions of the state, so let's
|
||||
// just say that means the state of balances has changed
|
||||
return true, nil
|
||||
}
|
||||
return !s.State.Proposals.Equals(otherState{{.v}}.State.Proposals), nil
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) Proposals() (DealProposals, error) {
|
||||
proposalArray, err := adt{{.v}}.AsArray(s.store, s.State.Proposals{{if (ge .v 3)}}, market{{.v}}.ProposalsAmtBitwidth{{end}})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &dealProposals{{.v}}{proposalArray}, nil
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) EscrowTable() (BalanceTable, error) {
|
||||
bt, err := adt{{.v}}.AsBalanceTable(s.store, s.State.EscrowTable)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &balanceTable{{.v}}{bt}, nil
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) LockedTable() (BalanceTable, error) {
|
||||
bt, err := adt{{.v}}.AsBalanceTable(s.store, s.State.LockedTable)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &balanceTable{{.v}}{bt}, nil
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) VerifyDealsForActivation(
|
||||
minerAddr address.Address, deals []abi.DealID, currEpoch, sectorExpiry abi.ChainEpoch,
|
||||
) (weight, verifiedWeight abi.DealWeight, err error) {
|
||||
w, vw{{if (ge .v 2)}}, _{{end}}, err := market{{.v}}.ValidateDealsForActivation(&s.State, s.store, deals, minerAddr, sectorExpiry, currEpoch)
|
||||
return w, vw, err
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) NextID() (abi.DealID, error) {
|
||||
return s.State.NextID, nil
|
||||
}
|
||||
|
||||
type balanceTable{{.v}} struct {
|
||||
*adt{{.v}}.BalanceTable
|
||||
}
|
||||
|
||||
func (bt *balanceTable{{.v}}) ForEach(cb func(address.Address, abi.TokenAmount) error) error {
|
||||
asMap := (*adt{{.v}}.Map)(bt.BalanceTable)
|
||||
var ta abi.TokenAmount
|
||||
return asMap.ForEach(&ta, func(key string) error {
|
||||
a, err := address.NewFromBytes([]byte(key))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return cb(a, ta)
|
||||
})
|
||||
}
|
||||
|
||||
type dealStates{{.v}} struct {
|
||||
adt.Array
|
||||
}
|
||||
|
||||
func (s *dealStates{{.v}}) Get(dealID abi.DealID) (*DealState, bool, error) {
|
||||
var deal{{.v}} market{{.v}}.DealState
|
||||
found, err := s.Array.Get(uint64(dealID), &deal{{.v}})
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
if !found {
|
||||
return nil, false, nil
|
||||
}
|
||||
deal := fromV{{.v}}DealState(deal{{.v}})
|
||||
return &deal, true, nil
|
||||
}
|
||||
|
||||
func (s *dealStates{{.v}}) ForEach(cb func(dealID abi.DealID, ds DealState) error) error {
|
||||
var ds{{.v}} market{{.v}}.DealState
|
||||
return s.Array.ForEach(&ds{{.v}}, func(idx int64) error {
|
||||
return cb(abi.DealID(idx), fromV{{.v}}DealState(ds{{.v}}))
|
||||
})
|
||||
}
|
||||
|
||||
func (s *dealStates{{.v}}) decode(val *cbg.Deferred) (*DealState, error) {
|
||||
var ds{{.v}} market{{.v}}.DealState
|
||||
if err := ds{{.v}}.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ds := fromV{{.v}}DealState(ds{{.v}})
|
||||
return &ds, nil
|
||||
}
|
||||
|
||||
func (s *dealStates{{.v}}) array() adt.Array {
|
||||
return s.Array
|
||||
}
|
||||
|
||||
func fromV{{.v}}DealState(v{{.v}} market{{.v}}.DealState) DealState {
|
||||
return (DealState)(v{{.v}})
|
||||
}
|
||||
|
||||
type dealProposals{{.v}} struct {
|
||||
adt.Array
|
||||
}
|
||||
|
||||
func (s *dealProposals{{.v}}) Get(dealID abi.DealID) (*DealProposal, bool, error) {
|
||||
var proposal{{.v}} market{{.v}}.DealProposal
|
||||
found, err := s.Array.Get(uint64(dealID), &proposal{{.v}})
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
if !found {
|
||||
return nil, false, nil
|
||||
}
|
||||
proposal := fromV{{.v}}DealProposal(proposal{{.v}})
|
||||
return &proposal, true, nil
|
||||
}
|
||||
|
||||
func (s *dealProposals{{.v}}) ForEach(cb func(dealID abi.DealID, dp DealProposal) error) error {
|
||||
var dp{{.v}} market{{.v}}.DealProposal
|
||||
return s.Array.ForEach(&dp{{.v}}, func(idx int64) error {
|
||||
return cb(abi.DealID(idx), fromV{{.v}}DealProposal(dp{{.v}}))
|
||||
})
|
||||
}
|
||||
|
||||
func (s *dealProposals{{.v}}) decode(val *cbg.Deferred) (*DealProposal, error) {
|
||||
var dp{{.v}} market{{.v}}.DealProposal
|
||||
if err := dp{{.v}}.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dp := fromV{{.v}}DealProposal(dp{{.v}})
|
||||
return &dp, nil
|
||||
}
|
||||
|
||||
func (s *dealProposals{{.v}}) array() adt.Array {
|
||||
return s.Array
|
||||
}
|
||||
|
||||
func fromV{{.v}}DealProposal(v{{.v}} market{{.v}}.DealProposal) DealProposal {
|
||||
return (DealProposal)(v{{.v}})
|
||||
}
|
@ -102,7 +102,8 @@ func (s *state0) LockedTable() (BalanceTable, error) {
|
||||
func (s *state0) VerifyDealsForActivation(
|
||||
minerAddr address.Address, deals []abi.DealID, currEpoch, sectorExpiry abi.ChainEpoch,
|
||||
) (weight, verifiedWeight abi.DealWeight, err error) {
|
||||
return market0.ValidateDealsForActivation(&s.State, s.store, deals, minerAddr, sectorExpiry, currEpoch)
|
||||
w, vw, err := market0.ValidateDealsForActivation(&s.State, s.store, deals, minerAddr, sectorExpiry, currEpoch)
|
||||
return w, vw, err
|
||||
}
|
||||
|
||||
func (s *state0) NextID() (abi.DealID, error) {
|
||||
|
@ -144,18 +144,18 @@ func (s *dealStates2) Get(dealID abi.DealID) (*DealState, bool, error) {
|
||||
}
|
||||
|
||||
func (s *dealStates2) ForEach(cb func(dealID abi.DealID, ds DealState) error) error {
|
||||
var ds1 market2.DealState
|
||||
return s.Array.ForEach(&ds1, func(idx int64) error {
|
||||
return cb(abi.DealID(idx), fromV2DealState(ds1))
|
||||
var ds2 market2.DealState
|
||||
return s.Array.ForEach(&ds2, func(idx int64) error {
|
||||
return cb(abi.DealID(idx), fromV2DealState(ds2))
|
||||
})
|
||||
}
|
||||
|
||||
func (s *dealStates2) decode(val *cbg.Deferred) (*DealState, error) {
|
||||
var ds1 market2.DealState
|
||||
if err := ds1.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
|
||||
var ds2 market2.DealState
|
||||
if err := ds2.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ds := fromV2DealState(ds1)
|
||||
ds := fromV2DealState(ds2)
|
||||
return &ds, nil
|
||||
}
|
||||
|
||||
@ -163,8 +163,8 @@ func (s *dealStates2) array() adt.Array {
|
||||
return s.Array
|
||||
}
|
||||
|
||||
func fromV2DealState(v1 market2.DealState) DealState {
|
||||
return (DealState)(v1)
|
||||
func fromV2DealState(v2 market2.DealState) DealState {
|
||||
return (DealState)(v2)
|
||||
}
|
||||
|
||||
type dealProposals2 struct {
|
||||
@ -185,18 +185,18 @@ func (s *dealProposals2) Get(dealID abi.DealID) (*DealProposal, bool, error) {
|
||||
}
|
||||
|
||||
func (s *dealProposals2) ForEach(cb func(dealID abi.DealID, dp DealProposal) error) error {
|
||||
var dp1 market2.DealProposal
|
||||
return s.Array.ForEach(&dp1, func(idx int64) error {
|
||||
return cb(abi.DealID(idx), fromV2DealProposal(dp1))
|
||||
var dp2 market2.DealProposal
|
||||
return s.Array.ForEach(&dp2, func(idx int64) error {
|
||||
return cb(abi.DealID(idx), fromV2DealProposal(dp2))
|
||||
})
|
||||
}
|
||||
|
||||
func (s *dealProposals2) decode(val *cbg.Deferred) (*DealProposal, error) {
|
||||
var dp1 market2.DealProposal
|
||||
if err := dp1.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
|
||||
var dp2 market2.DealProposal
|
||||
if err := dp2.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dp := fromV2DealProposal(dp1)
|
||||
dp := fromV2DealProposal(dp2)
|
||||
return &dp, nil
|
||||
}
|
||||
|
||||
@ -204,6 +204,6 @@ func (s *dealProposals2) array() adt.Array {
|
||||
return s.Array
|
||||
}
|
||||
|
||||
func fromV2DealProposal(v1 market2.DealProposal) DealProposal {
|
||||
return (DealProposal)(v1)
|
||||
func fromV2DealProposal(v2 market2.DealProposal) DealProposal {
|
||||
return (DealProposal)(v2)
|
||||
}
|
||||
|
@ -38,23 +38,23 @@ func (s *state3) TotalLocked() (abi.TokenAmount, error) {
|
||||
}
|
||||
|
||||
func (s *state3) BalancesChanged(otherState State) (bool, error) {
|
||||
otherState2, ok := otherState.(*state3)
|
||||
otherState3, ok := otherState.(*state3)
|
||||
if !ok {
|
||||
// there's no way to compare different versions of the state, so let's
|
||||
// just say that means the state of balances has changed
|
||||
return true, nil
|
||||
}
|
||||
return !s.State.EscrowTable.Equals(otherState2.State.EscrowTable) || !s.State.LockedTable.Equals(otherState2.State.LockedTable), nil
|
||||
return !s.State.EscrowTable.Equals(otherState3.State.EscrowTable) || !s.State.LockedTable.Equals(otherState3.State.LockedTable), nil
|
||||
}
|
||||
|
||||
func (s *state3) StatesChanged(otherState State) (bool, error) {
|
||||
otherState2, ok := otherState.(*state3)
|
||||
otherState3, ok := otherState.(*state3)
|
||||
if !ok {
|
||||
// there's no way to compare different versions of the state, so let's
|
||||
// just say that means the state of balances has changed
|
||||
return true, nil
|
||||
}
|
||||
return !s.State.States.Equals(otherState2.State.States), nil
|
||||
return !s.State.States.Equals(otherState3.State.States), nil
|
||||
}
|
||||
|
||||
func (s *state3) States() (DealStates, error) {
|
||||
@ -66,13 +66,13 @@ func (s *state3) States() (DealStates, error) {
|
||||
}
|
||||
|
||||
func (s *state3) ProposalsChanged(otherState State) (bool, error) {
|
||||
otherState2, ok := otherState.(*state3)
|
||||
otherState3, ok := otherState.(*state3)
|
||||
if !ok {
|
||||
// there's no way to compare different versions of the state, so let's
|
||||
// just say that means the state of balances has changed
|
||||
return true, nil
|
||||
}
|
||||
return !s.State.Proposals.Equals(otherState2.State.Proposals), nil
|
||||
return !s.State.Proposals.Equals(otherState3.State.Proposals), nil
|
||||
}
|
||||
|
||||
func (s *state3) Proposals() (DealProposals, error) {
|
||||
@ -131,31 +131,31 @@ type dealStates3 struct {
|
||||
}
|
||||
|
||||
func (s *dealStates3) Get(dealID abi.DealID) (*DealState, bool, error) {
|
||||
var deal2 market3.DealState
|
||||
found, err := s.Array.Get(uint64(dealID), &deal2)
|
||||
var deal3 market3.DealState
|
||||
found, err := s.Array.Get(uint64(dealID), &deal3)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
if !found {
|
||||
return nil, false, nil
|
||||
}
|
||||
deal := fromV3DealState(deal2)
|
||||
deal := fromV3DealState(deal3)
|
||||
return &deal, true, nil
|
||||
}
|
||||
|
||||
func (s *dealStates3) ForEach(cb func(dealID abi.DealID, ds DealState) error) error {
|
||||
var ds1 market3.DealState
|
||||
return s.Array.ForEach(&ds1, func(idx int64) error {
|
||||
return cb(abi.DealID(idx), fromV3DealState(ds1))
|
||||
var ds3 market3.DealState
|
||||
return s.Array.ForEach(&ds3, func(idx int64) error {
|
||||
return cb(abi.DealID(idx), fromV3DealState(ds3))
|
||||
})
|
||||
}
|
||||
|
||||
func (s *dealStates3) decode(val *cbg.Deferred) (*DealState, error) {
|
||||
var ds1 market3.DealState
|
||||
if err := ds1.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
|
||||
var ds3 market3.DealState
|
||||
if err := ds3.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ds := fromV3DealState(ds1)
|
||||
ds := fromV3DealState(ds3)
|
||||
return &ds, nil
|
||||
}
|
||||
|
||||
@ -163,8 +163,8 @@ func (s *dealStates3) array() adt.Array {
|
||||
return s.Array
|
||||
}
|
||||
|
||||
func fromV3DealState(v1 market3.DealState) DealState {
|
||||
return (DealState)(v1)
|
||||
func fromV3DealState(v3 market3.DealState) DealState {
|
||||
return (DealState)(v3)
|
||||
}
|
||||
|
||||
type dealProposals3 struct {
|
||||
@ -172,31 +172,31 @@ type dealProposals3 struct {
|
||||
}
|
||||
|
||||
func (s *dealProposals3) Get(dealID abi.DealID) (*DealProposal, bool, error) {
|
||||
var proposal2 market3.DealProposal
|
||||
found, err := s.Array.Get(uint64(dealID), &proposal2)
|
||||
var proposal3 market3.DealProposal
|
||||
found, err := s.Array.Get(uint64(dealID), &proposal3)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
if !found {
|
||||
return nil, false, nil
|
||||
}
|
||||
proposal := fromV3DealProposal(proposal2)
|
||||
proposal := fromV3DealProposal(proposal3)
|
||||
return &proposal, true, nil
|
||||
}
|
||||
|
||||
func (s *dealProposals3) ForEach(cb func(dealID abi.DealID, dp DealProposal) error) error {
|
||||
var dp1 market3.DealProposal
|
||||
return s.Array.ForEach(&dp1, func(idx int64) error {
|
||||
return cb(abi.DealID(idx), fromV3DealProposal(dp1))
|
||||
var dp3 market3.DealProposal
|
||||
return s.Array.ForEach(&dp3, func(idx int64) error {
|
||||
return cb(abi.DealID(idx), fromV3DealProposal(dp3))
|
||||
})
|
||||
}
|
||||
|
||||
func (s *dealProposals3) decode(val *cbg.Deferred) (*DealProposal, error) {
|
||||
var dp1 market3.DealProposal
|
||||
if err := dp1.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
|
||||
var dp3 market3.DealProposal
|
||||
if err := dp3.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dp := fromV3DealProposal(dp1)
|
||||
dp := fromV3DealProposal(dp3)
|
||||
return &dp, nil
|
||||
}
|
||||
|
||||
@ -204,6 +204,6 @@ func (s *dealProposals3) array() adt.Array {
|
||||
return s.Array
|
||||
}
|
||||
|
||||
func fromV3DealProposal(v1 market3.DealProposal) DealProposal {
|
||||
return (DealProposal)(v1)
|
||||
func fromV3DealProposal(v3 market3.DealProposal) DealProposal {
|
||||
return (DealProposal)(v3)
|
||||
}
|
||||
|
@ -38,23 +38,23 @@ func (s *state4) TotalLocked() (abi.TokenAmount, error) {
|
||||
}
|
||||
|
||||
func (s *state4) BalancesChanged(otherState State) (bool, error) {
|
||||
otherState2, ok := otherState.(*state4)
|
||||
otherState4, ok := otherState.(*state4)
|
||||
if !ok {
|
||||
// there's no way to compare different versions of the state, so let's
|
||||
// just say that means the state of balances has changed
|
||||
return true, nil
|
||||
}
|
||||
return !s.State.EscrowTable.Equals(otherState2.State.EscrowTable) || !s.State.LockedTable.Equals(otherState2.State.LockedTable), nil
|
||||
return !s.State.EscrowTable.Equals(otherState4.State.EscrowTable) || !s.State.LockedTable.Equals(otherState4.State.LockedTable), nil
|
||||
}
|
||||
|
||||
func (s *state4) StatesChanged(otherState State) (bool, error) {
|
||||
otherState2, ok := otherState.(*state4)
|
||||
otherState4, ok := otherState.(*state4)
|
||||
if !ok {
|
||||
// there's no way to compare different versions of the state, so let's
|
||||
// just say that means the state of balances has changed
|
||||
return true, nil
|
||||
}
|
||||
return !s.State.States.Equals(otherState2.State.States), nil
|
||||
return !s.State.States.Equals(otherState4.State.States), nil
|
||||
}
|
||||
|
||||
func (s *state4) States() (DealStates, error) {
|
||||
@ -66,13 +66,13 @@ func (s *state4) States() (DealStates, error) {
|
||||
}
|
||||
|
||||
func (s *state4) ProposalsChanged(otherState State) (bool, error) {
|
||||
otherState2, ok := otherState.(*state4)
|
||||
otherState4, ok := otherState.(*state4)
|
||||
if !ok {
|
||||
// there's no way to compare different versions of the state, so let's
|
||||
// just say that means the state of balances has changed
|
||||
return true, nil
|
||||
}
|
||||
return !s.State.Proposals.Equals(otherState2.State.Proposals), nil
|
||||
return !s.State.Proposals.Equals(otherState4.State.Proposals), nil
|
||||
}
|
||||
|
||||
func (s *state4) Proposals() (DealProposals, error) {
|
||||
@ -131,31 +131,31 @@ type dealStates4 struct {
|
||||
}
|
||||
|
||||
func (s *dealStates4) Get(dealID abi.DealID) (*DealState, bool, error) {
|
||||
var deal2 market4.DealState
|
||||
found, err := s.Array.Get(uint64(dealID), &deal2)
|
||||
var deal4 market4.DealState
|
||||
found, err := s.Array.Get(uint64(dealID), &deal4)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
if !found {
|
||||
return nil, false, nil
|
||||
}
|
||||
deal := fromV4DealState(deal2)
|
||||
deal := fromV4DealState(deal4)
|
||||
return &deal, true, nil
|
||||
}
|
||||
|
||||
func (s *dealStates4) ForEach(cb func(dealID abi.DealID, ds DealState) error) error {
|
||||
var ds1 market4.DealState
|
||||
return s.Array.ForEach(&ds1, func(idx int64) error {
|
||||
return cb(abi.DealID(idx), fromV4DealState(ds1))
|
||||
var ds4 market4.DealState
|
||||
return s.Array.ForEach(&ds4, func(idx int64) error {
|
||||
return cb(abi.DealID(idx), fromV4DealState(ds4))
|
||||
})
|
||||
}
|
||||
|
||||
func (s *dealStates4) decode(val *cbg.Deferred) (*DealState, error) {
|
||||
var ds1 market4.DealState
|
||||
if err := ds1.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
|
||||
var ds4 market4.DealState
|
||||
if err := ds4.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ds := fromV4DealState(ds1)
|
||||
ds := fromV4DealState(ds4)
|
||||
return &ds, nil
|
||||
}
|
||||
|
||||
@ -172,31 +172,31 @@ type dealProposals4 struct {
|
||||
}
|
||||
|
||||
func (s *dealProposals4) Get(dealID abi.DealID) (*DealProposal, bool, error) {
|
||||
var proposal2 market4.DealProposal
|
||||
found, err := s.Array.Get(uint64(dealID), &proposal2)
|
||||
var proposal4 market4.DealProposal
|
||||
found, err := s.Array.Get(uint64(dealID), &proposal4)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
if !found {
|
||||
return nil, false, nil
|
||||
}
|
||||
proposal := fromV4DealProposal(proposal2)
|
||||
proposal := fromV4DealProposal(proposal4)
|
||||
return &proposal, true, nil
|
||||
}
|
||||
|
||||
func (s *dealProposals4) ForEach(cb func(dealID abi.DealID, dp DealProposal) error) error {
|
||||
var dp1 market4.DealProposal
|
||||
return s.Array.ForEach(&dp1, func(idx int64) error {
|
||||
return cb(abi.DealID(idx), fromV4DealProposal(dp1))
|
||||
var dp4 market4.DealProposal
|
||||
return s.Array.ForEach(&dp4, func(idx int64) error {
|
||||
return cb(abi.DealID(idx), fromV4DealProposal(dp4))
|
||||
})
|
||||
}
|
||||
|
||||
func (s *dealProposals4) decode(val *cbg.Deferred) (*DealProposal, error) {
|
||||
var dp1 market4.DealProposal
|
||||
if err := dp1.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
|
||||
var dp4 market4.DealProposal
|
||||
if err := dp4.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dp := fromV4DealProposal(dp1)
|
||||
dp := fromV4DealProposal(dp4)
|
||||
return &dp, nil
|
||||
}
|
||||
|
||||
|
270
chain/actors/builtin/miner/actor.go.template
Normal file
270
chain/actors/builtin/miner/actor.go.template
Normal file
@ -0,0 +1,270 @@
|
||||
package miner
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-bitfield"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/cbor"
|
||||
"github.com/filecoin-project/go-state-types/dline"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
|
||||
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
miner2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner"
|
||||
miner3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/miner"
|
||||
{{range .versions}}
|
||||
builtin{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin"
|
||||
{{end}}
|
||||
)
|
||||
|
||||
func init() {
|
||||
{{range .versions}}
|
||||
builtin.RegisterActorState(builtin{{.}}.StorageMinerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||
return load{{.}}(store, root)
|
||||
})
|
||||
{{end}}
|
||||
}
|
||||
|
||||
var Methods = builtin{{.latestVersion}}.MethodsMiner
|
||||
|
||||
// Unchanged between v0, v2, v3, and v4 actors
|
||||
var WPoStProvingPeriod = miner0.WPoStProvingPeriod
|
||||
var WPoStPeriodDeadlines = miner0.WPoStPeriodDeadlines
|
||||
var WPoStChallengeWindow = miner0.WPoStChallengeWindow
|
||||
var WPoStChallengeLookback = miner0.WPoStChallengeLookback
|
||||
var FaultDeclarationCutoff = miner0.FaultDeclarationCutoff
|
||||
|
||||
const MinSectorExpiration = miner0.MinSectorExpiration
|
||||
|
||||
// Not used / checked in v0
|
||||
// TODO: Abstract over network versions
|
||||
var DeclarationsMax = miner2.DeclarationsMax
|
||||
var AddressedSectorsMax = miner2.AddressedSectorsMax
|
||||
|
||||
func Load(store adt.Store, act *types.Actor) (State, error) {
|
||||
switch act.Code {
|
||||
{{range .versions}}
|
||||
case builtin{{.}}.StorageMinerActorCodeID:
|
||||
return load{{.}}(store, act.Head)
|
||||
{{end}}
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||
}
|
||||
|
||||
type State interface {
|
||||
cbor.Marshaler
|
||||
|
||||
// Total available balance to spend.
|
||||
AvailableBalance(abi.TokenAmount) (abi.TokenAmount, error)
|
||||
// Funds that will vest by the given epoch.
|
||||
VestedFunds(abi.ChainEpoch) (abi.TokenAmount, error)
|
||||
// Funds locked for various reasons.
|
||||
LockedFunds() (LockedFunds, error)
|
||||
FeeDebt() (abi.TokenAmount, error)
|
||||
|
||||
GetSector(abi.SectorNumber) (*SectorOnChainInfo, error)
|
||||
FindSector(abi.SectorNumber) (*SectorLocation, error)
|
||||
GetSectorExpiration(abi.SectorNumber) (*SectorExpiration, error)
|
||||
GetPrecommittedSector(abi.SectorNumber) (*SectorPreCommitOnChainInfo, error)
|
||||
LoadSectors(sectorNos *bitfield.BitField) ([]*SectorOnChainInfo, error)
|
||||
NumLiveSectors() (uint64, error)
|
||||
IsAllocated(abi.SectorNumber) (bool, error)
|
||||
|
||||
LoadDeadline(idx uint64) (Deadline, error)
|
||||
ForEachDeadline(cb func(idx uint64, dl Deadline) error) error
|
||||
NumDeadlines() (uint64, error)
|
||||
DeadlinesChanged(State) (bool, error)
|
||||
|
||||
Info() (MinerInfo, error)
|
||||
MinerInfoChanged(State) (bool, error)
|
||||
|
||||
DeadlineInfo(epoch abi.ChainEpoch) (*dline.Info, error)
|
||||
DeadlineCronActive() (bool, error)
|
||||
|
||||
// Diff helpers. Used by Diff* functions internally.
|
||||
sectors() (adt.Array, error)
|
||||
decodeSectorOnChainInfo(*cbg.Deferred) (SectorOnChainInfo, error)
|
||||
precommits() (adt.Map, error)
|
||||
decodeSectorPreCommitOnChainInfo(*cbg.Deferred) (SectorPreCommitOnChainInfo, error)
|
||||
}
|
||||
|
||||
type Deadline interface {
|
||||
LoadPartition(idx uint64) (Partition, error)
|
||||
ForEachPartition(cb func(idx uint64, part Partition) error) error
|
||||
PartitionsPoSted() (bitfield.BitField, error)
|
||||
|
||||
PartitionsChanged(Deadline) (bool, error)
|
||||
DisputableProofCount() (uint64, error)
|
||||
}
|
||||
|
||||
type Partition interface {
|
||||
AllSectors() (bitfield.BitField, error)
|
||||
FaultySectors() (bitfield.BitField, error)
|
||||
RecoveringSectors() (bitfield.BitField, error)
|
||||
LiveSectors() (bitfield.BitField, error)
|
||||
ActiveSectors() (bitfield.BitField, error)
|
||||
}
|
||||
|
||||
type SectorOnChainInfo struct {
|
||||
SectorNumber abi.SectorNumber
|
||||
SealProof abi.RegisteredSealProof
|
||||
SealedCID cid.Cid
|
||||
DealIDs []abi.DealID
|
||||
Activation abi.ChainEpoch
|
||||
Expiration abi.ChainEpoch
|
||||
DealWeight abi.DealWeight
|
||||
VerifiedDealWeight abi.DealWeight
|
||||
InitialPledge abi.TokenAmount
|
||||
ExpectedDayReward abi.TokenAmount
|
||||
ExpectedStoragePledge abi.TokenAmount
|
||||
}
|
||||
|
||||
type SectorPreCommitInfo = miner0.SectorPreCommitInfo
|
||||
|
||||
type SectorPreCommitOnChainInfo struct {
|
||||
Info SectorPreCommitInfo
|
||||
PreCommitDeposit abi.TokenAmount
|
||||
PreCommitEpoch abi.ChainEpoch
|
||||
DealWeight abi.DealWeight
|
||||
VerifiedDealWeight abi.DealWeight
|
||||
}
|
||||
|
||||
type PoStPartition = miner0.PoStPartition
|
||||
type RecoveryDeclaration = miner0.RecoveryDeclaration
|
||||
type FaultDeclaration = miner0.FaultDeclaration
|
||||
|
||||
// Params
|
||||
type DeclareFaultsParams = miner0.DeclareFaultsParams
|
||||
type DeclareFaultsRecoveredParams = miner0.DeclareFaultsRecoveredParams
|
||||
type SubmitWindowedPoStParams = miner0.SubmitWindowedPoStParams
|
||||
type ProveCommitSectorParams = miner0.ProveCommitSectorParams
|
||||
type DisputeWindowedPoStParams = miner3.DisputeWindowedPoStParams
|
||||
|
||||
func PreferredSealProofTypeFromWindowPoStType(nver network.Version, proof abi.RegisteredPoStProof) (abi.RegisteredSealProof, error) {
|
||||
// We added support for the new proofs in network version 7, and removed support for the old
|
||||
// ones in network version 8.
|
||||
if nver < network.Version7 {
|
||||
switch proof {
|
||||
case abi.RegisteredPoStProof_StackedDrgWindow2KiBV1:
|
||||
return abi.RegisteredSealProof_StackedDrg2KiBV1, nil
|
||||
case abi.RegisteredPoStProof_StackedDrgWindow8MiBV1:
|
||||
return abi.RegisteredSealProof_StackedDrg8MiBV1, nil
|
||||
case abi.RegisteredPoStProof_StackedDrgWindow512MiBV1:
|
||||
return abi.RegisteredSealProof_StackedDrg512MiBV1, nil
|
||||
case abi.RegisteredPoStProof_StackedDrgWindow32GiBV1:
|
||||
return abi.RegisteredSealProof_StackedDrg32GiBV1, nil
|
||||
case abi.RegisteredPoStProof_StackedDrgWindow64GiBV1:
|
||||
return abi.RegisteredSealProof_StackedDrg64GiBV1, nil
|
||||
default:
|
||||
return -1, xerrors.Errorf("unrecognized window post type: %d", proof)
|
||||
}
|
||||
}
|
||||
|
||||
switch proof {
|
||||
case abi.RegisteredPoStProof_StackedDrgWindow2KiBV1:
|
||||
return abi.RegisteredSealProof_StackedDrg2KiBV1_1, nil
|
||||
case abi.RegisteredPoStProof_StackedDrgWindow8MiBV1:
|
||||
return abi.RegisteredSealProof_StackedDrg8MiBV1_1, nil
|
||||
case abi.RegisteredPoStProof_StackedDrgWindow512MiBV1:
|
||||
return abi.RegisteredSealProof_StackedDrg512MiBV1_1, nil
|
||||
case abi.RegisteredPoStProof_StackedDrgWindow32GiBV1:
|
||||
return abi.RegisteredSealProof_StackedDrg32GiBV1_1, nil
|
||||
case abi.RegisteredPoStProof_StackedDrgWindow64GiBV1:
|
||||
return abi.RegisteredSealProof_StackedDrg64GiBV1_1, nil
|
||||
default:
|
||||
return -1, xerrors.Errorf("unrecognized window post type: %d", proof)
|
||||
}
|
||||
}
|
||||
|
||||
func WinningPoStProofTypeFromWindowPoStProofType(nver network.Version, proof abi.RegisteredPoStProof) (abi.RegisteredPoStProof, error) {
|
||||
switch proof {
|
||||
case abi.RegisteredPoStProof_StackedDrgWindow2KiBV1:
|
||||
return abi.RegisteredPoStProof_StackedDrgWinning2KiBV1, nil
|
||||
case abi.RegisteredPoStProof_StackedDrgWindow8MiBV1:
|
||||
return abi.RegisteredPoStProof_StackedDrgWinning8MiBV1, nil
|
||||
case abi.RegisteredPoStProof_StackedDrgWindow512MiBV1:
|
||||
return abi.RegisteredPoStProof_StackedDrgWinning512MiBV1, nil
|
||||
case abi.RegisteredPoStProof_StackedDrgWindow32GiBV1:
|
||||
return abi.RegisteredPoStProof_StackedDrgWinning32GiBV1, nil
|
||||
case abi.RegisteredPoStProof_StackedDrgWindow64GiBV1:
|
||||
return abi.RegisteredPoStProof_StackedDrgWinning64GiBV1, nil
|
||||
default:
|
||||
return -1, xerrors.Errorf("unknown proof type %d", proof)
|
||||
}
|
||||
}
|
||||
|
||||
type MinerInfo struct {
|
||||
Owner address.Address // Must be an ID-address.
|
||||
Worker address.Address // Must be an ID-address.
|
||||
NewWorker address.Address // Must be an ID-address.
|
||||
ControlAddresses []address.Address // Must be an ID-addresses.
|
||||
WorkerChangeEpoch abi.ChainEpoch
|
||||
PeerId *peer.ID
|
||||
Multiaddrs []abi.Multiaddrs
|
||||
WindowPoStProofType abi.RegisteredPoStProof
|
||||
SectorSize abi.SectorSize
|
||||
WindowPoStPartitionSectors uint64
|
||||
ConsensusFaultElapsed abi.ChainEpoch
|
||||
}
|
||||
|
||||
func (mi MinerInfo) IsController(addr address.Address) bool {
|
||||
if addr == mi.Owner || addr == mi.Worker {
|
||||
return true
|
||||
}
|
||||
|
||||
for _, ca := range mi.ControlAddresses {
|
||||
if addr == ca {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
type SectorExpiration struct {
|
||||
OnTime abi.ChainEpoch
|
||||
|
||||
// non-zero if sector is faulty, epoch at which it will be permanently
|
||||
// removed if it doesn't recover
|
||||
Early abi.ChainEpoch
|
||||
}
|
||||
|
||||
type SectorLocation struct {
|
||||
Deadline uint64
|
||||
Partition uint64
|
||||
}
|
||||
|
||||
type SectorChanges struct {
|
||||
Added []SectorOnChainInfo
|
||||
Extended []SectorExtensions
|
||||
Removed []SectorOnChainInfo
|
||||
}
|
||||
|
||||
type SectorExtensions struct {
|
||||
From SectorOnChainInfo
|
||||
To SectorOnChainInfo
|
||||
}
|
||||
|
||||
type PreCommitChanges struct {
|
||||
Added []SectorPreCommitOnChainInfo
|
||||
Removed []SectorPreCommitOnChainInfo
|
||||
}
|
||||
|
||||
type LockedFunds struct {
|
||||
VestingFunds abi.TokenAmount
|
||||
InitialPledgeRequirement abi.TokenAmount
|
||||
PreCommitDeposits abi.TokenAmount
|
||||
}
|
||||
|
||||
func (lf LockedFunds) TotalLockedFunds() abi.TokenAmount {
|
||||
return big.Add(lf.VestingFunds, big.Add(lf.InitialPledgeRequirement, lf.PreCommitDeposits))
|
||||
}
|
@ -18,28 +18,37 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
|
||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||
miner2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner"
|
||||
builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin"
|
||||
miner3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/miner"
|
||||
|
||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
|
||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||
|
||||
builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin"
|
||||
|
||||
builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
||||
builtin.RegisterActorState(builtin0.StorageMinerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||
return load0(store, root)
|
||||
})
|
||||
|
||||
builtin.RegisterActorState(builtin2.StorageMinerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||
return load2(store, root)
|
||||
})
|
||||
|
||||
builtin.RegisterActorState(builtin3.StorageMinerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||
return load3(store, root)
|
||||
})
|
||||
|
||||
builtin.RegisterActorState(builtin4.StorageMinerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||
return load4(store, root)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
var Methods = builtin4.MethodsMiner
|
||||
@ -58,16 +67,21 @@ const MinSectorExpiration = miner0.MinSectorExpiration
|
||||
var DeclarationsMax = miner2.DeclarationsMax
|
||||
var AddressedSectorsMax = miner2.AddressedSectorsMax
|
||||
|
||||
func Load(store adt.Store, act *types.Actor) (st State, err error) {
|
||||
func Load(store adt.Store, act *types.Actor) (State, error) {
|
||||
switch act.Code {
|
||||
|
||||
case builtin0.StorageMinerActorCodeID:
|
||||
return load0(store, act.Head)
|
||||
|
||||
case builtin2.StorageMinerActorCodeID:
|
||||
return load2(store, act.Head)
|
||||
|
||||
case builtin3.StorageMinerActorCodeID:
|
||||
return load3(store, act.Head)
|
||||
|
||||
case builtin4.StorageMinerActorCodeID:
|
||||
return load4(store, act.Head)
|
||||
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||
}
|
||||
|
460
chain/actors/builtin/miner/state.go.template
Normal file
460
chain/actors/builtin/miner/state.go.template
Normal file
@ -0,0 +1,460 @@
|
||||
package miner
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
{{if (le .v 1)}}
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
{{end}}
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-bitfield"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/dline"
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
|
||||
{{if (ge .v 3)}}
|
||||
builtin{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin"
|
||||
{{end}}
|
||||
miner{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/miner"
|
||||
adt{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/util/adt"
|
||||
)
|
||||
|
||||
var _ State = (*state{{.v}})(nil)
|
||||
|
||||
func load{{.v}}(store adt.Store, root cid.Cid) (State, error) {
|
||||
out := state{{.v}}{store: store}
|
||||
err := store.Get(store.Context(), root, &out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
type state{{.v}} struct {
|
||||
miner{{.v}}.State
|
||||
store adt.Store
|
||||
}
|
||||
|
||||
type deadline{{.v}} struct {
|
||||
miner{{.v}}.Deadline
|
||||
store adt.Store
|
||||
}
|
||||
|
||||
type partition{{.v}} struct {
|
||||
miner{{.v}}.Partition
|
||||
store adt.Store
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) AvailableBalance(bal abi.TokenAmount) (available abi.TokenAmount, err error) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
err = xerrors.Errorf("failed to get available balance: %w", r)
|
||||
available = abi.NewTokenAmount(0)
|
||||
}
|
||||
}()
|
||||
// this panics if the miner doesnt have enough funds to cover their locked pledge
|
||||
available{{if (ge .v 2)}}, err{{end}} = s.GetAvailableBalance(bal)
|
||||
return available, err
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) VestedFunds(epoch abi.ChainEpoch) (abi.TokenAmount, error) {
|
||||
return s.CheckVestedFunds(s.store, epoch)
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) LockedFunds() (LockedFunds, error) {
|
||||
return LockedFunds{
|
||||
VestingFunds: s.State.LockedFunds,
|
||||
InitialPledgeRequirement: s.State.InitialPledge{{if (le .v 1)}}Requirement{{end}},
|
||||
PreCommitDeposits: s.State.PreCommitDeposits,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) FeeDebt() (abi.TokenAmount, error) {
|
||||
return {{if (ge .v 2)}}s.State.FeeDebt{{else}}big.Zero(){{end}}, nil
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) InitialPledge() (abi.TokenAmount, error) {
|
||||
return s.State.InitialPledge{{if (le .v 1)}}Requirement{{end}}, nil
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) PreCommitDeposits() (abi.TokenAmount, error) {
|
||||
return s.State.PreCommitDeposits, nil
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) GetSector(num abi.SectorNumber) (*SectorOnChainInfo, error) {
|
||||
info, ok, err := s.State.GetSector(s.store, num)
|
||||
if !ok || err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ret := fromV{{.v}}SectorOnChainInfo(*info)
|
||||
return &ret, nil
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) FindSector(num abi.SectorNumber) (*SectorLocation, error) {
|
||||
dlIdx, partIdx, err := s.State.FindSector(s.store, num)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &SectorLocation{
|
||||
Deadline: dlIdx,
|
||||
Partition: partIdx,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) NumLiveSectors() (uint64, error) {
|
||||
dls, err := s.State.LoadDeadlines(s.store)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
var total uint64
|
||||
if err := dls.ForEach(s.store, func(dlIdx uint64, dl *miner{{.v}}.Deadline) error {
|
||||
total += dl.LiveSectors
|
||||
return nil
|
||||
}); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return total, nil
|
||||
}
|
||||
|
||||
// GetSectorExpiration returns the effective expiration of the given sector.
|
||||
//
|
||||
// If the sector does not expire early, the Early expiration field is 0.
|
||||
func (s *state{{.v}}) GetSectorExpiration(num abi.SectorNumber) (*SectorExpiration, error) {
|
||||
dls, err := s.State.LoadDeadlines(s.store)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// NOTE: this can be optimized significantly.
|
||||
// 1. If the sector is non-faulty, it will either expire on-time (can be
|
||||
// learned from the sector info), or in the next quantized expiration
|
||||
// epoch (i.e., the first element in the partition's expiration queue.
|
||||
// 2. If it's faulty, it will expire early within the first 14 entries
|
||||
// of the expiration queue.
|
||||
stopErr := errors.New("stop")
|
||||
out := SectorExpiration{}
|
||||
err = dls.ForEach(s.store, func(dlIdx uint64, dl *miner{{.v}}.Deadline) error {
|
||||
partitions, err := dl.PartitionsArray(s.store)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
quant := s.State.QuantSpecForDeadline(dlIdx)
|
||||
var part miner{{.v}}.Partition
|
||||
return partitions.ForEach(&part, func(partIdx int64) error {
|
||||
if found, err := part.Sectors.IsSet(uint64(num)); err != nil {
|
||||
return err
|
||||
} else if !found {
|
||||
return nil
|
||||
}
|
||||
if found, err := part.Terminated.IsSet(uint64(num)); err != nil {
|
||||
return err
|
||||
} else if found {
|
||||
// already terminated
|
||||
return stopErr
|
||||
}
|
||||
|
||||
q, err := miner{{.v}}.LoadExpirationQueue(s.store, part.ExpirationsEpochs, quant{{if (ge .v 3)}}, miner{{.v}}.PartitionExpirationAmtBitwidth{{end}})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var exp miner{{.v}}.ExpirationSet
|
||||
return q.ForEach(&exp, func(epoch int64) error {
|
||||
if early, err := exp.EarlySectors.IsSet(uint64(num)); err != nil {
|
||||
return err
|
||||
} else if early {
|
||||
out.Early = abi.ChainEpoch(epoch)
|
||||
return nil
|
||||
}
|
||||
if onTime, err := exp.OnTimeSectors.IsSet(uint64(num)); err != nil {
|
||||
return err
|
||||
} else if onTime {
|
||||
out.OnTime = abi.ChainEpoch(epoch)
|
||||
return stopErr
|
||||
}
|
||||
return nil
|
||||
})
|
||||
})
|
||||
})
|
||||
if err == stopErr {
|
||||
err = nil
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if out.Early == 0 && out.OnTime == 0 {
|
||||
return nil, xerrors.Errorf("failed to find sector %d", num)
|
||||
}
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) GetPrecommittedSector(num abi.SectorNumber) (*SectorPreCommitOnChainInfo, error) {
|
||||
info, ok, err := s.State.GetPrecommittedSector(s.store, num)
|
||||
if !ok || err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ret := fromV{{.v}}SectorPreCommitOnChainInfo(*info)
|
||||
|
||||
return &ret, nil
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) LoadSectors(snos *bitfield.BitField) ([]*SectorOnChainInfo, error) {
|
||||
sectors, err := miner{{.v}}.LoadSectors(s.store, s.State.Sectors)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// If no sector numbers are specified, load all.
|
||||
if snos == nil {
|
||||
infos := make([]*SectorOnChainInfo, 0, sectors.Length())
|
||||
var info{{.v}} miner{{.v}}.SectorOnChainInfo
|
||||
if err := sectors.ForEach(&info{{.v}}, func(_ int64) error {
|
||||
info := fromV{{.v}}SectorOnChainInfo(info{{.v}})
|
||||
infos = append(infos, &info)
|
||||
return nil
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return infos, nil
|
||||
}
|
||||
|
||||
// Otherwise, load selected.
|
||||
infos{{.v}}, err := sectors.Load(*snos)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
infos := make([]*SectorOnChainInfo, len(infos{{.v}}))
|
||||
for i, info{{.v}} := range infos{{.v}} {
|
||||
info := fromV{{.v}}SectorOnChainInfo(*info{{.v}})
|
||||
infos[i] = &info
|
||||
}
|
||||
return infos, nil
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) IsAllocated(num abi.SectorNumber) (bool, error) {
|
||||
var allocatedSectors bitfield.BitField
|
||||
if err := s.store.Get(s.store.Context(), s.State.AllocatedSectors, &allocatedSectors); err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return allocatedSectors.IsSet(uint64(num))
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) LoadDeadline(idx uint64) (Deadline, error) {
|
||||
dls, err := s.State.LoadDeadlines(s.store)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dl, err := dls.LoadDeadline(s.store, idx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &deadline{{.v}}{*dl, s.store}, nil
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) ForEachDeadline(cb func(uint64, Deadline) error) error {
|
||||
dls, err := s.State.LoadDeadlines(s.store)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return dls.ForEach(s.store, func(i uint64, dl *miner{{.v}}.Deadline) error {
|
||||
return cb(i, &deadline{{.v}}{*dl, s.store})
|
||||
})
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) NumDeadlines() (uint64, error) {
|
||||
return miner{{.v}}.WPoStPeriodDeadlines, nil
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) DeadlinesChanged(other State) (bool, error) {
|
||||
other{{.v}}, ok := other.(*state{{.v}})
|
||||
if !ok {
|
||||
// treat an upgrade as a change, always
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return !s.State.Deadlines.Equals(other{{.v}}.Deadlines), nil
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) MinerInfoChanged(other State) (bool, error) {
|
||||
other0, ok := other.(*state{{.v}})
|
||||
if !ok {
|
||||
// treat an upgrade as a change, always
|
||||
return true, nil
|
||||
}
|
||||
return !s.State.Info.Equals(other0.State.Info), nil
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) Info() (MinerInfo, error) {
|
||||
info, err := s.State.GetInfo(s.store)
|
||||
if err != nil {
|
||||
return MinerInfo{}, err
|
||||
}
|
||||
|
||||
var pid *peer.ID
|
||||
if peerID, err := peer.IDFromBytes(info.PeerId); err == nil {
|
||||
pid = &peerID
|
||||
}
|
||||
{{if (le .v 2)}}
|
||||
wpp, err := info.SealProofType.RegisteredWindowPoStProof()
|
||||
if err != nil {
|
||||
return MinerInfo{}, err
|
||||
}
|
||||
{{end}}
|
||||
mi := MinerInfo{
|
||||
Owner: info.Owner,
|
||||
Worker: info.Worker,
|
||||
ControlAddresses: info.ControlAddresses,
|
||||
|
||||
NewWorker: address.Undef,
|
||||
WorkerChangeEpoch: -1,
|
||||
|
||||
PeerId: pid,
|
||||
Multiaddrs: info.Multiaddrs,
|
||||
WindowPoStProofType: {{if (ge .v 3)}}info.WindowPoStProofType{{else}}wpp{{end}},
|
||||
SectorSize: info.SectorSize,
|
||||
WindowPoStPartitionSectors: info.WindowPoStPartitionSectors,
|
||||
ConsensusFaultElapsed: {{if (ge .v 2)}}info.ConsensusFaultElapsed{{else}}-1{{end}},
|
||||
}
|
||||
|
||||
if info.PendingWorkerKey != nil {
|
||||
mi.NewWorker = info.PendingWorkerKey.NewWorker
|
||||
mi.WorkerChangeEpoch = info.PendingWorkerKey.EffectiveAt
|
||||
}
|
||||
|
||||
return mi, nil
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) DeadlineInfo(epoch abi.ChainEpoch) (*dline.Info, error) {
|
||||
return s.State.{{if (ge .v 4)}}Recorded{{end}}DeadlineInfo(epoch), nil
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) DeadlineCronActive() (bool, error) {
|
||||
return {{if (ge .v 4)}}s.State.DeadlineCronActive{{else}}true{{end}}, nil{{if (lt .v 4)}} // always active in this version{{end}}
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) sectors() (adt.Array, error) {
|
||||
return adt{{.v}}.AsArray(s.store, s.Sectors{{if (ge .v 3)}}, miner{{.v}}.SectorsAmtBitwidth{{end}})
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) decodeSectorOnChainInfo(val *cbg.Deferred) (SectorOnChainInfo, error) {
|
||||
var si miner{{.v}}.SectorOnChainInfo
|
||||
err := si.UnmarshalCBOR(bytes.NewReader(val.Raw))
|
||||
if err != nil {
|
||||
return SectorOnChainInfo{}, err
|
||||
}
|
||||
|
||||
return fromV{{.v}}SectorOnChainInfo(si), nil
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) precommits() (adt.Map, error) {
|
||||
return adt{{.v}}.AsMap(s.store, s.PreCommittedSectors{{if (ge .v 3)}}, builtin{{.v}}.DefaultHamtBitwidth{{end}})
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) decodeSectorPreCommitOnChainInfo(val *cbg.Deferred) (SectorPreCommitOnChainInfo, error) {
|
||||
var sp miner{{.v}}.SectorPreCommitOnChainInfo
|
||||
err := sp.UnmarshalCBOR(bytes.NewReader(val.Raw))
|
||||
if err != nil {
|
||||
return SectorPreCommitOnChainInfo{}, err
|
||||
}
|
||||
|
||||
return fromV{{.v}}SectorPreCommitOnChainInfo(sp), nil
|
||||
}
|
||||
|
||||
func (d *deadline{{.v}}) LoadPartition(idx uint64) (Partition, error) {
|
||||
p, err := d.Deadline.LoadPartition(d.store, idx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &partition{{.v}}{*p, d.store}, nil
|
||||
}
|
||||
|
||||
func (d *deadline{{.v}}) ForEachPartition(cb func(uint64, Partition) error) error {
|
||||
ps, err := d.Deadline.PartitionsArray(d.store)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var part miner{{.v}}.Partition
|
||||
return ps.ForEach(&part, func(i int64) error {
|
||||
return cb(uint64(i), &partition{{.v}}{part, d.store})
|
||||
})
|
||||
}
|
||||
|
||||
func (d *deadline{{.v}}) PartitionsChanged(other Deadline) (bool, error) {
|
||||
other{{.v}}, ok := other.(*deadline{{.v}})
|
||||
if !ok {
|
||||
// treat an upgrade as a change, always
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return !d.Deadline.Partitions.Equals(other{{.v}}.Deadline.Partitions), nil
|
||||
}
|
||||
|
||||
func (d *deadline{{.v}}) PartitionsPoSted() (bitfield.BitField, error) {
|
||||
return d.Deadline.{{if (ge .v 3)}}PartitionsPoSted{{else}}PostSubmissions{{end}}, nil
|
||||
}
|
||||
|
||||
func (d *deadline{{.v}}) DisputableProofCount() (uint64, error) {
|
||||
{{if (ge .v 3)}}
|
||||
ops, err := d.OptimisticProofsSnapshotArray(d.store)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return ops.Length(), nil
|
||||
{{else}}
|
||||
// field doesn't exist until v3
|
||||
return 0, nil
|
||||
{{end}}
|
||||
}
|
||||
|
||||
func (p *partition{{.v}}) AllSectors() (bitfield.BitField, error) {
|
||||
return p.Partition.Sectors, nil
|
||||
}
|
||||
|
||||
func (p *partition{{.v}}) FaultySectors() (bitfield.BitField, error) {
|
||||
return p.Partition.Faults, nil
|
||||
}
|
||||
|
||||
func (p *partition{{.v}}) RecoveringSectors() (bitfield.BitField, error) {
|
||||
return p.Partition.Recoveries, nil
|
||||
}
|
||||
|
||||
func fromV{{.v}}SectorOnChainInfo(v{{.v}} miner{{.v}}.SectorOnChainInfo) SectorOnChainInfo {
|
||||
{{if (ge .v 2)}}
|
||||
return SectorOnChainInfo{
|
||||
SectorNumber: v{{.v}}.SectorNumber,
|
||||
SealProof: v{{.v}}.SealProof,
|
||||
SealedCID: v{{.v}}.SealedCID,
|
||||
DealIDs: v{{.v}}.DealIDs,
|
||||
Activation: v{{.v}}.Activation,
|
||||
Expiration: v{{.v}}.Expiration,
|
||||
DealWeight: v{{.v}}.DealWeight,
|
||||
VerifiedDealWeight: v{{.v}}.VerifiedDealWeight,
|
||||
InitialPledge: v{{.v}}.InitialPledge,
|
||||
ExpectedDayReward: v{{.v}}.ExpectedDayReward,
|
||||
ExpectedStoragePledge: v{{.v}}.ExpectedStoragePledge,
|
||||
}
|
||||
{{else}}
|
||||
return (SectorOnChainInfo)(v0)
|
||||
{{end}}
|
||||
}
|
||||
|
||||
func fromV{{.v}}SectorPreCommitOnChainInfo(v{{.v}} miner{{.v}}.SectorPreCommitOnChainInfo) SectorPreCommitOnChainInfo {
|
||||
{{if (ge .v 2)}}
|
||||
return SectorPreCommitOnChainInfo{
|
||||
Info: (SectorPreCommitInfo)(v{{.v}}.Info),
|
||||
PreCommitDeposit: v{{.v}}.PreCommitDeposit,
|
||||
PreCommitEpoch: v{{.v}}.PreCommitEpoch,
|
||||
DealWeight: v{{.v}}.DealWeight,
|
||||
VerifiedDealWeight: v{{.v}}.VerifiedDealWeight,
|
||||
}
|
||||
{{else}}
|
||||
return (SectorPreCommitOnChainInfo)(v0)
|
||||
{{end}}
|
||||
}
|
@ -196,6 +196,7 @@ func (s *state0) GetPrecommittedSector(num abi.SectorNumber) (*SectorPreCommitOn
|
||||
}
|
||||
|
||||
ret := fromV0SectorPreCommitOnChainInfo(*info)
|
||||
|
||||
return &ret, nil
|
||||
}
|
||||
|
||||
@ -396,8 +397,10 @@ func (d *deadline0) PartitionsPoSted() (bitfield.BitField, error) {
|
||||
}
|
||||
|
||||
func (d *deadline0) DisputableProofCount() (uint64, error) {
|
||||
|
||||
// field doesn't exist until v3
|
||||
return 0, nil
|
||||
|
||||
}
|
||||
|
||||
func (p *partition0) AllSectors() (bitfield.BitField, error) {
|
||||
@ -413,9 +416,13 @@ func (p *partition0) RecoveringSectors() (bitfield.BitField, error) {
|
||||
}
|
||||
|
||||
func fromV0SectorOnChainInfo(v0 miner0.SectorOnChainInfo) SectorOnChainInfo {
|
||||
|
||||
return (SectorOnChainInfo)(v0)
|
||||
|
||||
}
|
||||
|
||||
func fromV0SectorPreCommitOnChainInfo(v0 miner0.SectorPreCommitOnChainInfo) SectorPreCommitOnChainInfo {
|
||||
|
||||
return (SectorPreCommitOnChainInfo)(v0)
|
||||
|
||||
}
|
||||
|
@ -395,8 +395,10 @@ func (d *deadline2) PartitionsPoSted() (bitfield.BitField, error) {
|
||||
}
|
||||
|
||||
func (d *deadline2) DisputableProofCount() (uint64, error) {
|
||||
|
||||
// field doesn't exist until v3
|
||||
return 0, nil
|
||||
|
||||
}
|
||||
|
||||
func (p *partition2) AllSectors() (bitfield.BitField, error) {
|
||||
@ -412,6 +414,7 @@ func (p *partition2) RecoveringSectors() (bitfield.BitField, error) {
|
||||
}
|
||||
|
||||
func fromV2SectorOnChainInfo(v2 miner2.SectorOnChainInfo) SectorOnChainInfo {
|
||||
|
||||
return SectorOnChainInfo{
|
||||
SectorNumber: v2.SectorNumber,
|
||||
SealProof: v2.SealProof,
|
||||
@ -425,9 +428,11 @@ func fromV2SectorOnChainInfo(v2 miner2.SectorOnChainInfo) SectorOnChainInfo {
|
||||
ExpectedDayReward: v2.ExpectedDayReward,
|
||||
ExpectedStoragePledge: v2.ExpectedStoragePledge,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func fromV2SectorPreCommitOnChainInfo(v2 miner2.SectorPreCommitOnChainInfo) SectorPreCommitOnChainInfo {
|
||||
|
||||
return SectorPreCommitOnChainInfo{
|
||||
Info: (SectorPreCommitInfo)(v2.Info),
|
||||
PreCommitDeposit: v2.PreCommitDeposit,
|
||||
@ -435,4 +440,5 @@ func fromV2SectorPreCommitOnChainInfo(v2 miner2.SectorPreCommitOnChainInfo) Sect
|
||||
DealWeight: v2.DealWeight,
|
||||
VerifiedDealWeight: v2.VerifiedDealWeight,
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
|
||||
builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin"
|
||||
|
||||
miner3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/miner"
|
||||
adt3 "github.com/filecoin-project/specs-actors/v3/actors/util/adt"
|
||||
)
|
||||
@ -208,9 +209,9 @@ func (s *state3) LoadSectors(snos *bitfield.BitField) ([]*SectorOnChainInfo, err
|
||||
// If no sector numbers are specified, load all.
|
||||
if snos == nil {
|
||||
infos := make([]*SectorOnChainInfo, 0, sectors.Length())
|
||||
var info2 miner3.SectorOnChainInfo
|
||||
if err := sectors.ForEach(&info2, func(_ int64) error {
|
||||
info := fromV3SectorOnChainInfo(info2)
|
||||
var info3 miner3.SectorOnChainInfo
|
||||
if err := sectors.ForEach(&info3, func(_ int64) error {
|
||||
info := fromV3SectorOnChainInfo(info3)
|
||||
infos = append(infos, &info)
|
||||
return nil
|
||||
}); err != nil {
|
||||
@ -220,13 +221,13 @@ func (s *state3) LoadSectors(snos *bitfield.BitField) ([]*SectorOnChainInfo, err
|
||||
}
|
||||
|
||||
// Otherwise, load selected.
|
||||
infos2, err := sectors.Load(*snos)
|
||||
infos3, err := sectors.Load(*snos)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
infos := make([]*SectorOnChainInfo, len(infos2))
|
||||
for i, info2 := range infos2 {
|
||||
info := fromV3SectorOnChainInfo(*info2)
|
||||
infos := make([]*SectorOnChainInfo, len(infos3))
|
||||
for i, info3 := range infos3 {
|
||||
info := fromV3SectorOnChainInfo(*info3)
|
||||
infos[i] = &info
|
||||
}
|
||||
return infos, nil
|
||||
@ -268,13 +269,13 @@ func (s *state3) NumDeadlines() (uint64, error) {
|
||||
}
|
||||
|
||||
func (s *state3) DeadlinesChanged(other State) (bool, error) {
|
||||
other2, ok := other.(*state3)
|
||||
other3, ok := other.(*state3)
|
||||
if !ok {
|
||||
// treat an upgrade as a change, always
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return !s.State.Deadlines.Equals(other2.Deadlines), nil
|
||||
return !s.State.Deadlines.Equals(other3.Deadlines), nil
|
||||
}
|
||||
|
||||
func (s *state3) MinerInfoChanged(other State) (bool, error) {
|
||||
@ -377,13 +378,13 @@ func (d *deadline3) ForEachPartition(cb func(uint64, Partition) error) error {
|
||||
}
|
||||
|
||||
func (d *deadline3) PartitionsChanged(other Deadline) (bool, error) {
|
||||
other2, ok := other.(*deadline3)
|
||||
other3, ok := other.(*deadline3)
|
||||
if !ok {
|
||||
// treat an upgrade as a change, always
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return !d.Deadline.Partitions.Equals(other2.Deadline.Partitions), nil
|
||||
return !d.Deadline.Partitions.Equals(other3.Deadline.Partitions), nil
|
||||
}
|
||||
|
||||
func (d *deadline3) PartitionsPoSted() (bitfield.BitField, error) {
|
||||
@ -391,12 +392,14 @@ func (d *deadline3) PartitionsPoSted() (bitfield.BitField, error) {
|
||||
}
|
||||
|
||||
func (d *deadline3) DisputableProofCount() (uint64, error) {
|
||||
|
||||
ops, err := d.OptimisticProofsSnapshotArray(d.store)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return ops.Length(), nil
|
||||
|
||||
}
|
||||
|
||||
func (p *partition3) AllSectors() (bitfield.BitField, error) {
|
||||
@ -412,6 +415,7 @@ func (p *partition3) RecoveringSectors() (bitfield.BitField, error) {
|
||||
}
|
||||
|
||||
func fromV3SectorOnChainInfo(v3 miner3.SectorOnChainInfo) SectorOnChainInfo {
|
||||
|
||||
return SectorOnChainInfo{
|
||||
SectorNumber: v3.SectorNumber,
|
||||
SealProof: v3.SealProof,
|
||||
@ -425,9 +429,11 @@ func fromV3SectorOnChainInfo(v3 miner3.SectorOnChainInfo) SectorOnChainInfo {
|
||||
ExpectedDayReward: v3.ExpectedDayReward,
|
||||
ExpectedStoragePledge: v3.ExpectedStoragePledge,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func fromV3SectorPreCommitOnChainInfo(v3 miner3.SectorPreCommitOnChainInfo) SectorPreCommitOnChainInfo {
|
||||
|
||||
return SectorPreCommitOnChainInfo{
|
||||
Info: (SectorPreCommitInfo)(v3.Info),
|
||||
PreCommitDeposit: v3.PreCommitDeposit,
|
||||
@ -435,4 +441,5 @@ func fromV3SectorPreCommitOnChainInfo(v3 miner3.SectorPreCommitOnChainInfo) Sect
|
||||
DealWeight: v3.DealWeight,
|
||||
VerifiedDealWeight: v3.VerifiedDealWeight,
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
|
||||
builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin"
|
||||
|
||||
miner4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/miner"
|
||||
adt4 "github.com/filecoin-project/specs-actors/v4/actors/util/adt"
|
||||
)
|
||||
@ -208,9 +209,9 @@ func (s *state4) LoadSectors(snos *bitfield.BitField) ([]*SectorOnChainInfo, err
|
||||
// If no sector numbers are specified, load all.
|
||||
if snos == nil {
|
||||
infos := make([]*SectorOnChainInfo, 0, sectors.Length())
|
||||
var info2 miner4.SectorOnChainInfo
|
||||
if err := sectors.ForEach(&info2, func(_ int64) error {
|
||||
info := fromV4SectorOnChainInfo(info2)
|
||||
var info4 miner4.SectorOnChainInfo
|
||||
if err := sectors.ForEach(&info4, func(_ int64) error {
|
||||
info := fromV4SectorOnChainInfo(info4)
|
||||
infos = append(infos, &info)
|
||||
return nil
|
||||
}); err != nil {
|
||||
@ -220,13 +221,13 @@ func (s *state4) LoadSectors(snos *bitfield.BitField) ([]*SectorOnChainInfo, err
|
||||
}
|
||||
|
||||
// Otherwise, load selected.
|
||||
infos2, err := sectors.Load(*snos)
|
||||
infos4, err := sectors.Load(*snos)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
infos := make([]*SectorOnChainInfo, len(infos2))
|
||||
for i, info2 := range infos2 {
|
||||
info := fromV4SectorOnChainInfo(*info2)
|
||||
infos := make([]*SectorOnChainInfo, len(infos4))
|
||||
for i, info4 := range infos4 {
|
||||
info := fromV4SectorOnChainInfo(*info4)
|
||||
infos[i] = &info
|
||||
}
|
||||
return infos, nil
|
||||
@ -268,13 +269,13 @@ func (s *state4) NumDeadlines() (uint64, error) {
|
||||
}
|
||||
|
||||
func (s *state4) DeadlinesChanged(other State) (bool, error) {
|
||||
other2, ok := other.(*state4)
|
||||
other4, ok := other.(*state4)
|
||||
if !ok {
|
||||
// treat an upgrade as a change, always
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return !s.State.Deadlines.Equals(other2.Deadlines), nil
|
||||
return !s.State.Deadlines.Equals(other4.Deadlines), nil
|
||||
}
|
||||
|
||||
func (s *state4) MinerInfoChanged(other State) (bool, error) {
|
||||
@ -377,13 +378,13 @@ func (d *deadline4) ForEachPartition(cb func(uint64, Partition) error) error {
|
||||
}
|
||||
|
||||
func (d *deadline4) PartitionsChanged(other Deadline) (bool, error) {
|
||||
other2, ok := other.(*deadline4)
|
||||
other4, ok := other.(*deadline4)
|
||||
if !ok {
|
||||
// treat an upgrade as a change, always
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return !d.Deadline.Partitions.Equals(other2.Deadline.Partitions), nil
|
||||
return !d.Deadline.Partitions.Equals(other4.Deadline.Partitions), nil
|
||||
}
|
||||
|
||||
func (d *deadline4) PartitionsPoSted() (bitfield.BitField, error) {
|
||||
@ -391,12 +392,14 @@ func (d *deadline4) PartitionsPoSted() (bitfield.BitField, error) {
|
||||
}
|
||||
|
||||
func (d *deadline4) DisputableProofCount() (uint64, error) {
|
||||
|
||||
ops, err := d.OptimisticProofsSnapshotArray(d.store)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return ops.Length(), nil
|
||||
|
||||
}
|
||||
|
||||
func (p *partition4) AllSectors() (bitfield.BitField, error) {
|
||||
@ -412,6 +415,7 @@ func (p *partition4) RecoveringSectors() (bitfield.BitField, error) {
|
||||
}
|
||||
|
||||
func fromV4SectorOnChainInfo(v4 miner4.SectorOnChainInfo) SectorOnChainInfo {
|
||||
|
||||
return SectorOnChainInfo{
|
||||
SectorNumber: v4.SectorNumber,
|
||||
SealProof: v4.SealProof,
|
||||
@ -425,9 +429,11 @@ func fromV4SectorOnChainInfo(v4 miner4.SectorOnChainInfo) SectorOnChainInfo {
|
||||
ExpectedDayReward: v4.ExpectedDayReward,
|
||||
ExpectedStoragePledge: v4.ExpectedStoragePledge,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func fromV4SectorPreCommitOnChainInfo(v4 miner4.SectorPreCommitOnChainInfo) SectorPreCommitOnChainInfo {
|
||||
|
||||
return SectorPreCommitOnChainInfo{
|
||||
Info: (SectorPreCommitInfo)(v4.Info),
|
||||
PreCommitDeposit: v4.PreCommitDeposit,
|
||||
@ -435,4 +441,5 @@ func fromV4SectorPreCommitOnChainInfo(v4 miner4.SectorPreCommitOnChainInfo) Sect
|
||||
DealWeight: v4.DealWeight,
|
||||
VerifiedDealWeight: v4.VerifiedDealWeight,
|
||||
}
|
||||
|
||||
}
|
||||
|
117
chain/actors/builtin/multisig/actor.go.template
Normal file
117
chain/actors/builtin/multisig/actor.go.template
Normal file
@ -0,0 +1,117 @@
|
||||
package multisig
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/minio/blake2b-simd"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/cbor"
|
||||
"github.com/ipfs/go-cid"
|
||||
|
||||
msig{{.latestVersion}} "github.com/filecoin-project/specs-actors/v4/actors/builtin/multisig"
|
||||
{{range .versions}}
|
||||
builtin{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin"
|
||||
{{end}}
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
func init() {
|
||||
{{range .versions}}
|
||||
builtin.RegisterActorState(builtin{{.}}.MultisigActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||
return load{{.}}(store, root)
|
||||
})
|
||||
{{end}}}
|
||||
|
||||
func Load(store adt.Store, act *types.Actor) (State, error) {
|
||||
switch act.Code {
|
||||
{{range .versions}}
|
||||
case builtin{{.}}.MultisigActorCodeID:
|
||||
return load{{.}}(store, act.Head)
|
||||
{{end}}
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||
}
|
||||
|
||||
type State interface {
|
||||
cbor.Marshaler
|
||||
|
||||
LockedBalance(epoch abi.ChainEpoch) (abi.TokenAmount, error)
|
||||
StartEpoch() (abi.ChainEpoch, error)
|
||||
UnlockDuration() (abi.ChainEpoch, error)
|
||||
InitialBalance() (abi.TokenAmount, error)
|
||||
Threshold() (uint64, error)
|
||||
Signers() ([]address.Address, error)
|
||||
|
||||
ForEachPendingTxn(func(id int64, txn Transaction) error) error
|
||||
PendingTxnChanged(State) (bool, error)
|
||||
|
||||
transactions() (adt.Map, error)
|
||||
decodeTransaction(val *cbg.Deferred) (Transaction, error)
|
||||
}
|
||||
|
||||
type Transaction = msig{{.latestVersion}}.Transaction
|
||||
|
||||
var Methods = builtin{{.latestVersion}}.MethodsMultisig
|
||||
|
||||
func Message(version actors.Version, from address.Address) MessageBuilder {
|
||||
switch version {
|
||||
{{range .versions}}
|
||||
case actors.Version{{.}}:
|
||||
return message{{.}}{{"{"}}{{if (ge . 2)}}message0{from}{{else}}from{{end}}}
|
||||
{{end}} default:
|
||||
panic(fmt.Sprintf("unsupported actors version: %d", version))
|
||||
}
|
||||
}
|
||||
|
||||
type MessageBuilder interface {
|
||||
// Create a new multisig with the specified parameters.
|
||||
Create(signers []address.Address, threshold uint64,
|
||||
vestingStart, vestingDuration abi.ChainEpoch,
|
||||
initialAmount abi.TokenAmount) (*types.Message, error)
|
||||
|
||||
// Propose a transaction to the given multisig.
|
||||
Propose(msig, target address.Address, amt abi.TokenAmount,
|
||||
method abi.MethodNum, params []byte) (*types.Message, error)
|
||||
|
||||
// Approve a multisig transaction. The "hash" is optional.
|
||||
Approve(msig address.Address, txID uint64, hash *ProposalHashData) (*types.Message, error)
|
||||
|
||||
// Cancel a multisig transaction. The "hash" is optional.
|
||||
Cancel(msig address.Address, txID uint64, hash *ProposalHashData) (*types.Message, error)
|
||||
}
|
||||
|
||||
// this type is the same between v0 and v2
|
||||
type ProposalHashData = msig{{.latestVersion}}.ProposalHashData
|
||||
type ProposeReturn = msig{{.latestVersion}}.ProposeReturn
|
||||
type ProposeParams = msig{{.latestVersion}}.ProposeParams
|
||||
|
||||
func txnParams(id uint64, data *ProposalHashData) ([]byte, error) {
|
||||
params := msig{{.latestVersion}}.TxnIDParams{ID: msig{{.latestVersion}}.TxnID(id)}
|
||||
if data != nil {
|
||||
if data.Requester.Protocol() != address.ID {
|
||||
return nil, xerrors.Errorf("proposer address must be an ID address, was %s", data.Requester)
|
||||
}
|
||||
if data.Value.Sign() == -1 {
|
||||
return nil, xerrors.Errorf("proposal value must be non-negative, was %s", data.Value)
|
||||
}
|
||||
if data.To == address.Undef {
|
||||
return nil, xerrors.Errorf("proposed destination address must be set")
|
||||
}
|
||||
pser, err := data.Serialize()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
hash := blake2b.Sum256(pser)
|
||||
params.ProposalHash = hash[:]
|
||||
}
|
||||
|
||||
return actors.SerializeParams(¶ms)
|
||||
}
|
@ -1,79 +0,0 @@
|
||||
package multisig
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/minio/blake2b-simd"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
|
||||
builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin"
|
||||
multisig4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/multisig"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
var Methods = builtin4.MethodsMultisig
|
||||
|
||||
func Message(version actors.Version, from address.Address) MessageBuilder {
|
||||
switch version {
|
||||
case actors.Version0:
|
||||
return message0{from}
|
||||
case actors.Version2:
|
||||
return message2{message0{from}}
|
||||
case actors.Version3:
|
||||
return message3{message0{from}}
|
||||
case actors.Version4:
|
||||
return message4{message0{from}}
|
||||
default:
|
||||
panic(fmt.Sprintf("unsupported actors version: %d", version))
|
||||
}
|
||||
}
|
||||
|
||||
type MessageBuilder interface {
|
||||
// Create a new multisig with the specified parameters.
|
||||
Create(signers []address.Address, threshold uint64,
|
||||
vestingStart, vestingDuration abi.ChainEpoch,
|
||||
initialAmount abi.TokenAmount) (*types.Message, error)
|
||||
|
||||
// Propose a transaction to the given multisig.
|
||||
Propose(msig, target address.Address, amt abi.TokenAmount,
|
||||
method abi.MethodNum, params []byte) (*types.Message, error)
|
||||
|
||||
// Approve a multisig transaction. The "hash" is optional.
|
||||
Approve(msig address.Address, txID uint64, hash *ProposalHashData) (*types.Message, error)
|
||||
|
||||
// Cancel a multisig transaction. The "hash" is optional.
|
||||
Cancel(msig address.Address, txID uint64, hash *ProposalHashData) (*types.Message, error)
|
||||
}
|
||||
|
||||
// this type is the same between v0 and v2
|
||||
type ProposalHashData = multisig4.ProposalHashData
|
||||
type ProposeReturn = multisig4.ProposeReturn
|
||||
type ProposeParams = multisig4.ProposeParams
|
||||
|
||||
func txnParams(id uint64, data *ProposalHashData) ([]byte, error) {
|
||||
params := multisig4.TxnIDParams{ID: multisig4.TxnID(id)}
|
||||
if data != nil {
|
||||
if data.Requester.Protocol() != address.ID {
|
||||
return nil, xerrors.Errorf("proposer address must be an ID address, was %s", data.Requester)
|
||||
}
|
||||
if data.Value.Sign() == -1 {
|
||||
return nil, xerrors.Errorf("proposal value must be non-negative, was %s", data.Value)
|
||||
}
|
||||
if data.To == address.Undef {
|
||||
return nil, xerrors.Errorf("proposed destination address must be set")
|
||||
}
|
||||
pser, err := data.Serialize()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
hash := blake2b.Sum256(pser)
|
||||
params.ProposalHash = hash[:]
|
||||
}
|
||||
|
||||
return actors.SerializeParams(¶ms)
|
||||
}
|
146
chain/actors/builtin/multisig/message.go.template
Normal file
146
chain/actors/builtin/multisig/message.go.template
Normal file
@ -0,0 +1,146 @@
|
||||
package multisig
|
||||
|
||||
import (
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
|
||||
builtin{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin"
|
||||
init{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/init"
|
||||
multisig{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/multisig"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
type message{{.v}} struct{ {{if (ge .v 2)}}message0{{else}}from address.Address{{end}} }
|
||||
|
||||
func (m message{{.v}}) Create(
|
||||
signers []address.Address, threshold uint64,
|
||||
unlockStart, unlockDuration abi.ChainEpoch,
|
||||
initialAmount abi.TokenAmount,
|
||||
) (*types.Message, error) {
|
||||
|
||||
lenAddrs := uint64(len(signers))
|
||||
|
||||
if lenAddrs < threshold {
|
||||
return nil, xerrors.Errorf("cannot require signing of more addresses than provided for multisig")
|
||||
}
|
||||
|
||||
if threshold == 0 {
|
||||
threshold = lenAddrs
|
||||
}
|
||||
|
||||
if m.from == address.Undef {
|
||||
return nil, xerrors.Errorf("must provide source address")
|
||||
}
|
||||
{{if (le .v 1)}}
|
||||
if unlockStart != 0 {
|
||||
return nil, xerrors.Errorf("actors v0 does not support a non-zero vesting start time")
|
||||
}
|
||||
{{end}}
|
||||
// Set up constructor parameters for multisig
|
||||
msigParams := &multisig{{.v}}.ConstructorParams{
|
||||
Signers: signers,
|
||||
NumApprovalsThreshold: threshold,
|
||||
UnlockDuration: unlockDuration,{{if (ge .v 2)}}
|
||||
StartEpoch: unlockStart,{{end}}
|
||||
}
|
||||
|
||||
enc, actErr := actors.SerializeParams(msigParams)
|
||||
if actErr != nil {
|
||||
return nil, actErr
|
||||
}
|
||||
|
||||
// new actors are created by invoking 'exec' on the init actor with the constructor params
|
||||
execParams := &init{{.v}}.ExecParams{
|
||||
CodeCID: builtin{{.v}}.MultisigActorCodeID,
|
||||
ConstructorParams: enc,
|
||||
}
|
||||
|
||||
enc, actErr = actors.SerializeParams(execParams)
|
||||
if actErr != nil {
|
||||
return nil, actErr
|
||||
}
|
||||
|
||||
return &types.Message{
|
||||
To: init_.Address,
|
||||
From: m.from,
|
||||
Method: builtin{{.v}}.MethodsInit.Exec,
|
||||
Params: enc,
|
||||
Value: initialAmount,
|
||||
}, nil
|
||||
}
|
||||
|
||||
{{if (le .v 1)}}
|
||||
|
||||
func (m message0) Propose(msig, to address.Address, amt abi.TokenAmount,
|
||||
method abi.MethodNum, params []byte) (*types.Message, error) {
|
||||
|
||||
if msig == address.Undef {
|
||||
return nil, xerrors.Errorf("must provide a multisig address for proposal")
|
||||
}
|
||||
|
||||
if to == address.Undef {
|
||||
return nil, xerrors.Errorf("must provide a target address for proposal")
|
||||
}
|
||||
|
||||
if amt.Sign() == -1 {
|
||||
return nil, xerrors.Errorf("must provide a non-negative amount for proposed send")
|
||||
}
|
||||
|
||||
if m.from == address.Undef {
|
||||
return nil, xerrors.Errorf("must provide source address")
|
||||
}
|
||||
|
||||
enc, actErr := actors.SerializeParams(&multisig0.ProposeParams{
|
||||
To: to,
|
||||
Value: amt,
|
||||
Method: method,
|
||||
Params: params,
|
||||
})
|
||||
if actErr != nil {
|
||||
return nil, xerrors.Errorf("failed to serialize parameters: %w", actErr)
|
||||
}
|
||||
|
||||
return &types.Message{
|
||||
To: msig,
|
||||
From: m.from,
|
||||
Value: abi.NewTokenAmount(0),
|
||||
Method: builtin0.MethodsMultisig.Propose,
|
||||
Params: enc,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (m message0) Approve(msig address.Address, txID uint64, hashData *ProposalHashData) (*types.Message, error) {
|
||||
enc, err := txnParams(txID, hashData)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &types.Message{
|
||||
To: msig,
|
||||
From: m.from,
|
||||
Value: types.NewInt(0),
|
||||
Method: builtin0.MethodsMultisig.Approve,
|
||||
Params: enc,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (m message0) Cancel(msig address.Address, txID uint64, hashData *ProposalHashData) (*types.Message, error) {
|
||||
enc, err := txnParams(txID, hashData)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &types.Message{
|
||||
To: msig,
|
||||
From: m.from,
|
||||
Value: types.NewInt(0),
|
||||
Method: builtin0.MethodsMultisig.Cancel,
|
||||
Params: enc,
|
||||
}, nil
|
||||
}
|
||||
{{end}}
|
152
chain/actors/builtin/multisig/multisig.go
Normal file
152
chain/actors/builtin/multisig/multisig.go
Normal file
@ -0,0 +1,152 @@
|
||||
package multisig
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/minio/blake2b-simd"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/cbor"
|
||||
"github.com/ipfs/go-cid"
|
||||
|
||||
msig4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/multisig"
|
||||
|
||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
|
||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||
|
||||
builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin"
|
||||
|
||||
builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
||||
builtin.RegisterActorState(builtin0.MultisigActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||
return load0(store, root)
|
||||
})
|
||||
|
||||
builtin.RegisterActorState(builtin2.MultisigActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||
return load2(store, root)
|
||||
})
|
||||
|
||||
builtin.RegisterActorState(builtin3.MultisigActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||
return load3(store, root)
|
||||
})
|
||||
|
||||
builtin.RegisterActorState(builtin4.MultisigActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||
return load4(store, root)
|
||||
})
|
||||
}
|
||||
|
||||
func Load(store adt.Store, act *types.Actor) (State, error) {
|
||||
switch act.Code {
|
||||
|
||||
case builtin0.MultisigActorCodeID:
|
||||
return load0(store, act.Head)
|
||||
|
||||
case builtin2.MultisigActorCodeID:
|
||||
return load2(store, act.Head)
|
||||
|
||||
case builtin3.MultisigActorCodeID:
|
||||
return load3(store, act.Head)
|
||||
|
||||
case builtin4.MultisigActorCodeID:
|
||||
return load4(store, act.Head)
|
||||
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||
}
|
||||
|
||||
type State interface {
|
||||
cbor.Marshaler
|
||||
|
||||
LockedBalance(epoch abi.ChainEpoch) (abi.TokenAmount, error)
|
||||
StartEpoch() (abi.ChainEpoch, error)
|
||||
UnlockDuration() (abi.ChainEpoch, error)
|
||||
InitialBalance() (abi.TokenAmount, error)
|
||||
Threshold() (uint64, error)
|
||||
Signers() ([]address.Address, error)
|
||||
|
||||
ForEachPendingTxn(func(id int64, txn Transaction) error) error
|
||||
PendingTxnChanged(State) (bool, error)
|
||||
|
||||
transactions() (adt.Map, error)
|
||||
decodeTransaction(val *cbg.Deferred) (Transaction, error)
|
||||
}
|
||||
|
||||
type Transaction = msig4.Transaction
|
||||
|
||||
var Methods = builtin4.MethodsMultisig
|
||||
|
||||
func Message(version actors.Version, from address.Address) MessageBuilder {
|
||||
switch version {
|
||||
|
||||
case actors.Version0:
|
||||
return message0{from}
|
||||
|
||||
case actors.Version2:
|
||||
return message2{message0{from}}
|
||||
|
||||
case actors.Version3:
|
||||
return message3{message0{from}}
|
||||
|
||||
case actors.Version4:
|
||||
return message4{message0{from}}
|
||||
default:
|
||||
panic(fmt.Sprintf("unsupported actors version: %d", version))
|
||||
}
|
||||
}
|
||||
|
||||
type MessageBuilder interface {
|
||||
// Create a new multisig with the specified parameters.
|
||||
Create(signers []address.Address, threshold uint64,
|
||||
vestingStart, vestingDuration abi.ChainEpoch,
|
||||
initialAmount abi.TokenAmount) (*types.Message, error)
|
||||
|
||||
// Propose a transaction to the given multisig.
|
||||
Propose(msig, target address.Address, amt abi.TokenAmount,
|
||||
method abi.MethodNum, params []byte) (*types.Message, error)
|
||||
|
||||
// Approve a multisig transaction. The "hash" is optional.
|
||||
Approve(msig address.Address, txID uint64, hash *ProposalHashData) (*types.Message, error)
|
||||
|
||||
// Cancel a multisig transaction. The "hash" is optional.
|
||||
Cancel(msig address.Address, txID uint64, hash *ProposalHashData) (*types.Message, error)
|
||||
}
|
||||
|
||||
// this type is the same between v0 and v2
|
||||
type ProposalHashData = msig4.ProposalHashData
|
||||
type ProposeReturn = msig4.ProposeReturn
|
||||
type ProposeParams = msig4.ProposeParams
|
||||
|
||||
func txnParams(id uint64, data *ProposalHashData) ([]byte, error) {
|
||||
params := msig4.TxnIDParams{ID: msig4.TxnID(id)}
|
||||
if data != nil {
|
||||
if data.Requester.Protocol() != address.ID {
|
||||
return nil, xerrors.Errorf("proposer address must be an ID address, was %s", data.Requester)
|
||||
}
|
||||
if data.Value.Sign() == -1 {
|
||||
return nil, xerrors.Errorf("proposal value must be non-negative, was %s", data.Value)
|
||||
}
|
||||
if data.To == address.Undef {
|
||||
return nil, xerrors.Errorf("proposed destination address must be set")
|
||||
}
|
||||
pser, err := data.Serialize()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
hash := blake2b.Sum256(pser)
|
||||
params.ProposalHash = hash[:]
|
||||
}
|
||||
|
||||
return actors.SerializeParams(¶ms)
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
package multisig
|
||||
|
||||
import (
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/cbor"
|
||||
"github.com/ipfs/go-cid"
|
||||
|
||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||
builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin"
|
||||
builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
func init() {
|
||||
builtin.RegisterActorState(builtin0.MultisigActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||
return load0(store, root)
|
||||
})
|
||||
builtin.RegisterActorState(builtin2.MultisigActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||
return load2(store, root)
|
||||
})
|
||||
builtin.RegisterActorState(builtin3.MultisigActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||
return load3(store, root)
|
||||
})
|
||||
builtin.RegisterActorState(builtin4.MultisigActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||
return load4(store, root)
|
||||
})
|
||||
}
|
||||
|
||||
func Load(store adt.Store, act *types.Actor) (State, error) {
|
||||
switch act.Code {
|
||||
case builtin0.MultisigActorCodeID:
|
||||
return load0(store, act.Head)
|
||||
case builtin2.MultisigActorCodeID:
|
||||
return load2(store, act.Head)
|
||||
case builtin3.MultisigActorCodeID:
|
||||
return load3(store, act.Head)
|
||||
case builtin4.MultisigActorCodeID:
|
||||
return load4(store, act.Head)
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||
}
|
||||
|
||||
type State interface {
|
||||
cbor.Marshaler
|
||||
|
||||
LockedBalance(epoch abi.ChainEpoch) (abi.TokenAmount, error)
|
||||
StartEpoch() (abi.ChainEpoch, error)
|
||||
UnlockDuration() (abi.ChainEpoch, error)
|
||||
InitialBalance() (abi.TokenAmount, error)
|
||||
Threshold() (uint64, error)
|
||||
Signers() ([]address.Address, error)
|
||||
|
||||
ForEachPendingTxn(func(id int64, txn Transaction) error) error
|
||||
PendingTxnChanged(State) (bool, error)
|
||||
|
||||
transactions() (adt.Map, error)
|
||||
decodeTransaction(val *cbg.Deferred) (Transaction, error)
|
||||
}
|
||||
|
||||
type Transaction = msig0.Transaction
|
97
chain/actors/builtin/multisig/state.go.template
Normal file
97
chain/actors/builtin/multisig/state.go.template
Normal file
@ -0,0 +1,97 @@
|
||||
package multisig
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
|
||||
adt{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/util/adt"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/ipfs/go-cid"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
|
||||
{{if (ge .v 3)}}
|
||||
builtin{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin"
|
||||
{{end}}
|
||||
msig{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/multisig"
|
||||
)
|
||||
|
||||
var _ State = (*state{{.v}})(nil)
|
||||
|
||||
func load{{.v}}(store adt.Store, root cid.Cid) (State, error) {
|
||||
out := state{{.v}}{store: store}
|
||||
err := store.Get(store.Context(), root, &out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
type state{{.v}} struct {
|
||||
msig{{.v}}.State
|
||||
store adt.Store
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) LockedBalance(currEpoch abi.ChainEpoch) (abi.TokenAmount, error) {
|
||||
return s.State.AmountLocked(currEpoch - s.State.StartEpoch), nil
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) StartEpoch() (abi.ChainEpoch, error) {
|
||||
return s.State.StartEpoch, nil
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) UnlockDuration() (abi.ChainEpoch, error) {
|
||||
return s.State.UnlockDuration, nil
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) InitialBalance() (abi.TokenAmount, error) {
|
||||
return s.State.InitialBalance, nil
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) Threshold() (uint64, error) {
|
||||
return s.State.NumApprovalsThreshold, nil
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) Signers() ([]address.Address, error) {
|
||||
return s.State.Signers, nil
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) ForEachPendingTxn(cb func(id int64, txn Transaction) error) error {
|
||||
arr, err := adt{{.v}}.AsMap(s.store, s.State.PendingTxns{{if (ge .v 3)}}, builtin{{.v}}.DefaultHamtBitwidth{{end}})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var out msig{{.v}}.Transaction
|
||||
return arr.ForEach(&out, func(key string) error {
|
||||
txid, n := binary.Varint([]byte(key))
|
||||
if n <= 0 {
|
||||
return xerrors.Errorf("invalid pending transaction key: %v", key)
|
||||
}
|
||||
return cb(txid, (Transaction)(out)) //nolint:unconvert
|
||||
})
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) PendingTxnChanged(other State) (bool, error) {
|
||||
other{{.v}}, ok := other.(*state{{.v}})
|
||||
if !ok {
|
||||
// treat an upgrade as a change, always
|
||||
return true, nil
|
||||
}
|
||||
return !s.State.PendingTxns.Equals(other{{.v}}.PendingTxns), nil
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) transactions() (adt.Map, error) {
|
||||
return adt{{.v}}.AsMap(s.store, s.PendingTxns{{if (ge .v 3)}}, builtin{{.v}}.DefaultHamtBitwidth{{end}})
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) decodeTransaction(val *cbg.Deferred) (Transaction, error) {
|
||||
var tx msig{{.v}}.Transaction
|
||||
if err := tx.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
|
||||
return Transaction{}, err
|
||||
}
|
||||
return tx, nil
|
||||
}
|
@ -4,6 +4,8 @@ import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
|
||||
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/ipfs/go-cid"
|
||||
@ -13,8 +15,6 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
|
||||
msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
||||
multisig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
||||
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
)
|
||||
|
||||
var _ State = (*state0)(nil)
|
||||
@ -86,7 +86,7 @@ func (s *state0) transactions() (adt.Map, error) {
|
||||
}
|
||||
|
||||
func (s *state0) decodeTransaction(val *cbg.Deferred) (Transaction, error) {
|
||||
var tx multisig0.Transaction
|
||||
var tx msig0.Transaction
|
||||
if err := tx.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
|
||||
return Transaction{}, err
|
||||
}
|
@ -4,6 +4,8 @@ import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
|
||||
adt2 "github.com/filecoin-project/specs-actors/v2/actors/util/adt"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/ipfs/go-cid"
|
||||
@ -13,7 +15,6 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
|
||||
msig2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/multisig"
|
||||
adt2 "github.com/filecoin-project/specs-actors/v2/actors/util/adt"
|
||||
)
|
||||
|
||||
var _ State = (*state2)(nil)
|
@ -15,6 +15,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
|
||||
builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin"
|
||||
|
||||
msig3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/multisig"
|
||||
)
|
||||
|
||||
@ -74,12 +75,12 @@ func (s *state3) ForEachPendingTxn(cb func(id int64, txn Transaction) error) err
|
||||
}
|
||||
|
||||
func (s *state3) PendingTxnChanged(other State) (bool, error) {
|
||||
other2, ok := other.(*state3)
|
||||
other3, ok := other.(*state3)
|
||||
if !ok {
|
||||
// treat an upgrade as a change, always
|
||||
return true, nil
|
||||
}
|
||||
return !s.State.PendingTxns.Equals(other2.PendingTxns), nil
|
||||
return !s.State.PendingTxns.Equals(other3.PendingTxns), nil
|
||||
}
|
||||
|
||||
func (s *state3) transactions() (adt.Map, error) {
|
@ -15,6 +15,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
|
||||
builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin"
|
||||
|
||||
msig4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/multisig"
|
||||
)
|
||||
|
||||
@ -69,17 +70,17 @@ func (s *state4) ForEachPendingTxn(cb func(id int64, txn Transaction) error) err
|
||||
if n <= 0 {
|
||||
return xerrors.Errorf("invalid pending transaction key: %v", key)
|
||||
}
|
||||
return cb(txid, (Transaction)(out))
|
||||
return cb(txid, (Transaction)(out)) //nolint:unconvert
|
||||
})
|
||||
}
|
||||
|
||||
func (s *state4) PendingTxnChanged(other State) (bool, error) {
|
||||
other2, ok := other.(*state4)
|
||||
other4, ok := other.(*state4)
|
||||
if !ok {
|
||||
// treat an upgrade as a change, always
|
||||
return true, nil
|
||||
}
|
||||
return !s.State.PendingTxns.Equals(other2.PendingTxns), nil
|
||||
return !s.State.PendingTxns.Equals(other4.PendingTxns), nil
|
||||
}
|
||||
|
||||
func (s *state4) transactions() (adt.Map, error) {
|
109
chain/actors/builtin/paych/actor.go.template
Normal file
109
chain/actors/builtin/paych/actor.go.template
Normal file
@ -0,0 +1,109 @@
|
||||
package paych
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
big "github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/go-state-types/cbor"
|
||||
"github.com/ipfs/go-cid"
|
||||
ipldcbor "github.com/ipfs/go-ipld-cbor"
|
||||
|
||||
paych0 "github.com/filecoin-project/specs-actors/actors/builtin/paych"
|
||||
{{range .versions}}
|
||||
builtin{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin"
|
||||
{{end}}
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
func init() {
|
||||
{{range .versions}}
|
||||
builtin.RegisterActorState(builtin{{.}}.PaymentChannelActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||
return load{{.}}(store, root)
|
||||
})
|
||||
{{end}}}
|
||||
|
||||
// Load returns an abstract copy of payment channel state, irregardless of actor version
|
||||
func Load(store adt.Store, act *types.Actor) (State, error) {
|
||||
switch act.Code {
|
||||
{{range .versions}}
|
||||
case builtin{{.}}.PaymentChannelActorCodeID:
|
||||
return load{{.}}(store, act.Head)
|
||||
{{end}}
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||
}
|
||||
|
||||
// State is an abstract version of payment channel state that works across
|
||||
// versions
|
||||
type State interface {
|
||||
cbor.Marshaler
|
||||
// Channel owner, who has funded the actor
|
||||
From() (address.Address, error)
|
||||
// Recipient of payouts from channel
|
||||
To() (address.Address, error)
|
||||
|
||||
// Height at which the channel can be `Collected`
|
||||
SettlingAt() (abi.ChainEpoch, error)
|
||||
|
||||
// Amount successfully redeemed through the payment channel, paid out on `Collect()`
|
||||
ToSend() (abi.TokenAmount, error)
|
||||
|
||||
// Get total number of lanes
|
||||
LaneCount() (uint64, error)
|
||||
|
||||
// Iterate lane states
|
||||
ForEachLaneState(cb func(idx uint64, dl LaneState) error) error
|
||||
}
|
||||
|
||||
// LaneState is an abstract copy of the state of a single lane
|
||||
type LaneState interface {
|
||||
Redeemed() (big.Int, error)
|
||||
Nonce() (uint64, error)
|
||||
}
|
||||
|
||||
type SignedVoucher = paych0.SignedVoucher
|
||||
type ModVerifyParams = paych0.ModVerifyParams
|
||||
|
||||
// DecodeSignedVoucher decodes base64 encoded signed voucher.
|
||||
func DecodeSignedVoucher(s string) (*SignedVoucher, error) {
|
||||
data, err := base64.RawURLEncoding.DecodeString(s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var sv SignedVoucher
|
||||
if err := ipldcbor.DecodeInto(data, &sv); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &sv, nil
|
||||
}
|
||||
|
||||
var Methods = builtin{{.latestVersion}}.MethodsPaych
|
||||
|
||||
func Message(version actors.Version, from address.Address) MessageBuilder {
|
||||
switch version {
|
||||
{{range .versions}}
|
||||
case actors.Version{{.}}:
|
||||
return message{{.}}{from}
|
||||
{{end}}
|
||||
default:
|
||||
panic(fmt.Sprintf("unsupported actors version: %d", version))
|
||||
}
|
||||
}
|
||||
|
||||
type MessageBuilder interface {
|
||||
Create(to address.Address, initialAmount abi.TokenAmount) (*types.Message, error)
|
||||
Update(paych address.Address, voucher *SignedVoucher, secret []byte) (*types.Message, error)
|
||||
Settle(paych address.Address) (*types.Message, error)
|
||||
Collect(paych address.Address) (*types.Message, error)
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
package paych
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
|
||||
builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin"
|
||||
)
|
||||
|
||||
var Methods = builtin4.MethodsPaych
|
||||
|
||||
func Message(version actors.Version, from address.Address) MessageBuilder {
|
||||
switch version {
|
||||
case actors.Version0:
|
||||
return message0{from}
|
||||
case actors.Version2:
|
||||
return message2{from}
|
||||
case actors.Version3:
|
||||
return message3{from}
|
||||
case actors.Version4:
|
||||
return message4{from}
|
||||
default:
|
||||
panic(fmt.Sprintf("unsupported actors version: %d", version))
|
||||
}
|
||||
}
|
||||
|
||||
type MessageBuilder interface {
|
||||
Create(to address.Address, initialAmount abi.TokenAmount) (*types.Message, error)
|
||||
Update(paych address.Address, voucher *SignedVoucher, secret []byte) (*types.Message, error)
|
||||
Settle(paych address.Address) (*types.Message, error)
|
||||
Collect(paych address.Address) (*types.Message, error)
|
||||
}
|
74
chain/actors/builtin/paych/message.go.template
Normal file
74
chain/actors/builtin/paych/message.go.template
Normal file
@ -0,0 +1,74 @@
|
||||
package paych
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
|
||||
builtin{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin"
|
||||
init{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/init"
|
||||
paych{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/paych"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
type message{{.v}} struct{ from address.Address }
|
||||
|
||||
func (m message{{.v}}) Create(to address.Address, initialAmount abi.TokenAmount) (*types.Message, error) {
|
||||
params, aerr := actors.SerializeParams(&paych{{.v}}.ConstructorParams{From: m.from, To: to})
|
||||
if aerr != nil {
|
||||
return nil, aerr
|
||||
}
|
||||
enc, aerr := actors.SerializeParams(&init{{.v}}.ExecParams{
|
||||
CodeCID: builtin{{.v}}.PaymentChannelActorCodeID,
|
||||
ConstructorParams: params,
|
||||
})
|
||||
if aerr != nil {
|
||||
return nil, aerr
|
||||
}
|
||||
|
||||
return &types.Message{
|
||||
To: init_.Address,
|
||||
From: m.from,
|
||||
Value: initialAmount,
|
||||
Method: builtin{{.v}}.MethodsInit.Exec,
|
||||
Params: enc,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (m message{{.v}}) Update(paych address.Address, sv *SignedVoucher, secret []byte) (*types.Message, error) {
|
||||
params, aerr := actors.SerializeParams(&paych{{.v}}.UpdateChannelStateParams{
|
||||
Sv: *sv,
|
||||
Secret: secret,
|
||||
})
|
||||
if aerr != nil {
|
||||
return nil, aerr
|
||||
}
|
||||
|
||||
return &types.Message{
|
||||
To: paych,
|
||||
From: m.from,
|
||||
Value: abi.NewTokenAmount(0),
|
||||
Method: builtin{{.v}}.MethodsPaych.UpdateChannelState,
|
||||
Params: params,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (m message{{.v}}) Settle(paych address.Address) (*types.Message, error) {
|
||||
return &types.Message{
|
||||
To: paych,
|
||||
From: m.from,
|
||||
Value: abi.NewTokenAmount(0),
|
||||
Method: builtin{{.v}}.MethodsPaych.Settle,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (m message{{.v}}) Collect(paych address.Address) (*types.Message, error) {
|
||||
return &types.Message{
|
||||
To: paych,
|
||||
From: m.from,
|
||||
Value: abi.NewTokenAmount(0),
|
||||
Method: builtin{{.v}}.MethodsPaych.Collect,
|
||||
}, nil
|
||||
}
|
@ -2,6 +2,7 @@ package paych
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
@ -12,27 +13,36 @@ import (
|
||||
"github.com/ipfs/go-cid"
|
||||
ipldcbor "github.com/ipfs/go-ipld-cbor"
|
||||
|
||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
paych0 "github.com/filecoin-project/specs-actors/actors/builtin/paych"
|
||||
|
||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
|
||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||
|
||||
builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin"
|
||||
|
||||
builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
||||
builtin.RegisterActorState(builtin0.PaymentChannelActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||
return load0(store, root)
|
||||
})
|
||||
|
||||
builtin.RegisterActorState(builtin2.PaymentChannelActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||
return load2(store, root)
|
||||
})
|
||||
|
||||
builtin.RegisterActorState(builtin3.PaymentChannelActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||
return load3(store, root)
|
||||
})
|
||||
|
||||
builtin.RegisterActorState(builtin4.PaymentChannelActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||
return load4(store, root)
|
||||
})
|
||||
@ -41,14 +51,19 @@ func init() {
|
||||
// Load returns an abstract copy of payment channel state, irregardless of actor version
|
||||
func Load(store adt.Store, act *types.Actor) (State, error) {
|
||||
switch act.Code {
|
||||
|
||||
case builtin0.PaymentChannelActorCodeID:
|
||||
return load0(store, act.Head)
|
||||
|
||||
case builtin2.PaymentChannelActorCodeID:
|
||||
return load2(store, act.Head)
|
||||
|
||||
case builtin3.PaymentChannelActorCodeID:
|
||||
return load3(store, act.Head)
|
||||
|
||||
case builtin4.PaymentChannelActorCodeID:
|
||||
return load4(store, act.Head)
|
||||
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||
}
|
||||
@ -98,3 +113,32 @@ func DecodeSignedVoucher(s string) (*SignedVoucher, error) {
|
||||
|
||||
return &sv, nil
|
||||
}
|
||||
|
||||
var Methods = builtin4.MethodsPaych
|
||||
|
||||
func Message(version actors.Version, from address.Address) MessageBuilder {
|
||||
switch version {
|
||||
|
||||
case actors.Version0:
|
||||
return message0{from}
|
||||
|
||||
case actors.Version2:
|
||||
return message2{from}
|
||||
|
||||
case actors.Version3:
|
||||
return message3{from}
|
||||
|
||||
case actors.Version4:
|
||||
return message4{from}
|
||||
|
||||
default:
|
||||
panic(fmt.Sprintf("unsupported actors version: %d", version))
|
||||
}
|
||||
}
|
||||
|
||||
type MessageBuilder interface {
|
||||
Create(to address.Address, initialAmount abi.TokenAmount) (*types.Message, error)
|
||||
Update(paych address.Address, voucher *SignedVoucher, secret []byte) (*types.Message, error)
|
||||
Settle(paych address.Address) (*types.Message, error)
|
||||
Collect(paych address.Address) (*types.Message, error)
|
||||
}
|
104
chain/actors/builtin/paych/state.go.template
Normal file
104
chain/actors/builtin/paych/state.go.template
Normal file
@ -0,0 +1,104 @@
|
||||
package paych
|
||||
|
||||
import (
|
||||
"github.com/ipfs/go-cid"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
|
||||
paych{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/paych"
|
||||
adt{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/util/adt"
|
||||
)
|
||||
|
||||
var _ State = (*state{{.v}})(nil)
|
||||
|
||||
func load{{.v}}(store adt.Store, root cid.Cid) (State, error) {
|
||||
out := state{{.v}}{store: store}
|
||||
err := store.Get(store.Context(), root, &out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
type state{{.v}} struct {
|
||||
paych{{.v}}.State
|
||||
store adt.Store
|
||||
lsAmt *adt{{.v}}.Array
|
||||
}
|
||||
|
||||
// Channel owner, who has funded the actor
|
||||
func (s *state{{.v}}) From() (address.Address, error) {
|
||||
return s.State.From, nil
|
||||
}
|
||||
|
||||
// Recipient of payouts from channel
|
||||
func (s *state{{.v}}) To() (address.Address, error) {
|
||||
return s.State.To, nil
|
||||
}
|
||||
|
||||
// Height at which the channel can be `Collected`
|
||||
func (s *state{{.v}}) SettlingAt() (abi.ChainEpoch, error) {
|
||||
return s.State.SettlingAt, nil
|
||||
}
|
||||
|
||||
// Amount successfully redeemed through the payment channel, paid out on `Collect()`
|
||||
func (s *state{{.v}}) ToSend() (abi.TokenAmount, error) {
|
||||
return s.State.ToSend, nil
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) getOrLoadLsAmt() (*adt{{.v}}.Array, error) {
|
||||
if s.lsAmt != nil {
|
||||
return s.lsAmt, nil
|
||||
}
|
||||
|
||||
// Get the lane state from the chain
|
||||
lsamt, err := adt{{.v}}.AsArray(s.store, s.State.LaneStates{{if (ge .v 3)}}, paych{{.v}}.LaneStatesAmtBitwidth{{end}})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s.lsAmt = lsamt
|
||||
return lsamt, nil
|
||||
}
|
||||
|
||||
// Get total number of lanes
|
||||
func (s *state{{.v}}) LaneCount() (uint64, error) {
|
||||
lsamt, err := s.getOrLoadLsAmt()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return lsamt.Length(), nil
|
||||
}
|
||||
|
||||
// Iterate lane states
|
||||
func (s *state{{.v}}) ForEachLaneState(cb func(idx uint64, dl LaneState) error) error {
|
||||
// Get the lane state from the chain
|
||||
lsamt, err := s.getOrLoadLsAmt()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Note: we use a map instead of an array to store laneStates because the
|
||||
// client sets the lane ID (the index) and potentially they could use a
|
||||
// very large index.
|
||||
var ls paych{{.v}}.LaneState
|
||||
return lsamt.ForEach(&ls, func(i int64) error {
|
||||
return cb(uint64(i), &laneState{{.v}}{ls})
|
||||
})
|
||||
}
|
||||
|
||||
type laneState{{.v}} struct {
|
||||
paych{{.v}}.LaneState
|
||||
}
|
||||
|
||||
func (ls *laneState{{.v}}) Redeemed() (big.Int, error) {
|
||||
return ls.LaneState.Redeemed, nil
|
||||
}
|
||||
|
||||
func (ls *laneState{{.v}}) Nonce() (uint64, error) {
|
||||
return ls.LaneState.Nonce, nil
|
||||
}
|
78
chain/actors/builtin/power/actor.go.template
Normal file
78
chain/actors/builtin/power/actor.go.template
Normal file
@ -0,0 +1,78 @@
|
||||
package power
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/ipfs/go-cid"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/cbor"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
{{range .versions}}
|
||||
builtin{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin"
|
||||
{{end}}
|
||||
)
|
||||
|
||||
func init() {
|
||||
{{range .versions}}
|
||||
builtin.RegisterActorState(builtin{{.}}.StoragePowerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||
return load{{.}}(store, root)
|
||||
})
|
||||
{{end}}}
|
||||
|
||||
var (
|
||||
Address = builtin{{.latestVersion}}.StoragePowerActorAddr
|
||||
Methods = builtin{{.latestVersion}}.MethodsPower
|
||||
)
|
||||
|
||||
func Load(store adt.Store, act *types.Actor) (State, error) {
|
||||
switch act.Code {
|
||||
{{range .versions}}
|
||||
case builtin{{.}}.StoragePowerActorCodeID:
|
||||
return load{{.}}(store, act.Head)
|
||||
{{end}}
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||
}
|
||||
|
||||
type State interface {
|
||||
cbor.Marshaler
|
||||
|
||||
TotalLocked() (abi.TokenAmount, error)
|
||||
TotalPower() (Claim, error)
|
||||
TotalCommitted() (Claim, error)
|
||||
TotalPowerSmoothed() (builtin.FilterEstimate, error)
|
||||
|
||||
// MinerCounts returns the number of miners. Participating is the number
|
||||
// with power above the minimum miner threshold.
|
||||
MinerCounts() (participating, total uint64, err error)
|
||||
MinerPower(address.Address) (Claim, bool, error)
|
||||
MinerNominalPowerMeetsConsensusMinimum(address.Address) (bool, error)
|
||||
ListAllMiners() ([]address.Address, error)
|
||||
ForEachClaim(func(miner address.Address, claim Claim) error) error
|
||||
ClaimsChanged(State) (bool, error)
|
||||
|
||||
// Diff helpers. Used by Diff* functions internally.
|
||||
claims() (adt.Map, error)
|
||||
decodeClaim(*cbg.Deferred) (Claim, error)
|
||||
}
|
||||
|
||||
type Claim struct {
|
||||
// Sum of raw byte power for a miner's sectors.
|
||||
RawBytePower abi.StoragePower
|
||||
|
||||
// Sum of quality adjusted power for a miner's sectors.
|
||||
QualityAdjPower abi.StoragePower
|
||||
}
|
||||
|
||||
func AddClaims(a Claim, b Claim) Claim {
|
||||
return Claim{
|
||||
RawBytePower: big.Add(a.RawBytePower, b.RawBytePower),
|
||||
QualityAdjPower: big.Add(a.QualityAdjPower, b.QualityAdjPower),
|
||||
}
|
||||
}
|
@ -15,21 +15,28 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
|
||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
|
||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||
|
||||
builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin"
|
||||
|
||||
builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
||||
builtin.RegisterActorState(builtin0.StoragePowerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||
return load0(store, root)
|
||||
})
|
||||
|
||||
builtin.RegisterActorState(builtin2.StoragePowerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||
return load2(store, root)
|
||||
})
|
||||
|
||||
builtin.RegisterActorState(builtin3.StoragePowerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||
return load3(store, root)
|
||||
})
|
||||
|
||||
builtin.RegisterActorState(builtin4.StoragePowerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||
return load4(store, root)
|
||||
})
|
||||
@ -40,16 +47,21 @@ var (
|
||||
Methods = builtin4.MethodsPower
|
||||
)
|
||||
|
||||
func Load(store adt.Store, act *types.Actor) (st State, err error) {
|
||||
func Load(store adt.Store, act *types.Actor) (State, error) {
|
||||
switch act.Code {
|
||||
|
||||
case builtin0.StoragePowerActorCodeID:
|
||||
return load0(store, act.Head)
|
||||
|
||||
case builtin2.StoragePowerActorCodeID:
|
||||
return load2(store, act.Head)
|
||||
|
||||
case builtin3.StoragePowerActorCodeID:
|
||||
return load3(store, act.Head)
|
||||
|
||||
case builtin4.StoragePowerActorCodeID:
|
||||
return load4(store, act.Head)
|
||||
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||
}
|
||||
|
151
chain/actors/builtin/power/state.go.template
Normal file
151
chain/actors/builtin/power/state.go.template
Normal file
@ -0,0 +1,151 @@
|
||||
package power
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/ipfs/go-cid"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
|
||||
{{if (ge .v 3)}}
|
||||
builtin{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin"
|
||||
{{end}}
|
||||
power{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/power"
|
||||
adt{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/util/adt"
|
||||
)
|
||||
|
||||
var _ State = (*state{{.v}})(nil)
|
||||
|
||||
func load{{.v}}(store adt.Store, root cid.Cid) (State, error) {
|
||||
out := state{{.v}}{store: store}
|
||||
err := store.Get(store.Context(), root, &out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
type state{{.v}} struct {
|
||||
power{{.v}}.State
|
||||
store adt.Store
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) TotalLocked() (abi.TokenAmount, error) {
|
||||
return s.TotalPledgeCollateral, nil
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) TotalPower() (Claim, error) {
|
||||
return Claim{
|
||||
RawBytePower: s.TotalRawBytePower,
|
||||
QualityAdjPower: s.TotalQualityAdjPower,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Committed power to the network. Includes miners below the minimum threshold.
|
||||
func (s *state{{.v}}) TotalCommitted() (Claim, error) {
|
||||
return Claim{
|
||||
RawBytePower: s.TotalBytesCommitted,
|
||||
QualityAdjPower: s.TotalQABytesCommitted,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) MinerPower(addr address.Address) (Claim, bool, error) {
|
||||
claims, err := s.claims()
|
||||
if err != nil {
|
||||
return Claim{}, false, err
|
||||
}
|
||||
var claim power{{.v}}.Claim
|
||||
ok, err := claims.Get(abi.AddrKey(addr), &claim)
|
||||
if err != nil {
|
||||
return Claim{}, false, err
|
||||
}
|
||||
return Claim{
|
||||
RawBytePower: claim.RawBytePower,
|
||||
QualityAdjPower: claim.QualityAdjPower,
|
||||
}, ok, nil
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) MinerNominalPowerMeetsConsensusMinimum(a address.Address) (bool, error) {
|
||||
return s.State.MinerNominalPowerMeetsConsensusMinimum(s.store, a)
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) TotalPowerSmoothed() (builtin.FilterEstimate, error) {
|
||||
return builtin.FromV{{.v}}FilterEstimate({{if (le .v 1)}}*{{end}}s.State.ThisEpochQAPowerSmoothed), nil
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) MinerCounts() (uint64, uint64, error) {
|
||||
return uint64(s.State.MinerAboveMinPowerCount), uint64(s.State.MinerCount), nil
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) ListAllMiners() ([]address.Address, error) {
|
||||
claims, err := s.claims()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var miners []address.Address
|
||||
err = claims.ForEach(nil, func(k string) error {
|
||||
a, err := address.NewFromBytes([]byte(k))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
miners = append(miners, a)
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return miners, nil
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) ForEachClaim(cb func(miner address.Address, claim Claim) error) error {
|
||||
claims, err := s.claims()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var claim power{{.v}}.Claim
|
||||
return claims.ForEach(&claim, func(k string) error {
|
||||
a, err := address.NewFromBytes([]byte(k))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return cb(a, Claim{
|
||||
RawBytePower: claim.RawBytePower,
|
||||
QualityAdjPower: claim.QualityAdjPower,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) ClaimsChanged(other State) (bool, error) {
|
||||
other{{.v}}, ok := other.(*state{{.v}})
|
||||
if !ok {
|
||||
// treat an upgrade as a change, always
|
||||
return true, nil
|
||||
}
|
||||
return !s.State.Claims.Equals(other{{.v}}.State.Claims), nil
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) claims() (adt.Map, error) {
|
||||
return adt{{.v}}.AsMap(s.store, s.Claims{{if (ge .v 3)}}, builtin{{.v}}.DefaultHamtBitwidth{{end}})
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) decodeClaim(val *cbg.Deferred) (Claim, error) {
|
||||
var ci power{{.v}}.Claim
|
||||
if err := ci.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
|
||||
return Claim{}, err
|
||||
}
|
||||
return fromV{{.v}}Claim(ci), nil
|
||||
}
|
||||
|
||||
func fromV{{.v}}Claim(v{{.v}} power{{.v}}.Claim) Claim {
|
||||
return Claim{
|
||||
RawBytePower: v{{.v}}.RawBytePower,
|
||||
QualityAdjPower: v{{.v}}.QualityAdjPower,
|
||||
}
|
||||
}
|
@ -51,7 +51,7 @@ func (s *state0) TotalCommitted() (Claim, error) {
|
||||
}
|
||||
|
||||
func (s *state0) MinerPower(addr address.Address) (Claim, bool, error) {
|
||||
claims, err := adt0.AsMap(s.store, s.Claims)
|
||||
claims, err := s.claims()
|
||||
if err != nil {
|
||||
return Claim{}, false, err
|
||||
}
|
||||
@ -79,7 +79,7 @@ func (s *state0) MinerCounts() (uint64, uint64, error) {
|
||||
}
|
||||
|
||||
func (s *state0) ListAllMiners() ([]address.Address, error) {
|
||||
claims, err := adt0.AsMap(s.store, s.Claims)
|
||||
claims, err := s.claims()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -101,7 +101,7 @@ func (s *state0) ListAllMiners() ([]address.Address, error) {
|
||||
}
|
||||
|
||||
func (s *state0) ForEachClaim(cb func(miner address.Address, claim Claim) error) error {
|
||||
claims, err := adt0.AsMap(s.store, s.Claims)
|
||||
claims, err := s.claims()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -141,5 +141,8 @@ func (s *state0) decodeClaim(val *cbg.Deferred) (Claim, error) {
|
||||
}
|
||||
|
||||
func fromV0Claim(v0 power0.Claim) Claim {
|
||||
return (Claim)(v0)
|
||||
return Claim{
|
||||
RawBytePower: v0.RawBytePower,
|
||||
QualityAdjPower: v0.QualityAdjPower,
|
||||
}
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ func (s *state2) TotalCommitted() (Claim, error) {
|
||||
}
|
||||
|
||||
func (s *state2) MinerPower(addr address.Address) (Claim, bool, error) {
|
||||
claims, err := adt2.AsMap(s.store, s.Claims)
|
||||
claims, err := s.claims()
|
||||
if err != nil {
|
||||
return Claim{}, false, err
|
||||
}
|
||||
@ -79,7 +79,7 @@ func (s *state2) MinerCounts() (uint64, uint64, error) {
|
||||
}
|
||||
|
||||
func (s *state2) ListAllMiners() ([]address.Address, error) {
|
||||
claims, err := adt2.AsMap(s.store, s.Claims)
|
||||
claims, err := s.claims()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -101,7 +101,7 @@ func (s *state2) ListAllMiners() ([]address.Address, error) {
|
||||
}
|
||||
|
||||
func (s *state2) ForEachClaim(cb func(miner address.Address, claim Claim) error) error {
|
||||
claims, err := adt2.AsMap(s.store, s.Claims)
|
||||
claims, err := s.claims()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
|
||||
builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin"
|
||||
|
||||
power3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/power"
|
||||
adt3 "github.com/filecoin-project/specs-actors/v3/actors/util/adt"
|
||||
)
|
||||
@ -121,12 +122,12 @@ func (s *state3) ForEachClaim(cb func(miner address.Address, claim Claim) error)
|
||||
}
|
||||
|
||||
func (s *state3) ClaimsChanged(other State) (bool, error) {
|
||||
other2, ok := other.(*state3)
|
||||
other3, ok := other.(*state3)
|
||||
if !ok {
|
||||
// treat an upgrade as a change, always
|
||||
return true, nil
|
||||
}
|
||||
return !s.State.Claims.Equals(other2.State.Claims), nil
|
||||
return !s.State.Claims.Equals(other3.State.Claims), nil
|
||||
}
|
||||
|
||||
func (s *state3) claims() (adt.Map, error) {
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
|
||||
builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin"
|
||||
|
||||
power4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/power"
|
||||
adt4 "github.com/filecoin-project/specs-actors/v4/actors/util/adt"
|
||||
)
|
||||
@ -121,12 +122,12 @@ func (s *state4) ForEachClaim(cb func(miner address.Address, claim Claim) error)
|
||||
}
|
||||
|
||||
func (s *state4) ClaimsChanged(other State) (bool, error) {
|
||||
other2, ok := other.(*state4)
|
||||
other4, ok := other.(*state4)
|
||||
if !ok {
|
||||
// treat an upgrade as a change, always
|
||||
return true, nil
|
||||
}
|
||||
return !s.State.Claims.Equals(other2.State.Claims), nil
|
||||
return !s.State.Claims.Equals(other4.State.Claims), nil
|
||||
}
|
||||
|
||||
func (s *state4) claims() (adt.Map, error) {
|
||||
|
60
chain/actors/builtin/reward/actor.go.template
Normal file
60
chain/actors/builtin/reward/actor.go.template
Normal file
@ -0,0 +1,60 @@
|
||||
package reward
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
reward0 "github.com/filecoin-project/specs-actors/actors/builtin/reward"
|
||||
"github.com/ipfs/go-cid"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/cbor"
|
||||
{{range .versions}}
|
||||
builtin{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin"
|
||||
{{end}}
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
func init() {
|
||||
{{range .versions}}
|
||||
builtin.RegisterActorState(builtin{{.}}.RewardActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||
return load{{.}}(store, root)
|
||||
})
|
||||
{{end}}}
|
||||
|
||||
var (
|
||||
Address = builtin{{.latestVersion}}.RewardActorAddr
|
||||
Methods = builtin{{.latestVersion}}.MethodsReward
|
||||
)
|
||||
|
||||
func Load(store adt.Store, act *types.Actor) (State, error) {
|
||||
switch act.Code {
|
||||
{{range .versions}}
|
||||
case builtin{{.}}.RewardActorCodeID:
|
||||
return load{{.}}(store, act.Head)
|
||||
{{end}}
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||
}
|
||||
|
||||
type State interface {
|
||||
cbor.Marshaler
|
||||
|
||||
ThisEpochBaselinePower() (abi.StoragePower, error)
|
||||
ThisEpochReward() (abi.StoragePower, error)
|
||||
ThisEpochRewardSmoothed() (builtin.FilterEstimate, error)
|
||||
|
||||
EffectiveBaselinePower() (abi.StoragePower, error)
|
||||
EffectiveNetworkTime() (abi.ChainEpoch, error)
|
||||
|
||||
TotalStoragePowerReward() (abi.TokenAmount, error)
|
||||
|
||||
CumsumBaseline() (abi.StoragePower, error)
|
||||
CumsumRealized() (abi.StoragePower, error)
|
||||
|
||||
InitialPledgeForPower(abi.StoragePower, abi.TokenAmount, *builtin.FilterEstimate, abi.TokenAmount) (abi.TokenAmount, error)
|
||||
PreCommitDepositForPower(builtin.FilterEstimate, abi.StoragePower) (abi.TokenAmount, error)
|
||||
}
|
||||
|
||||
type AwardBlockRewardParams = reward0.AwardBlockRewardParams
|
@ -7,9 +7,13 @@ import (
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/cbor"
|
||||
|
||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
|
||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||
|
||||
builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin"
|
||||
|
||||
builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
@ -18,15 +22,19 @@ import (
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
||||
builtin.RegisterActorState(builtin0.RewardActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||
return load0(store, root)
|
||||
})
|
||||
|
||||
builtin.RegisterActorState(builtin2.RewardActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||
return load2(store, root)
|
||||
})
|
||||
|
||||
builtin.RegisterActorState(builtin3.RewardActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||
return load3(store, root)
|
||||
})
|
||||
|
||||
builtin.RegisterActorState(builtin4.RewardActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||
return load4(store, root)
|
||||
})
|
||||
@ -37,16 +45,21 @@ var (
|
||||
Methods = builtin4.MethodsReward
|
||||
)
|
||||
|
||||
func Load(store adt.Store, act *types.Actor) (st State, err error) {
|
||||
func Load(store adt.Store, act *types.Actor) (State, error) {
|
||||
switch act.Code {
|
||||
|
||||
case builtin0.RewardActorCodeID:
|
||||
return load0(store, act.Head)
|
||||
|
||||
case builtin2.RewardActorCodeID:
|
||||
return load2(store, act.Head)
|
||||
|
||||
case builtin3.RewardActorCodeID:
|
||||
return load3(store, act.Head)
|
||||
|
||||
case builtin4.RewardActorCodeID:
|
||||
return load4(store, act.Head)
|
||||
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||
}
|
||||
|
103
chain/actors/builtin/reward/state.go.template
Normal file
103
chain/actors/builtin/reward/state.go.template
Normal file
@ -0,0 +1,103 @@
|
||||
package reward
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/ipfs/go-cid"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
|
||||
miner{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/miner"
|
||||
reward{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/reward"
|
||||
smoothing{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/util/smoothing"
|
||||
)
|
||||
|
||||
var _ State = (*state{{.v}})(nil)
|
||||
|
||||
func load{{.v}}(store adt.Store, root cid.Cid) (State, error) {
|
||||
out := state{{.v}}{store: store}
|
||||
err := store.Get(store.Context(), root, &out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
type state{{.v}} struct {
|
||||
reward{{.v}}.State
|
||||
store adt.Store
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) ThisEpochReward() (abi.TokenAmount, error) {
|
||||
return s.State.ThisEpochReward, nil
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) ThisEpochRewardSmoothed() (builtin.FilterEstimate, error) {
|
||||
{{if (ge .v 2)}}
|
||||
return builtin.FilterEstimate{
|
||||
PositionEstimate: s.State.ThisEpochRewardSmoothed.PositionEstimate,
|
||||
VelocityEstimate: s.State.ThisEpochRewardSmoothed.VelocityEstimate,
|
||||
}, nil
|
||||
{{else}}
|
||||
return builtin.FromV0FilterEstimate(*s.State.ThisEpochRewardSmoothed), nil
|
||||
{{end}}
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) ThisEpochBaselinePower() (abi.StoragePower, error) {
|
||||
return s.State.ThisEpochBaselinePower, nil
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) TotalStoragePowerReward() (abi.TokenAmount, error) {
|
||||
return s.State.{{if (ge .v 2)}}TotalStoragePowerReward{{else}}TotalMined{{end}}, nil
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) EffectiveBaselinePower() (abi.StoragePower, error) {
|
||||
return s.State.EffectiveBaselinePower, nil
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) EffectiveNetworkTime() (abi.ChainEpoch, error) {
|
||||
return s.State.EffectiveNetworkTime, nil
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) CumsumBaseline() (reward{{.v}}.Spacetime, error) {
|
||||
return s.State.CumsumBaseline, nil
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) CumsumRealized() (reward{{.v}}.Spacetime, error) {
|
||||
return s.State.CumsumRealized, nil
|
||||
}
|
||||
{{if (ge .v 2)}}
|
||||
func (s *state{{.v}}) InitialPledgeForPower(qaPower abi.StoragePower, networkTotalPledge abi.TokenAmount, networkQAPower *builtin.FilterEstimate, circSupply abi.TokenAmount) (abi.TokenAmount, error) {
|
||||
return miner{{.v}}.InitialPledgeForPower(
|
||||
qaPower,
|
||||
s.State.ThisEpochBaselinePower,
|
||||
s.State.ThisEpochRewardSmoothed,
|
||||
smoothing{{.v}}.FilterEstimate{
|
||||
PositionEstimate: networkQAPower.PositionEstimate,
|
||||
VelocityEstimate: networkQAPower.VelocityEstimate,
|
||||
},
|
||||
circSupply,
|
||||
), nil
|
||||
}
|
||||
{{else}}
|
||||
func (s *state0) InitialPledgeForPower(sectorWeight abi.StoragePower, networkTotalPledge abi.TokenAmount, networkQAPower *builtin.FilterEstimate, circSupply abi.TokenAmount) (abi.TokenAmount, error) {
|
||||
return miner0.InitialPledgeForPower(
|
||||
sectorWeight,
|
||||
s.State.ThisEpochBaselinePower,
|
||||
networkTotalPledge,
|
||||
s.State.ThisEpochRewardSmoothed,
|
||||
&smoothing0.FilterEstimate{
|
||||
PositionEstimate: networkQAPower.PositionEstimate,
|
||||
VelocityEstimate: networkQAPower.VelocityEstimate,
|
||||
},
|
||||
circSupply), nil
|
||||
}
|
||||
{{end}}
|
||||
func (s *state{{.v}}) PreCommitDepositForPower(networkQAPower builtin.FilterEstimate, sectorWeight abi.StoragePower) (abi.TokenAmount, error) {
|
||||
return miner{{.v}}.PreCommitDepositForPower(s.State.ThisEpochRewardSmoothed,
|
||||
{{if (le .v 0)}}&{{end}}smoothing{{.v}}.FilterEstimate{
|
||||
PositionEstimate: networkQAPower.PositionEstimate,
|
||||
VelocityEstimate: networkQAPower.VelocityEstimate,
|
||||
},
|
||||
sectorWeight), nil
|
||||
}
|
@ -28,12 +28,14 @@ type state0 struct {
|
||||
store adt.Store
|
||||
}
|
||||
|
||||
func (s *state0) ThisEpochReward() (abi.StoragePower, error) {
|
||||
func (s *state0) ThisEpochReward() (abi.TokenAmount, error) {
|
||||
return s.State.ThisEpochReward, nil
|
||||
}
|
||||
|
||||
func (s *state0) ThisEpochRewardSmoothed() (builtin.FilterEstimate, error) {
|
||||
|
||||
return builtin.FromV0FilterEstimate(*s.State.ThisEpochRewardSmoothed), nil
|
||||
|
||||
}
|
||||
|
||||
func (s *state0) ThisEpochBaselinePower() (abi.StoragePower, error) {
|
||||
@ -52,11 +54,11 @@ func (s *state0) EffectiveNetworkTime() (abi.ChainEpoch, error) {
|
||||
return s.State.EffectiveNetworkTime, nil
|
||||
}
|
||||
|
||||
func (s *state0) CumsumBaseline() (abi.StoragePower, error) {
|
||||
func (s *state0) CumsumBaseline() (reward0.Spacetime, error) {
|
||||
return s.State.CumsumBaseline, nil
|
||||
}
|
||||
|
||||
func (s *state0) CumsumRealized() (abi.StoragePower, error) {
|
||||
func (s *state0) CumsumRealized() (reward0.Spacetime, error) {
|
||||
return s.State.CumsumRealized, nil
|
||||
}
|
||||
|
||||
|
@ -33,10 +33,12 @@ func (s *state2) ThisEpochReward() (abi.TokenAmount, error) {
|
||||
}
|
||||
|
||||
func (s *state2) ThisEpochRewardSmoothed() (builtin.FilterEstimate, error) {
|
||||
|
||||
return builtin.FilterEstimate{
|
||||
PositionEstimate: s.State.ThisEpochRewardSmoothed.PositionEstimate,
|
||||
VelocityEstimate: s.State.ThisEpochRewardSmoothed.VelocityEstimate,
|
||||
}, nil
|
||||
|
||||
}
|
||||
|
||||
func (s *state2) ThisEpochBaselinePower() (abi.StoragePower, error) {
|
||||
|
@ -33,10 +33,12 @@ func (s *state3) ThisEpochReward() (abi.TokenAmount, error) {
|
||||
}
|
||||
|
||||
func (s *state3) ThisEpochRewardSmoothed() (builtin.FilterEstimate, error) {
|
||||
|
||||
return builtin.FilterEstimate{
|
||||
PositionEstimate: s.State.ThisEpochRewardSmoothed.PositionEstimate,
|
||||
VelocityEstimate: s.State.ThisEpochRewardSmoothed.VelocityEstimate,
|
||||
}, nil
|
||||
|
||||
}
|
||||
|
||||
func (s *state3) ThisEpochBaselinePower() (abi.StoragePower, error) {
|
||||
|
@ -33,10 +33,12 @@ func (s *state4) ThisEpochReward() (abi.TokenAmount, error) {
|
||||
}
|
||||
|
||||
func (s *state4) ThisEpochRewardSmoothed() (builtin.FilterEstimate, error) {
|
||||
|
||||
return builtin.FilterEstimate{
|
||||
PositionEstimate: s.State.ThisEpochRewardSmoothed.PositionEstimate,
|
||||
VelocityEstimate: s.State.ThisEpochRewardSmoothed.VelocityEstimate,
|
||||
}, nil
|
||||
|
||||
}
|
||||
|
||||
func (s *state4) ThisEpochBaselinePower() (abi.StoragePower, error) {
|
||||
|
51
chain/actors/builtin/verifreg/actor.go.template
Normal file
51
chain/actors/builtin/verifreg/actor.go.template
Normal file
@ -0,0 +1,51 @@
|
||||
package verifreg
|
||||
|
||||
import (
|
||||
"github.com/ipfs/go-cid"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/cbor"
|
||||
{{range .versions}}
|
||||
builtin{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin"
|
||||
{{end}}
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
func init() {
|
||||
{{range .versions}}
|
||||
builtin.RegisterActorState(builtin{{.}}.VerifiedRegistryActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||
return load{{.}}(store, root)
|
||||
})
|
||||
{{end}}
|
||||
}
|
||||
|
||||
var (
|
||||
Address = builtin{{.latestVersion}}.VerifiedRegistryActorAddr
|
||||
Methods = builtin{{.latestVersion}}.MethodsVerifiedRegistry
|
||||
)
|
||||
|
||||
func Load(store adt.Store, act *types.Actor) (State, error) {
|
||||
switch act.Code {
|
||||
{{range .versions}}
|
||||
case builtin{{.}}.VerifiedRegistryActorCodeID:
|
||||
return load{{.}}(store, act.Head)
|
||||
{{end}}
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||
}
|
||||
|
||||
type State interface {
|
||||
cbor.Marshaler
|
||||
|
||||
RootKey() (address.Address, error)
|
||||
VerifiedClientDataCap(address.Address) (bool, abi.StoragePower, error)
|
||||
VerifierDataCap(address.Address) (bool, abi.StoragePower, error)
|
||||
ForEachVerifier(func(addr address.Address, dcap abi.StoragePower) error) error
|
||||
ForEachClient(func(addr address.Address, dcap abi.StoragePower) error) error
|
||||
}
|
58
chain/actors/builtin/verifreg/state.go.template
Normal file
58
chain/actors/builtin/verifreg/state.go.template
Normal file
@ -0,0 +1,58 @@
|
||||
package verifreg
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/ipfs/go-cid"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
|
||||
{{if (ge .v 3)}} builtin{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin"
|
||||
{{end}} verifreg{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/verifreg"
|
||||
adt{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/util/adt"
|
||||
)
|
||||
|
||||
var _ State = (*state{{.v}})(nil)
|
||||
|
||||
func load{{.v}}(store adt.Store, root cid.Cid) (State, error) {
|
||||
out := state{{.v}}{store: store}
|
||||
err := store.Get(store.Context(), root, &out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
type state{{.v}} struct {
|
||||
verifreg{{.v}}.State
|
||||
store adt.Store
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) RootKey() (address.Address, error) {
|
||||
return s.State.RootKey, nil
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) VerifiedClientDataCap(addr address.Address) (bool, abi.StoragePower, error) {
|
||||
return getDataCap(s.store, actors.Version{{.v}}, s.verifiedClients, addr)
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) VerifierDataCap(addr address.Address) (bool, abi.StoragePower, error) {
|
||||
return getDataCap(s.store, actors.Version{{.v}}, s.verifiers, addr)
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) ForEachVerifier(cb func(addr address.Address, dcap abi.StoragePower) error) error {
|
||||
return forEachCap(s.store, actors.Version{{.v}}, s.verifiers, cb)
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) ForEachClient(cb func(addr address.Address, dcap abi.StoragePower) error) error {
|
||||
return forEachCap(s.store, actors.Version{{.v}}, s.verifiedClients, cb)
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) verifiedClients() (adt.Map, error) {
|
||||
return adt{{.v}}.AsMap(s.store, s.VerifiedClients{{if (ge .v 3)}}, builtin{{.v}}.DefaultHamtBitwidth{{end}})
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) verifiers() (adt.Map, error) {
|
||||
return adt{{.v}}.AsMap(s.store, s.Verifiers{{if (ge .v 3)}}, builtin{{.v}}.DefaultHamtBitwidth{{end}})
|
||||
}
|
@ -8,9 +8,13 @@ import (
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/cbor"
|
||||
|
||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
|
||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||
|
||||
builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin"
|
||||
|
||||
builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
@ -19,18 +23,23 @@ import (
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
||||
builtin.RegisterActorState(builtin0.VerifiedRegistryActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||
return load0(store, root)
|
||||
})
|
||||
|
||||
builtin.RegisterActorState(builtin2.VerifiedRegistryActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||
return load2(store, root)
|
||||
})
|
||||
|
||||
builtin.RegisterActorState(builtin3.VerifiedRegistryActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||
return load3(store, root)
|
||||
})
|
||||
|
||||
builtin.RegisterActorState(builtin4.VerifiedRegistryActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||
return load4(store, root)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
var (
|
||||
@ -40,14 +49,19 @@ var (
|
||||
|
||||
func Load(store adt.Store, act *types.Actor) (State, error) {
|
||||
switch act.Code {
|
||||
|
||||
case builtin0.VerifiedRegistryActorCodeID:
|
||||
return load0(store, act.Head)
|
||||
|
||||
case builtin2.VerifiedRegistryActorCodeID:
|
||||
return load2(store, act.Head)
|
||||
|
||||
case builtin3.VerifiedRegistryActorCodeID:
|
||||
return load3(store, act.Head)
|
||||
|
||||
case builtin4.VerifiedRegistryActorCodeID:
|
||||
return load4(store, act.Head)
|
||||
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||
}
|
||||
|
@ -25,8 +25,9 @@ import (
|
||||
builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin"
|
||||
market4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/market"
|
||||
miner4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/miner"
|
||||
paych4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/paych"
|
||||
verifreg4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/verifreg"
|
||||
|
||||
paych4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/paych"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -39,7 +40,9 @@ const (
|
||||
// SetSupportedProofTypes sets supported proof types, across all actor versions.
|
||||
// This should only be used for testing.
|
||||
func SetSupportedProofTypes(types ...abi.RegisteredSealProof) {
|
||||
|
||||
miner0.SupportedProofTypes = make(map[abi.RegisteredSealProof]struct{}, len(types))
|
||||
|
||||
miner2.PreCommitSealProofTypesV0 = make(map[abi.RegisteredSealProof]struct{}, len(types))
|
||||
miner2.PreCommitSealProofTypesV7 = make(map[abi.RegisteredSealProof]struct{}, len(types)*2)
|
||||
miner2.PreCommitSealProofTypesV8 = make(map[abi.RegisteredSealProof]struct{}, len(types))
|
||||
@ -63,6 +66,7 @@ func AddSupportedProofTypes(types ...abi.RegisteredSealProof) {
|
||||
panic("must specify v1 proof types only")
|
||||
}
|
||||
// Set for all miner versions.
|
||||
|
||||
miner0.SupportedProofTypes[t] = struct{}{}
|
||||
|
||||
miner2.PreCommitSealProofTypesV0[t] = struct{}{}
|
||||
@ -79,6 +83,7 @@ func AddSupportedProofTypes(types ...abi.RegisteredSealProof) {
|
||||
miner4.PreCommitSealProofTypesV7[t] = struct{}{}
|
||||
miner4.PreCommitSealProofTypesV7[t+abi.RegisteredSealProof_StackedDrg2KiBV1_1] = struct{}{}
|
||||
miner4.PreCommitSealProofTypesV8[t+abi.RegisteredSealProof_StackedDrg2KiBV1_1] = struct{}{}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -86,22 +91,29 @@ func AddSupportedProofTypes(types ...abi.RegisteredSealProof) {
|
||||
// actors versions. Use for testing.
|
||||
func SetPreCommitChallengeDelay(delay abi.ChainEpoch) {
|
||||
// Set for all miner versions.
|
||||
|
||||
miner0.PreCommitChallengeDelay = delay
|
||||
|
||||
miner2.PreCommitChallengeDelay = delay
|
||||
|
||||
miner3.PreCommitChallengeDelay = delay
|
||||
|
||||
miner4.PreCommitChallengeDelay = delay
|
||||
|
||||
}
|
||||
|
||||
// TODO: this function shouldn't really exist. Instead, the API should expose the precommit delay.
|
||||
func GetPreCommitChallengeDelay() abi.ChainEpoch {
|
||||
return miner0.PreCommitChallengeDelay
|
||||
return miner4.PreCommitChallengeDelay
|
||||
}
|
||||
|
||||
// SetConsensusMinerMinPower sets the minimum power of an individual miner must
|
||||
// meet for leader election, across all actor versions. This should only be used
|
||||
// for testing.
|
||||
func SetConsensusMinerMinPower(p abi.StoragePower) {
|
||||
|
||||
power0.ConsensusMinerMinPower = p
|
||||
|
||||
for _, policy := range builtin2.SealProofPolicies {
|
||||
policy.ConsensusMinerMinPower = p
|
||||
}
|
||||
@ -113,27 +125,42 @@ func SetConsensusMinerMinPower(p abi.StoragePower) {
|
||||
for _, policy := range builtin4.PoStProofPolicies {
|
||||
policy.ConsensusMinerMinPower = p
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// SetMinVerifiedDealSize sets the minimum size of a verified deal. This should
|
||||
// only be used for testing.
|
||||
func SetMinVerifiedDealSize(size abi.StoragePower) {
|
||||
|
||||
verifreg0.MinVerifiedDealSize = size
|
||||
|
||||
verifreg2.MinVerifiedDealSize = size
|
||||
|
||||
verifreg3.MinVerifiedDealSize = size
|
||||
|
||||
verifreg4.MinVerifiedDealSize = size
|
||||
|
||||
}
|
||||
|
||||
func GetMaxProveCommitDuration(ver actors.Version, t abi.RegisteredSealProof) abi.ChainEpoch {
|
||||
switch ver {
|
||||
|
||||
case actors.Version0:
|
||||
|
||||
return miner0.MaxSealDuration[t]
|
||||
|
||||
case actors.Version2:
|
||||
|
||||
return miner2.MaxProveCommitDuration[t]
|
||||
|
||||
case actors.Version3:
|
||||
|
||||
return miner3.MaxProveCommitDuration[t]
|
||||
|
||||
case actors.Version4:
|
||||
|
||||
return miner4.MaxProveCommitDuration[t]
|
||||
|
||||
default:
|
||||
panic("unsupported actors version")
|
||||
}
|
||||
@ -145,26 +172,36 @@ func DealProviderCollateralBounds(
|
||||
circulatingFil abi.TokenAmount, nwVer network.Version,
|
||||
) (min, max abi.TokenAmount) {
|
||||
switch actors.VersionForNetwork(nwVer) {
|
||||
|
||||
case actors.Version0:
|
||||
|
||||
return market0.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil, nwVer)
|
||||
|
||||
case actors.Version2:
|
||||
|
||||
return market2.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil)
|
||||
|
||||
case actors.Version3:
|
||||
|
||||
return market3.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil)
|
||||
|
||||
case actors.Version4:
|
||||
|
||||
return market4.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil)
|
||||
|
||||
default:
|
||||
panic("unsupported actors version")
|
||||
}
|
||||
}
|
||||
|
||||
func DealDurationBounds(pieceSize abi.PaddedPieceSize) (min, max abi.ChainEpoch) {
|
||||
return market2.DealDurationBounds(pieceSize)
|
||||
return market4.DealDurationBounds(pieceSize)
|
||||
}
|
||||
|
||||
// Sets the challenge window and scales the proving period to match (such that
|
||||
// there are always 48 challenge windows in a proving period).
|
||||
func SetWPoStChallengeWindow(period abi.ChainEpoch) {
|
||||
|
||||
miner0.WPoStChallengeWindow = period
|
||||
miner0.WPoStProvingPeriod = period * abi.ChainEpoch(miner0.WPoStPeriodDeadlines)
|
||||
|
||||
@ -173,13 +210,18 @@ func SetWPoStChallengeWindow(period abi.ChainEpoch) {
|
||||
|
||||
miner3.WPoStChallengeWindow = period
|
||||
miner3.WPoStProvingPeriod = period * abi.ChainEpoch(miner3.WPoStPeriodDeadlines)
|
||||
|
||||
// by default, this is 2x finality which is 30 periods.
|
||||
// scale it if we're scaling the challenge period.
|
||||
miner3.WPoStDisputeWindow = period * 30
|
||||
|
||||
miner4.WPoStChallengeWindow = period
|
||||
miner4.WPoStProvingPeriod = period * abi.ChainEpoch(miner4.WPoStPeriodDeadlines)
|
||||
miner4.WPoStDisputeWindow = period * 30 // see the miner3 comment
|
||||
|
||||
// by default, this is 2x finality which is 30 periods.
|
||||
// scale it if we're scaling the challenge period.
|
||||
miner4.WPoStDisputeWindow = period * 30
|
||||
|
||||
}
|
||||
|
||||
func GetWinningPoStSectorSetLookback(nwVer network.Version) abi.ChainEpoch {
|
||||
@ -187,16 +229,17 @@ func GetWinningPoStSectorSetLookback(nwVer network.Version) abi.ChainEpoch {
|
||||
return 10
|
||||
}
|
||||
|
||||
// NOTE: if this ever changes, adjust it in a (*Miner).mineOne() logline as well
|
||||
return ChainFinality
|
||||
}
|
||||
|
||||
func GetMaxSectorExpirationExtension() abi.ChainEpoch {
|
||||
return miner0.MaxSectorExpirationExtension
|
||||
return miner4.MaxSectorExpirationExtension
|
||||
}
|
||||
|
||||
// TODO: we'll probably need to abstract over this better in the future.
|
||||
func GetMaxPoStPartitions(p abi.RegisteredPoStProof) (int, error) {
|
||||
sectorsPerPart, err := builtin3.PoStProofWindowPoStPartitionSectors(p)
|
||||
sectorsPerPart, err := builtin4.PoStProofWindowPoStPartitionSectors(p)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@ -232,14 +275,19 @@ func GetSectorMaxLifetime(proof abi.RegisteredSealProof, nwVer network.Version)
|
||||
|
||||
func GetAddressedSectorsMax(nwVer network.Version) int {
|
||||
switch actors.VersionForNetwork(nwVer) {
|
||||
|
||||
case actors.Version0:
|
||||
return miner0.AddressedSectorsMax
|
||||
|
||||
case actors.Version2:
|
||||
return miner2.AddressedSectorsMax
|
||||
|
||||
case actors.Version3:
|
||||
return miner3.AddressedSectorsMax
|
||||
|
||||
case actors.Version4:
|
||||
return miner4.AddressedSectorsMax
|
||||
|
||||
default:
|
||||
panic("unsupported network version")
|
||||
}
|
||||
@ -247,15 +295,24 @@ func GetAddressedSectorsMax(nwVer network.Version) int {
|
||||
|
||||
func GetDeclarationsMax(nwVer network.Version) int {
|
||||
switch actors.VersionForNetwork(nwVer) {
|
||||
|
||||
case actors.Version0:
|
||||
|
||||
// TODO: Should we instead panic here since the concept doesn't exist yet?
|
||||
return miner0.AddressedPartitionsMax
|
||||
|
||||
case actors.Version2:
|
||||
|
||||
return miner2.DeclarationsMax
|
||||
|
||||
case actors.Version3:
|
||||
|
||||
return miner3.DeclarationsMax
|
||||
|
||||
case actors.Version4:
|
||||
|
||||
return miner4.DeclarationsMax
|
||||
|
||||
default:
|
||||
panic("unsupported network version")
|
||||
}
|
||||
|
233
chain/actors/policy/policy.go.template
Normal file
233
chain/actors/policy/policy.go.template
Normal file
@ -0,0 +1,233 @@
|
||||
package policy
|
||||
|
||||
import (
|
||||
"sort"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
|
||||
{{range .versions}}
|
||||
{{if (ge . 2)}} builtin{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin" {{end}}
|
||||
market{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin/market"
|
||||
miner{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin/miner"
|
||||
verifreg{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin/verifreg"
|
||||
{{if (eq . 0)}} power{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin/power" {{end}}
|
||||
{{end}}
|
||||
|
||||
paych{{.latestVersion}} "github.com/filecoin-project/specs-actors{{import .latestVersion}}actors/builtin/paych"
|
||||
)
|
||||
|
||||
const (
|
||||
ChainFinality = miner{{.latestVersion}}.ChainFinality
|
||||
SealRandomnessLookback = ChainFinality
|
||||
PaychSettleDelay = paych{{.latestVersion}}.SettleDelay
|
||||
MaxPreCommitRandomnessLookback = builtin{{.latestVersion}}.EpochsInDay + SealRandomnessLookback
|
||||
)
|
||||
|
||||
// SetSupportedProofTypes sets supported proof types, across all actor versions.
|
||||
// This should only be used for testing.
|
||||
func SetSupportedProofTypes(types ...abi.RegisteredSealProof) {
|
||||
{{range .versions}}
|
||||
{{if (eq . 0)}}
|
||||
miner{{.}}.SupportedProofTypes = make(map[abi.RegisteredSealProof]struct{}, len(types))
|
||||
{{else}}
|
||||
miner{{.}}.PreCommitSealProofTypesV0 = make(map[abi.RegisteredSealProof]struct{}, len(types))
|
||||
miner{{.}}.PreCommitSealProofTypesV7 = make(map[abi.RegisteredSealProof]struct{}, len(types)*2)
|
||||
miner{{.}}.PreCommitSealProofTypesV8 = make(map[abi.RegisteredSealProof]struct{}, len(types))
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
||||
AddSupportedProofTypes(types...)
|
||||
}
|
||||
|
||||
// AddSupportedProofTypes sets supported proof types, across all actor versions.
|
||||
// This should only be used for testing.
|
||||
func AddSupportedProofTypes(types ...abi.RegisteredSealProof) {
|
||||
for _, t := range types {
|
||||
if t >= abi.RegisteredSealProof_StackedDrg2KiBV1_1 {
|
||||
panic("must specify v1 proof types only")
|
||||
}
|
||||
// Set for all miner versions.
|
||||
|
||||
{{range .versions}}
|
||||
{{if (eq . 0)}}
|
||||
miner{{.}}.SupportedProofTypes[t] = struct{}{}
|
||||
{{else}}
|
||||
miner{{.}}.PreCommitSealProofTypesV0[t] = struct{}{}
|
||||
miner{{.}}.PreCommitSealProofTypesV7[t] = struct{}{}
|
||||
miner{{.}}.PreCommitSealProofTypesV7[t+abi.RegisteredSealProof_StackedDrg2KiBV1_1] = struct{}{}
|
||||
miner{{.}}.PreCommitSealProofTypesV8[t+abi.RegisteredSealProof_StackedDrg2KiBV1_1] = struct{}{}
|
||||
{{end}}
|
||||
{{end}}
|
||||
}
|
||||
}
|
||||
|
||||
// SetPreCommitChallengeDelay sets the pre-commit challenge delay across all
|
||||
// actors versions. Use for testing.
|
||||
func SetPreCommitChallengeDelay(delay abi.ChainEpoch) {
|
||||
// Set for all miner versions.
|
||||
{{range .versions}}
|
||||
miner{{.}}.PreCommitChallengeDelay = delay
|
||||
{{end}}
|
||||
}
|
||||
|
||||
// TODO: this function shouldn't really exist. Instead, the API should expose the precommit delay.
|
||||
func GetPreCommitChallengeDelay() abi.ChainEpoch {
|
||||
return miner{{.latestVersion}}.PreCommitChallengeDelay
|
||||
}
|
||||
|
||||
// SetConsensusMinerMinPower sets the minimum power of an individual miner must
|
||||
// meet for leader election, across all actor versions. This should only be used
|
||||
// for testing.
|
||||
func SetConsensusMinerMinPower(p abi.StoragePower) {
|
||||
{{range .versions}}
|
||||
{{if (eq . 0)}}
|
||||
power{{.}}.ConsensusMinerMinPower = p
|
||||
{{else if (eq . 2)}}
|
||||
for _, policy := range builtin{{.}}.SealProofPolicies {
|
||||
policy.ConsensusMinerMinPower = p
|
||||
}
|
||||
{{else}}
|
||||
for _, policy := range builtin{{.}}.PoStProofPolicies {
|
||||
policy.ConsensusMinerMinPower = p
|
||||
}
|
||||
{{end}}
|
||||
{{end}}
|
||||
}
|
||||
|
||||
// SetMinVerifiedDealSize sets the minimum size of a verified deal. This should
|
||||
// only be used for testing.
|
||||
func SetMinVerifiedDealSize(size abi.StoragePower) {
|
||||
{{range .versions}}
|
||||
verifreg{{.}}.MinVerifiedDealSize = size
|
||||
{{end}}
|
||||
}
|
||||
|
||||
func GetMaxProveCommitDuration(ver actors.Version, t abi.RegisteredSealProof) abi.ChainEpoch {
|
||||
switch ver {
|
||||
{{range .versions}}
|
||||
case actors.Version{{.}}:
|
||||
{{if (eq . 0)}}
|
||||
return miner{{.}}.MaxSealDuration[t]
|
||||
{{else}}
|
||||
return miner{{.}}.MaxProveCommitDuration[t]
|
||||
{{end}}
|
||||
{{end}}
|
||||
default:
|
||||
panic("unsupported actors version")
|
||||
}
|
||||
}
|
||||
|
||||
func DealProviderCollateralBounds(
|
||||
size abi.PaddedPieceSize, verified bool,
|
||||
rawBytePower, qaPower, baselinePower abi.StoragePower,
|
||||
circulatingFil abi.TokenAmount, nwVer network.Version,
|
||||
) (min, max abi.TokenAmount) {
|
||||
switch actors.VersionForNetwork(nwVer) {
|
||||
{{range .versions}}
|
||||
case actors.Version{{.}}:
|
||||
{{if (eq . 0)}}
|
||||
return market{{.}}.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil, nwVer)
|
||||
{{else}}
|
||||
return market{{.}}.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil)
|
||||
{{end}}
|
||||
{{end}}
|
||||
default:
|
||||
panic("unsupported actors version")
|
||||
}
|
||||
}
|
||||
|
||||
func DealDurationBounds(pieceSize abi.PaddedPieceSize) (min, max abi.ChainEpoch) {
|
||||
return market{{.latestVersion}}.DealDurationBounds(pieceSize)
|
||||
}
|
||||
|
||||
// Sets the challenge window and scales the proving period to match (such that
|
||||
// there are always 48 challenge windows in a proving period).
|
||||
func SetWPoStChallengeWindow(period abi.ChainEpoch) {
|
||||
{{range .versions}}
|
||||
miner{{.}}.WPoStChallengeWindow = period
|
||||
miner{{.}}.WPoStProvingPeriod = period * abi.ChainEpoch(miner{{.}}.WPoStPeriodDeadlines)
|
||||
{{if (ge . 3)}}
|
||||
// by default, this is 2x finality which is 30 periods.
|
||||
// scale it if we're scaling the challenge period.
|
||||
miner{{.}}.WPoStDisputeWindow = period * 30
|
||||
{{end}}
|
||||
{{end}}
|
||||
}
|
||||
|
||||
func GetWinningPoStSectorSetLookback(nwVer network.Version) abi.ChainEpoch {
|
||||
if nwVer <= network.Version3 {
|
||||
return 10
|
||||
}
|
||||
|
||||
// NOTE: if this ever changes, adjust it in a (*Miner).mineOne() logline as well
|
||||
return ChainFinality
|
||||
}
|
||||
|
||||
func GetMaxSectorExpirationExtension() abi.ChainEpoch {
|
||||
return miner{{.latestVersion}}.MaxSectorExpirationExtension
|
||||
}
|
||||
|
||||
// TODO: we'll probably need to abstract over this better in the future.
|
||||
func GetMaxPoStPartitions(p abi.RegisteredPoStProof) (int, error) {
|
||||
sectorsPerPart, err := builtin{{.latestVersion}}.PoStProofWindowPoStPartitionSectors(p)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return int(miner{{.latestVersion}}.AddressedSectorsMax / sectorsPerPart), nil
|
||||
}
|
||||
|
||||
func GetDefaultSectorSize() abi.SectorSize {
|
||||
// supported sector sizes are the same across versions.
|
||||
szs := make([]abi.SectorSize, 0, len(miner{{.latestVersion}}.PreCommitSealProofTypesV8))
|
||||
for spt := range miner{{.latestVersion}}.PreCommitSealProofTypesV8 {
|
||||
ss, err := spt.SectorSize()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
szs = append(szs, ss)
|
||||
}
|
||||
|
||||
sort.Slice(szs, func(i, j int) bool {
|
||||
return szs[i] < szs[j]
|
||||
})
|
||||
|
||||
return szs[0]
|
||||
}
|
||||
|
||||
func GetSectorMaxLifetime(proof abi.RegisteredSealProof, nwVer network.Version) abi.ChainEpoch {
|
||||
if nwVer <= network.Version10 {
|
||||
return builtin{{.latestVersion}}.SealProofPoliciesV0[proof].SectorMaxLifetime
|
||||
}
|
||||
|
||||
return builtin{{.latestVersion}}.SealProofPoliciesV11[proof].SectorMaxLifetime
|
||||
}
|
||||
|
||||
func GetAddressedSectorsMax(nwVer network.Version) int {
|
||||
switch actors.VersionForNetwork(nwVer) {
|
||||
{{range .versions}}
|
||||
case actors.Version{{.}}:
|
||||
return miner{{.}}.AddressedSectorsMax
|
||||
{{end}}
|
||||
default:
|
||||
panic("unsupported network version")
|
||||
}
|
||||
}
|
||||
|
||||
func GetDeclarationsMax(nwVer network.Version) int {
|
||||
switch actors.VersionForNetwork(nwVer) {
|
||||
{{range .versions}}
|
||||
case actors.Version{{.}}:
|
||||
{{if (eq . 0)}}
|
||||
// TODO: Should we instead panic here since the concept doesn't exist yet?
|
||||
return miner{{.}}.AddressedPartitionsMax
|
||||
{{else}}
|
||||
return miner{{.}}.DeclarationsMax
|
||||
{{end}}
|
||||
{{end}}
|
||||
default:
|
||||
panic("unsupported network version")
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@ package gen
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
@ -610,6 +611,8 @@ func (wpp *wppProvider) ComputeProof(context.Context, []proof2.SectorInfo, abi.P
|
||||
return ValidWpostForTesting, nil
|
||||
}
|
||||
|
||||
var b64 = base64.URLEncoding.WithPadding(base64.NoPadding)
|
||||
|
||||
func IsRoundWinner(ctx context.Context, ts *types.TipSet, round abi.ChainEpoch,
|
||||
miner address.Address, brand types.BeaconEntry, mbi *api.MiningBaseInfo, a MiningCheckAPI) (*types.ElectionProof, error) {
|
||||
|
||||
@ -631,6 +634,15 @@ func IsRoundWinner(ctx context.Context, ts *types.TipSet, round abi.ChainEpoch,
|
||||
ep := &types.ElectionProof{VRFProof: vrfout}
|
||||
j := ep.ComputeWinCount(mbi.MinerPower, mbi.NetworkPower)
|
||||
ep.WinCount = j
|
||||
|
||||
log.Infow("completed winAttemptVRF",
|
||||
"beaconRound", brand.Round,
|
||||
"beaconDataB64", b64.EncodeToString(brand.Data),
|
||||
"electionRandB64", b64.EncodeToString(electionRand),
|
||||
"vrfB64", b64.EncodeToString(vrfout),
|
||||
"winCount", j,
|
||||
)
|
||||
|
||||
if j < 1 {
|
||||
return nil, nil
|
||||
}
|
||||
|
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
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user