github.com/neatlab/neatio@v1.7.3-0.20220425043230-d903e92fcc75/chain/core/state/dump.go (about)

     1  package state
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"fmt"
     7  	"math/big"
     8  
     9  	"github.com/neatlab/neatio/chain/trie"
    10  	"github.com/neatlab/neatio/utilities/common"
    11  	"github.com/neatlab/neatio/utilities/rlp"
    12  )
    13  
    14  type DumpAccount struct {
    15  	Balance        string                  `json:"balance"`
    16  	Deposit        string                  `json:"deposit_balance"`
    17  	Delegate       string                  `json:"delegate_balance"`
    18  	Proxied        string                  `json:"proxied_balance"`
    19  	DepositProxied string                  `json:"deposit_proxied_balance"`
    20  	PendingRefund  string                  `json:"pending_refund_balance"`
    21  	ProxiedRoot    string                  `json:"proxied_root"`
    22  	ProxiedDetail  map[string]*DumpProxied `json:"proxied_detail"`
    23  
    24  	Reward          string            `json:"reward_balance"`
    25  	AvailableReward string            `json:"available_reward_balance"`
    26  	RewardRoot      string            `json:"reward_root"`
    27  	RewardDetail    map[string]string `json:"reward_detail"`
    28  
    29  	Tx1Root   string   `json:"tx1_root"`
    30  	Tx1Detail []string `json:"tx1_detail"`
    31  	Tx3Root   string   `json:"tx3_root"`
    32  	Tx3Detail []string `json:"tx3_detail"`
    33  
    34  	Nonce    uint64            `json:"nonce"`
    35  	Root     string            `json:"root"`
    36  	CodeHash string            `json:"codeHash"`
    37  	Code     string            `json:"code"`
    38  	Storage  map[string]string `json:"storage"`
    39  
    40  	Candidate  bool  `json:"candidate"`
    41  	Commission uint8 `json:"commission"`
    42  }
    43  
    44  type DumpProxied struct {
    45  	Proxied        string `json:"proxied_balance"`
    46  	DepositProxied string `json:"deposit_proxied_balance"`
    47  	PendingRefund  string `json:"pending_refund_balance"`
    48  }
    49  
    50  type Dump struct {
    51  	Root           string                 `json:"root"`
    52  	Accounts       map[string]DumpAccount `json:"accounts"`
    53  	RewardAccounts []string               `json:"reward_accounts"`
    54  	RefundAccounts []string               `json:"refund_accounts"`
    55  }
    56  
    57  func (self *StateDB) RawDump() Dump {
    58  	dump := Dump{
    59  		Root:     fmt.Sprintf("%x", self.trie.Hash()),
    60  		Accounts: make(map[string]DumpAccount),
    61  	}
    62  
    63  	it := trie.NewIterator(self.trie.NodeIterator(nil))
    64  	for it.Next() {
    65  		addr := self.trie.GetKey(it.Key)
    66  		if len(addr) == 20 {
    67  			var data Account
    68  			if err := rlp.DecodeBytes(it.Value, &data); err != nil {
    69  				panic(err)
    70  			}
    71  
    72  			obj := newObject(nil, common.BytesToAddress(addr), data, nil)
    73  			account := DumpAccount{
    74  				Balance:        data.Balance.String(),
    75  				Deposit:        data.DepositBalance.String(),
    76  				Delegate:       data.DelegateBalance.String(),
    77  				Proxied:        data.ProxiedBalance.String(),
    78  				DepositProxied: data.DepositProxiedBalance.String(),
    79  				PendingRefund:  data.PendingRefundBalance.String(),
    80  				ProxiedRoot:    data.ProxiedRoot.String(),
    81  				ProxiedDetail:  make(map[string]*DumpProxied),
    82  				Reward:         data.RewardBalance.String(),
    83  
    84  				RewardRoot:   data.RewardRoot.String(),
    85  				RewardDetail: make(map[string]string),
    86  
    87  				Tx1Root: data.TX1Root.String(),
    88  				Tx3Root: data.TX3Root.String(),
    89  
    90  				Nonce:    data.Nonce,
    91  				Root:     common.Bytes2Hex(data.Root[:]),
    92  				CodeHash: common.Bytes2Hex(data.CodeHash),
    93  				Code:     common.Bytes2Hex(obj.Code(self.db)),
    94  				Storage:  make(map[string]string),
    95  
    96  				Candidate:  data.Candidate,
    97  				Commission: data.Commission,
    98  			}
    99  			storageIt := trie.NewIterator(obj.getTrie(self.db).NodeIterator(nil))
   100  			for storageIt.Next() {
   101  				account.Storage[common.Bytes2Hex(self.trie.GetKey(storageIt.Key))] = common.Bytes2Hex(storageIt.Value)
   102  			}
   103  
   104  			tx1It := trie.NewIterator(obj.getTX1Trie(self.db).NodeIterator(nil))
   105  			for tx1It.Next() {
   106  				tx1hash := common.BytesToHash(self.trie.GetKey(tx1It.Key))
   107  				account.Tx1Detail = append(account.Tx1Detail, tx1hash.Hex())
   108  			}
   109  
   110  			tx3It := trie.NewIterator(obj.getTX3Trie(self.db).NodeIterator(nil))
   111  			for tx3It.Next() {
   112  				tx3hash := common.BytesToHash(self.trie.GetKey(tx3It.Key))
   113  				account.Tx3Detail = append(account.Tx3Detail, tx3hash.Hex())
   114  			}
   115  
   116  			if data.ProxiedRoot.String() != "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" {
   117  				proxiedIt := trie.NewIterator(obj.getProxiedTrie(self.db).NodeIterator(nil))
   118  				for proxiedIt.Next() {
   119  					var apb accountProxiedBalance
   120  					rlp.DecodeBytes(proxiedIt.Value, &apb)
   121  					account.ProxiedDetail[common.Bytes2Hex(self.trie.GetKey(proxiedIt.Key))] = &DumpProxied{
   122  						Proxied:        apb.ProxiedBalance.String(),
   123  						DepositProxied: apb.DepositProxiedBalance.String(),
   124  						PendingRefund:  apb.PendingRefundBalance.String(),
   125  					}
   126  				}
   127  			}
   128  
   129  			if data.RewardRoot.String() != "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" {
   130  				rewardIt := trie.NewIterator(obj.getRewardTrie(self.db).NodeIterator(nil))
   131  				for rewardIt.Next() {
   132  					var key uint64
   133  					rlp.DecodeBytes(self.trie.GetKey(rewardIt.Key), &key)
   134  					var value big.Int
   135  					rlp.DecodeBytes(rewardIt.Value, &value)
   136  					account.RewardDetail[fmt.Sprintf("epoch_%d", key)] = value.String()
   137  				}
   138  			}
   139  
   140  			dump.Accounts[common.Bytes2Hex(addr)] = account
   141  		} else {
   142  			if bytes.Equal(addr, rewardSetKey) {
   143  				var data []common.Address
   144  				if err := rlp.DecodeBytes(it.Value, &data); err != nil {
   145  					panic(err)
   146  				}
   147  				for _, rewardAddr := range data {
   148  
   149  					dump.RewardAccounts = append(dump.RewardAccounts, rewardAddr.String())
   150  				}
   151  			} else if bytes.Equal(addr, refundSetKey) {
   152  				var data []common.Address
   153  				if err := rlp.DecodeBytes(it.Value, &data); err != nil {
   154  					panic(err)
   155  				}
   156  				for _, refundAddr := range data {
   157  
   158  					dump.RefundAccounts = append(dump.RefundAccounts, refundAddr.String())
   159  				}
   160  			}
   161  		}
   162  	}
   163  	return dump
   164  }
   165  
   166  func (self *StateDB) Dump() []byte {
   167  	json, err := json.MarshalIndent(self.RawDump(), "", "    ")
   168  	if err != nil {
   169  		fmt.Println("dump err", err)
   170  	}
   171  
   172  	return json
   173  }