github.com/bigzoro/my_simplechain@v0.0.0-20240315012955-8ad0a2a29bb9/core/state/parallel_statedb.go (about) 1 // Copyright 2020 The go-simplechain Authors 2 // This file is part of the go-simplechain library. 3 // 4 // The go-simplechain library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-simplechain library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-simplechain library. If not, see <http://www.gnu.org/licenses/>. 16 17 package state 18 19 import ( 20 "math/big" 21 "sync" 22 "time" 23 24 "github.com/bigzoro/my_simplechain/common" 25 "github.com/bigzoro/my_simplechain/log" 26 "github.com/bigzoro/my_simplechain/rlp" 27 ) 28 29 func (s *StateDB) Merge(idx int, from, to *ParallelStateObject, deleteEmptyObjects bool) { 30 if from.stateObject.address != to.stateObject.address { 31 if from.stateObject.suicided || (deleteEmptyObjects && from.stateObject.empty()) { 32 log.Warn("deleteStateObject", "from", from.stateObject.address.String(), "suicided", from.stateObject.suicided, "empty", from.stateObject.empty()) 33 s.deleteStateObject(from.stateObject) 34 } else { 35 s.stateObjects[from.stateObject.address] = from.stateObject 36 s.journal.append(balanceChange{ 37 account: &from.stateObject.address, 38 prev: from.prevAmount, 39 }) 40 s.stateObjectsDirty[from.stateObject.address] = struct{}{} 41 } 42 } 43 if to.stateObject.suicided || (deleteEmptyObjects && to.stateObject.empty()) { 44 log.Warn("deleteStateObject", "to", to.stateObject.address.String(), "suicided", to.stateObject.suicided, "empty", to.stateObject.empty()) 45 s.deleteStateObject(to.stateObject) 46 } else { 47 if to.createFlag { 48 s.journal.append(createObjectChange{account: &to.stateObject.address}) 49 } 50 s.stateObjects[to.stateObject.address] = to.stateObject 51 s.journal.append(balanceChange{ 52 account: &to.stateObject.address, 53 prev: to.prevAmount, 54 }) 55 s.stateObjectsDirty[to.stateObject.address] = struct{}{} 56 } 57 } 58 59 func (s *StateDB) AddMinerEarnings(addr common.Address, amount *big.Int) { 60 stateObject := s.GetOrNewStateObject(addr) 61 if stateObject != nil { 62 //stateObject.db = s 63 stateObject.AddBalance(amount) 64 } 65 } 66 67 var ( 68 parallelLocker sync.Mutex 69 ) 70 71 func (s *StateDB) GetOrNewParallelStateObject(addr common.Address) *ParallelStateObject { 72 stateObject := s.justGetStateObject(addr) 73 if stateObject == nil || stateObject.deleted { 74 log.Debug("Cannot find stateObject in Parallel", "addr", addr.String(), "isNil", stateObject == nil) 75 return s.justCreateObject(addr) 76 } 77 return NewParallelStateObject(stateObject, false) 78 } 79 80 func (s *StateDB) justGetStateObject(addr common.Address) (stateObject *stateObject) { 81 if obj := s.justGetStateObjectCache(addr); obj != nil { 82 if obj.deleted { 83 return nil 84 } 85 return obj 86 } 87 // Load the object from the database. 88 start := time.Now() 89 parallelLocker.Lock() 90 if start.Add(20 * time.Millisecond).Before(time.Now()) { 91 log.Trace("Get parallelLocker overtime", "address", addr.String(), "duration", time.Since(start)) 92 } 93 start = time.Now() 94 enc, err := s.trie.TryGet(addr[:]) 95 if start.Add(20 * time.Millisecond).Before(time.Now()) { 96 log.Trace("Trie tryGet overtime", "address", addr.String(), "duration", time.Since(start)) 97 } 98 parallelLocker.Unlock() 99 if len(enc) == 0 { 100 s.setError(err) 101 return nil 102 } 103 var data Account 104 if err := rlp.DecodeBytes(enc, &data); err != nil { 105 log.Error("Failed to decode state object", "addr", addr, "err", err) 106 return nil 107 } 108 obj := newObject(s, addr, data) 109 //do not set to state.stateObjects. 110 //self.setStateObject(obj) 111 return obj 112 } 113 114 func (s *StateDB) justGetStateObjectCache(addr common.Address) (stateObject *stateObject) { 115 // Prefer 'live' objects. 116 if obj := s.stateObjects[addr]; obj != nil { 117 return obj 118 } 119 120 //TODO(yc) chained bft statedb 121 //self.refLock.Lock() 122 //parentDB := self.parent 123 //parentCommitted := self.parentCommitted 124 //refLock := &self.refLock 125 // 126 //for parentDB != nil { 127 // obj := parentDB.getStateObjectLocalCache(addr) 128 // if obj != nil { 129 // refLock.Unlock() 130 // cpy := obj.copy(self) 131 // //do not set to state.stateObjects. 132 // //self.setStateObject(cpy) 133 // return cpy 134 // } else if parentCommitted { 135 // refLock.Unlock() 136 // return nil 137 // } 138 // 139 // if obj == nil { 140 // refLock.Unlock() 141 // parentDB.refLock.Lock() 142 // refLock = &parentDB.refLock 143 // if parentDB.parent == nil { 144 // break 145 // } 146 // parentCommitted = parentDB.parentCommitted 147 // parentDB = parentDB.parent 148 // } 149 //} 150 // 151 //refLock.Unlock() 152 return nil 153 } 154 155 func (s *StateDB) justCreateObject(addr common.Address) *ParallelStateObject { 156 //newobj := newObject(self, addr, Account{}) 157 newobj := newObject(s, addr, Account{}) 158 //self.journal.append(createObjectChange{account: &addr}) 159 newobj.setNonce(0) 160 return &ParallelStateObject{ 161 stateObject: newobj, 162 prevAmount: big.NewInt(0), 163 createFlag: true, 164 } 165 //return self.createObject(addr) 166 }