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  }