Skip to content

Commit 72c72b6

Browse files
authored
6.0.8-stable backports (#37)
* Replace repository reference for accounts/abi/bind (#29) * docs: update badges (#34) * docs: add gitter badge * docs: add circle-ci badge * Update README.md * Update README.md * Update README.md * docs: update repository path * Update README.md * Tx Encoding and decoding fix (#33) * Added test for decoding old encoding function * Fixed decoding issue and improved tests to handle all cases including previous client * Add compatibility with previous version * Rename receipt storage variable * Storage and edge case fixes (#28) * Applied storage fixes and updates * Minor execution refactor
1 parent b898609 commit 72c72b6

12 files changed

Lines changed: 214 additions & 107 deletions

File tree

README.md

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,19 @@
11
# Geth Classic
22

3-
[![GitHub release](https://img.shields.io/github/release-pre/eth-classic/go-ethereum.svg)](https://github.com/eth-classic/go-ethereum/releases/latest)
4-
![GitHub All Releases](https://img.shields.io/github/downloads/eth-classic/go-ethereum/total.svg)
5-
![LICENSE](https://img.shields.io/github/license/eth-classic/go-ethereum.svg)
3+
[![GitHub release](https://img.shields.io/github/release-pre/etclabscore/go-ethereum.svg)](https://github.com/etclabscore/go-ethereum/releases/latest)
4+
![GitHub All Releases](https://img.shields.io/github/downloads/etclabscore/go-ethereum/total.svg)
5+
![LICENSE](https://img.shields.io/github/license/etclabscore/go-ethereum.svg)
66

7-
8-
[![CircleCI](https://img.shields.io/circleci/build/gh/eth-classic/go-ethereum/development.svg)](https://circleci.com/gh/eth-classic/go-ethereum/tree/development)
9-
![GitHub last commit](https://img.shields.io/github/last-commit/eth-classic/go-ethereum.svg)
10-
[![Join the chat at https://gitter.im/eth-classic/go-ethereum](https://badges.gitter.im/eth-classic/go-ethereum.svg)](https://gitter.im/eth-classic/go-ethereum?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
7+
[![CircleCI](https://img.shields.io/circleci/build/gh/etclabscore/go-ethereum/development.svg)](https://circleci.com/gh/etclabscore/go-ethereum/tree/development)
8+
![GitHub last commit](https://img.shields.io/github/last-commit/etclabscore/go-ethereum.svg)
9+
[![Join the chat at https://gitter.im/etclabscore/go-ethereum](https://badges.gitter.im/etclabscore/go-ethereum.svg)](https://gitter.im/etclabscore/go-ethereum?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
1110

1211
Official Go-language implementation of the Ethereum Classic protocol. Ethereum Classic (ETC) offers a censorship-resistant and powerful application platform for developers in parallel to the Ethereum Foundation network (ETH), while differentially rejecting the DAO transition.
1312

1413
## Install Geth Classic
1514

1615
### :gift: Official Releases
17-
Regular releases will be published on the [release page](https://github.com/eth-classic/go-ethereum/releases). Binaries will be provided for all releases that are considered fairly stable.
16+
Regular releases will be published on the [release page](https://github.com/etclabscore/go-ethereum/releases). Binaries will be provided for all releases that are considered fairly stable.
1817

1918
### :hammer: Building the source
2019
If your heart is set on the bleeding edge, install from source. However, please be advised that you may encounter some strange things, and we can't prioritize support beyond the release versions. Recommended for developers only.
@@ -28,7 +27,7 @@ With [Go modules](https://github.com/golang/go/wiki/Modules), dependencies will
2827
Clone the repository:
2928

3029
```
31-
git clone https://github.com/eth-classic/go-ethereum.git getc && cd getc
30+
git clone https://github.com/etclabscore/go-ethereum.git getc && cd getc
3231
```
3332

3433
Build all executables:
@@ -79,7 +78,7 @@ This repository includes several wrappers/executables found in the `cmd` directo
7978
| `bootnode` | Stripped down version of our Ethereum client implementation that only takes part in the network node discovery protocol, but does not run any of the higher level application protocols. It can be used as a lightweight bootstrap node to aid in finding peers in private networks. |
8079
| `disasm` | Bytecode disassembler to convert EVM (Ethereum Virtual Machine) bytecode into more user friendly assembly-like opcodes (e.g. `echo "6001" | disasm`). For details on the individual opcodes, please see pages 22-30 of the [Ethereum Yellow Paper](http://gavwood.com/paper.pdf). |
8180
| `evm` | Developer utility version of the EVM (Ethereum Virtual Machine) that is capable of running bytecode snippets within a configurable environment and execution mode. Its purpose is to allow insolated, fine graned debugging of EVM opcodes (e.g. `evm --code 60ff60ff --debug`). |
82-
| `gethrpctest` | Developer utility tool to support our [ethereum/rpc-test](https://github.com/eth-classic/rpc-tests) test suite which validates baseline conformity to the [Ethereum JSON RPC](https://github.com/ethereumproject/wiki/wiki/JSON-RPC) specs. Please see the [test suite's readme](https://github.com/eth-classic/rpc-tests/blob/master/README.md) for details. |
81+
| `gethrpctest` | Developer utility tool to support our [ethereum/rpc-test](https://github.com/etclabscore/rpc-tests) test suite which validates baseline conformity to the [Ethereum JSON RPC](https://github.com/ethereumproject/wiki/wiki/JSON-RPC) specs. Please see the [test suite's readme](https://github.com/etclabscore/rpc-tests/blob/master/README.md) for details. |
8382
| `rlpdump` | Developer utility tool to convert binary RLP ([Recursive Length Prefix](https://github.com/ethereumproject/wiki/wiki/RLP)) dumps (data encoding used by the Ethereum protocol both network as well as consensus wise) to user friendlier hierarchical representation (e.g. `rlpdump --hex CE0183FFFFFFC4C304050583616263`). |
8483

8584
## :green_book: Getting started with Geth Classic
@@ -207,7 +206,7 @@ You'll need to use your own programming environments' capabilities (libraries, t
207206
> Note: Please understand the security implications of opening up an HTTP/WS based transport before doing so! Hackers on the internet are actively trying to subvert Ethereum nodes with exposed APIs! Further, all browser tabs can access locally running webservers, so malicious webpages could try to subvert locally available APIs!*
208207
209208
### Operating a private/custom network
210-
As of [Geth 3.4](https://github.com/eth-classic/go-ethereum/releases) you are now able to configure a private chain by specifying an __external chain configuration__ JSON file, which includes necessary genesis block data as well as feature configurations for protocol forks, bootnodes, and chainID.
209+
As of [Geth 3.4](https://github.com/etclabscore/go-ethereum/releases) you are now able to configure a private chain by specifying an __external chain configuration__ JSON file, which includes necessary genesis block data as well as feature configurations for protocol forks, bootnodes, and chainID.
211210

212211
Please find full [example external configuration files representing the Mainnet and Morden Testnet specs in the /config subdirectory of this repo](). You can use either of these files as a starting point for your own customizations.
213212

core/database_util_test.go

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -702,6 +702,112 @@ func TestReceiptStorage(t *testing.T) {
702702
}
703703
}
704704

705+
func TestReceiptStorageEncoding(t *testing.T) {
706+
var w bytes.Buffer
707+
r := &types.ReceiptForStorage{
708+
PostState: []byte{0x01, 0x02},
709+
Status: types.TxSuccess,
710+
CumulativeGasUsed: big.NewInt(1),
711+
Logs: vm.Logs{
712+
&vm.Log{Address: common.BytesToAddress([]byte{0x11})},
713+
&vm.Log{Address: common.BytesToAddress([]byte{0x01, 0x11})},
714+
},
715+
TxHash: common.BytesToHash([]byte{0x12, 0x11}),
716+
ContractAddress: common.BytesToAddress([]byte{0x01, 0x11, 0x11}),
717+
GasUsed: big.NewInt(111111),
718+
}
719+
720+
r.EncodeRLP(&w)
721+
722+
var encodedReceipt types.ReceiptForStorage
723+
stream := rlp.NewStream(bytes.NewReader(w.Bytes()), 0)
724+
encodedReceipt.DecodeRLP(stream)
725+
726+
if bytes.Compare(encodedReceipt.PostState, r.PostState) != 0 {
727+
t.Errorf("Old storage receipt PostState: have (%v) want (%v)", encodedReceipt.PostState, r.PostState)
728+
}
729+
if encodedReceipt.Status != r.Status {
730+
t.Errorf("Old storage receipt status: have (%v) want (%v)", encodedReceipt.Status, r.Status)
731+
}
732+
if encodedReceipt.CumulativeGasUsed.Cmp(r.CumulativeGasUsed) != 0 {
733+
t.Errorf("Old storage receipt CumulativeGasUsed: have (%v) want (%v)", encodedReceipt.CumulativeGasUsed, r.CumulativeGasUsed)
734+
}
735+
if encodedReceipt.TxHash != r.TxHash {
736+
t.Errorf("Old storage receipt TxHash: have (%v) want (%v)", encodedReceipt.TxHash, r.TxHash)
737+
}
738+
if encodedReceipt.ContractAddress != r.ContractAddress {
739+
t.Errorf("Old storage receipt ContractAddress: have (%v) want (%v)", encodedReceipt.ContractAddress, r.ContractAddress)
740+
}
741+
if encodedReceipt.GasUsed.Cmp(r.GasUsed) != 0 {
742+
t.Errorf("Old storage receipt GasUsed: have (%v) want (%v)", encodedReceipt.GasUsed, r.GasUsed)
743+
}
744+
for i, log := range r.Logs {
745+
if bytes.Compare(r.Logs[i].Data, log.Data) != 0 {
746+
t.Errorf("Old storage receipt Log: have (%v) want (%v)", log.Data, r.Logs[i].Data)
747+
}
748+
}
749+
}
750+
751+
func TestOldReceiptStorageTransition(t *testing.T) {
752+
var w bytes.Buffer
753+
r := &types.Receipt{
754+
PostState: []byte{0x24, 0x12},
755+
Status: types.TxSuccess,
756+
CumulativeGasUsed: big.NewInt(1),
757+
Logs: vm.Logs{
758+
&vm.Log{Address: common.BytesToAddress([]byte{0x11})},
759+
&vm.Log{Address: common.BytesToAddress([]byte{0x01, 0x11})},
760+
},
761+
TxHash: common.BytesToHash([]byte{0x11, 0x11}),
762+
ContractAddress: common.BytesToAddress([]byte{0x01, 0x11, 0x11}),
763+
GasUsed: big.NewInt(111111),
764+
}
765+
766+
logs := make([]*vm.LogForStorage, len(r.Logs))
767+
for i, log := range r.Logs {
768+
logs[i] = (*vm.LogForStorage)(log)
769+
}
770+
771+
rlp.Encode(&w, []interface{}{
772+
r.PostState,
773+
r.CumulativeGasUsed,
774+
r.Bloom,
775+
r.TxHash,
776+
r.ContractAddress,
777+
logs,
778+
r.GasUsed,
779+
r.Status,
780+
})
781+
782+
var encodedReceipt types.ReceiptForStorage
783+
stream := rlp.NewStream(bytes.NewReader(w.Bytes()), 0)
784+
encodedReceipt.DecodeRLP(stream)
785+
786+
if bytes.Compare(encodedReceipt.PostState, r.PostState) != 0 {
787+
t.Errorf("Old storage receipt PostState: have (%v) want (%v)", encodedReceipt.PostState, r.PostState)
788+
}
789+
if encodedReceipt.Status != r.Status {
790+
t.Errorf("Old storage receipt status: have (%v) want (%v)", encodedReceipt.Status, r.Status)
791+
}
792+
if encodedReceipt.CumulativeGasUsed.Cmp(r.CumulativeGasUsed) != 0 {
793+
t.Errorf("Old storage receipt CumulativeGasUsed: have (%v) want (%v)", encodedReceipt.CumulativeGasUsed, r.CumulativeGasUsed)
794+
}
795+
if encodedReceipt.TxHash != r.TxHash {
796+
t.Errorf("Old storage receipt TxHash: have (%v) want (%v)", encodedReceipt.TxHash, r.TxHash)
797+
}
798+
if encodedReceipt.ContractAddress != r.ContractAddress {
799+
t.Errorf("Old storage receipt ContractAddress: have (%v) want (%v)", encodedReceipt.ContractAddress, r.ContractAddress)
800+
}
801+
if encodedReceipt.GasUsed.Cmp(r.GasUsed) != 0 {
802+
t.Errorf("Old storage receipt GasUsed: have (%v) want (%v)", encodedReceipt.GasUsed, r.GasUsed)
803+
}
804+
for i, log := range r.Logs {
805+
if bytes.Compare(r.Logs[i].Data, log.Data) != 0 {
806+
t.Errorf("Old storage receipt Log: have (%v) want (%v)", log.Data, r.Logs[i].Data)
807+
}
808+
}
809+
}
810+
705811
// Tests that receipts associated with a single block can be stored and retrieved.
706812
func TestBlockReceiptStorage(t *testing.T) {
707813
db, _ := ethdb.NewMemDatabase()

core/execution.go

Lines changed: 10 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ var (
4545
// the necessary steps to create accounts and reverses the state in case of an
4646
// execution error or failed value transfer.
4747
func Call(env vm.Environment, caller vm.ContractRef, addr common.Address, input []byte, gas, gasPrice, value *big.Int) (ret []byte, err error) {
48-
evm := env.Vm()
4948
// Depth check execution. Fail if we're trying to execute above the limit.
5049
if env.Depth() > callCreateDepthMax {
5150
caller.ReturnGas(gas, gasPrice)
@@ -86,7 +85,7 @@ func Call(env vm.Environment, caller vm.ContractRef, addr common.Address, input
8685
defer contract.Finalise()
8786

8887
// Even if the account has no code, we need to continue because it might be a precompile
89-
ret, err = evm.Run(contract, input, false)
88+
ret, err = env.Vm().Run(contract, input, false)
9089

9190
// When an error was returned by the EVM or when setting the creation code
9291
// above we revert to the snapshot and consume any gas remaining. Additionally
@@ -102,7 +101,6 @@ func Call(env vm.Environment, caller vm.ContractRef, addr common.Address, input
102101

103102
// CallCode executes the given address' code as the given contract address
104103
func CallCode(env vm.Environment, caller vm.ContractRef, addr common.Address, input []byte, gas, gasPrice, value *big.Int) (ret []byte, err error) {
105-
evm := env.Vm()
106104
// Depth check execution. Fail if we're trying to execute above the limit.
107105
if env.Depth() > callCreateDepthMax {
108106
caller.ReturnGas(gas, gasPrice)
@@ -127,7 +125,7 @@ func CallCode(env vm.Environment, caller vm.ContractRef, addr common.Address, in
127125
defer contract.Finalise()
128126

129127
// Even if the account has no code, we need to continue because it might be a precompile
130-
ret, err = evm.Run(contract, input, false)
128+
ret, err = env.Vm().Run(contract, input, false)
131129

132130
if err != nil {
133131
env.RevertToSnapshot(snapshot)
@@ -140,7 +138,6 @@ func CallCode(env vm.Environment, caller vm.ContractRef, addr common.Address, in
140138

141139
// DelegateCall is equivalent to CallCode except that sender and value propagates from parent scope to child scope
142140
func DelegateCall(env vm.Environment, caller vm.ContractRef, addr common.Address, input []byte, gas, gasPrice *big.Int) (ret []byte, err error) {
143-
evm := env.Vm()
144141
// Depth check execution. Fail if we're trying to execute above the limit.
145142
if env.Depth() > callCreateDepthMax {
146143
caller.ReturnGas(gas, gasPrice)
@@ -165,7 +162,7 @@ func DelegateCall(env vm.Environment, caller vm.ContractRef, addr common.Address
165162
defer contract.Finalise()
166163

167164
// Even if the account has no code, we need to continue because it might be a precompile
168-
ret, err = evm.Run(contract, input, false)
165+
ret, err = env.Vm().Run(contract, input, false)
169166

170167
// When an error was returned by the EVM or when setting the creation code
171168
// above we revert to the snapshot and consume any gas remaining. Additionally
@@ -181,7 +178,6 @@ func DelegateCall(env vm.Environment, caller vm.ContractRef, addr common.Address
181178

182179
// StaticCall executes within the given contract and throws exception if state is attempted to be changed
183180
func StaticCall(env vm.Environment, caller vm.ContractRef, addr common.Address, input []byte, gas, gasPrice *big.Int) (ret []byte, err error) {
184-
evm := env.Vm()
185181
// Depth check execution. Fail if we're trying to execute above the limit.
186182
if env.Depth() > callCreateDepthMax {
187183
caller.ReturnGas(gas, gasPrice)
@@ -211,7 +207,7 @@ func StaticCall(env vm.Environment, caller vm.ContractRef, addr common.Address,
211207
env.Db().AddBalance(addr, big.NewInt(0))
212208

213209
// Even if the account has no code, we need to continue because it might be a precompile
214-
ret, err = evm.Run(contract, input, true)
210+
ret, err = env.Vm().Run(contract, input, true)
215211

216212
// When an error was returned by the EVM or when setting the creation code
217213
// above we revert to the snapshot and consume any gas remaining. Additionally
@@ -227,20 +223,6 @@ func StaticCall(env vm.Environment, caller vm.ContractRef, addr common.Address,
227223

228224
// Create creates a new contract with the given code
229225
func Create(env vm.Environment, caller vm.ContractRef, code []byte, gas, gasPrice, value *big.Int) (ret []byte, address common.Address, err error) {
230-
ret, address, err = create(env, caller, crypto.Keccak256Hash(code), code, gas, gasPrice, value)
231-
// Here we get an error if we run into maximum stack depth,
232-
// See: https://github.com/ethereum/yellowpaper/pull/131
233-
// and YP definitions for CREATE
234-
235-
//if there's an error we return nothing
236-
if err != nil && err != vm.ErrRevert {
237-
return nil, address, err
238-
}
239-
return ret, address, err
240-
}
241-
242-
func create(env vm.Environment, caller vm.ContractRef, codeHash common.Hash, code []byte, gas, gasPrice, value *big.Int) (ret []byte, address common.Address, err error) {
243-
evm := env.Vm()
244226
// Depth check execution. Fail if we're trying to execute above the limit.
245227
if env.Depth() > callCreateDepthMax {
246228
caller.ReturnGas(gas, gasPrice)
@@ -281,10 +263,10 @@ func create(env vm.Environment, caller vm.ContractRef, codeHash common.Hash, cod
281263
// EVM. The contract is a scoped environment for this execution context
282264
// only.
283265
contract := vm.NewContract(caller, to, value, gas, gasPrice)
284-
contract.SetCallCode(nil, codeHash, code)
266+
contract.SetCallCode(nil, crypto.Keccak256Hash(code), code)
285267
defer contract.Finalise()
286268

287-
ret, err = evm.Run(contract, nil, false)
269+
ret, err = env.Vm().Run(contract, nil, false)
288270

289271
maxCodeSizeExceeded := len(ret) > maxCodeSize && env.RuleSet().IsAtlantis(env.BlockNumber())
290272
// if the contract creation ran successfully and no errors were returned
@@ -317,6 +299,10 @@ func create(env vm.Environment, caller vm.ContractRef, codeHash common.Hash, cod
317299
err = errMaxCodeSizeExceeded
318300
}
319301

302+
//if there's an error we return nothing
303+
if err != nil && err != vm.ErrRevert {
304+
return nil, address, err
305+
}
320306
return ret, address, err
321307
}
322308

core/state/state_object.go

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -386,18 +386,27 @@ func (self *StateObject) Value() *big.Int {
386386
panic("Value on StateObject should never be called")
387387
}
388388

389-
func (self *StateObject) ForEachStorage(cb func(key, value common.Hash) bool) {
390-
// When iterating over the storage check the cache first
391-
for h, value := range self.cachedStorage {
392-
cb(h, value)
393-
}
394-
395-
it := trie.NewIterator(self.getTrie(self.db.db).NodeIterator(nil))
389+
func (s *StateObject) ForEachStorage(cb func(key, value common.Hash) bool) error {
390+
it := trie.NewIterator(s.getTrie(s.db.db).NodeIterator(nil))
396391
for it.Next() {
397392
// ignore cached values
398-
key := common.BytesToHash(self.trie.GetKey(it.Key))
399-
if _, ok := self.cachedStorage[key]; !ok {
400-
cb(key, common.BytesToHash(it.Value))
393+
key := common.BytesToHash(s.trie.GetKey(it.Key))
394+
if value, dirty := s.dirtyStorage[key]; dirty {
395+
if cb(key, value) {
396+
return nil
397+
}
398+
continue
399+
}
400+
401+
if len(it.Value) > 0 {
402+
_, content, _, err := rlp.Split(it.Value)
403+
if err != nil {
404+
return err
405+
}
406+
if !cb(key, common.BytesToHash(content)) {
407+
return nil
408+
}
401409
}
402410
}
411+
return nil
403412
}

0 commit comments

Comments
 (0)