package filcns import ( "context" "math/big" cbor "github.com/ipfs/go-ipld-cbor" "golang.org/x/xerrors" big2 "github.com/filecoin-project/go-state-types/big" bstore "github.com/filecoin-project/lotus/blockstore" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors/builtin/power" "github.com/filecoin-project/lotus/chain/state" "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" ) var zero = types.NewInt(0) func Weight(ctx context.Context, stateBs bstore.Blockstore, 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(stateBs) 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(power.Address) if err != nil { return types.NewInt(0), xerrors.Errorf("get power actor: %w", err) } powState, err := power.Load(store.ActorStore(ctx, stateBs), 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 }