From 1973e44f49ca84103c742d2d6901346261c74391 Mon Sep 17 00:00:00 2001 From: Geoff Stuart Date: Thu, 22 Sep 2022 16:25:51 -0400 Subject: [PATCH] Update datacap actor to query datacap instead of verifreg --- .../actors/builtin/datacap/actor.go.template | 2 + chain/actors/builtin/datacap/datacap.go | 3 ++ .../actors/builtin/datacap/state.go.template | 15 +++++- chain/actors/builtin/datacap/util.go | 52 +++++++++++++++++++ chain/actors/builtin/datacap/v9.go | 15 ++++++ cli/filplus.go | 37 +++++++++++-- cmd/lotus-shed/verifreg.go | 33 ------------ node/impl/full/state.go | 49 +++++++++++++---- 8 files changed, 157 insertions(+), 49 deletions(-) create mode 100644 chain/actors/builtin/datacap/util.go diff --git a/chain/actors/builtin/datacap/actor.go.template b/chain/actors/builtin/datacap/actor.go.template index 2f40fc96e..4a9ac7c35 100644 --- a/chain/actors/builtin/datacap/actor.go.template +++ b/chain/actors/builtin/datacap/actor.go.template @@ -50,6 +50,8 @@ func MakeState(store adt.Store, av actorstypes.Version, governor address.Address type State interface { cbor.Marshaler + ForEachClient(func(addr address.Address, dcap abi.StoragePower) error) error + VerifiedClientDataCap(address.Address) (bool, abi.StoragePower, error) Governor() (address.Address, error) GetState() interface{} } diff --git a/chain/actors/builtin/datacap/datacap.go b/chain/actors/builtin/datacap/datacap.go index 0fcaa7ffa..3915c01e5 100644 --- a/chain/actors/builtin/datacap/datacap.go +++ b/chain/actors/builtin/datacap/datacap.go @@ -4,6 +4,7 @@ import ( "golang.org/x/xerrors" "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" actorstypes "github.com/filecoin-project/go-state-types/actors" builtin9 "github.com/filecoin-project/go-state-types/builtin" "github.com/filecoin-project/go-state-types/cbor" @@ -50,6 +51,8 @@ func MakeState(store adt.Store, av actorstypes.Version, governor address.Address type State interface { cbor.Marshaler + ForEachClient(func(addr address.Address, dcap abi.StoragePower) error) error + VerifiedClientDataCap(address.Address) (bool, abi.StoragePower, error) Governor() (address.Address, error) GetState() interface{} } diff --git a/chain/actors/builtin/datacap/state.go.template b/chain/actors/builtin/datacap/state.go.template index 899f352eb..f5b993bfb 100644 --- a/chain/actors/builtin/datacap/state.go.template +++ b/chain/actors/builtin/datacap/state.go.template @@ -10,7 +10,6 @@ import ( datacap{{.v}} "github.com/filecoin-project/go-state-types/builtin{{.import}}datacap" adt{{.v}} "github.com/filecoin-project/go-state-types/builtin{{.import}}util/adt" - builtin{{.v}} "github.com/filecoin-project/go-state-types/builtin" ) var _ State = (*state{{.v}})(nil) @@ -47,4 +46,16 @@ func (s *state{{.v}}) Governor() (address.Address, error) { func (s *state{{.v}}) GetState() interface{} { return &s.State -} \ No newline at end of file +} + +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.Token.Balances, int(s.Token.HamtBitWidth)) +} + +func (s *state{{.v}}) VerifiedClientDataCap(addr address.Address) (bool, abi.StoragePower, error) { + return getDataCap(s.store, actors.Version{{.v}}, s.verifiedClients, addr) +} diff --git a/chain/actors/builtin/datacap/util.go b/chain/actors/builtin/datacap/util.go new file mode 100644 index 000000000..d6f652024 --- /dev/null +++ b/chain/actors/builtin/datacap/util.go @@ -0,0 +1,52 @@ +package datacap + +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/lotus/chain/actors" + "github.com/filecoin-project/lotus/chain/actors/adt" +) + +// taking this as a function instead of asking the caller to call it helps reduce some of the error +// checking boilerplate. +// +// "go made me do it" +type rootFunc func() (adt.Map, error) + +func getDataCap(store adt.Store, ver actors.Version, root rootFunc, addr address.Address) (bool, abi.StoragePower, error) { + if addr.Protocol() != address.ID { + return false, big.Zero(), xerrors.Errorf("can only look up ID addresses") + } + vh, err := root() + if err != nil { + return false, big.Zero(), xerrors.Errorf("loading datacap actor: %w", err) + } + + var dcap abi.StoragePower + if found, err := vh.Get(abi.AddrKey(addr), &dcap); err != nil { + return false, big.Zero(), xerrors.Errorf("looking up addr: %w", err) + } else if !found { + return false, big.Zero(), nil + } + + return true, dcap, nil +} + +func forEachCap(store adt.Store, ver actors.Version, root rootFunc, cb func(addr address.Address, dcap abi.StoragePower) error) error { + vh, err := root() + if err != nil { + return xerrors.Errorf("loading verified clients: %w", err) + } + var dcap abi.StoragePower + return vh.ForEach(&dcap, func(key string) error { + a, err := address.NewFromBytes([]byte(key)) + if err != nil { + return err + } + return cb(a, dcap) + }) +} diff --git a/chain/actors/builtin/datacap/v9.go b/chain/actors/builtin/datacap/v9.go index dab7eb646..9e03a4779 100644 --- a/chain/actors/builtin/datacap/v9.go +++ b/chain/actors/builtin/datacap/v9.go @@ -4,8 +4,11 @@ import ( "github.com/ipfs/go-cid" "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" datacap9 "github.com/filecoin-project/go-state-types/builtin/v9/datacap" + adt9 "github.com/filecoin-project/go-state-types/builtin/v9/util/adt" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" ) @@ -44,3 +47,15 @@ func (s *state9) Governor() (address.Address, error) { func (s *state9) GetState() interface{} { return &s.State } + +func (s *state9) ForEachClient(cb func(addr address.Address, dcap abi.StoragePower) error) error { + return forEachCap(s.store, actors.Version9, s.verifiedClients, cb) +} + +func (s *state9) verifiedClients() (adt.Map, error) { + return adt9.AsMap(s.store, s.Token.Balances, int(s.Token.HamtBitWidth)) +} + +func (s *state9) VerifiedClientDataCap(addr address.Address) (bool, abi.StoragePower, error) { + return getDataCap(s.store, actors.Version9, s.verifiedClients, addr) +} diff --git a/cli/filplus.go b/cli/filplus.go index d74171dd6..f7014ac7b 100644 --- a/cli/filplus.go +++ b/cli/filplus.go @@ -12,6 +12,7 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" "github.com/filecoin-project/go-state-types/big" verifregtypes8 "github.com/filecoin-project/go-state-types/builtin/v8/verifreg" verifregtypes9 "github.com/filecoin-project/go-state-types/builtin/v9/verifreg" @@ -22,6 +23,7 @@ import ( "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/chain/actors/builtin/datacap" "github.com/filecoin-project/lotus/chain/actors/builtin/verifreg" "github.com/filecoin-project/lotus/chain/types" ) @@ -169,15 +171,40 @@ var filplusListClientsCmd = &cli.Command{ defer closer() ctx := ReqContext(cctx) - act, err := api.StateGetActor(ctx, verifreg.Address, types.EmptyTSK) + apibs := blockstore.NewAPIBlockstore(api) + store := adt.WrapStore(ctx, cbor.NewCborStore(apibs)) + + nv, err := api.StateNetworkVersion(ctx, types.EmptyTSK) if err != nil { return err } - apibs := blockstore.NewAPIBlockstore(api) - store := adt.WrapStore(ctx, cbor.NewCborStore(apibs)) + av, err := actorstypes.VersionForNetwork(nv) + if err != nil { + return err + } - st, err := verifreg.Load(store, act) + if av <= 8 { + act, err := api.StateGetActor(ctx, verifreg.Address, types.EmptyTSK) + if err != nil { + return err + } + + st, err := verifreg.Load(store, act) + if err != nil { + return err + } + return st.ForEachClient(func(addr address.Address, dcap abi.StoragePower) error { + _, err := fmt.Printf("%s: %s\n", addr, dcap) + return err + }) + } + act, err := api.StateGetActor(ctx, datacap.Address, types.EmptyTSK) + if err != nil { + return err + } + + st, err := datacap.Load(store, act) if err != nil { return err } @@ -336,7 +363,7 @@ var filplusSignRemoveDataCapProposal = &cli.Command{ return err } - _, dataCap, err := st.VerifiedClientDataCap(clientIdAddr) + dataCap, err := api.StateVerifiedClientStatus(ctx, clientIdAddr, types.EmptyTSK) if err != nil { return xerrors.Errorf("failed to find verified client data cap: %w", err) } diff --git a/cmd/lotus-shed/verifreg.go b/cmd/lotus-shed/verifreg.go index 0fa905b5f..872b4228d 100644 --- a/cmd/lotus-shed/verifreg.go +++ b/cmd/lotus-shed/verifreg.go @@ -34,7 +34,6 @@ var verifRegCmd = &cli.Command{ verifRegAddVerifierFromAccountCmd, verifRegVerifyClientCmd, verifRegListVerifiersCmd, - verifRegListClientsCmd, verifRegCheckClientCmd, verifRegCheckVerifierCmd, verifRegRemoveVerifiedClientDataCapCmd, @@ -286,38 +285,6 @@ var verifRegListVerifiersCmd = &cli.Command{ }, } -var verifRegListClientsCmd = &cli.Command{ - Name: "list-clients", - Usage: "list all verified clients", - Hidden: true, - Action: func(cctx *cli.Context) error { - fmt.Println("DEPRECATED: This behavior is being moved to `lotus filplus`") - api, closer, err := lcli.GetFullNodeAPI(cctx) - if err != nil { - return err - } - defer closer() - ctx := lcli.ReqContext(cctx) - - act, err := api.StateGetActor(ctx, verifreg.Address, types.EmptyTSK) - if err != nil { - return err - } - - apibs := blockstore.NewAPIBlockstore(api) - store := adt.WrapStore(ctx, cbor.NewCborStore(apibs)) - - st, err := verifreg.Load(store, act) - if err != nil { - return err - } - return st.ForEachClient(func(addr address.Address, dcap abi.StoragePower) error { - _, err := fmt.Printf("%s: %s\n", addr, dcap) - return err - }) - }, -} - var verifRegCheckClientCmd = &cli.Command{ Name: "check-client", Usage: "check verified client remaining bytes", diff --git a/node/impl/full/state.go b/node/impl/full/state.go index 97f3c83dc..f2fa7ad26 100644 --- a/node/impl/full/state.go +++ b/node/impl/full/state.go @@ -30,6 +30,7 @@ import ( "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/builtin" + "github.com/filecoin-project/lotus/chain/actors/builtin/datacap" "github.com/filecoin-project/lotus/chain/actors/builtin/market" "github.com/filecoin-project/lotus/chain/actors/builtin/miner" "github.com/filecoin-project/lotus/chain/actors/builtin/multisig" @@ -1399,26 +1400,56 @@ func (a *StateAPI) StateVerifierStatus(ctx context.Context, addr address.Address // Returns zero if there is no entry in the data cap table for the // address. func (m *StateModule) StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error) { - act, err := m.StateGetActor(ctx, verifreg.Address, tsk) - if err != nil { - return nil, err - } - aid, err := m.StateLookupID(ctx, addr, tsk) if err != nil { log.Warnf("lookup failure %v", err) return nil, err } - vrs, err := verifreg.Load(m.StateManager.ChainStore().ActorStore(ctx), act) + nv, err := m.StateNetworkVersion(ctx, tsk) if err != nil { - return nil, xerrors.Errorf("failed to load verified registry state: %w", err) + return nil, err } - verified, dcap, err := vrs.VerifiedClientDataCap(aid) + av, err := actorstypes.VersionForNetwork(nv) if err != nil { - return nil, xerrors.Errorf("looking up verified client: %w", err) + return nil, err } + + var dcap abi.StoragePower + var verified bool + if av <= 8 { + act, err := m.StateGetActor(ctx, verifreg.Address, tsk) + if err != nil { + return nil, err + } + + vrs, err := verifreg.Load(m.StateManager.ChainStore().ActorStore(ctx), act) + if err != nil { + return nil, xerrors.Errorf("failed to load verified registry state: %w", err) + } + + verified, dcap, err = vrs.VerifiedClientDataCap(aid) + if err != nil { + return nil, xerrors.Errorf("looking up verified client: %w", err) + } + } else { + act, err := m.StateGetActor(ctx, datacap.Address, tsk) + if err != nil { + return nil, err + } + + dcs, err := datacap.Load(m.StateManager.ChainStore().ActorStore(ctx), act) + if err != nil { + return nil, xerrors.Errorf("failed to load datacap actor state: %w", err) + } + + verified, dcap, err = dcs.VerifiedClientDataCap(aid) + if err != nil { + return nil, xerrors.Errorf("looking up verified client: %w", err) + } + } + if !verified { return nil, nil }