92 lines
2.2 KiB
Go
92 lines
2.2 KiB
Go
|
package storage
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"golang.org/x/xerrors"
|
||
|
|
||
|
"github.com/filecoin-project/go-address"
|
||
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||
|
|
||
|
"github.com/filecoin-project/lotus/api"
|
||
|
"github.com/filecoin-project/lotus/chain/types"
|
||
|
)
|
||
|
|
||
|
type AddrUse int
|
||
|
|
||
|
const (
|
||
|
PreCommitAddr AddrUse = iota
|
||
|
CommitAddr
|
||
|
PoStAddr
|
||
|
)
|
||
|
|
||
|
type addrSelectApi interface {
|
||
|
WalletBalance(context.Context, address.Address) (types.BigInt, error)
|
||
|
WalletHas(context.Context, address.Address) (bool, error)
|
||
|
|
||
|
StateAccountKey(context.Context, address.Address, types.TipSetKey) (address.Address, error)
|
||
|
}
|
||
|
|
||
|
func AddressFor(ctx context.Context, a addrSelectApi, mi api.MinerInfo, use AddrUse, minFunds abi.TokenAmount) (address.Address, error) {
|
||
|
switch use {
|
||
|
case PreCommitAddr, CommitAddr:
|
||
|
// always use worker, at least for now
|
||
|
return mi.Worker, nil
|
||
|
}
|
||
|
|
||
|
for _, addr := range mi.ControlAddresses {
|
||
|
b, err := a.WalletBalance(ctx, addr)
|
||
|
if err != nil {
|
||
|
return address.Undef, xerrors.Errorf("checking control address balance: %w", err)
|
||
|
}
|
||
|
|
||
|
if b.GreaterThanEqual(minFunds) {
|
||
|
k, err := a.StateAccountKey(ctx, addr, types.EmptyTSK)
|
||
|
if err != nil {
|
||
|
log.Errorw("getting account key", "error", err)
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
have, err := a.WalletHas(ctx, k)
|
||
|
if err != nil {
|
||
|
return address.Undef, xerrors.Errorf("failed to check control address: %w", err)
|
||
|
}
|
||
|
|
||
|
if !have {
|
||
|
log.Errorw("don't have key", "key", k)
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
return addr, nil
|
||
|
}
|
||
|
|
||
|
log.Warnw("control address didn't have enough funds for PoSt message", "address", addr, "required", types.FIL(minFunds), "balance", types.FIL(b))
|
||
|
}
|
||
|
|
||
|
// Try to use the owner account if we can, fallback to worker if we can't
|
||
|
|
||
|
b, err := a.WalletBalance(ctx, mi.Owner)
|
||
|
if err != nil {
|
||
|
return address.Undef, xerrors.Errorf("checking owner balance: %w", err)
|
||
|
}
|
||
|
|
||
|
if !b.GreaterThanEqual(minFunds) {
|
||
|
return mi.Worker, nil
|
||
|
}
|
||
|
|
||
|
k, err := a.StateAccountKey(ctx, mi.Owner, types.EmptyTSK)
|
||
|
if err != nil {
|
||
|
log.Errorw("getting owner account key", "error", err)
|
||
|
return mi.Worker, nil
|
||
|
}
|
||
|
|
||
|
have, err := a.WalletHas(ctx, k)
|
||
|
if err != nil {
|
||
|
return address.Undef, xerrors.Errorf("failed to check owner address: %w", err)
|
||
|
}
|
||
|
|
||
|
if !have {
|
||
|
return mi.Worker, nil
|
||
|
}
|
||
|
|
||
|
return mi.Owner, nil
|
||
|
}
|