diff --git a/chain/actors/builtin/paych/message.go b/chain/actors/builtin/paych/message.go new file mode 100644 index 000000000..d19f0c38f --- /dev/null +++ b/chain/actors/builtin/paych/message.go @@ -0,0 +1,28 @@ +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" +) + +func Message(version actors.Version) MessageBuilder { + switch version { + case actors.Version0: + return message0{} + case actors.Version2: + return message2{} + default: + panic(fmt.Sprintf("unsupported actors version: %d", version)) + } +} + +type MessageBuilder interface { + Create(from, to address.Address, initialAmount abi.TokenAmount) (*types.Message, error) + Update(from, paych address.Address, voucher *SignedVoucher, secret []byte) (*types.Message, error) + Settle(from, paych address.Address) (*types.Message, error) + Collect(from, paych address.Address) (*types.Message, error) +} diff --git a/chain/actors/builtin/paych/message0.go b/chain/actors/builtin/paych/message0.go new file mode 100644 index 000000000..0e7bbff92 --- /dev/null +++ b/chain/actors/builtin/paych/message0.go @@ -0,0 +1,74 @@ +package paych + +import ( + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + + builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" + init0 "github.com/filecoin-project/specs-actors/actors/builtin/init" + paych0 "github.com/filecoin-project/specs-actors/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 message0 struct{} + +func (message0) Create(from, to address.Address, initialAmount abi.TokenAmount) (*types.Message, error) { + params, aerr := actors.SerializeParams(&paych0.ConstructorParams{From: from, To: to}) + if aerr != nil { + return nil, aerr + } + enc, aerr := actors.SerializeParams(&init0.ExecParams{ + CodeCID: builtin0.PaymentChannelActorCodeID, + ConstructorParams: params, + }) + if aerr != nil { + return nil, aerr + } + + return &types.Message{ + To: init_.Address, + From: from, + Value: initialAmount, + Method: builtin0.MethodsInit.Exec, + Params: enc, + }, nil +} + +func (message0) Update(from, paych address.Address, sv *SignedVoucher, secret []byte) (*types.Message, error) { + params, aerr := actors.SerializeParams(&paych0.UpdateChannelStateParams{ + Sv: *sv, + Secret: secret, + }) + if aerr != nil { + return nil, aerr + } + + return &types.Message{ + To: paych, + From: from, + Value: abi.NewTokenAmount(0), + Method: builtin0.MethodsPaych.UpdateChannelState, + Params: params, + }, nil +} + +func (message0) Settle(from, paych address.Address) (*types.Message, error) { + return &types.Message{ + To: paych, + From: from, + Value: abi.NewTokenAmount(0), + Method: builtin0.MethodsPaych.Settle, + }, nil +} + +func (message0) Collect(from, paych address.Address) (*types.Message, error) { + return &types.Message{ + To: paych, + From: from, + Value: abi.NewTokenAmount(0), + Method: builtin0.MethodsPaych.Collect, + }, nil +} diff --git a/chain/actors/builtin/paych/message2.go b/chain/actors/builtin/paych/message2.go new file mode 100644 index 000000000..94538bc49 --- /dev/null +++ b/chain/actors/builtin/paych/message2.go @@ -0,0 +1,74 @@ +package paych + +import ( + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + + builtin2 "github.com/filecoin-project/specs-actors/actors/builtin" + init2 "github.com/filecoin-project/specs-actors/actors/builtin/init" + paych2 "github.com/filecoin-project/specs-actors/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 message2 struct{} + +func (message2) Create(from, to address.Address, initialAmount abi.TokenAmount) (*types.Message, error) { + params, aerr := actors.SerializeParams(&paych2.ConstructorParams{From: from, To: to}) + if aerr != nil { + return nil, aerr + } + enc, aerr := actors.SerializeParams(&init2.ExecParams{ + CodeCID: builtin2.PaymentChannelActorCodeID, + ConstructorParams: params, + }) + if aerr != nil { + return nil, aerr + } + + return &types.Message{ + To: init_.Address, + From: from, + Value: initialAmount, + Method: builtin2.MethodsInit.Exec, + Params: enc, + }, nil +} + +func (message2) Update(from, paych address.Address, sv *SignedVoucher, secret []byte) (*types.Message, error) { + params, aerr := actors.SerializeParams(&paych2.UpdateChannelStateParams{ + Sv: *sv, + Secret: secret, + }) + if aerr != nil { + return nil, aerr + } + + return &types.Message{ + To: paych, + From: from, + Value: abi.NewTokenAmount(0), + Method: builtin2.MethodsPaych.UpdateChannelState, + Params: params, + }, nil +} + +func (message2) Settle(from, paych address.Address) (*types.Message, error) { + return &types.Message{ + To: paych, + From: from, + Value: abi.NewTokenAmount(0), + Method: builtin2.MethodsPaych.Settle, + }, nil +} + +func (message2) Collect(from, paych address.Address) (*types.Message, error) { + return &types.Message{ + To: paych, + From: from, + Value: abi.NewTokenAmount(0), + Method: builtin2.MethodsPaych.Collect, + }, nil +} diff --git a/chain/actors/builtin/paych/paych.go b/chain/actors/builtin/paych/state.go similarity index 100% rename from chain/actors/builtin/paych/paych.go rename to chain/actors/builtin/paych/state.go diff --git a/chain/actors/builtin/paych/v0.go b/chain/actors/builtin/paych/state0.go similarity index 100% rename from chain/actors/builtin/paych/v0.go rename to chain/actors/builtin/paych/state0.go diff --git a/chain/actors/builtin/paych/v2.go b/chain/actors/builtin/paych/state2.go similarity index 100% rename from chain/actors/builtin/paych/v2.go rename to chain/actors/builtin/paych/state2.go diff --git a/paychmgr/manager.go b/paychmgr/manager.go index 1b2acfd2f..f2fc190c7 100644 --- a/paychmgr/manager.go +++ b/paychmgr/manager.go @@ -13,6 +13,7 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/crypto" + "github.com/filecoin-project/go-state-types/network" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/actors/adt" @@ -49,6 +50,7 @@ type paychAPI interface { MpoolPushMessage(ctx context.Context, msg *types.Message, maxFee *api.MessageSendSpec) (*types.SignedMessage, error) WalletHas(ctx context.Context, addr address.Address) (bool, error) WalletSign(ctx context.Context, k address.Address, msg []byte) (*crypto.Signature, error) + StateNetworkVersion(context.Context, types.TipSetKey) (network.Version, error) } // managerAPI defines all methods needed by the manager diff --git a/paychmgr/mock_test.go b/paychmgr/mock_test.go index c761221d2..3393a3072 100644 --- a/paychmgr/mock_test.go +++ b/paychmgr/mock_test.go @@ -9,8 +9,10 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/crypto" + "github.com/filecoin-project/go-state-types/network" "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors/builtin/paych" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/lib/sigs" @@ -241,3 +243,7 @@ func (pchapi *mockPaychAPI) addSigningKey(key []byte) { pchapi.signingKey = key } + +func (pchapi *mockPaychAPI) StateNetworkVersion(ctx context.Context, tsk types.TipSetKey) (network.Version, error) { + return build.NewestNetworkVersion, nil +} diff --git a/paychmgr/paych.go b/paychmgr/paych.go index 056140653..96ba43543 100644 --- a/paychmgr/paych.go +++ b/paychmgr/paych.go @@ -10,8 +10,6 @@ import ( "github.com/filecoin-project/go-address" cborutil "github.com/filecoin-project/go-cbor-util" "github.com/filecoin-project/go-state-types/big" - "github.com/filecoin-project/specs-actors/actors/builtin" - paych0 "github.com/filecoin-project/specs-actors/actors/builtin/paych" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/actors" @@ -84,6 +82,15 @@ func newChannelAccessor(pm *Manager, from address.Address, to address.Address) * } } +func (ca *channelAccessor) messageBuilder(ctx context.Context) (paych.MessageBuilder, error) { + nwVersion, err := ca.api.StateNetworkVersion(ctx, types.EmptyTSK) + if err != nil { + return nil, err + } + + return paych.Message(actors.VersionForNetwork(nwVersion)), nil +} + func (ca *channelAccessor) getChannelInfo(addr address.Address) (*ChannelInfo, error) { ca.lk.Lock() defer ca.lk.Unlock() @@ -294,20 +301,17 @@ func (ca *channelAccessor) checkVoucherSpendable(ctx context.Context, ch address return false, nil } - enc, err := actors.SerializeParams(&paych0.UpdateChannelStateParams{ - Sv: *sv, - Secret: secret, - }) + mb, err := ca.messageBuilder(ctx) if err != nil { return false, err } - ret, err := ca.api.Call(ctx, &types.Message{ - From: recipient, - To: ch, - Method: builtin.MethodsPaych.UpdateChannelState, - Params: enc, - }, nil) + mes, err := mb.Update(recipient, ch, sv, secret) + if err != nil { + return false, err + } + + ret, err := ca.api.Call(ctx, mes, nil) if err != nil { return false, err } @@ -414,21 +418,14 @@ func (ca *channelAccessor) submitVoucher(ctx context.Context, ch address.Address } } - // TODO: ActorUpgrade - enc, err := actors.SerializeParams(&paych0.UpdateChannelStateParams{ - Sv: *sv, - Secret: secret, - }) + mb, err := ca.messageBuilder(ctx) if err != nil { return cid.Undef, err } - msg := &types.Message{ - From: ci.Control, - To: ch, - Value: types.NewInt(0), - Method: builtin.MethodsPaych.UpdateChannelState, - Params: enc, + msg, err := mb.Update(ci.Control, ch, sv, secret) + if err != nil { + return cid.Undef, err } smsg, err := ca.api.MpoolPushMessage(ctx, msg, nil) @@ -577,11 +574,13 @@ func (ca *channelAccessor) settle(ctx context.Context, ch address.Address) (cid. return cid.Undef, err } - msg := &types.Message{ - To: ch, - From: ci.Control, - Value: types.NewInt(0), - Method: builtin.MethodsPaych.Settle, + mb, err := ca.messageBuilder(ctx) + if err != nil { + return cid.Undef, err + } + msg, err := mb.Settle(ci.Control, ch) + if err != nil { + return cid.Undef, err } smgs, err := ca.api.MpoolPushMessage(ctx, msg, nil) if err != nil { @@ -606,11 +605,14 @@ func (ca *channelAccessor) collect(ctx context.Context, ch address.Address) (cid return cid.Undef, err } - msg := &types.Message{ - To: ch, - From: ci.Control, - Value: types.NewInt(0), - Method: builtin.MethodsPaych.Collect, + mb, err := ca.messageBuilder(ctx) + if err != nil { + return cid.Undef, err + } + + msg, err := mb.Collect(ci.Control, ch) + if err != nil { + return cid.Undef, err } smsg, err := ca.api.MpoolPushMessage(ctx, msg, nil) diff --git a/paychmgr/paychget_test.go b/paychmgr/paychget_test.go index 430e66c67..28e2ac7e3 100644 --- a/paychmgr/paychget_test.go +++ b/paychmgr/paychget_test.go @@ -15,9 +15,9 @@ import ( "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/specs-actors/actors/builtin" - init_ "github.com/filecoin-project/specs-actors/actors/builtin/init" - tutils "github.com/filecoin-project/specs-actors/support/testing" + "github.com/filecoin-project/specs-actors/v2/actors/builtin" + init_ "github.com/filecoin-project/specs-actors/v2/actors/builtin/init" + tutils "github.com/filecoin-project/specs-actors/v2/support/testing" lotusinit "github.com/filecoin-project/lotus/chain/actors/builtin/init" "github.com/filecoin-project/lotus/chain/actors/builtin/paych" diff --git a/paychmgr/simple.go b/paychmgr/simple.go index d49ccafe6..38804b7ea 100644 --- a/paychmgr/simple.go +++ b/paychmgr/simple.go @@ -12,14 +12,11 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/big" - "github.com/filecoin-project/specs-actors/actors/builtin" - init0 "github.com/filecoin-project/specs-actors/actors/builtin/init" - paych0 "github.com/filecoin-project/specs-actors/actors/builtin/paych" + + init2 "github.com/filecoin-project/specs-actors/actors/builtin/init" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" - "github.com/filecoin-project/lotus/chain/actors" - lotusinit "github.com/filecoin-project/lotus/chain/actors/builtin/init" "github.com/filecoin-project/lotus/chain/types" ) @@ -387,25 +384,13 @@ func (ca *channelAccessor) processTask(ctx context.Context, amt types.BigInt) *p // createPaych sends a message to create the channel and returns the message cid func (ca *channelAccessor) createPaych(ctx context.Context, amt types.BigInt) (cid.Cid, error) { - params, aerr := actors.SerializeParams(&paych0.ConstructorParams{From: ca.from, To: ca.to}) - if aerr != nil { - return cid.Undef, aerr + mb, err := ca.messageBuilder(ctx) + if err != nil { + return cid.Undef, err } - - enc, aerr := actors.SerializeParams(&init0.ExecParams{ - CodeCID: builtin.PaymentChannelActorCodeID, - ConstructorParams: params, - }) - if aerr != nil { - return cid.Undef, aerr - } - - msg := &types.Message{ - To: lotusinit.Address, - From: ca.from, - Value: amt, - Method: builtin.MethodsInit.Exec, - Params: enc, + msg, err := mb.Create(ca.from, ca.to, amt) + if err != nil { + return cid.Undef, err } smsg, err := ca.api.MpoolPushMessage(ctx, msg, nil) @@ -457,7 +442,10 @@ func (ca *channelAccessor) waitPaychCreateMsg(channelID string, mcid cid.Cid) er return err } - var decodedReturn init0.ExecReturn + // TODO: ActorUpgrade abstract over this. + // This "works" because it hasn't changed from v0 to v2, but we still + // need an abstraction here. + var decodedReturn init2.ExecReturn err = decodedReturn.UnmarshalCBOR(bytes.NewReader(mwait.Receipt.Return)) if err != nil { log.Error(err)