wip
This commit is contained in:
parent
5f5491a9e5
commit
3d5ecf25b2
@ -7,6 +7,10 @@ import (
|
||||
"io"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/power"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/market"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
@ -36,6 +40,7 @@ import (
|
||||
)
|
||||
|
||||
const APPROVE = 49
|
||||
const Reject = 50
|
||||
|
||||
type Vote struct {
|
||||
OptionID uint64 `json: "optionId"`
|
||||
@ -62,8 +67,7 @@ var fip0036PollResultcmd = &cli.Command{
|
||||
},
|
||||
},
|
||||
Subcommands: []*cli.Command{
|
||||
//spRBPCmd,
|
||||
//spDealByteCmd,
|
||||
spRBPAndDealCmd,
|
||||
clientCmd,
|
||||
tokenHolderCmd,
|
||||
//coreDevCmd,
|
||||
@ -85,6 +89,23 @@ func getVoters(file string) ([]Vote, error) {
|
||||
return votes, nil
|
||||
}
|
||||
|
||||
func getVotesMap(file string, st *state.StateTree) (map[address.Address]uint64, error) {
|
||||
votes, err := getVoters(file)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("cant get voters")
|
||||
}
|
||||
|
||||
vm := make(map[address.Address]uint64)
|
||||
for _, v := range votes {
|
||||
si, err := st.LookupID(v.SignerAddress)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("fail to lookup address")
|
||||
}
|
||||
vm[si] = v.OptionID
|
||||
}
|
||||
return vm, nil
|
||||
}
|
||||
|
||||
func getAllMsig(st *state.StateTree, store adt.Store) ([]msigBriefInfo, error) {
|
||||
|
||||
var msigActorsInfo []msigBriefInfo
|
||||
@ -115,6 +136,310 @@ func getAllMsig(st *state.StateTree, store adt.Store) ([]msigBriefInfo, error) {
|
||||
return msigActorsInfo, nil
|
||||
}
|
||||
|
||||
func getAllMsigMap(st *state.StateTree, store adt.Store) (map[address.Address]msigBriefInfo, error) {
|
||||
|
||||
msigActorsInfo := make(map[address.Address]msigBriefInfo)
|
||||
err := st.ForEach(func(addr address.Address, act *types.Actor) error {
|
||||
if builtin.IsMultisigActor(act.Code) {
|
||||
ms, err := multisig.Load(store, act)
|
||||
if err != nil {
|
||||
return fmt.Errorf("load msig failed %v", err)
|
||||
|
||||
}
|
||||
|
||||
signers, _ := ms.Signers()
|
||||
threshold, _ := ms.Threshold()
|
||||
info := msigBriefInfo{
|
||||
ID: addr,
|
||||
Signer: signers,
|
||||
Balance: act.Balance,
|
||||
Threshold: threshold,
|
||||
}
|
||||
msigActorsInfo[addr] = info
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return msigActorsInfo, nil
|
||||
}
|
||||
|
||||
type MinerVoteInfo struct {
|
||||
AvailableBalance abi.TokenAmount
|
||||
DealBytes abi.PaddedPieceSize
|
||||
RBP abi.StoragePower
|
||||
Option uint64
|
||||
}
|
||||
|
||||
func getStorageMinerRBP(miner address.Address, st *state.StateTree, store adt.Store) (abi.StoragePower, error) {
|
||||
pa, err := st.GetActor(power.Address)
|
||||
if err != nil {
|
||||
return types.NewInt(0), xerrors.Errorf("failed to get power actor: \n", err)
|
||||
}
|
||||
|
||||
ps, err := power.Load(store, pa)
|
||||
if err != nil {
|
||||
return types.NewInt(0), xerrors.Errorf("failed to get power state: \n", err)
|
||||
}
|
||||
|
||||
mp, _, err := ps.MinerPower(miner)
|
||||
if err != nil {
|
||||
return types.NewInt(0), xerrors.Errorf("failed to get miner power: \n", err)
|
||||
}
|
||||
|
||||
return mp.RawBytePower, nil
|
||||
}
|
||||
|
||||
func getStorageMinerVotes(st *state.StateTree, votes map[address.Address]uint64, store adt.Store) (map[address.Address]MinerVoteInfo /*key: miner actor id*/, error) {
|
||||
smv := make(map[address.Address]MinerVoteInfo)
|
||||
msigs, err := getAllMsigMap(st, store)
|
||||
if err != nil {
|
||||
xerrors.Errorf("fail to get msigs", err)
|
||||
}
|
||||
err = st.ForEach(func(addr address.Address, act *types.Actor) error {
|
||||
if builtin.IsStorageMinerActor(act.Code) {
|
||||
m, err := miner.Load(store, act)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("fail to load miner actor: \n", err)
|
||||
}
|
||||
|
||||
info, err := m.Info()
|
||||
if err != nil {
|
||||
return xerrors.Errorf("fail to get miner info: \n", err)
|
||||
}
|
||||
//check if owner voted
|
||||
o := info.Owner
|
||||
if v, found := votes[o]; found {
|
||||
//check if it is msig
|
||||
oa, err := st.GetActor(o)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("fail to get owner actor: \n", err)
|
||||
}
|
||||
if builtin.IsMultisigActor(oa.Code) {
|
||||
if ms, found := msigs[o]; found {
|
||||
ac := uint64(0)
|
||||
rc := uint64(0)
|
||||
for _, s := range ms.Signer {
|
||||
if v, found := votes[s]; found {
|
||||
if v == APPROVE {
|
||||
ac += 1
|
||||
} else {
|
||||
rc += 1
|
||||
}
|
||||
}
|
||||
mp, err := getStorageMinerRBP(addr, st, store)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("fail to get miner actor rbp", err)
|
||||
}
|
||||
m := MinerVoteInfo{
|
||||
AvailableBalance: act.Balance,
|
||||
RBP: mp,
|
||||
}
|
||||
if ac == ms.Threshold {
|
||||
m.Option = APPROVE
|
||||
smv[addr] = m
|
||||
} else if rc == ms.Threshold {
|
||||
m.Option = Reject
|
||||
smv[addr] = m
|
||||
} else {
|
||||
smv[addr] = m
|
||||
}
|
||||
}
|
||||
}
|
||||
} else { //owner is regular wallet account
|
||||
mp, err := getStorageMinerRBP(addr, st, store)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("fail to get miner actor rbp", err)
|
||||
}
|
||||
m := MinerVoteInfo{
|
||||
AvailableBalance: act.Balance,
|
||||
RBP: mp,
|
||||
Option: v,
|
||||
}
|
||||
smv[addr] = m
|
||||
}
|
||||
}
|
||||
|
||||
//check if owner not voted but worker voted
|
||||
if _, found := smv[addr]; !found {
|
||||
w := info.Worker
|
||||
if v, found := votes[w]; found {
|
||||
mp, err := getStorageMinerRBP(addr, st, store)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("fail to get miner actor rbp", err)
|
||||
}
|
||||
m := MinerVoteInfo{
|
||||
AvailableBalance: act.Balance,
|
||||
RBP: mp,
|
||||
Option: v,
|
||||
}
|
||||
smv[addr] = m
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return smv, nil
|
||||
}
|
||||
|
||||
var spRBPAndDealCmd = &cli.Command{
|
||||
Name: "sp",
|
||||
Usage: "get poll result for storage group",
|
||||
ArgsUsage: "[state root]",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "repo",
|
||||
Value: "~/.lotus",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "rbp-only",
|
||||
Value: false,
|
||||
},
|
||||
},
|
||||
|
||||
Action: func(cctx *cli.Context) error {
|
||||
if cctx.NArg() != 2 {
|
||||
return xerrors.New("filpoll0036 token-holder [state root] [votes.json]")
|
||||
}
|
||||
|
||||
ctx := context.TODO()
|
||||
if !cctx.Args().Present() {
|
||||
return fmt.Errorf("must pass state root")
|
||||
}
|
||||
|
||||
sroot, err := cid.Decode(cctx.Args().First())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to parse input: %w", err)
|
||||
}
|
||||
|
||||
fsrepo, err := repo.NewFS(cctx.String("repo"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
lkrepo, err := fsrepo.Lock(repo.FullNode)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer lkrepo.Close() //nolint:errcheck
|
||||
|
||||
bs, err := lkrepo.Blockstore(ctx, repo.UniversalBlockstore)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to open blockstore: %w", err)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if c, ok := bs.(io.Closer); ok {
|
||||
if err := c.Close(); err != nil {
|
||||
log.Warnf("failed to close blockstore: %s", err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
mds, err := lkrepo.Datastore(context.Background(), "/metadata")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cs := store.NewChainStore(bs, bs, mds, filcns.Weight, nil)
|
||||
defer cs.Close() //nolint:errcheck
|
||||
|
||||
cst := cbor.NewCborStore(bs)
|
||||
store := adt.WrapStore(ctx, cst)
|
||||
|
||||
tree, err := state.LoadStateTree(cst, sroot)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
//get all the votes' singer address && their vote
|
||||
vj, err := homedir.Expand(cctx.Args().Get(1))
|
||||
if err != nil {
|
||||
return xerrors.Errorf("fail to get votes json")
|
||||
}
|
||||
votes, err := getVotesMap(vj, tree)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("fail to get votesrs: ", err)
|
||||
}
|
||||
|
||||
//get all storage miner votes
|
||||
smv, err := getStorageMinerVotes(tree, votes, store)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("fail to get storage miner votes", err)
|
||||
}
|
||||
acceptanceVote := 0
|
||||
rejectionVote := 0
|
||||
acceptanceRBP := abi.NewStoragePower(0)
|
||||
rejectRBP := abi.NewStoragePower(0)
|
||||
acceptanceDealBytes := abi.PaddedPieceSize(0)
|
||||
rejectDealBytes := abi.PaddedPieceSize(0)
|
||||
ownerMsigUnderThreshold := 0
|
||||
|
||||
//process the votes
|
||||
//get all market proposals, add load the # of the bytes each provider has made
|
||||
pds := make(map[address.Address]abi.PaddedPieceSize)
|
||||
if !cctx.Bool("rbp-only") {
|
||||
ma, err := tree.GetActor(market.Address)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("fail to get market actor: ", err)
|
||||
}
|
||||
|
||||
ms, err := market.Load(store, ma)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("fail to load market actor: ", err)
|
||||
}
|
||||
dps, _ := ms.Proposals()
|
||||
if err := dps.ForEach(func(dealID abi.DealID, d market.DealProposal) error {
|
||||
if pd, found := pds[d.Provider]; found {
|
||||
s := d.PieceSize + pd
|
||||
pds[d.Provider] = s
|
||||
} else {
|
||||
pds[d.Provider] = d.PieceSize
|
||||
}
|
||||
return xerrors.Errorf("fail to load deals")
|
||||
}); err != nil {
|
||||
return xerrors.Errorf("fail to get deals")
|
||||
}
|
||||
}
|
||||
|
||||
//process the vote
|
||||
for m, mvi := range smv {
|
||||
if mvi.Option == APPROVE {
|
||||
acceptanceVote += 1
|
||||
acceptanceRBP = types.BigAdd(acceptanceRBP, mvi.RBP)
|
||||
if d, found := pds[m]; found {
|
||||
acceptanceDealBytes += d
|
||||
}
|
||||
} else if mvi.Option == Reject {
|
||||
rejectionVote += 1
|
||||
rejectRBP = types.BigAdd(rejectRBP, mvi.RBP)
|
||||
if d, found := pds[m]; found {
|
||||
rejectDealBytes += d
|
||||
}
|
||||
} else { //owner is msig and didnt reach threshold
|
||||
ownerMsigUnderThreshold += 1
|
||||
}
|
||||
}
|
||||
fmt.Printf("\nTotal amount of storage provider: %v\n", len(smv))
|
||||
fmt.Printf("Accept (#): %v\n", acceptanceVote)
|
||||
fmt.Printf("Reject (#): %v\n", rejectionVote)
|
||||
fmt.Printf("Total RPB voted: %v\n", types.BigAdd(acceptanceRBP, rejectRBP))
|
||||
fmt.Printf("Accept (rbp): %v\n", acceptanceRBP)
|
||||
fmt.Printf("Reject (rbp): %v\n", rejectRBP)
|
||||
|
||||
if !cctx.Bool("rbp-only") {
|
||||
fmt.Printf("Total deal bytes: %v\n", acceptanceDealBytes+rejectDealBytes)
|
||||
fmt.Printf("Accept (deal bytes): %v\n", acceptanceDealBytes)
|
||||
fmt.Printf("Reject (byte): %v\n", rejectDealBytes)
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
var tokenHolderCmd = &cli.Command{
|
||||
Name: "token-holder",
|
||||
Usage: "get poll result for token holder group",
|
||||
@ -223,13 +548,11 @@ var tokenHolderCmd = &cli.Command{
|
||||
for _, ms := range m.Signer {
|
||||
if ms == si {
|
||||
if mv, found := msigPendingVotes[m.ID]; found { //other singer has voted
|
||||
|
||||
if v.OptionID == APPROVE {
|
||||
mv.AcceptanceSingers = append(mv.AcceptanceSingers, v.SignerAddress)
|
||||
} else {
|
||||
mv.RejectionSigners = append(mv.RejectionSigners, v.SignerAddress)
|
||||
}
|
||||
|
||||
//check if threshold meet
|
||||
if uint64(len(mv.AcceptanceSingers)) == m.Threshold {
|
||||
delete(msigPendingVotes, m.ID)
|
||||
@ -243,7 +566,6 @@ var tokenHolderCmd = &cli.Command{
|
||||
msigPendingVotes[m.ID] = mv
|
||||
}
|
||||
} else {
|
||||
|
||||
n := msigVote{
|
||||
Multisig: m,
|
||||
}
|
||||
@ -274,9 +596,9 @@ var tokenHolderCmd = &cli.Command{
|
||||
fmt.Printf("\nTotal amount of singers: %v\n ", len(votes))
|
||||
fmt.Printf("Total amount of valid multisig vote: %v\n ", len(msigFinalVotes))
|
||||
fmt.Printf("Total balance: %v\n", types.BigAdd(acceptanceBalance, rejectionBalance).String())
|
||||
fmt.Printf("Approve (#): %v\n", acceptanceVote)
|
||||
fmt.Printf("Option (#): %v\n", acceptanceVote)
|
||||
fmt.Printf("Reject (#): %v\n", rejectionVote)
|
||||
fmt.Printf("Approve (FIL): %v\n", acceptanceBalance.String())
|
||||
fmt.Printf("Option (FIL): %v\n", acceptanceBalance.String())
|
||||
fmt.Printf("Reject (FIL): %v\n", rejectionBalance.String())
|
||||
av := types.BigDivFloat(acceptanceBalance, types.BigAdd(acceptanceBalance, rejectionBalance))
|
||||
rv := types.BigDivFloat(rejectionBalance, types.BigAdd(rejectionBalance, acceptanceBalance))
|
||||
@ -376,7 +698,21 @@ var clientCmd = &cli.Command{
|
||||
return xerrors.Errorf("fail to load market actor: ", err)
|
||||
}
|
||||
|
||||
//get all market proposals, add load the # of the bytes each client has made
|
||||
dps, _ := ms.Proposals()
|
||||
cds := make(map[address.Address]abi.PaddedPieceSize)
|
||||
if err := dps.ForEach(func(dealID abi.DealID, d market.DealProposal) error {
|
||||
if cd, found := cds[d.Client]; found {
|
||||
s := d.PieceSize + cd
|
||||
cds[d.Client] = s
|
||||
} else {
|
||||
cds[d.Client] = d.PieceSize
|
||||
}
|
||||
return xerrors.Errorf("fail to load deals")
|
||||
}); err != nil {
|
||||
return xerrors.Errorf("fail to get deals")
|
||||
}
|
||||
|
||||
acceptanceBytes := abi.PaddedPieceSize(0)
|
||||
rejectionBytes := abi.PaddedPieceSize(0)
|
||||
acceptanceCount := 0
|
||||
@ -389,27 +725,22 @@ var clientCmd = &cli.Command{
|
||||
if err != nil {
|
||||
return xerrors.Errorf("cannot resolve singer: ", ai)
|
||||
}
|
||||
if err := dps.ForEach(func(dealID abi.DealID, d market.DealProposal) error {
|
||||
|
||||
if d.Client == ai {
|
||||
if v.OptionID == APPROVE {
|
||||
acceptanceBytes += d.PieceSize
|
||||
acceptanceCount += 1
|
||||
} else {
|
||||
rejectionBytes += d.PieceSize
|
||||
rejectionCount += 1
|
||||
}
|
||||
if ds, found := cds[ai]; found {
|
||||
if v.OptionID == APPROVE {
|
||||
acceptanceBytes += ds
|
||||
acceptanceCount += 1
|
||||
} else {
|
||||
rejectionBytes += ds
|
||||
rejectionCount += 1
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
fmt.Printf("\nTotal amount of clients: %v\n", acceptanceCount+rejectionCount)
|
||||
fmt.Printf("Total deal bytes: %v\n", acceptanceBytes+rejectionBytes)
|
||||
fmt.Printf("Approve (#): %v\n", acceptanceCount)
|
||||
fmt.Printf("Accept (#): %v\n", acceptanceCount)
|
||||
fmt.Printf("Reject (#): %v\n", rejectionCount)
|
||||
fmt.Printf("Approve (byte): %v\n", acceptanceBytes)
|
||||
fmt.Printf("Accept (byte): %v\n", acceptanceBytes)
|
||||
fmt.Printf("Reject (byte): %v\n", rejectionBytes)
|
||||
av := float64(acceptanceBytes) / float64(acceptanceBytes+rejectionBytes)
|
||||
rv := float64(rejectionBytes) / float64(acceptanceBytes+rejectionBytes)
|
||||
|
Loading…
Reference in New Issue
Block a user