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 }