From 82b03025789891ccfec8240675e03298079411be Mon Sep 17 00:00:00 2001 From: Rod Vagg Date: Sat, 3 Aug 2024 16:58:42 +1000 Subject: [PATCH 1/2] feat: make ActorTree an interface --- builtin/actor_tree.go | 45 ++++++++++++++++++++--------- builtin/v10/check.go | 47 ++++++++++++++++--------------- builtin/v10/init/invariants.go | 4 +-- builtin/v11/check.go | 46 +++++++++++++++--------------- builtin/v11/init/invariants.go | 4 +-- builtin/v12/check.go | 46 +++++++++++++++--------------- builtin/v12/init/invariants.go | 4 +-- builtin/v13/check.go | 46 +++++++++++++++--------------- builtin/v13/init/invariants.go | 4 +-- builtin/v14/check.go | 46 +++++++++++++++--------------- builtin/v14/init/invariants.go | 4 +-- builtin/v14/migration/top.go | 4 +-- builtin/v8/check.go | 40 +++++++++++++------------- builtin/v9/check.go | 44 ++++++++++++++--------------- builtin/v9/migration/test/util.go | 2 +- migration/runner.go | 2 +- 16 files changed, 204 insertions(+), 184 deletions(-) diff --git a/builtin/actor_tree.go b/builtin/actor_tree.go index 0e0b48b3..b4565317 100644 --- a/builtin/actor_tree.go +++ b/builtin/actor_tree.go @@ -9,6 +9,21 @@ import ( "golang.org/x/xerrors" ) +type ActorTree interface { + GetStore() adt.Store + + Flush() (cid.Cid, error) + GetActorV4(addr address.Address) (*ActorV4, bool, error) + GetActorV5(addr address.Address) (*ActorV5, bool, error) + SetActorV4(addr address.Address, actor *ActorV4) error + SetActorV5(addr address.Address, actor *ActorV5) error + ForEachV4(fn func(addr address.Address, actor *ActorV4) error) error + ForEachV5(fn func(addr address.Address, actor *ActorV5) error) error + ForEachKey(fn func(addr address.Address) error) error +} + +var _ ActorTree = (*actorTree)(nil) + // Value type of the top level of the state tree. // Represents the on-chain state of a single actor. // This is the actor state for state tree version up to 4 @@ -29,42 +44,46 @@ type ActorV5 struct { } // A specialization of a map of ID-addresses to actor heads. -type ActorTree struct { +type actorTree struct { Map *adt.Map Store adt.Store } // Initializes a new, empty state tree backed by a store. -func NewTree(store adt.Store) (*ActorTree, error) { +func NewTree(store adt.Store) (ActorTree, error) { emptyMap, err := adt.MakeEmptyMap(store, DefaultHamtBitwidth) if err != nil { return nil, err } - return &ActorTree{ + return &actorTree{ Map: emptyMap, Store: store, }, nil } // Loads a tree from a root CID and store. -func LoadTree(s adt.Store, r cid.Cid) (*ActorTree, error) { +func LoadTree(s adt.Store, r cid.Cid) (ActorTree, error) { m, err := adt.AsMap(s, r, DefaultHamtBitwidth) if err != nil { return nil, err } - return &ActorTree{ + return &actorTree{ Map: m, Store: s, }, nil } +func (t *actorTree) GetStore() adt.Store { + return t.Store +} + // Writes the tree root node to the store, and returns its CID. -func (t *ActorTree) Flush() (cid.Cid, error) { +func (t *actorTree) Flush() (cid.Cid, error) { return t.Map.Root() } // Loads the state associated with an address. -func (t *ActorTree) GetActorV4(addr address.Address) (*ActorV4, bool, error) { +func (t *actorTree) GetActorV4(addr address.Address) (*ActorV4, bool, error) { if addr.Protocol() != address.ID { return nil, false, xerrors.Errorf("non-ID address %v invalid as actor key", addr) } @@ -73,7 +92,7 @@ func (t *ActorTree) GetActorV4(addr address.Address) (*ActorV4, bool, error) { return &actor, found, err } -func (t *ActorTree) GetActorV5(addr address.Address) (*ActorV5, bool, error) { +func (t *actorTree) GetActorV5(addr address.Address) (*ActorV5, bool, error) { if addr.Protocol() != address.ID { return nil, false, xerrors.Errorf("non-ID address %v invalid as actor key", addr) } @@ -83,14 +102,14 @@ func (t *ActorTree) GetActorV5(addr address.Address) (*ActorV5, bool, error) { } // Sets the state associated with an address, overwriting if it already present. -func (t *ActorTree) SetActorV4(addr address.Address, actor *ActorV4) error { +func (t *actorTree) SetActorV4(addr address.Address, actor *ActorV4) error { if addr.Protocol() != address.ID { return xerrors.Errorf("non-ID address %v invalid as actor key", addr) } return t.Map.Put(abi.AddrKey(addr), actor) } -func (t *ActorTree) SetActorV5(addr address.Address, actor *ActorV5) error { +func (t *actorTree) SetActorV5(addr address.Address, actor *ActorV5) error { if addr.Protocol() != address.ID { return xerrors.Errorf("non-ID address %v invalid as actor key", addr) } @@ -98,7 +117,7 @@ func (t *ActorTree) SetActorV5(addr address.Address, actor *ActorV5) error { } // Traverses all entries in the tree. -func (t *ActorTree) ForEachV4(fn func(addr address.Address, actor *ActorV4) error) error { +func (t *actorTree) ForEachV4(fn func(addr address.Address, actor *ActorV4) error) error { var val ActorV4 return t.Map.ForEach(&val, func(key string) error { addr, err := address.NewFromBytes([]byte(key)) @@ -109,7 +128,7 @@ func (t *ActorTree) ForEachV4(fn func(addr address.Address, actor *ActorV4) erro }) } -func (t *ActorTree) ForEachV5(fn func(addr address.Address, actor *ActorV5) error) error { +func (t *actorTree) ForEachV5(fn func(addr address.Address, actor *ActorV5) error) error { var val ActorV5 return t.Map.ForEach(&val, func(key string) error { addr, err := address.NewFromBytes([]byte(key)) @@ -121,7 +140,7 @@ func (t *ActorTree) ForEachV5(fn func(addr address.Address, actor *ActorV5) erro } // Traverses all keys in the tree, without decoding the actor states. -func (t *ActorTree) ForEachKey(fn func(addr address.Address) error) error { +func (t *actorTree) ForEachKey(fn func(addr address.Address) error) error { return t.Map.ForEach(nil, func(key string) error { addr, err := address.NewFromBytes([]byte(key)) if err != nil { diff --git a/builtin/v10/check.go b/builtin/v10/check.go index b20e40d0..89707189 100644 --- a/builtin/v10/check.go +++ b/builtin/v10/check.go @@ -3,6 +3,7 @@ package v10 import ( "bytes" "fmt" + "github.com/filecoin-project/go-state-types/builtin/v10/datacap" "github.com/filecoin-project/go-state-types/builtin/v10/evm" "github.com/filecoin-project/go-state-types/manifest" @@ -30,7 +31,7 @@ import ( // Within this code, Go errors are not expected, but are often converted to messages so that execution // can continue to find more errors rather than fail with no insight. // Only errors thar are particularly troublesome to recover from should propagate as Go errors. -func CheckStateInvariants(tree *builtin.ActorTree, priorEpoch abi.ChainEpoch, actorCodes map[string]cid.Cid) (*builtin.MessageAccumulator, error) { +func CheckStateInvariants(tree builtin.ActorTree, priorEpoch abi.ChainEpoch, actorCodes map[string]cid.Cid) (*builtin.MessageAccumulator, error) { acc := &builtin.MessageAccumulator{} totalFIl := big.Zero() var initSummary *init_.StateSummary @@ -70,7 +71,7 @@ func CheckStateInvariants(tree *builtin.ActorTree, priorEpoch abi.ChainEpoch, ac case actorCodes[manifest.InitKey]: var st init_.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { fmt.Println("init invariant error = ", err) return err } @@ -79,15 +80,15 @@ func CheckStateInvariants(tree *builtin.ActorTree, priorEpoch abi.ChainEpoch, ac initSummary = summary case actorCodes[manifest.CronKey]: var st cron.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := cron.CheckStateInvariants(&st, tree.Store) + summary, msgs := cron.CheckStateInvariants(&st, tree.GetStore()) acc.WithPrefix("cron: ").AddAll(msgs) cronSummary = summary case actorCodes[manifest.AccountKey]: var st account.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } summary, msgs := account.CheckStateInvariants(&st, key) @@ -95,74 +96,74 @@ func CheckStateInvariants(tree *builtin.ActorTree, priorEpoch abi.ChainEpoch, ac accountSummaries = append(accountSummaries, summary) case actorCodes[manifest.PowerKey]: var st power.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := power.CheckStateInvariants(&st, tree.Store) + summary, msgs := power.CheckStateInvariants(&st, tree.GetStore()) acc.WithPrefix("power: ").AddAll(msgs) powerSummary = summary case actorCodes[manifest.MinerKey]: var st miner.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := miner.CheckStateInvariants(&st, tree.Store, actor.Balance) + summary, msgs := miner.CheckStateInvariants(&st, tree.GetStore(), actor.Balance) acc.WithPrefix("miner: ").AddAll(msgs) minerSummaries[key] = summary case actorCodes[manifest.MarketKey]: var st market.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := market.CheckStateInvariants(&st, tree.Store, actor.Balance, priorEpoch) + summary, msgs := market.CheckStateInvariants(&st, tree.GetStore(), actor.Balance, priorEpoch) acc.WithPrefix("market: ").AddAll(msgs) marketSummary = summary case actorCodes[manifest.PaychKey]: var st paych.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := paych.CheckStateInvariants(&st, tree.Store, actor.Balance) + summary, msgs := paych.CheckStateInvariants(&st, tree.GetStore(), actor.Balance) acc.WithPrefix("paych: ").AddAll(msgs) paychSummaries = append(paychSummaries, summary) case actorCodes[manifest.MultisigKey]: var st multisig.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := multisig.CheckStateInvariants(&st, tree.Store) + summary, msgs := multisig.CheckStateInvariants(&st, tree.GetStore()) acc.WithPrefix("multisig: ").AddAll(msgs) multisigSummaries = append(multisigSummaries, summary) case actorCodes[manifest.RewardKey]: var st reward.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := reward.CheckStateInvariants(&st, tree.Store, priorEpoch, actor.Balance) + summary, msgs := reward.CheckStateInvariants(&st, tree.GetStore(), priorEpoch, actor.Balance) acc.WithPrefix("reward: ").AddAll(msgs) rewardSummary = summary case actorCodes[manifest.VerifregKey]: var st verifreg.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := verifreg.CheckStateInvariants(&st, tree.Store, priorEpoch) + summary, msgs := verifreg.CheckStateInvariants(&st, tree.GetStore(), priorEpoch) acc.WithPrefix("verifreg: ").AddAll(msgs) verifregSummary = summary case actorCodes[manifest.DatacapKey]: var st datacap.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := datacap.CheckStateInvariants(&st, tree.Store) + summary, msgs := datacap.CheckStateInvariants(&st, tree.GetStore()) acc.WithPrefix("datacap: ").AddAll(msgs) datacapSummary = summary case actorCodes[manifest.EvmKey]: var st evm.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - msgs := evm.CheckStateInvariants(&st, tree.Store) + msgs := evm.CheckStateInvariants(&st, tree.GetStore()) acc.WithPrefix("evm: ").AddAll(msgs) case actorCodes[manifest.PlaceholderKey]: acc.Require(actor.Head == emptyObjectCid, "Placeholder actor head %v unequal to emptyObjectCid %v", actor.Head, emptyObjectCid) diff --git a/builtin/v10/init/invariants.go b/builtin/v10/init/invariants.go index 193fb210..88a984ff 100644 --- a/builtin/v10/init/invariants.go +++ b/builtin/v10/init/invariants.go @@ -17,9 +17,9 @@ type StateSummary struct { } // Checks internal invariants of init state. -func CheckStateInvariants(st *State, tree *builtin.ActorTree, actorCodes map[string]cid.Cid) (*StateSummary, *builtin.MessageAccumulator) { +func CheckStateInvariants(st *State, tree builtin.ActorTree, actorCodes map[string]cid.Cid) (*StateSummary, *builtin.MessageAccumulator) { acc := &builtin.MessageAccumulator{} - store := tree.Store + store := tree.GetStore() acc.Require(len(st.NetworkName) > 0, "network name is empty") acc.Require(st.NextID >= builtin.FirstNonSingletonActorId, "next id %d is too low", st.NextID) diff --git a/builtin/v11/check.go b/builtin/v11/check.go index 6519f229..763b7857 100644 --- a/builtin/v11/check.go +++ b/builtin/v11/check.go @@ -31,7 +31,7 @@ import ( // Within this code, Go errors are not expected, but are often converted to messages so that execution // can continue to find more errors rather than fail with no insight. // Only errors thar are particularly troublesome to recover from should propagate as Go errors. -func CheckStateInvariants(tree *builtin.ActorTree, priorEpoch abi.ChainEpoch, actorCodes map[string]cid.Cid) (*builtin.MessageAccumulator, error) { +func CheckStateInvariants(tree builtin.ActorTree, priorEpoch abi.ChainEpoch, actorCodes map[string]cid.Cid) (*builtin.MessageAccumulator, error) { acc := &builtin.MessageAccumulator{} totalFIl := big.Zero() var initSummary *init_.StateSummary @@ -71,7 +71,7 @@ func CheckStateInvariants(tree *builtin.ActorTree, priorEpoch abi.ChainEpoch, ac case actorCodes[manifest.InitKey]: var st init_.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { fmt.Println("init invariant error = ", err) return err } @@ -80,15 +80,15 @@ func CheckStateInvariants(tree *builtin.ActorTree, priorEpoch abi.ChainEpoch, ac initSummary = summary case actorCodes[manifest.CronKey]: var st cron.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := cron.CheckStateInvariants(&st, tree.Store) + summary, msgs := cron.CheckStateInvariants(&st, tree.GetStore()) acc.WithPrefix("cron: ").AddAll(msgs) cronSummary = summary case actorCodes[manifest.AccountKey]: var st account.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } summary, msgs := account.CheckStateInvariants(&st, key) @@ -96,74 +96,74 @@ func CheckStateInvariants(tree *builtin.ActorTree, priorEpoch abi.ChainEpoch, ac accountSummaries = append(accountSummaries, summary) case actorCodes[manifest.PowerKey]: var st power.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := power.CheckStateInvariants(&st, tree.Store) + summary, msgs := power.CheckStateInvariants(&st, tree.GetStore()) acc.WithPrefix("power: ").AddAll(msgs) powerSummary = summary case actorCodes[manifest.MinerKey]: var st miner.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := miner.CheckStateInvariants(&st, tree.Store, actor.Balance) + summary, msgs := miner.CheckStateInvariants(&st, tree.GetStore(), actor.Balance) acc.WithPrefix("miner: ").AddAll(msgs) minerSummaries[key] = summary case actorCodes[manifest.MarketKey]: var st market.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := market.CheckStateInvariants(&st, tree.Store, actor.Balance, priorEpoch) + summary, msgs := market.CheckStateInvariants(&st, tree.GetStore(), actor.Balance, priorEpoch) acc.WithPrefix("market: ").AddAll(msgs) marketSummary = summary case actorCodes[manifest.PaychKey]: var st paych.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := paych.CheckStateInvariants(&st, tree.Store, actor.Balance) + summary, msgs := paych.CheckStateInvariants(&st, tree.GetStore(), actor.Balance) acc.WithPrefix("paych: ").AddAll(msgs) paychSummaries = append(paychSummaries, summary) case actorCodes[manifest.MultisigKey]: var st multisig.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := multisig.CheckStateInvariants(&st, tree.Store) + summary, msgs := multisig.CheckStateInvariants(&st, tree.GetStore()) acc.WithPrefix("multisig: ").AddAll(msgs) multisigSummaries = append(multisigSummaries, summary) case actorCodes[manifest.RewardKey]: var st reward.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := reward.CheckStateInvariants(&st, tree.Store, priorEpoch, actor.Balance) + summary, msgs := reward.CheckStateInvariants(&st, tree.GetStore(), priorEpoch, actor.Balance) acc.WithPrefix("reward: ").AddAll(msgs) rewardSummary = summary case actorCodes[manifest.VerifregKey]: var st verifreg.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := verifreg.CheckStateInvariants(&st, tree.Store, priorEpoch) + summary, msgs := verifreg.CheckStateInvariants(&st, tree.GetStore(), priorEpoch) acc.WithPrefix("verifreg: ").AddAll(msgs) verifregSummary = summary case actorCodes[manifest.DatacapKey]: var st datacap.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := datacap.CheckStateInvariants(&st, tree.Store) + summary, msgs := datacap.CheckStateInvariants(&st, tree.GetStore()) acc.WithPrefix("datacap: ").AddAll(msgs) datacapSummary = summary case actorCodes[manifest.EvmKey]: var st evm.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - msgs := evm.CheckStateInvariants(&st, tree.Store) + msgs := evm.CheckStateInvariants(&st, tree.GetStore()) acc.WithPrefix("evm: ").AddAll(msgs) case actorCodes[manifest.PlaceholderKey]: acc.Require(actor.Head == emptyObjectCid, "Placeholder actor head %v unequal to emptyObjectCid %v", actor.Head, emptyObjectCid) diff --git a/builtin/v11/init/invariants.go b/builtin/v11/init/invariants.go index 67472a12..53f7aacc 100644 --- a/builtin/v11/init/invariants.go +++ b/builtin/v11/init/invariants.go @@ -17,9 +17,9 @@ type StateSummary struct { } // Checks internal invariants of init state. -func CheckStateInvariants(st *State, tree *builtin.ActorTree, actorCodes map[string]cid.Cid) (*StateSummary, *builtin.MessageAccumulator) { +func CheckStateInvariants(st *State, tree builtin.ActorTree, actorCodes map[string]cid.Cid) (*StateSummary, *builtin.MessageAccumulator) { acc := &builtin.MessageAccumulator{} - store := tree.Store + store := tree.GetStore() acc.Require(len(st.NetworkName) > 0, "network name is empty") acc.Require(st.NextID >= builtin.FirstNonSingletonActorId, "next id %d is too low", st.NextID) diff --git a/builtin/v12/check.go b/builtin/v12/check.go index d67b76e4..5dff6d64 100644 --- a/builtin/v12/check.go +++ b/builtin/v12/check.go @@ -29,7 +29,7 @@ import ( // Within this code, Go errors are not expected, but are often converted to messages so that execution // can continue to find more errors rather than fail with no insight. // Only errors thar are particularly troublesome to recover from should propagate as Go errors. -func CheckStateInvariants(tree *builtin.ActorTree, priorEpoch abi.ChainEpoch, actorCodes map[string]cid.Cid) (*builtin.MessageAccumulator, error) { +func CheckStateInvariants(tree builtin.ActorTree, priorEpoch abi.ChainEpoch, actorCodes map[string]cid.Cid) (*builtin.MessageAccumulator, error) { acc := &builtin.MessageAccumulator{} totalFIl := big.Zero() var initSummary *init_.StateSummary @@ -69,7 +69,7 @@ func CheckStateInvariants(tree *builtin.ActorTree, priorEpoch abi.ChainEpoch, ac case actorCodes[manifest.InitKey]: var st init_.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { fmt.Println("init invariant error = ", err) return err } @@ -78,15 +78,15 @@ func CheckStateInvariants(tree *builtin.ActorTree, priorEpoch abi.ChainEpoch, ac initSummary = summary case actorCodes[manifest.CronKey]: var st cron.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := cron.CheckStateInvariants(&st, tree.Store) + summary, msgs := cron.CheckStateInvariants(&st, tree.GetStore()) acc.WithPrefix("cron: ").AddAll(msgs) cronSummary = summary case actorCodes[manifest.AccountKey]: var st account.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } summary, msgs := account.CheckStateInvariants(&st, key) @@ -94,74 +94,74 @@ func CheckStateInvariants(tree *builtin.ActorTree, priorEpoch abi.ChainEpoch, ac accountSummaries = append(accountSummaries, summary) case actorCodes[manifest.PowerKey]: var st power.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := power.CheckStateInvariants(&st, tree.Store) + summary, msgs := power.CheckStateInvariants(&st, tree.GetStore()) acc.WithPrefix("power: ").AddAll(msgs) powerSummary = summary case actorCodes[manifest.MinerKey]: var st miner.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := miner.CheckStateInvariants(&st, tree.Store, actor.Balance) + summary, msgs := miner.CheckStateInvariants(&st, tree.GetStore(), actor.Balance) acc.WithPrefix("miner: ").AddAll(msgs) minerSummaries[key] = summary case actorCodes[manifest.MarketKey]: var st market.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := market.CheckStateInvariants(&st, tree.Store, actor.Balance, priorEpoch) + summary, msgs := market.CheckStateInvariants(&st, tree.GetStore(), actor.Balance, priorEpoch) acc.WithPrefix("market: ").AddAll(msgs) marketSummary = summary case actorCodes[manifest.PaychKey]: var st paych.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := paych.CheckStateInvariants(&st, tree.Store, actor.Balance) + summary, msgs := paych.CheckStateInvariants(&st, tree.GetStore(), actor.Balance) acc.WithPrefix("paych: ").AddAll(msgs) paychSummaries = append(paychSummaries, summary) case actorCodes[manifest.MultisigKey]: var st multisig.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := multisig.CheckStateInvariants(&st, tree.Store) + summary, msgs := multisig.CheckStateInvariants(&st, tree.GetStore()) acc.WithPrefix("multisig: ").AddAll(msgs) multisigSummaries = append(multisigSummaries, summary) case actorCodes[manifest.RewardKey]: var st reward.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := reward.CheckStateInvariants(&st, tree.Store, priorEpoch, actor.Balance) + summary, msgs := reward.CheckStateInvariants(&st, tree.GetStore(), priorEpoch, actor.Balance) acc.WithPrefix("reward: ").AddAll(msgs) rewardSummary = summary case actorCodes[manifest.VerifregKey]: var st verifreg.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := verifreg.CheckStateInvariants(&st, tree.Store, priorEpoch) + summary, msgs := verifreg.CheckStateInvariants(&st, tree.GetStore(), priorEpoch) acc.WithPrefix("verifreg: ").AddAll(msgs) verifregSummary = summary case actorCodes[manifest.DatacapKey]: var st datacap.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := datacap.CheckStateInvariants(&st, tree.Store) + summary, msgs := datacap.CheckStateInvariants(&st, tree.GetStore()) acc.WithPrefix("datacap: ").AddAll(msgs) datacapSummary = summary case actorCodes[manifest.EvmKey]: var st evm.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - msgs := evm.CheckStateInvariants(&st, tree.Store) + msgs := evm.CheckStateInvariants(&st, tree.GetStore()) acc.WithPrefix("evm: ").AddAll(msgs) case actorCodes[manifest.PlaceholderKey]: acc.Require(actor.Head == emptyObjectCid, "Placeholder actor head %v unequal to emptyObjectCid %v", actor.Head, emptyObjectCid) diff --git a/builtin/v12/init/invariants.go b/builtin/v12/init/invariants.go index 220f6f30..e679f6b4 100644 --- a/builtin/v12/init/invariants.go +++ b/builtin/v12/init/invariants.go @@ -17,9 +17,9 @@ type StateSummary struct { } // Checks internal invariants of init state. -func CheckStateInvariants(st *State, tree *builtin.ActorTree, actorCodes map[string]cid.Cid) (*StateSummary, *builtin.MessageAccumulator) { +func CheckStateInvariants(st *State, tree builtin.ActorTree, actorCodes map[string]cid.Cid) (*StateSummary, *builtin.MessageAccumulator) { acc := &builtin.MessageAccumulator{} - store := tree.Store + store := tree.GetStore() acc.Require(len(st.NetworkName) > 0, "network name is empty") acc.Require(st.NextID >= builtin.FirstNonSingletonActorId, "next id %d is too low", st.NextID) diff --git a/builtin/v13/check.go b/builtin/v13/check.go index 7de8fe05..a380de32 100644 --- a/builtin/v13/check.go +++ b/builtin/v13/check.go @@ -29,7 +29,7 @@ import ( // Within this code, Go errors are not expected, but are often converted to messages so that execution // can continue to find more errors rather than fail with no insight. // Only errors thar are particularly troublesome to recover from should propagate as Go errors. -func CheckStateInvariants(tree *builtin.ActorTree, priorEpoch abi.ChainEpoch, actorCodes map[string]cid.Cid) (*builtin.MessageAccumulator, error) { +func CheckStateInvariants(tree builtin.ActorTree, priorEpoch abi.ChainEpoch, actorCodes map[string]cid.Cid) (*builtin.MessageAccumulator, error) { acc := &builtin.MessageAccumulator{} totalFIl := big.Zero() var initSummary *init_.StateSummary @@ -69,7 +69,7 @@ func CheckStateInvariants(tree *builtin.ActorTree, priorEpoch abi.ChainEpoch, ac case actorCodes[manifest.InitKey]: var st init_.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { fmt.Println("init invariant error = ", err) return err } @@ -78,15 +78,15 @@ func CheckStateInvariants(tree *builtin.ActorTree, priorEpoch abi.ChainEpoch, ac initSummary = summary case actorCodes[manifest.CronKey]: var st cron.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := cron.CheckStateInvariants(&st, tree.Store) + summary, msgs := cron.CheckStateInvariants(&st, tree.GetStore()) acc.WithPrefix("cron: ").AddAll(msgs) cronSummary = summary case actorCodes[manifest.AccountKey]: var st account.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } summary, msgs := account.CheckStateInvariants(&st, key) @@ -94,74 +94,74 @@ func CheckStateInvariants(tree *builtin.ActorTree, priorEpoch abi.ChainEpoch, ac accountSummaries = append(accountSummaries, summary) case actorCodes[manifest.PowerKey]: var st power.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := power.CheckStateInvariants(&st, tree.Store) + summary, msgs := power.CheckStateInvariants(&st, tree.GetStore()) acc.WithPrefix("power: ").AddAll(msgs) powerSummary = summary case actorCodes[manifest.MinerKey]: var st miner.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := miner.CheckStateInvariants(&st, tree.Store, actor.Balance) + summary, msgs := miner.CheckStateInvariants(&st, tree.GetStore(), actor.Balance) acc.WithPrefix("miner: ").AddAll(msgs) minerSummaries[key] = summary case actorCodes[manifest.MarketKey]: var st market.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := market.CheckStateInvariants(&st, tree.Store, actor.Balance, priorEpoch) + summary, msgs := market.CheckStateInvariants(&st, tree.GetStore(), actor.Balance, priorEpoch) acc.WithPrefix("market: ").AddAll(msgs) marketSummary = summary case actorCodes[manifest.PaychKey]: var st paych.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := paych.CheckStateInvariants(&st, tree.Store, actor.Balance) + summary, msgs := paych.CheckStateInvariants(&st, tree.GetStore(), actor.Balance) acc.WithPrefix("paych: ").AddAll(msgs) paychSummaries = append(paychSummaries, summary) case actorCodes[manifest.MultisigKey]: var st multisig.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := multisig.CheckStateInvariants(&st, tree.Store) + summary, msgs := multisig.CheckStateInvariants(&st, tree.GetStore()) acc.WithPrefix("multisig: ").AddAll(msgs) multisigSummaries = append(multisigSummaries, summary) case actorCodes[manifest.RewardKey]: var st reward.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := reward.CheckStateInvariants(&st, tree.Store, priorEpoch, actor.Balance) + summary, msgs := reward.CheckStateInvariants(&st, tree.GetStore(), priorEpoch, actor.Balance) acc.WithPrefix("reward: ").AddAll(msgs) rewardSummary = summary case actorCodes[manifest.VerifregKey]: var st verifreg.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := verifreg.CheckStateInvariants(&st, tree.Store, priorEpoch) + summary, msgs := verifreg.CheckStateInvariants(&st, tree.GetStore(), priorEpoch) acc.WithPrefix("verifreg: ").AddAll(msgs) verifregSummary = summary case actorCodes[manifest.DatacapKey]: var st datacap.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := datacap.CheckStateInvariants(&st, tree.Store) + summary, msgs := datacap.CheckStateInvariants(&st, tree.GetStore()) acc.WithPrefix("datacap: ").AddAll(msgs) datacapSummary = summary case actorCodes[manifest.EvmKey]: var st evm.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - msgs := evm.CheckStateInvariants(&st, tree.Store) + msgs := evm.CheckStateInvariants(&st, tree.GetStore()) acc.WithPrefix("evm: ").AddAll(msgs) case actorCodes[manifest.PlaceholderKey]: acc.Require(actor.Head == emptyObjectCid, "Placeholder actor head %v unequal to emptyObjectCid %v", actor.Head, emptyObjectCid) diff --git a/builtin/v13/init/invariants.go b/builtin/v13/init/invariants.go index c949c43d..f9d6a610 100644 --- a/builtin/v13/init/invariants.go +++ b/builtin/v13/init/invariants.go @@ -17,9 +17,9 @@ type StateSummary struct { } // Checks internal invariants of init state. -func CheckStateInvariants(st *State, tree *builtin.ActorTree, actorCodes map[string]cid.Cid) (*StateSummary, *builtin.MessageAccumulator) { +func CheckStateInvariants(st *State, tree builtin.ActorTree, actorCodes map[string]cid.Cid) (*StateSummary, *builtin.MessageAccumulator) { acc := &builtin.MessageAccumulator{} - store := tree.Store + store := tree.GetStore() acc.Require(len(st.NetworkName) > 0, "network name is empty") acc.Require(st.NextID >= builtin.FirstNonSingletonActorId, "next id %d is too low", st.NextID) diff --git a/builtin/v14/check.go b/builtin/v14/check.go index 1522f977..8449b07f 100644 --- a/builtin/v14/check.go +++ b/builtin/v14/check.go @@ -29,7 +29,7 @@ import ( // Within this code, Go errors are not expected, but are often converted to messages so that execution // can continue to find more errors rather than fail with no insight. // Only errors thar are particularly troublesome to recover from should propagate as Go errors. -func CheckStateInvariants(tree *builtin.ActorTree, priorEpoch abi.ChainEpoch, actorCodes map[string]cid.Cid) (*builtin.MessageAccumulator, error) { +func CheckStateInvariants(tree builtin.ActorTree, priorEpoch abi.ChainEpoch, actorCodes map[string]cid.Cid) (*builtin.MessageAccumulator, error) { acc := &builtin.MessageAccumulator{} totalFIl := big.Zero() var initSummary *init_.StateSummary @@ -69,7 +69,7 @@ func CheckStateInvariants(tree *builtin.ActorTree, priorEpoch abi.ChainEpoch, ac case actorCodes[manifest.InitKey]: var st init_.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { fmt.Println("init invariant error = ", err) return err } @@ -78,15 +78,15 @@ func CheckStateInvariants(tree *builtin.ActorTree, priorEpoch abi.ChainEpoch, ac initSummary = summary case actorCodes[manifest.CronKey]: var st cron.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := cron.CheckStateInvariants(&st, tree.Store) + summary, msgs := cron.CheckStateInvariants(&st, tree.GetStore()) acc.WithPrefix("cron: ").AddAll(msgs) cronSummary = summary case actorCodes[manifest.AccountKey]: var st account.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } summary, msgs := account.CheckStateInvariants(&st, key) @@ -94,74 +94,74 @@ func CheckStateInvariants(tree *builtin.ActorTree, priorEpoch abi.ChainEpoch, ac accountSummaries = append(accountSummaries, summary) case actorCodes[manifest.PowerKey]: var st power.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := power.CheckStateInvariants(&st, tree.Store) + summary, msgs := power.CheckStateInvariants(&st, tree.GetStore()) acc.WithPrefix("power: ").AddAll(msgs) powerSummary = summary case actorCodes[manifest.MinerKey]: var st miner.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := miner.CheckStateInvariants(&st, tree.Store, actor.Balance) + summary, msgs := miner.CheckStateInvariants(&st, tree.GetStore(), actor.Balance) acc.WithPrefix("miner: ").AddAll(msgs) minerSummaries[key] = summary case actorCodes[manifest.MarketKey]: var st market.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := market.CheckStateInvariants(&st, tree.Store, actor.Balance, priorEpoch) + summary, msgs := market.CheckStateInvariants(&st, tree.GetStore(), actor.Balance, priorEpoch) acc.WithPrefix("market: ").AddAll(msgs) marketSummary = summary case actorCodes[manifest.PaychKey]: var st paych.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := paych.CheckStateInvariants(&st, tree.Store, actor.Balance) + summary, msgs := paych.CheckStateInvariants(&st, tree.GetStore(), actor.Balance) acc.WithPrefix("paych: ").AddAll(msgs) paychSummaries = append(paychSummaries, summary) case actorCodes[manifest.MultisigKey]: var st multisig.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := multisig.CheckStateInvariants(&st, tree.Store) + summary, msgs := multisig.CheckStateInvariants(&st, tree.GetStore()) acc.WithPrefix("multisig: ").AddAll(msgs) multisigSummaries = append(multisigSummaries, summary) case actorCodes[manifest.RewardKey]: var st reward.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := reward.CheckStateInvariants(&st, tree.Store, priorEpoch, actor.Balance) + summary, msgs := reward.CheckStateInvariants(&st, tree.GetStore(), priorEpoch, actor.Balance) acc.WithPrefix("reward: ").AddAll(msgs) rewardSummary = summary case actorCodes[manifest.VerifregKey]: var st verifreg.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := verifreg.CheckStateInvariants(&st, tree.Store, priorEpoch) + summary, msgs := verifreg.CheckStateInvariants(&st, tree.GetStore(), priorEpoch) acc.WithPrefix("verifreg: ").AddAll(msgs) verifregSummary = summary case actorCodes[manifest.DatacapKey]: var st datacap.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := datacap.CheckStateInvariants(&st, tree.Store) + summary, msgs := datacap.CheckStateInvariants(&st, tree.GetStore()) acc.WithPrefix("datacap: ").AddAll(msgs) datacapSummary = summary case actorCodes[manifest.EvmKey]: var st evm.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - msgs := evm.CheckStateInvariants(&st, tree.Store) + msgs := evm.CheckStateInvariants(&st, tree.GetStore()) acc.WithPrefix("evm: ").AddAll(msgs) case actorCodes[manifest.PlaceholderKey]: acc.Require(actor.Head == emptyObjectCid, "Placeholder actor head %v unequal to emptyObjectCid %v", actor.Head, emptyObjectCid) diff --git a/builtin/v14/init/invariants.go b/builtin/v14/init/invariants.go index 00c62d53..89e4f446 100644 --- a/builtin/v14/init/invariants.go +++ b/builtin/v14/init/invariants.go @@ -17,9 +17,9 @@ type StateSummary struct { } // Checks internal invariants of init state. -func CheckStateInvariants(st *State, tree *builtin.ActorTree, actorCodes map[string]cid.Cid) (*StateSummary, *builtin.MessageAccumulator) { +func CheckStateInvariants(st *State, tree builtin.ActorTree, actorCodes map[string]cid.Cid) (*StateSummary, *builtin.MessageAccumulator) { acc := &builtin.MessageAccumulator{} - store := tree.Store + store := tree.GetStore() acc.Require(len(st.NetworkName) > 0, "network name is empty") acc.Require(st.NextID >= builtin.FirstNonSingletonActorId, "next id %d is too low", st.NextID) diff --git a/builtin/v14/migration/top.go b/builtin/v14/migration/top.go index 943d95bd..d9af95a0 100644 --- a/builtin/v14/migration/top.go +++ b/builtin/v14/migration/top.go @@ -98,7 +98,7 @@ func MigrateStateTree(ctx context.Context, store cbor.IpldStore, newManifestCID // FIP 0085. f090 multisig => unkeyed account actor // Account state now points to id address requiring upgrade to release funds - f090Migration := func(actors *builtin.ActorTree) error { + f090Migration := func(actors builtin.ActorTree) error { f090ID, err := address.NewIDAddress(90) if err != nil { return xerrors.Errorf("failed to construct f090 id addr: %w", err) @@ -122,7 +122,7 @@ func MigrateStateTree(ctx context.Context, store cbor.IpldStore, newManifestCID } f090NewSt := account14.State{Address: f090ID} // State points to ID addr - h, err := actors.Store.Put(ctx, &f090NewSt) + h, err := actors.GetStore().Put(ctx, &f090NewSt) if err != nil { return xerrors.Errorf("failed to write new f090 state: %w", err) } diff --git a/builtin/v8/check.go b/builtin/v8/check.go index 52f8263f..3ffa2471 100644 --- a/builtin/v8/check.go +++ b/builtin/v8/check.go @@ -28,7 +28,7 @@ import ( // Within this code, Go errors are not expected, but are often converted to messages so that execution // can continue to find more errors rather than fail with no insight. // Only errors thar are particularly troublesome to recover from should propagate as Go errors. -func CheckStateInvariants(tree *builtin.ActorTree, priorEpoch abi.ChainEpoch, actorCodes map[string]cid.Cid) (*builtin.MessageAccumulator, error) { +func CheckStateInvariants(tree builtin.ActorTree, priorEpoch abi.ChainEpoch, actorCodes map[string]cid.Cid) (*builtin.MessageAccumulator, error) { acc := &builtin.MessageAccumulator{} totalFIl := big.Zero() var initSummary *init_.StateSummary @@ -54,23 +54,23 @@ func CheckStateInvariants(tree *builtin.ActorTree, priorEpoch abi.ChainEpoch, ac case actorCodes[manifest.InitKey]: var st init_.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := init_.CheckStateInvariants(&st, tree.Store) + summary, msgs := init_.CheckStateInvariants(&st, tree.GetStore()) acc.WithPrefix("init: ").AddAll(msgs) initSummary = summary case actorCodes[manifest.CronKey]: var st cron.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := cron.CheckStateInvariants(&st, tree.Store) + summary, msgs := cron.CheckStateInvariants(&st, tree.GetStore()) acc.WithPrefix("cron: ").AddAll(msgs) cronSummary = summary case actorCodes[manifest.AccountKey]: var st account.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } summary, msgs := account.CheckStateInvariants(&st, key) @@ -78,58 +78,58 @@ func CheckStateInvariants(tree *builtin.ActorTree, priorEpoch abi.ChainEpoch, ac accountSummaries = append(accountSummaries, summary) case actorCodes[manifest.PowerKey]: var st power.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := power.CheckStateInvariants(&st, tree.Store) + summary, msgs := power.CheckStateInvariants(&st, tree.GetStore()) acc.WithPrefix("power: ").AddAll(msgs) powerSummary = summary case actorCodes[manifest.MinerKey]: var st miner.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := miner.CheckStateInvariants(&st, tree.Store, actor.Balance) + summary, msgs := miner.CheckStateInvariants(&st, tree.GetStore(), actor.Balance) acc.WithPrefix("miner: ").AddAll(msgs) minerSummaries[key] = summary case actorCodes[manifest.MarketKey]: var st market.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := market.CheckStateInvariants(&st, tree.Store, actor.Balance, priorEpoch) + summary, msgs := market.CheckStateInvariants(&st, tree.GetStore(), actor.Balance, priorEpoch) acc.WithPrefix("market: ").AddAll(msgs) marketSummary = summary case actorCodes[manifest.PaychKey]: var st paych.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := paych.CheckStateInvariants(&st, tree.Store, actor.Balance) + summary, msgs := paych.CheckStateInvariants(&st, tree.GetStore(), actor.Balance) acc.WithPrefix("paych: ").AddAll(msgs) paychSummaries = append(paychSummaries, summary) case actorCodes[manifest.MultisigKey]: var st multisig.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := multisig.CheckStateInvariants(&st, tree.Store) + summary, msgs := multisig.CheckStateInvariants(&st, tree.GetStore()) acc.WithPrefix("multisig: ").AddAll(msgs) multisigSummaries = append(multisigSummaries, summary) case actorCodes[manifest.RewardKey]: var st reward.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := reward.CheckStateInvariants(&st, tree.Store, priorEpoch, actor.Balance) + summary, msgs := reward.CheckStateInvariants(&st, tree.GetStore(), priorEpoch, actor.Balance) acc.WithPrefix("reward: ").AddAll(msgs) rewardSummary = summary case actorCodes[manifest.VerifregKey]: var st verifreg.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := verifreg.CheckStateInvariants(&st, tree.Store) + summary, msgs := verifreg.CheckStateInvariants(&st, tree.GetStore()) acc.WithPrefix("verifreg: ").AddAll(msgs) verifregSummary = summary default: diff --git a/builtin/v9/check.go b/builtin/v9/check.go index ef308de6..a9942507 100644 --- a/builtin/v9/check.go +++ b/builtin/v9/check.go @@ -30,7 +30,7 @@ import ( // Within this code, Go errors are not expected, but are often converted to messages so that execution // can continue to find more errors rather than fail with no insight. // Only errors thar are particularly troublesome to recover from should propagate as Go errors. -func CheckStateInvariants(tree *builtin.ActorTree, priorEpoch abi.ChainEpoch, actorCodes map[string]cid.Cid) (*builtin.MessageAccumulator, error) { +func CheckStateInvariants(tree builtin.ActorTree, priorEpoch abi.ChainEpoch, actorCodes map[string]cid.Cid) (*builtin.MessageAccumulator, error) { acc := &builtin.MessageAccumulator{} totalFIl := big.Zero() var initSummary *init_.StateSummary @@ -57,23 +57,23 @@ func CheckStateInvariants(tree *builtin.ActorTree, priorEpoch abi.ChainEpoch, ac case actorCodes[manifest.InitKey]: var st init_.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := init_.CheckStateInvariants(&st, tree.Store) + summary, msgs := init_.CheckStateInvariants(&st, tree.GetStore()) acc.WithPrefix("init: ").AddAll(msgs) initSummary = summary case actorCodes[manifest.CronKey]: var st cron.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := cron.CheckStateInvariants(&st, tree.Store) + summary, msgs := cron.CheckStateInvariants(&st, tree.GetStore()) acc.WithPrefix("cron: ").AddAll(msgs) cronSummary = summary case actorCodes[manifest.AccountKey]: var st account.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } summary, msgs := account.CheckStateInvariants(&st, key) @@ -81,66 +81,66 @@ func CheckStateInvariants(tree *builtin.ActorTree, priorEpoch abi.ChainEpoch, ac accountSummaries = append(accountSummaries, summary) case actorCodes[manifest.PowerKey]: var st power.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := power.CheckStateInvariants(&st, tree.Store) + summary, msgs := power.CheckStateInvariants(&st, tree.GetStore()) acc.WithPrefix("power: ").AddAll(msgs) powerSummary = summary case actorCodes[manifest.MinerKey]: var st miner.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := miner.CheckStateInvariants(&st, tree.Store, actor.Balance) + summary, msgs := miner.CheckStateInvariants(&st, tree.GetStore(), actor.Balance) acc.WithPrefix("miner: ").AddAll(msgs) minerSummaries[key] = summary case actorCodes[manifest.MarketKey]: var st market.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := market.CheckStateInvariants(&st, tree.Store, actor.Balance, priorEpoch) + summary, msgs := market.CheckStateInvariants(&st, tree.GetStore(), actor.Balance, priorEpoch) acc.WithPrefix("market: ").AddAll(msgs) marketSummary = summary case actorCodes[manifest.PaychKey]: var st paych.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := paych.CheckStateInvariants(&st, tree.Store, actor.Balance) + summary, msgs := paych.CheckStateInvariants(&st, tree.GetStore(), actor.Balance) acc.WithPrefix("paych: ").AddAll(msgs) paychSummaries = append(paychSummaries, summary) case actorCodes[manifest.MultisigKey]: var st multisig.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := multisig.CheckStateInvariants(&st, tree.Store) + summary, msgs := multisig.CheckStateInvariants(&st, tree.GetStore()) acc.WithPrefix("multisig: ").AddAll(msgs) multisigSummaries = append(multisigSummaries, summary) case actorCodes[manifest.RewardKey]: var st reward.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := reward.CheckStateInvariants(&st, tree.Store, priorEpoch, actor.Balance) + summary, msgs := reward.CheckStateInvariants(&st, tree.GetStore(), priorEpoch, actor.Balance) acc.WithPrefix("reward: ").AddAll(msgs) rewardSummary = summary case actorCodes[manifest.VerifregKey]: var st verifreg.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := verifreg.CheckStateInvariants(&st, tree.Store, priorEpoch) + summary, msgs := verifreg.CheckStateInvariants(&st, tree.GetStore(), priorEpoch) acc.WithPrefix("verifreg: ").AddAll(msgs) verifregSummary = summary case actorCodes[manifest.DatacapKey]: var st datacap.State - if err := tree.Store.Get(tree.Store.Context(), actor.Head, &st); err != nil { + if err := tree.GetStore().Get(tree.GetStore().Context(), actor.Head, &st); err != nil { return err } - summary, msgs := datacap.CheckStateInvariants(&st, tree.Store) + summary, msgs := datacap.CheckStateInvariants(&st, tree.GetStore()) acc.WithPrefix("datacap: ").AddAll(msgs) datacapSummary = summary default: diff --git a/builtin/v9/migration/test/util.go b/builtin/v9/migration/test/util.go index e755c024..868ad836 100644 --- a/builtin/v9/migration/test/util.go +++ b/builtin/v9/migration/test/util.go @@ -139,7 +139,7 @@ func makeInputTree(ctx context.Context, t *testing.T, store adt.Store) cid.Cid { return root } -func initializeActor(ctx context.Context, t testing.TB, tree *builtin.ActorTree, store adt.Store, state cbor.Marshaler, code cid.Cid, a address.Address, balance abi.TokenAmount) { +func initializeActor(ctx context.Context, t testing.TB, tree builtin.ActorTree, store adt.Store, state cbor.Marshaler, code cid.Cid, a address.Address, balance abi.TokenAmount) { stateCID, err := store.Put(ctx, state) require.NoError(t, err) actor := &builtin.ActorV4{ diff --git a/migration/runner.go b/migration/runner.go index 2a614aa1..067fdb42 100644 --- a/migration/runner.go +++ b/migration/runner.go @@ -16,7 +16,7 @@ import ( "golang.org/x/xerrors" ) -func RunMigration(ctx context.Context, cfg Config, cache MigrationCache, store cbor.IpldStore, log Logger, actorsIn *builtin.ActorTree, migrations map[cid.Cid]ActorMigration) (*builtin.ActorTree, error) { +func RunMigration(ctx context.Context, cfg Config, cache MigrationCache, store cbor.IpldStore, log Logger, actorsIn builtin.ActorTree, migrations map[cid.Cid]ActorMigration) (builtin.ActorTree, error) { startTime := time.Now() deferred := map[address.Address]struct{}{} From 3308f25136e7ab3a96d59c0307844db36095f089 Mon Sep 17 00:00:00 2001 From: Rod Vagg Date: Sat, 3 Aug 2024 18:29:30 +1000 Subject: [PATCH 2/2] feat!: LegacyActorTree vs ActorTree, use HAMT v4 with generics Ref: https://github.com/filecoin-project/go-hamt-ipld/pull/122 --- builtin/actor_tree.go | 175 ++++++++++++++++++-- builtin/v10/migration/top.go | 4 +- builtin/v11/migration/top.go | 2 +- builtin/v12/migration/top.go | 2 +- builtin/v13/migration/top.go | 2 +- builtin/v8/check.go | 2 +- builtin/v9/check.go | 2 +- builtin/v9/migration/test/migration_test.go | 4 +- builtin/v9/migration/test/miner_test.go | 8 +- builtin/v9/migration/test/util.go | 4 +- builtin/v9/migration/top.go | 4 +- go.mod | 13 +- go.sum | 27 +-- 13 files changed, 197 insertions(+), 52 deletions(-) diff --git a/builtin/actor_tree.go b/builtin/actor_tree.go index b4565317..d063e73f 100644 --- a/builtin/actor_tree.go +++ b/builtin/actor_tree.go @@ -1,17 +1,20 @@ package builtin import ( + "crypto/sha256" + "github.com/filecoin-project/go-address" + hamt "github.com/filecoin-project/go-hamt-ipld/v4" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/big" - "github.com/filecoin-project/go-state-types/builtin/v8/util/adt" + "github.com/filecoin-project/go-state-types/builtin/v14/util/adt" "github.com/ipfs/go-cid" "golang.org/x/xerrors" ) -type ActorTree interface { +type LegacyActorTree interface { GetStore() adt.Store - + GetMap() *adt.Map Flush() (cid.Cid, error) GetActorV4(addr address.Address) (*ActorV4, bool, error) GetActorV5(addr address.Address) (*ActorV5, bool, error) @@ -22,7 +25,19 @@ type ActorTree interface { ForEachKey(fn func(addr address.Address) error) error } -var _ ActorTree = (*actorTree)(nil) +type ActorTree interface { + GetStore() adt.Store + Flush() (cid.Cid, error) + GetActorV5(addr address.Address) (*ActorV5, bool, error) + SetActorV5(addr address.Address, actor *ActorV5) error + ForEachV5(fn func(addr address.Address, actor *ActorV5) error) error + ForEachKey(fn func(addr address.Address) error) error +} + +var _ LegacyActorTree = (*legacyActorTree)(nil) +var _ ActorTree = (*legacyActorTree)(nil) + +// var _ ActorTree = (*actorTree)(nil) // Value type of the top level of the state tree. // Represents the on-chain state of a single actor. @@ -43,47 +58,173 @@ type ActorV5 struct { DelegatedAddress *address.Address // Delegated (f4) actor address } +func (a *ActorV5) Equals(o *ActorV5) bool { + if a == nil && o == nil { + return true + } + if a == nil || o == nil { + return false + } + return a.Code == o.Code && + a.Head == o.Head && + a.CallSeqNum == o.CallSeqNum && + a.Balance.Equals(o.Balance) && + ((a.DelegatedAddress == nil && o.DelegatedAddress == nil) || (a.DelegatedAddress != nil && o.DelegatedAddress != nil && *a.DelegatedAddress == *o.DelegatedAddress)) +} + +func (a *ActorV5) New() *ActorV5 { + return new(ActorV5) +} + // A specialization of a map of ID-addresses to actor heads. type actorTree struct { + Map *hamt.Node[*ActorV5] + LastRoot cid.Cid + Store adt.Store +} + +// Initializes a new, empty state tree backed by a store. +func NewTree(store adt.Store) (ActorTree, error) { + nd, err := hamt.NewNode[*ActorV5]( + store, + hamt.UseHashFunction(func(input []byte) []byte { + res := sha256.Sum256(input) + return res[:] + }), + hamt.UseTreeBitWidth(DefaultHamtBitwidth), + ) + if err != nil { + return nil, err + } + return &actorTree{ + Map: nd, + LastRoot: cid.Undef, + Store: store, + }, nil +} + +// Loads a tree from a root CID and store. +func LoadTree(store adt.Store, root cid.Cid) (ActorTree, error) { + nd, err := hamt.LoadNode[*ActorV5]( + store.Context(), + store, + root, + hamt.UseHashFunction(func(input []byte) []byte { + res := sha256.Sum256(input) + return res[:] + }), + hamt.UseTreeBitWidth(DefaultHamtBitwidth), + ) + if err != nil { + return nil, err + } + return &actorTree{ + Map: nd, + LastRoot: root, + Store: store, + }, nil +} + +func (t *actorTree) GetStore() adt.Store { + return t.Store +} + +// Writes the tree root node to the store, and returns its CID. +func (t *actorTree) Flush() (cid.Cid, error) { + if err := t.Map.Flush(t.Store.Context()); err != nil { + return cid.Undef, xerrors.Errorf("failed to flush map root: %w", err) + } + c, err := t.Store.Put(t.Store.Context(), t.Map) + if err != nil { + return cid.Undef, xerrors.Errorf("writing map root object: %w", err) + } + t.LastRoot = c + return c, nil +} + +func (t *actorTree) GetActorV5(addr address.Address) (*ActorV5, bool, error) { + if addr.Protocol() != address.ID { + return nil, false, xerrors.Errorf("non-ID address %v invalid as actor key", addr) + } + if addr.Protocol() != address.ID { + return nil, false, xerrors.Errorf("non-ID address %v invalid as actor key", addr) + } + return t.Map.Find(t.Store.Context(), abi.AddrKey(addr).Key()) +} + +func (t *actorTree) SetActorV5(addr address.Address, actor *ActorV5) error { + if addr.Protocol() != address.ID { + return xerrors.Errorf("non-ID address %v invalid as actor key", addr) + } + return t.Map.Set(t.Store.Context(), abi.AddrKey(addr).Key(), actor) +} + +func (t *actorTree) ForEachV5(fn func(addr address.Address, actor *ActorV5) error) error { + return t.Map.ForEach(t.Store.Context(), func(key string, val *ActorV5) error { + addr, err := address.NewFromBytes([]byte(key)) + if err != nil { + return err + } + return fn(addr, val) + }) +} + +// Traverses all keys in the tree, without decoding the actor states. +func (t *actorTree) ForEachKey(fn func(addr address.Address) error) error { + return t.Map.ForEach(t.Store.Context(), func(key string, _ *ActorV5) error { + addr, err := address.NewFromBytes([]byte(key)) + if err != nil { + return err + } + return fn(addr) + }) +} + +// A specialization of a map of ID-addresses to actor heads. +type legacyActorTree struct { Map *adt.Map Store adt.Store } // Initializes a new, empty state tree backed by a store. -func NewTree(store adt.Store) (ActorTree, error) { +func NewLegacyTree(store adt.Store) (LegacyActorTree, error) { emptyMap, err := adt.MakeEmptyMap(store, DefaultHamtBitwidth) if err != nil { return nil, err } - return &actorTree{ + return &legacyActorTree{ Map: emptyMap, Store: store, }, nil } // Loads a tree from a root CID and store. -func LoadTree(s adt.Store, r cid.Cid) (ActorTree, error) { +func LoadLegacyTree(s adt.Store, r cid.Cid) (LegacyActorTree, error) { m, err := adt.AsMap(s, r, DefaultHamtBitwidth) if err != nil { return nil, err } - return &actorTree{ + return &legacyActorTree{ Map: m, Store: s, }, nil } -func (t *actorTree) GetStore() adt.Store { +func (t *legacyActorTree) GetStore() adt.Store { return t.Store } +func (t *legacyActorTree) GetMap() *adt.Map { + return t.Map +} + // Writes the tree root node to the store, and returns its CID. -func (t *actorTree) Flush() (cid.Cid, error) { +func (t *legacyActorTree) Flush() (cid.Cid, error) { return t.Map.Root() } // Loads the state associated with an address. -func (t *actorTree) GetActorV4(addr address.Address) (*ActorV4, bool, error) { +func (t *legacyActorTree) GetActorV4(addr address.Address) (*ActorV4, bool, error) { if addr.Protocol() != address.ID { return nil, false, xerrors.Errorf("non-ID address %v invalid as actor key", addr) } @@ -92,7 +233,7 @@ func (t *actorTree) GetActorV4(addr address.Address) (*ActorV4, bool, error) { return &actor, found, err } -func (t *actorTree) GetActorV5(addr address.Address) (*ActorV5, bool, error) { +func (t *legacyActorTree) GetActorV5(addr address.Address) (*ActorV5, bool, error) { if addr.Protocol() != address.ID { return nil, false, xerrors.Errorf("non-ID address %v invalid as actor key", addr) } @@ -102,14 +243,14 @@ func (t *actorTree) GetActorV5(addr address.Address) (*ActorV5, bool, error) { } // Sets the state associated with an address, overwriting if it already present. -func (t *actorTree) SetActorV4(addr address.Address, actor *ActorV4) error { +func (t *legacyActorTree) SetActorV4(addr address.Address, actor *ActorV4) error { if addr.Protocol() != address.ID { return xerrors.Errorf("non-ID address %v invalid as actor key", addr) } return t.Map.Put(abi.AddrKey(addr), actor) } -func (t *actorTree) SetActorV5(addr address.Address, actor *ActorV5) error { +func (t *legacyActorTree) SetActorV5(addr address.Address, actor *ActorV5) error { if addr.Protocol() != address.ID { return xerrors.Errorf("non-ID address %v invalid as actor key", addr) } @@ -117,7 +258,7 @@ func (t *actorTree) SetActorV5(addr address.Address, actor *ActorV5) error { } // Traverses all entries in the tree. -func (t *actorTree) ForEachV4(fn func(addr address.Address, actor *ActorV4) error) error { +func (t *legacyActorTree) ForEachV4(fn func(addr address.Address, actor *ActorV4) error) error { var val ActorV4 return t.Map.ForEach(&val, func(key string) error { addr, err := address.NewFromBytes([]byte(key)) @@ -128,7 +269,7 @@ func (t *actorTree) ForEachV4(fn func(addr address.Address, actor *ActorV4) erro }) } -func (t *actorTree) ForEachV5(fn func(addr address.Address, actor *ActorV5) error) error { +func (t *legacyActorTree) ForEachV5(fn func(addr address.Address, actor *ActorV5) error) error { var val ActorV5 return t.Map.ForEach(&val, func(key string) error { addr, err := address.NewFromBytes([]byte(key)) @@ -140,7 +281,7 @@ func (t *actorTree) ForEachV5(fn func(addr address.Address, actor *ActorV5) erro } // Traverses all keys in the tree, without decoding the actor states. -func (t *actorTree) ForEachKey(fn func(addr address.Address) error) error { +func (t *legacyActorTree) ForEachKey(fn func(addr address.Address) error) error { return t.Map.ForEach(nil, func(key string) error { addr, err := address.NewFromBytes([]byte(key)) if err != nil { diff --git a/builtin/v10/migration/top.go b/builtin/v10/migration/top.go index 7713ca93..71705cb9 100644 --- a/builtin/v10/migration/top.go +++ b/builtin/v10/migration/top.go @@ -33,11 +33,11 @@ func MigrateStateTree(ctx context.Context, store cbor.IpldStore, newManifestCID adtStore := adt9.WrapStore(ctx, store) // Load input and output state trees - actorsIn, err := builtin.LoadTree(adtStore, actorsRootIn) + actorsIn, err := builtin.LoadLegacyTree(adtStore, actorsRootIn) if err != nil { return cid.Undef, xerrors.Errorf("loading state tree: %w", err) } - actorsOut, err := builtin.NewTree(adtStore) + actorsOut, err := builtin.NewLegacyTree(adtStore) if err != nil { return cid.Undef, xerrors.Errorf("creating new state tree: %w", err) } diff --git a/builtin/v11/migration/top.go b/builtin/v11/migration/top.go index fb456e38..12fb5aea 100644 --- a/builtin/v11/migration/top.go +++ b/builtin/v11/migration/top.go @@ -26,7 +26,7 @@ func MigrateStateTree(ctx context.Context, store cbor.IpldStore, newManifestCID adtStore := adt10.WrapStore(ctx, store) // Load input and output state trees - actorsIn, err := builtin.LoadTree(adtStore, actorsRootIn) + actorsIn, err := builtin.LoadLegacyTree(adtStore, actorsRootIn) if err != nil { return cid.Undef, xerrors.Errorf("loading state tree: %w", err) } diff --git a/builtin/v12/migration/top.go b/builtin/v12/migration/top.go index b6344cbd..55084ccb 100644 --- a/builtin/v12/migration/top.go +++ b/builtin/v12/migration/top.go @@ -25,7 +25,7 @@ func MigrateStateTree(ctx context.Context, store cbor.IpldStore, newManifestCID adtStore := adt11.WrapStore(ctx, store) // Load input and output state trees - actorsIn, err := builtin.LoadTree(adtStore, actorsRootIn) + actorsIn, err := builtin.LoadLegacyTree(adtStore, actorsRootIn) if err != nil { return cid.Undef, xerrors.Errorf("loading state tree: %w", err) } diff --git a/builtin/v13/migration/top.go b/builtin/v13/migration/top.go index 96e68077..325f1a23 100644 --- a/builtin/v13/migration/top.go +++ b/builtin/v13/migration/top.go @@ -27,7 +27,7 @@ func MigrateStateTree(ctx context.Context, store cbor.IpldStore, newManifestCID adtStore := adt13.WrapStore(ctx, store) // Load input and output state trees - actorsIn, err := builtin.LoadTree(adtStore, actorsRootIn) + actorsIn, err := builtin.LoadLegacyTree(adtStore, actorsRootIn) if err != nil { return cid.Undef, xerrors.Errorf("loading state tree: %w", err) } diff --git a/builtin/v8/check.go b/builtin/v8/check.go index 3ffa2471..d09124c3 100644 --- a/builtin/v8/check.go +++ b/builtin/v8/check.go @@ -28,7 +28,7 @@ import ( // Within this code, Go errors are not expected, but are often converted to messages so that execution // can continue to find more errors rather than fail with no insight. // Only errors thar are particularly troublesome to recover from should propagate as Go errors. -func CheckStateInvariants(tree builtin.ActorTree, priorEpoch abi.ChainEpoch, actorCodes map[string]cid.Cid) (*builtin.MessageAccumulator, error) { +func CheckStateInvariants(tree builtin.LegacyActorTree, priorEpoch abi.ChainEpoch, actorCodes map[string]cid.Cid) (*builtin.MessageAccumulator, error) { acc := &builtin.MessageAccumulator{} totalFIl := big.Zero() var initSummary *init_.StateSummary diff --git a/builtin/v9/check.go b/builtin/v9/check.go index a9942507..07eb6b66 100644 --- a/builtin/v9/check.go +++ b/builtin/v9/check.go @@ -30,7 +30,7 @@ import ( // Within this code, Go errors are not expected, but are often converted to messages so that execution // can continue to find more errors rather than fail with no insight. // Only errors thar are particularly troublesome to recover from should propagate as Go errors. -func CheckStateInvariants(tree builtin.ActorTree, priorEpoch abi.ChainEpoch, actorCodes map[string]cid.Cid) (*builtin.MessageAccumulator, error) { +func CheckStateInvariants(tree builtin.LegacyActorTree, priorEpoch abi.ChainEpoch, actorCodes map[string]cid.Cid) (*builtin.MessageAccumulator, error) { acc := &builtin.MessageAccumulator{} totalFIl := big.Zero() var initSummary *init_.StateSummary diff --git a/builtin/v9/migration/test/migration_test.go b/builtin/v9/migration/test/migration_test.go index e5e60845..82b815a3 100644 --- a/builtin/v9/migration/test/migration_test.go +++ b/builtin/v9/migration/test/migration_test.go @@ -26,7 +26,7 @@ func TestMigration(t *testing.T) { startRoot := makeInputTree(ctx, t, adtStore) - oldStateTree, err := builtin.LoadTree(adtStore, startRoot) + oldStateTree, err := builtin.LoadLegacyTree(adtStore, startRoot) require.NoError(t, err) oldSystemActor, found, err := oldStateTree.GetActorV4(builtin.SystemActorAddr) @@ -60,7 +60,7 @@ func TestMigration(t *testing.T) { // check that the system actor state was correctly updated - newStateTree, err := builtin.LoadTree(adtStore, cacheRoot) + newStateTree, err := builtin.LoadLegacyTree(adtStore, cacheRoot) require.NoError(t, err) newSystemActor, found, err := newStateTree.GetActorV4(builtin.SystemActorAddr) diff --git a/builtin/v9/migration/test/miner_test.go b/builtin/v9/migration/test/miner_test.go index 49de35e9..fc0b29a4 100644 --- a/builtin/v9/migration/test/miner_test.go +++ b/builtin/v9/migration/test/miner_test.go @@ -32,7 +32,7 @@ func TestMinerMigration(t *testing.T) { startRoot := makeInputTree(ctx, t, adtStore) - oldStateTree, err := builtin.LoadTree(adtStore, startRoot) + oldStateTree, err := builtin.LoadLegacyTree(adtStore, startRoot) require.NoError(t, err) oldSystemActor, found, err := oldStateTree.GetActorV4(builtin.SystemActorAddr) @@ -237,7 +237,7 @@ func TestMinerMigration(t *testing.T) { // check that the actor states were correctly updated - newStateTree, err := builtin.LoadTree(adtStore, cacheRoot) + newStateTree, err := builtin.LoadLegacyTree(adtStore, cacheRoot) require.NoError(t, err) // miner 1 is just empty precommits @@ -324,7 +324,7 @@ func TestFip0029MinerMigration(t *testing.T) { startRoot := makeInputTree(ctx, t, adtStore) - oldStateTree, err := builtin.LoadTree(adtStore, startRoot) + oldStateTree, err := builtin.LoadLegacyTree(adtStore, startRoot) require.NoError(t, err) oldSystemActor, found, err := oldStateTree.GetActorV4(builtin.SystemActorAddr) @@ -386,7 +386,7 @@ func TestFip0029MinerMigration(t *testing.T) { // check that the actor states were correctly updated - newStateTree, err := builtin.LoadTree(adtStore, cacheRoot) + newStateTree, err := builtin.LoadLegacyTree(adtStore, cacheRoot) require.NoError(t, err) newMinerActor, ok, err := newStateTree.GetActorV4(addr) diff --git a/builtin/v9/migration/test/util.go b/builtin/v9/migration/test/util.go index 868ad836..23437da8 100644 --- a/builtin/v9/migration/test/util.go +++ b/builtin/v9/migration/test/util.go @@ -67,7 +67,7 @@ func makeTestManifest(t *testing.T, store adt.Store, prefix string) (cid.Cid, ci } func makeInputTree(ctx context.Context, t *testing.T, store adt.Store) cid.Cid { - tree, err := builtin.NewTree(store) + tree, err := builtin.NewLegacyTree(store) require.NoError(t, err, "failed to create empty actors tree") manifestCid, manifestDataCid := makeTestManifest(t, store, "fil/8/") @@ -139,7 +139,7 @@ func makeInputTree(ctx context.Context, t *testing.T, store adt.Store) cid.Cid { return root } -func initializeActor(ctx context.Context, t testing.TB, tree builtin.ActorTree, store adt.Store, state cbor.Marshaler, code cid.Cid, a address.Address, balance abi.TokenAmount) { +func initializeActor(ctx context.Context, t testing.TB, tree builtin.LegacyActorTree, store adt.Store, state cbor.Marshaler, code cid.Cid, a address.Address, balance abi.TokenAmount) { stateCID, err := store.Put(ctx, state) require.NoError(t, err) actor := &builtin.ActorV4{ diff --git a/builtin/v9/migration/top.go b/builtin/v9/migration/top.go index 860fe4a5..b11b4934 100644 --- a/builtin/v9/migration/top.go +++ b/builtin/v9/migration/top.go @@ -101,11 +101,11 @@ func MigrateStateTree(ctx context.Context, store cbor.IpldStore, newManifestCID } // Load input and output state trees - actorsIn, err := builtin.LoadTree(adtStore, actorsRootIn) + actorsIn, err := builtin.LoadLegacyTree(adtStore, actorsRootIn) if err != nil { return cid.Undef, err } - actorsOut, err := builtin.NewTree(adtStore) + actorsOut, err := builtin.NewLegacyTree(adtStore) if err != nil { return cid.Undef, err } diff --git a/go.mod b/go.mod index 714de735..9b4dbe9a 100644 --- a/go.mod +++ b/go.mod @@ -10,6 +10,7 @@ require ( github.com/filecoin-project/go-bitfield v0.2.4 github.com/filecoin-project/go-commp-utils/nonffi v0.0.0-20220905160352-62059082a837 github.com/filecoin-project/go-hamt-ipld/v3 v3.4.0 + github.com/filecoin-project/go-hamt-ipld/v4 v4.0.0-20240803092811-1295558c39ec github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-ipld-cbor v0.1.0 @@ -30,16 +31,16 @@ require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/filecoin-project/go-commp-utils v0.1.3 // indirect github.com/filecoin-project/go-fil-commcid v0.1.0 // indirect - github.com/ipfs/go-ipfs-util v0.0.2 // indirect - github.com/ipfs/go-ipld-format v0.5.0 // indirect - github.com/klauspost/cpuid/v2 v2.2.3 // indirect + github.com/ipfs/go-ipfs-util v0.0.3 // indirect + github.com/ipfs/go-ipld-format v0.6.0 // indirect + github.com/klauspost/cpuid/v2 v2.2.8 // indirect github.com/mr-tron/base58 v1.2.0 // indirect - github.com/multiformats/go-base32 v0.0.3 // indirect - github.com/multiformats/go-base36 v0.1.0 // indirect + github.com/multiformats/go-base32 v0.1.0 // indirect + github.com/multiformats/go-base36 v0.2.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polydawn/refmt v0.89.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect golang.org/x/sys v0.22.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - lukechampine.com/blake3 v1.1.6 // indirect + lukechampine.com/blake3 v1.3.0 // indirect ) diff --git a/go.sum b/go.sum index 6d84febf..e63e1f22 100644 --- a/go.sum +++ b/go.sum @@ -26,6 +26,8 @@ github.com/filecoin-project/go-fil-commcid v0.1.0 h1:3R4ds1A9r6cr8mvZBfMYxTS88Oq github.com/filecoin-project/go-fil-commcid v0.1.0/go.mod h1:Eaox7Hvus1JgPrL5+M3+h7aSPHc0cVqpSxA+TxIEpZQ= github.com/filecoin-project/go-hamt-ipld/v3 v3.4.0 h1:nYs6OPUF8KbZ3E8o9p9HJnQaE8iugjHR5WYVMcicDJc= github.com/filecoin-project/go-hamt-ipld/v3 v3.4.0/go.mod h1:s0qiHRhFyrgW0SvdQMSJFQxNa4xEIG5XvqCBZUEgcbc= +github.com/filecoin-project/go-hamt-ipld/v4 v4.0.0-20240803092811-1295558c39ec h1:iuCyqify0N6O2OJ9WuA14qLg04ICPCL0iZmiwyzcmHI= +github.com/filecoin-project/go-hamt-ipld/v4 v4.0.0-20240803092811-1295558c39ec/go.mod h1:yYwUIWtxrMOCoMKVmsKCh7eXurFdyaFtQL6aAhVYb34= github.com/filecoin-project/go-padreader v0.0.0-20200903213702-ed5fae088b20/go.mod h1:mPn+LRRd5gEKNAtc+r3ScpW2JRU/pj4NBKdADYWHiak= github.com/filecoin-project/go-state-types v0.0.0-20200903145444-247639ffa6ad/go.mod h1:IQ0MBPnonv35CJHtWSN3YY1Hz2gkPru1Q9qoaYLxx9I= github.com/filecoin-project/go-state-types v0.0.0-20200904021452-1883f36ca2f4/go.mod h1:IQ0MBPnonv35CJHtWSN3YY1Hz2gkPru1Q9qoaYLxx9I= @@ -59,15 +61,15 @@ github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= github.com/ipfs/go-cid v0.4.1/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk= github.com/ipfs/go-hamt-ipld v0.1.1/go.mod h1:1EZCr2v0jlCnhpa+aZ0JZYp8Tt2w16+JJOAVz17YcDk= github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= -github.com/ipfs/go-ipfs-util v0.0.2 h1:59Sswnk1MFaiq+VcaknX7aYEyGyGDAA73ilhEK2POp8= -github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ= +github.com/ipfs/go-ipfs-util v0.0.3 h1:2RFdGez6bu2ZlZdI+rWfIdbQb1KudQp3VGwPtdNCmE0= +github.com/ipfs/go-ipfs-util v0.0.3/go.mod h1:LHzG1a0Ig4G+iZ26UUOMjHd+lfM84LZCrn17xAKWBvs= github.com/ipfs/go-ipld-cbor v0.0.4/go.mod h1:BkCduEx3XBCO6t2Sfo5BaHzuok7hbhdMm9Oh8B2Ftq4= github.com/ipfs/go-ipld-cbor v0.1.0 h1:dx0nS0kILVivGhfWuB6dUpMa/LAwElHPw1yOGYopoYs= github.com/ipfs/go-ipld-cbor v0.1.0/go.mod h1:U2aYlmVrJr2wsUBU67K4KgepApSZddGRDWBYR0H4sCk= github.com/ipfs/go-ipld-format v0.0.1/go.mod h1:kyJtbkDALmFHv3QR6et67i35QzO3S0dCDnkOJhcZkms= github.com/ipfs/go-ipld-format v0.0.2/go.mod h1:4B6+FM2u9OJ9zCV+kSbgFAZlOrv1Hqbf0INGQgiKf9k= -github.com/ipfs/go-ipld-format v0.5.0 h1:WyEle9K96MSrvr47zZHKKcDxJ/vlpET6PSiQsAFO+Ds= -github.com/ipfs/go-ipld-format v0.5.0/go.mod h1:ImdZqJQaEouMjCvqCe0ORUS+uoBmf7Hf+EO/jh+nk3M= +github.com/ipfs/go-ipld-format v0.6.0 h1:VEJlA2kQ3LqFSIm5Vu6eIlSxD/Ze90xtc4Meten1F5U= +github.com/ipfs/go-ipld-format v0.6.0/go.mod h1:g4QVMTn3marU3qXchwjpKPKgJv+zF+OlaKMyhJ4LHPg= github.com/ipfs/go-log v1.0.4 h1:6nLQdX4W8P9yZZFH7mO+X/PzjN8Laozm/lMJ6esdgzY= github.com/ipfs/go-log v1.0.4/go.mod h1:oDCg2FkjogeFOhqqb+N39l2RpTNPL6F/StPkB3kPgcs= github.com/ipfs/go-log/v2 v2.0.5/go.mod h1:eZs4Xt4ZUJQFM3DlanGhy7TkwwawCZcSByscwkWG+dw= @@ -82,9 +84,8 @@ github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7 github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.3 h1:sxCkb+qR91z4vsqw4vGGZlDgPz3G7gjaLyK3V8y70BU= -github.com/klauspost/cpuid/v2 v2.2.3/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= +github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM= +github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= @@ -104,10 +105,12 @@ github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjW github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= -github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI= github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= -github.com/multiformats/go-base36 v0.1.0 h1:JR6TyF7JjGd3m6FbLU2cOxhC0Li8z8dLNGQ89tUg4F4= +github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE= +github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI= github.com/multiformats/go-base36 v0.1.0/go.mod h1:kFGE83c6s80PklsHO9sRn2NCoffoRdUUOENyW/Vv6sM= +github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= +github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc= github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g= @@ -210,7 +213,7 @@ golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -243,8 +246,8 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -lukechampine.com/blake3 v1.1.6 h1:H3cROdztr7RCfoaTpGZFQsrqvweFLrqS73j7L7cmR5c= -lukechampine.com/blake3 v1.1.6/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= +lukechampine.com/blake3 v1.3.0 h1:sJ3XhFINmHSrYCgl958hscfIa3bw8x4DqMP3u1YvoYE= +lukechampine.com/blake3 v1.3.0/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= modernc.org/cc v1.0.0 h1:nPibNuDEx6tvYrUAtvDTTw98rx5juGsa5zuDnKwEEQQ= modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw= modernc.org/golex v1.0.0 h1:wWpDlbK8ejRfSyi0frMyhilD3JBvtcx2AdGDnU+JtsE=