github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/token/export_accounts.go (about)

     1  package token
     2  
     3  import (
     4  	"bufio"
     5  	"bytes"
     6  	"fmt"
     7  	"io"
     8  	"os"
     9  	"path"
    10  	"time"
    11  
    12  	"github.com/aliyun/aliyun-oss-go-sdk/oss"
    13  	ethcrypto "github.com/ethereum/go-ethereum/crypto"
    14  	ethermint "github.com/fibonacci-chain/fbc/app/types"
    15  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
    16  	authexported "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth/exported"
    17  	"github.com/fibonacci-chain/fbc/libs/tendermint/libs/cli"
    18  	"github.com/spf13/viper"
    19  )
    20  
    21  const (
    22  	FlagOSSEnable          = "oss-enable"
    23  	FlagOSSEndpoint        = "oss-endpoint"
    24  	FlagOSSAccessKeyID     = "oss-access-key-id"
    25  	FlagOSSAccessKeySecret = "oss-access-key-secret"
    26  	FlagOSSBucketName      = "oss-bucket-name"
    27  	FlagOSSObjectPath      = "oss-object-path"
    28  )
    29  
    30  var (
    31  	logFileName = "export-upload-account.log"
    32  )
    33  
    34  type AccType int
    35  
    36  const (
    37  	UserAccount AccType = iota
    38  	ContractAccount
    39  	ModuleAccount
    40  	OtherAccount
    41  	WasmAccount
    42  )
    43  
    44  func exportAccounts(ctx sdk.Context, keeper Keeper) (filePath string) {
    45  	pt := time.Now().UTC().Format(time.RFC3339)
    46  	rootDir := viper.GetString(cli.HomeFlag)
    47  
    48  	accFileName := fmt.Sprintf("accounts-%d-%s.csv", ctx.BlockHeight(), pt)
    49  
    50  	// 1. open log file
    51  	logFile, logWr, err := openLogFile()
    52  	if err != nil {
    53  		return
    54  	}
    55  	defer logFile.Close()
    56  	defer logWr.Flush()
    57  
    58  	recodeLog(logWr, "===============")
    59  	recodeLog(logWr, fmt.Sprintf("time: %s", pt))
    60  	recodeLog(logWr, fmt.Sprintf("height: %d", ctx.BlockHeight()))
    61  	recodeLog(logWr, fmt.Sprintf("file name: %s", accFileName))
    62  
    63  	// 2. open account file
    64  	accFile, err := os.OpenFile(path.Join(rootDir, accFileName), os.O_CREATE|os.O_RDWR|os.O_APPEND, 0666)
    65  	if err != nil {
    66  		recodeLog(logWr, fmt.Sprintf("open account file error: %s", err))
    67  		return
    68  	}
    69  	defer accFile.Close()
    70  	accWr := bufio.NewWriter(accFile)
    71  	defer accWr.Flush()
    72  	defer func() {
    73  		if err := recover(); err != nil {
    74  			recodeLog(logWr, fmt.Sprintf("export accounts panic: %s", err))
    75  		}
    76  	}()
    77  
    78  	count := 0
    79  	startTime := time.Now()
    80  	keeper.accountKeeper.IterateAccounts(ctx, func(account authexported.Account) bool {
    81  		ethAcc, ok := account.(*ethermint.EthAccount)
    82  		if !ok {
    83  			return false
    84  		}
    85  
    86  		//account.SpendableCoins()
    87  		fiboBalance := account.GetCoins().AmountOf(sdk.DefaultBondDenom)
    88  		if !fiboBalance.GT(sdk.ZeroDec()) {
    89  			return false
    90  		}
    91  
    92  		accType := UserAccount
    93  		if !bytes.Equal(ethAcc.CodeHash, ethcrypto.Keccak256(nil)) {
    94  			accType = ContractAccount
    95  		}
    96  
    97  		csvStr := fmt.Sprintf("%s,%d,%s,%d,%s",
    98  			ethAcc.EthAddress().String(),
    99  			accType,
   100  			fiboBalance.String(),
   101  			ctx.BlockHeight(),
   102  			pt,
   103  		)
   104  		fmt.Fprintln(accWr, csvStr)
   105  		count++
   106  		return false
   107  	})
   108  	recodeLog(logWr, fmt.Sprintf("count: %d", count))
   109  	recodeLog(logWr, fmt.Sprintf("export duration: %s", time.Since(startTime).String()))
   110  	return path.Join(rootDir, accFileName)
   111  }
   112  
   113  func uploadOSS(filePath string) {
   114  	// 1. open log file
   115  	logFile, logWr, err := openLogFile()
   116  	if err != nil {
   117  		return
   118  	}
   119  	defer logFile.Close()
   120  	defer logWr.Flush()
   121  	defer func() {
   122  		if err := recover(); err != nil {
   123  			recodeLog(logWr, fmt.Sprintf("upload OSS panic: %s", err))
   124  		}
   125  	}()
   126  
   127  	startTime := time.Now()
   128  	// create OSSClient
   129  	ossClient, err := oss.New(viper.GetString(FlagOSSEndpoint), viper.GetString(FlagOSSAccessKeyID), viper.GetString(FlagOSSAccessKeySecret))
   130  	if err != nil {
   131  		recodeLog(logWr, fmt.Sprintf("creates oss lcient error: %s", err))
   132  		return
   133  	}
   134  
   135  	// gets the bucket instance
   136  	bucket, err := ossClient.Bucket(viper.GetString(FlagOSSBucketName))
   137  	if err != nil {
   138  		recodeLog(logWr, fmt.Sprintf("gets the bucket instance error: %s", err))
   139  		return
   140  	}
   141  
   142  	_, fileName := path.Split(filePath)
   143  	objectName := viper.GetString(FlagOSSObjectPath) + fmt.Sprintf("accounts-%s/", time.Now().Format("20060102")) + fileName
   144  	// multipart file upload
   145  	err = bucket.UploadFile(objectName, filePath, 100*1024, oss.Routines(3), oss.Checkpoint(true, ""))
   146  	if err != nil {
   147  		recodeLog(logWr, fmt.Sprintf("multipart file upload error: %s", err))
   148  		return
   149  	}
   150  	recodeLog(logWr, fmt.Sprintf("oss file: %s", objectName))
   151  	recodeLog(logWr, fmt.Sprintf("upload duration: %s", time.Since(startTime).String()))
   152  }
   153  
   154  func openLogFile() (*os.File, *bufio.Writer, error) {
   155  	rootDir := viper.GetString(cli.HomeFlag)
   156  
   157  	file, err := os.OpenFile(path.Join(rootDir, logFileName), os.O_CREATE|os.O_RDWR|os.O_APPEND, 0666)
   158  	if err != nil {
   159  		return nil, nil, err
   160  	}
   161  
   162  	logWr := bufio.NewWriter(file)
   163  	return file, logWr, nil
   164  }
   165  func recodeLog(w io.Writer, s string) {
   166  	fmt.Fprintln(w, s)
   167  }