94 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			94 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package storage
 | |
| 
 | |
| import (
 | |
| 	"context"
 | |
| 
 | |
| 	"golang.org/x/xerrors"
 | |
| 
 | |
| 	"github.com/filecoin-project/go-address"
 | |
| 	"github.com/filecoin-project/go-state-types/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
 | |
| }
 |