check invariance for pending deals and allocations
This commit is contained in:
parent
3c1b723c7f
commit
0ab9e4359a
@ -17,6 +17,7 @@ import (
|
|||||||
"github.com/filecoin-project/lotus/blockstore"
|
"github.com/filecoin-project/lotus/blockstore"
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
"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/datacap"
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors/builtin/market"
|
||||||
"github.com/filecoin-project/lotus/chain/actors/builtin/verifreg"
|
"github.com/filecoin-project/lotus/chain/actors/builtin/verifreg"
|
||||||
"github.com/filecoin-project/lotus/chain/consensus/filcns"
|
"github.com/filecoin-project/lotus/chain/consensus/filcns"
|
||||||
"github.com/filecoin-project/lotus/chain/state"
|
"github.com/filecoin-project/lotus/chain/state"
|
||||||
@ -141,15 +142,39 @@ var migrationsCmd = &cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkStateInvariants(ctx context.Context, oldStateRoot cid.Cid, newStateRoot cid.Cid, bs blockstore.Blockstore) error {
|
func checkStateInvariants(ctx context.Context, v8StateRoot cid.Cid, v9StateRoot cid.Cid, bs blockstore.Blockstore) error {
|
||||||
actorStore := store.ActorStore(ctx, blockstore.NewTieredBstore(bs, blockstore.NewMemorySync()))
|
actorStore := store.ActorStore(ctx, blockstore.NewTieredBstore(bs, blockstore.NewMemorySync()))
|
||||||
|
|
||||||
verifregDatacaps, err := getVerifreg8Datacaps(ctx, oldStateRoot, actorStore)
|
stateTreeV8, err := state.LoadStateTree(actorStore, v8StateRoot)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
newDatacaps, err := getDatacap9Datacaps(ctx, newStateRoot, actorStore)
|
stateTreeV9, err := state.LoadStateTree(actorStore, v9StateRoot)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = checkDatacaps(*stateTreeV8, *stateTreeV9, actorStore)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = checkPendingVerifiedDeals(*stateTreeV8, *stateTreeV9, actorStore)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkDatacaps(stateTreeV8 state.StateTree, stateTreeV9 state.StateTree, actorStore adt.Store) error {
|
||||||
|
verifregDatacaps, err := getVerifreg8Datacaps(stateTreeV8, actorStore)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
newDatacaps, err := getDatacap9Datacaps(stateTreeV9, actorStore)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -171,24 +196,14 @@ func checkStateInvariants(ctx context.Context, oldStateRoot cid.Cid, newStateRoo
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getVerifreg8Datacaps(ctx context.Context, v8StateRoot cid.Cid, actorStore adt.Store) (map[address.Address]abi.StoragePower, error) {
|
func getVerifreg8Datacaps(stateTreeV8 state.StateTree, actorStore adt.Store) (map[address.Address]abi.StoragePower, error) {
|
||||||
stateTreeV8, err := state.LoadStateTree(actorStore, v8StateRoot)
|
verifregStateV8, err := getVerifregV8State(stateTreeV8, actorStore)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
verifregV8, err := stateTreeV8.GetActor(verifreg.Address)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
verifregV8State, err := verifreg.Load(actorStore, verifregV8)
|
|
||||||
if err = actorStore.Get(ctx, verifregV8.Head, &verifregV8State); err != nil {
|
|
||||||
return nil, xerrors.Errorf("failed to get verifreg actor state: %w", err)
|
return nil, xerrors.Errorf("failed to get verifreg actor state: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var verifregDatacaps = make(map[address.Address]abi.StoragePower)
|
var verifregDatacaps = make(map[address.Address]abi.StoragePower)
|
||||||
err = verifregV8State.ForEachClient(func(addr address.Address, dcap abi.StoragePower) error {
|
err = verifregStateV8.ForEachClient(func(addr address.Address, dcap abi.StoragePower) error {
|
||||||
verifregDatacaps[addr] = dcap
|
verifregDatacaps[addr] = dcap
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
@ -199,24 +214,14 @@ func getVerifreg8Datacaps(ctx context.Context, v8StateRoot cid.Cid, actorStore a
|
|||||||
return verifregDatacaps, nil
|
return verifregDatacaps, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getDatacap9Datacaps(ctx context.Context, v9StateRoot cid.Cid, actorStore adt.Store) (map[address.Address]abi.StoragePower, error) {
|
func getDatacap9Datacaps(stateTreeV9 state.StateTree, actorStore adt.Store) (map[address.Address]abi.StoragePower, error) {
|
||||||
stateTreeV9, err := state.LoadStateTree(actorStore, v9StateRoot)
|
datacapStateV9, err := getDatacapV9State(stateTreeV9, actorStore)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, xerrors.Errorf("failed to get datacap actor state: %w", err)
|
||||||
}
|
|
||||||
|
|
||||||
datacapV9, err := stateTreeV9.GetActor(datacap.Address)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
datacapV9State, err := datacap.Load(actorStore, datacapV9)
|
|
||||||
if err = actorStore.Get(ctx, datacapV9.Head, &datacapV9State); err != nil {
|
|
||||||
return nil, xerrors.Errorf("failed to get verifreg actor state: %w", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var datacaps = make(map[address.Address]abi.StoragePower)
|
var datacaps = make(map[address.Address]abi.StoragePower)
|
||||||
err = datacapV9State.ForEachClient(func(addr address.Address, dcap abi.StoragePower) error {
|
err = datacapStateV9.ForEachClient(func(addr address.Address, dcap abi.StoragePower) error {
|
||||||
datacaps[addr] = dcap
|
datacaps[addr] = dcap
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
@ -226,3 +231,135 @@ func getDatacap9Datacaps(ctx context.Context, v9StateRoot cid.Cid, actorStore ad
|
|||||||
|
|
||||||
return datacaps, nil
|
return datacaps, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func checkPendingVerifiedDeals(stateTreeV8 state.StateTree, stateTreeV9 state.StateTree, actorStore adt.Store) error {
|
||||||
|
marketStateV8, err := getMarketV8State(stateTreeV8, actorStore)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
marketStateV9, err := getMarketV9State(stateTreeV9, actorStore)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
verifregStateV9, err := getVerifregV9State(stateTreeV9, actorStore)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
v8DealStates, err := marketStateV8.States()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
v8DealProposals, err := marketStateV8.Proposals()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var numPendingVerifiedDeals = 0
|
||||||
|
err = v8DealStates.ForEach(func(id abi.DealID, ds market.DealState) error {
|
||||||
|
// Proposal hasn't been activated yet
|
||||||
|
if ds.SectorStartEpoch == -1 {
|
||||||
|
proposal, _, err := v8DealProposals.Get(id)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verified deal
|
||||||
|
if proposal.VerifiedDeal {
|
||||||
|
numPendingVerifiedDeals++
|
||||||
|
// Checks if allocation ID is in market map
|
||||||
|
allocationId, err := marketStateV9.GetAllocationIdForPendingDeal(id)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// Checks if allocation is in verifreg
|
||||||
|
_, found, err := verifregStateV9.GetAllocation(proposal.Client, allocationId)
|
||||||
|
if !found {
|
||||||
|
return xerrors.Errorf("allocation %d not found for address %s", allocationId, proposal.Client)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
numAllocations, err := countAllocations(verifregStateV9)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if numAllocations != numPendingVerifiedDeals {
|
||||||
|
return xerrors.Errorf("number of allocations: %d did not match the number of pending verified deals: %d", numAllocations, numPendingVerifiedDeals)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getMarketV8State(stateTreeV8 state.StateTree, actorStore adt.Store) (market.State, error) {
|
||||||
|
marketV9, err := stateTreeV8.GetActor(market.Address)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return market.Load(actorStore, marketV9)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getMarketV9State(stateTreeV9 state.StateTree, actorStore adt.Store) (market.State, error) {
|
||||||
|
marketV9, err := stateTreeV9.GetActor(market.Address)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return market.Load(actorStore, marketV9)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getVerifregV8State(stateTreeV8 state.StateTree, actorStore adt.Store) (verifreg.State, error) {
|
||||||
|
verifregV8, err := stateTreeV8.GetActor(verifreg.Address)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return verifreg.Load(actorStore, verifregV8)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getVerifregV9State(stateTreeV9 state.StateTree, actorStore adt.Store) (verifreg.State, error) {
|
||||||
|
verifregV9, err := stateTreeV9.GetActor(verifreg.Address)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return verifreg.Load(actorStore, verifregV9)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getDatacapV9State(stateTreeV9 state.StateTree, actorStore adt.Store) (datacap.State, error) {
|
||||||
|
datacapV9, err := stateTreeV9.GetActor(datacap.Address)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return datacap.Load(actorStore, datacapV9)
|
||||||
|
}
|
||||||
|
|
||||||
|
func countAllocations(verifregState verifreg.State) (int, error) {
|
||||||
|
var count int
|
||||||
|
err := verifregState.ForEachClient(func(addr address.Address, dcap abi.StoragePower) error {
|
||||||
|
allocations, err := verifregState.GetAllocations(addr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
count += len(allocations)
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return count, nil
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user