From ed839907e592ad25e6119e145e7e05ca78b00fcd Mon Sep 17 00:00:00 2001 From: Determinant Date: Wed, 16 Sep 2020 22:54:37 -0400 Subject: ... --- core/blockchain.go | 17 ++++++++-------- core/state/database.go | 2 +- core/state/dump.go | 43 ++++++++++++++++++++++------------------- core/state/snapshot/account.go | 20 ++++++++++--------- core/state/snapshot/generate.go | 11 ++++++----- core/state/statedb.go | 5 +++-- core/types/block.go | 32 +++++++++++++++++++----------- core/vm/evm.go | 12 +++++++----- 8 files changed, 81 insertions(+), 61 deletions(-) (limited to 'core') diff --git a/core/blockchain.go b/core/blockchain.go index 82e3b6c..b3a7ffa 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -2492,12 +2492,13 @@ func (bc *BlockChain) SubscribeBlockProcessingEvent(ch chan<- bool) event.Subscr } func (bc *BlockChain) ManualHead(hash common.Hash) error { - block := bc.GetBlockByHash(hash) - if block == nil { - return errors.New("block not found") - } - bc.chainmu.Lock() - defer bc.chainmu.Unlock() - bc.writeHeadBlock(block) - return nil + return bc.FastSyncCommitHead(hash) + //block := bc.GetBlockByHash(hash) + //if block == nil { + // return errors.New("block not found") + //} + //bc.chainmu.Lock() + //defer bc.chainmu.Unlock() + //bc.writeHeadBlock(block) + //return nil } diff --git a/core/state/database.go b/core/state/database.go index a9342f5..385c25d 100644 --- a/core/state/database.go +++ b/core/state/database.go @@ -21,8 +21,8 @@ import ( "fmt" "github.com/VictoriaMetrics/fastcache" + "github.com/ava-labs/coreth/core/rawdb" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/trie" lru "github.com/hashicorp/golang-lru" diff --git a/core/state/dump.go b/core/state/dump.go index 9bb946d..6f09398 100644 --- a/core/state/dump.go +++ b/core/state/dump.go @@ -37,14 +37,15 @@ type DumpCollector interface { // DumpAccount represents an account in the state. type DumpAccount struct { - Balance string `json:"balance"` - Nonce uint64 `json:"nonce"` - Root string `json:"root"` - CodeHash string `json:"codeHash"` - Code string `json:"code,omitempty"` - Storage map[common.Hash]string `json:"storage,omitempty"` - Address *common.Address `json:"address,omitempty"` // Address only present in iterative (line-by-line) mode - SecureKey hexutil.Bytes `json:"key,omitempty"` // If we don't have address, we can output the key + Balance string `json:"balance"` + Nonce uint64 `json:"nonce"` + Root string `json:"root"` + CodeHash string `json:"codeHash"` + IsMultiCoin bool `json:"isMultiCoin"` + Code string `json:"code,omitempty"` + Storage map[common.Hash]string `json:"storage,omitempty"` + Address *common.Address `json:"address,omitempty"` // Address only present in iterative (line-by-line) mode + SecureKey hexutil.Bytes `json:"key,omitempty"` // If we don't have address, we can output the key } @@ -89,14 +90,15 @@ type iterativeDump struct { // OnAccount implements DumpCollector interface func (d iterativeDump) OnAccount(addr common.Address, account DumpAccount) { dumpAccount := &DumpAccount{ - Balance: account.Balance, - Nonce: account.Nonce, - Root: account.Root, - CodeHash: account.CodeHash, - Code: account.Code, - Storage: account.Storage, - SecureKey: account.SecureKey, - Address: nil, + Balance: account.Balance, + Nonce: account.Nonce, + Root: account.Root, + CodeHash: account.CodeHash, + IsMultiCoin: account.IsMultiCoin, + Code: account.Code, + Storage: account.Storage, + SecureKey: account.SecureKey, + Address: nil, } if addr != (common.Address{}) { dumpAccount.Address = &addr @@ -123,10 +125,11 @@ func (s *StateDB) DumpToCollector(c DumpCollector, excludeCode, excludeStorage, panic(err) } account := DumpAccount{ - Balance: data.Balance.String(), - Nonce: data.Nonce, - Root: common.Bytes2Hex(data.Root[:]), - CodeHash: common.Bytes2Hex(data.CodeHash), + Balance: data.Balance.String(), + Nonce: data.Nonce, + Root: common.Bytes2Hex(data.Root[:]), + CodeHash: common.Bytes2Hex(data.CodeHash), + IsMultiCoin: data.IsMultiCoin, } addrBytes := s.trie.GetKey(it.Key) if addrBytes == nil { diff --git a/core/state/snapshot/account.go b/core/state/snapshot/account.go index b92e942..303c2fc 100644 --- a/core/state/snapshot/account.go +++ b/core/state/snapshot/account.go @@ -29,17 +29,19 @@ import ( // or slim-snapshot format which replaces the empty root and code hash as nil // byte slice. type Account struct { - Nonce uint64 - Balance *big.Int - Root []byte - CodeHash []byte + Nonce uint64 + Balance *big.Int + Root []byte + CodeHash []byte + IsMultiCoin bool } // SlimAccount converts a state.Account content into a slim snapshot account -func SlimAccount(nonce uint64, balance *big.Int, root common.Hash, codehash []byte) Account { +func SlimAccount(nonce uint64, balance *big.Int, root common.Hash, codehash []byte, isMultiCoin bool) Account { slim := Account{ - Nonce: nonce, - Balance: balance, + Nonce: nonce, + Balance: balance, + IsMultiCoin: isMultiCoin, } if root != emptyRoot { slim.Root = root[:] @@ -52,8 +54,8 @@ func SlimAccount(nonce uint64, balance *big.Int, root common.Hash, codehash []by // SlimAccountRLP converts a state.Account content into a slim snapshot // version RLP encoded. -func SlimAccountRLP(nonce uint64, balance *big.Int, root common.Hash, codehash []byte) []byte { - data, err := rlp.EncodeToBytes(SlimAccount(nonce, balance, root, codehash)) +func SlimAccountRLP(nonce uint64, balance *big.Int, root common.Hash, codehash []byte, isMultiCoin bool) []byte { + data, err := rlp.EncodeToBytes(SlimAccount(nonce, balance, root, codehash, isMultiCoin)) if err != nil { panic(err) } diff --git a/core/state/snapshot/generate.go b/core/state/snapshot/generate.go index dac782f..27f8dfc 100644 --- a/core/state/snapshot/generate.go +++ b/core/state/snapshot/generate.go @@ -161,15 +161,16 @@ func (dl *diskLayer) generate(stats *generatorStats) { accountHash := common.BytesToHash(accIt.Key) var acc struct { - Nonce uint64 - Balance *big.Int - Root common.Hash - CodeHash []byte + Nonce uint64 + Balance *big.Int + Root common.Hash + CodeHash []byte + IsMultiCoin bool } if err := rlp.DecodeBytes(accIt.Value, &acc); err != nil { log.Crit("Invalid account encountered during snapshot creation", "err", err) } - data := SlimAccountRLP(acc.Nonce, acc.Balance, acc.Root, acc.CodeHash) + data := SlimAccountRLP(acc.Nonce, acc.Balance, acc.Root, acc.CodeHash, acc.IsMultiCoin) // If the account is not yet in-progress, write it out if accMarker == nil || !bytes.Equal(accountHash[:], accMarker) { diff --git a/core/state/statedb.go b/core/state/statedb.go index 805c607..b472bd7 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -270,11 +270,12 @@ func (self *StateDB) GetBalanceMultiCoin(addr common.Address, coinID common.Hash func (self *StateDB) EnableMultiCoin(addr common.Address) error { stateObject := self.GetOrNewStateObject(addr) if stateObject.data.Root != emptyRoot && stateObject.data.Root != zeroRoot { - return errors.New("not a fresh account") + return errors.New(fmt.Sprintf("not a fresh account: %s", stateObject.data.Root.Hex())) } if !stateObject.EnableMultiCoin() { return errors.New("multi-coin mode already enabled") } + log.Debug(fmt.Sprintf("enabled MC for %s", addr.Hex())) return nil } @@ -527,7 +528,7 @@ func (s *StateDB) updateStateObject(obj *stateObject) { // enough to track account updates at commit time, deletions need tracking // at transaction boundary level to ensure we capture state clearing. if s.snap != nil { - s.snapAccounts[obj.addrHash] = snapshot.SlimAccountRLP(obj.data.Nonce, obj.data.Balance, obj.data.Root, obj.data.CodeHash) + s.snapAccounts[obj.addrHash] = snapshot.SlimAccountRLP(obj.data.Nonce, obj.data.Balance, obj.data.Root, obj.data.CodeHash, obj.data.IsMultiCoin) } } diff --git a/core/types/block.go b/core/types/block.go index 37f3464..99d6cc8 100644 --- a/core/types/block.go +++ b/core/types/block.go @@ -166,7 +166,7 @@ type Body struct { Transactions []*Transaction Uncles []*Header Version uint32 - ExtData []byte `rlp:"nil"` + ExtData *[]byte `rlp:"nil"` } // Block represents an entire block in the Ethereum blockchain. @@ -175,7 +175,7 @@ type Block struct { uncles []*Header transactions Transactions version uint32 - extdata []byte + extdata *[]byte // caches hash atomic.Value @@ -216,7 +216,7 @@ type myextblock struct { Txs []*Transaction Uncles []*Header Version uint32 - ExtData []byte `rlp:"nil"` + ExtData *[]byte `rlp:"nil"` } // [deprecated by eth/63] @@ -235,7 +235,7 @@ type storageblock struct { // The values of TxHash, UncleHash, ReceiptHash and Bloom in header // are ignored and set to values derived from the given txs, uncles // and receipts. -func NewBlock(header *Header, txs []*Transaction, uncles []*Header, receipts []*Receipt, hasher Hasher, extdata []byte) *Block { +func NewBlock(header *Header, txs []*Transaction, uncles []*Header, receipts []*Receipt, hasher Hasher, extdata *[]byte) *Block { b := &Block{header: CopyHeader(header), td: new(big.Int)} // TODO: panic if len(txs) != len(receipts) @@ -264,8 +264,11 @@ func NewBlock(header *Header, txs []*Transaction, uncles []*Header, receipts []* } } - b.extdata = make([]byte, len(extdata)) - copy(b.extdata, extdata) + if extdata != nil { + data := make([]byte, len(*extdata)) + b.extdata = &data + copy(*b.extdata, *extdata) + } return b } @@ -321,13 +324,13 @@ func (b *Block) DecodeRLP(s *rlp.Stream) error { } func (b *Block) SetExtraData(data []byte) { - b.extdata = data + b.extdata = &data b.header.ExtDataHash = rlpHash(data) b.hash = atomic.Value{} } func (b *Block) ExtraData() []byte { - return b.extdata + return *b.extdata } func (b *Block) SetVersion(ver uint32) { @@ -460,16 +463,23 @@ func (b *Block) WithSeal(header *Header) *Block { } // WithBody returns a new block with the given transaction and uncle contents. -func (b *Block) WithBody(transactions []*Transaction, uncles []*Header, version uint32, extdata []byte) *Block { +func (b *Block) WithBody(transactions []*Transaction, uncles []*Header, version uint32, extdata *[]byte) *Block { + var data *[]byte + if extdata != nil { + _data := make([]byte, len(*extdata)) + data = &_data + } block := &Block{ header: CopyHeader(b.header), transactions: make([]*Transaction, len(transactions)), uncles: make([]*Header, len(uncles)), - extdata: make([]byte, len(extdata)), + extdata: data, version: version, } copy(block.transactions, transactions) - copy(block.extdata, extdata) + if data != nil { + copy(*block.extdata, *extdata) + } for i := range uncles { block.uncles[i] = CopyHeader(uncles[i]) } diff --git a/core/vm/evm.go b/core/vm/evm.go index 85b7ba7..e895211 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -275,17 +275,19 @@ func (evm *EVM) CallExpert(caller ContractRef, addr common.Address, input []byte return nil, gas, ErrDepth } - mcerr := evm.Context.CanTransferMC(evm.StateDB, caller.Address(), addr, coinID, value2) + // Fail if we're trying to transfer more than the available balance + if value.Sign() != 0 && !evm.Context.CanTransfer(evm.StateDB, caller.Address(), value) { + return nil, gas, ErrInsufficientBalance + } + + var to = AccountRef(addr) + mcerr := evm.Context.CanTransferMC(evm.StateDB, caller.Address(), to.Address(), coinID, value2) if mcerr == 1 { return nil, gas, ErrInsufficientBalance } else if mcerr != 0 { return nil, gas, ErrIncompatibleAccount } - // Fail if we're trying to transfer more than the available balance - if value.Sign() != 0 && !evm.Context.CanTransfer(evm.StateDB, caller.Address(), value) { - return nil, gas, ErrInsufficientBalance - } snapshot := evm.StateDB.Snapshot() p, isPrecompile := evm.precompile(addr) -- cgit v1.2.3-70-g09d2