package store import ( "context" "math/big" "github.com/filecoin-project/lotus/chain/actors/builtin/power" big2 "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/state" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/specs-actors/actors/builtin" cbor "github.com/ipfs/go-ipld-cbor" "golang.org/x/xerrors" ) var zero = types.NewInt(0) func (cs *ChainStore) Weight(ctx context.Context, ts *types.TipSet) (types.BigInt, error) { if ts == nil { return types.NewInt(0), nil } // >>> w[r] <<< + wFunction(totalPowerAtTipset(ts)) * 2^8 + (wFunction(totalPowerAtTipset(ts)) * sum(ts.blocks[].ElectionProof.WinCount) * wRatio_num * 2^8) / (e * wRatio_den) var out = new(big.Int).Set(ts.ParentWeight().Int) // >>> wFunction(totalPowerAtTipset(ts)) * 2^8 <<< + (wFunction(totalPowerAtTipset(ts)) * sum(ts.blocks[].ElectionProof.WinCount) * wRatio_num * 2^8) / (e * wRatio_den) tpow := big2.Zero() { cst := cbor.NewCborStore(cs.Blockstore()) state, err := state.LoadStateTree(cst, ts.ParentState()) if err != nil { return types.NewInt(0), xerrors.Errorf("load state tree: %w", err) } act, err := state.GetActor(builtin.StoragePowerActorAddr) if err != nil { return types.NewInt(0), xerrors.Errorf("get power actor: %w", err) } powState, err := power.Load(cs.Store(ctx), act) if err != nil { return types.NewInt(0), xerrors.Errorf("failed to load power actor state: %w", err) } claim, err := powState.TotalPower() if err != nil { return types.NewInt(0), xerrors.Errorf("failed to get total power: %w", err) } tpow = claim.QualityAdjPower // TODO: REVIEW: Is this correct? } log2P := int64(0) if tpow.GreaterThan(zero) { log2P = int64(tpow.BitLen() - 1) } else { // Not really expect to be here ... return types.EmptyInt, xerrors.Errorf("All power in the net is gone. You network might be disconnected, or the net is dead!") } out.Add(out, big.NewInt(log2P<<8)) // (wFunction(totalPowerAtTipset(ts)) * sum(ts.blocks[].ElectionProof.WinCount) * wRatio_num * 2^8) / (e * wRatio_den) totalJ := int64(0) for _, b := range ts.Blocks() { totalJ += b.ElectionProof.WinCount } eWeight := big.NewInt((log2P * build.WRatioNum)) eWeight = eWeight.Lsh(eWeight, 8) eWeight = eWeight.Mul(eWeight, new(big.Int).SetInt64(totalJ)) eWeight = eWeight.Div(eWeight, big.NewInt(int64(build.BlocksPerEpoch*build.WRatioDen))) out = out.Add(out, eWeight) return types.BigInt{Int: out}, nil }