diff --git a/.gitmodules b/.gitmodules index 32bdb3b6e5..4437cd0058 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "tests"] path = tests/testdata - url = https://github.com/ethereum/tests + url = https://github.com/pavelkrolevets/tests diff --git a/.travis.yml b/.travis.yml index 24b5bb9480..eb008c4f11 100644 --- a/.travis.yml +++ b/.travis.yml @@ -157,8 +157,8 @@ matrix: - mv android-ndk-r17b $HOME - export ANDROID_NDK=$HOME/android-ndk-r17b - - mkdir -p $GOPATH/src/github.com/ethereum - - ln -s `pwd` $GOPATH/src/github.com/ethereum + - mkdir -p $GOPATH/src/github.com/pavelkrolevets + - ln -s `pwd` $GOPATH/src/github.com/pavelkrolevets - go run build/ci.go aar -signer ANDROID_SIGNING_KEY -deploy https://oss.sonatype.org -upload gethstore/builds # This builder does the OSX Azure, iOS CocoaPods and iOS Azure uploads diff --git a/README.md b/README.md index 729839c155..36dbac701d 100644 --- a/README.md +++ b/README.md @@ -35,11 +35,11 @@ The go-ethereum project comes with several wrappers/executables found in the `cm | Command | Description | |:----------:|-------------| | **`geth`** | Our main Ethereum CLI client. It is the entry point into the Ethereum network (main-, test- or private net), capable of running as a full node (default) archive node (retaining all historical state) or a light node (retrieving data live). It can be used by other processes as a gateway into the Ethereum network via JSON RPC endpoints exposed on top of HTTP, WebSocket and/or IPC transports. `geth --help` and the [CLI Wiki page](https://github.com/pavelkrolevets/go-ethereum/wiki/Command-Line-Options) for command line options. | -| `abigen` | Source code generator to convert Ethereum contract definitions into easy to use, compile-time type-safe Go packages. It operates on plain [Ethereum contract ABIs](https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI) with expanded functionality if the contract bytecode is also available. However it also accepts Solidity source files, making development much more streamlined. Please see our [Native DApps](https://github.com/pavelkrolevets/go-ethereum/wiki/Native-DApps:-Go-bindings-to-Ethereum-contracts) wiki page for details. | +| `abigen` | Source code generator to convert Ethereum contract definitions into easy to use, compile-time type-safe Go packages. It operates on plain [Ethereum contract ABIs](https://github.com/pavelkrolevets/wiki/wiki/Ethereum-Contract-ABI) with expanded functionality if the contract bytecode is also available. However it also accepts Solidity source files, making development much more streamlined. Please see our [Native DApps](https://github.com/pavelkrolevets/go-ethereum/wiki/Native-DApps:-Go-bindings-to-Ethereum-contracts) wiki page for details. | | `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. | | `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 isolated, fine-grained debugging of EVM opcodes (e.g. `evm --code 60ff60ff --debug`). | -| `gethrpctest` | Developer utility tool to support our [ethereum/rpc-test](https://github.com/ethereum/rpc-tests) test suite which validates baseline conformity to the [Ethereum JSON RPC](https://github.com/ethereum/wiki/wiki/JSON-RPC) specs. Please see the [test suite's readme](https://github.com/ethereum/rpc-tests/blob/master/README.md) for details. | -| `rlpdump` | Developer utility tool to convert binary RLP ([Recursive Length Prefix](https://github.com/ethereum/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`). | +| `gethrpctest` | Developer utility tool to support our [ethereum/rpc-test](https://github.com/pavelkrolevets/rpc-tests) test suite which validates baseline conformity to the [Ethereum JSON RPC](https://github.com/pavelkrolevets/wiki/wiki/JSON-RPC) specs. Please see the [test suite's readme](https://github.com/pavelkrolevets/rpc-tests/blob/master/README.md) for details. | +| `rlpdump` | Developer utility tool to convert binary RLP ([Recursive Length Prefix](https://github.com/pavelkrolevets/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`). | | `swarm` | Swarm daemon and tools. This is the entrypoint for the Swarm network. `swarm --help` for command line options and subcommands. See [Swarm README](https://github.com/pavelkrolevets/go-ethereum/tree/master/swarm) for more information. | | `puppeth` | a CLI wizard that aids in creating a new Ethereum network. | @@ -67,7 +67,7 @@ This command will: download more data in exchange for avoiding processing the entire history of the Ethereum network, which is very CPU intensive. * Start up Geth's built-in interactive [JavaScript console](https://github.com/pavelkrolevets/go-ethereum/wiki/JavaScript-Console), - (via the trailing `console` subcommand) through which you can invoke all official [`web3` methods](https://github.com/ethereum/wiki/wiki/JavaScript-API) + (via the trailing `console` subcommand) through which you can invoke all official [`web3` methods](https://github.com/pavelkrolevets/wiki/wiki/JavaScript-API) as well as Geth's own [management APIs](https://github.com/pavelkrolevets/go-ethereum/wiki/Management-APIs). This too is optional and if you leave it out you can always attach to an already running Geth instance with `geth attach`. @@ -143,7 +143,7 @@ Do not forget `--rpcaddr 0.0.0.0`, if you want to access RPC from other containe As a developer, sooner rather than later you'll want to start interacting with Geth and the Ethereum network via your own programs and not manually through the console. To aid this, Geth has built-in -support for a JSON-RPC based APIs ([standard APIs](https://github.com/ethereum/wiki/wiki/JSON-RPC) and +support for a JSON-RPC based APIs ([standard APIs](https://github.com/pavelkrolevets/wiki/wiki/JSON-RPC) and [Geth specific APIs](https://github.com/pavelkrolevets/go-ethereum/wiki/Management-APIs)). These can be exposed via HTTP, WebSockets and IPC (unix sockets on unix based platforms, and named pipes on Windows). @@ -236,7 +236,7 @@ $ bootnode --genkey=boot.key $ bootnode --nodekey=boot.key ``` -With the bootnode online, it will display an [`enode` URL](https://github.com/ethereum/wiki/wiki/enode-url-format) +With the bootnode online, it will display an [`enode` URL](https://github.com/pavelkrolevets/wiki/wiki/enode-url-format) that other nodes can use to connect to it and exchange peer information. Make sure to replace the displayed IP address information (most probably `[::]`) with your externally accessible IP to get the actual `enode` URL. diff --git a/accounts/hd.go b/accounts/hd.go index 277f688e48..87d4cef8a8 100644 --- a/accounts/hd.go +++ b/accounts/hd.go @@ -53,7 +53,7 @@ var DefaultLedgerBaseDerivationPath = DerivationPath{0x80000000 + 44, 0x80000000 // the `coin_type` 60' (or 0x8000003C) to Ethereum. // // The root path for Ethereum is m/44'/60'/0'/0 according to the specification -// from https://github.com/ethereum/EIPs/issues/84, albeit it's not set in stone +// from https://github.com/pavelkrolevets/EIPs/issues/84, albeit it's not set in stone // yet whether accounts should increment the last component or the children of // that. We will go with the simpler approach of incrementing the last component. type DerivationPath []uint32 diff --git a/accounts/keystore/keystore.go b/accounts/keystore/keystore.go index ac384d5ebf..0d3c7cef64 100644 --- a/accounts/keystore/keystore.go +++ b/accounts/keystore/keystore.go @@ -17,7 +17,7 @@ // Package keystore implements encrypted storage of secp256k1 private keys. // // Keys are stored as encrypted JSON files according to the Web3 Secret Storage specification. -// See https://github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition for more information. +// See https://github.com/pavelkrolevets/wiki/wiki/Web3-Secret-Storage-Definition for more information. package keystore import ( diff --git a/accounts/keystore/keystore_passphrase.go b/accounts/keystore/keystore_passphrase.go index 053a96185f..e8d109487a 100644 --- a/accounts/keystore/keystore_passphrase.go +++ b/accounts/keystore/keystore_passphrase.go @@ -19,7 +19,7 @@ This key store behaves as KeyStorePlain with the difference that the private key is encrypted and on disk uses another JSON encoding. -The crypto is documented at https://github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition +The crypto is documented at https://github.com/pavelkrolevets/wiki/wiki/Web3-Secret-Storage-Definition */ diff --git a/accounts/keystore/presale.go b/accounts/keystore/presale.go index 41c9781573..1336b7c16e 100644 --- a/accounts/keystore/presale.go +++ b/accounts/keystore/presale.go @@ -64,7 +64,7 @@ func decryptPreSaleKey(fileContent []byte, password string) (key *Key, err error iv := encSeedBytes[:16] cipherText := encSeedBytes[16:] /* - See https://github.com/ethereum/pyethsaletool + See https://github.com/pavelkrolevets/pyethsaletool pyethsaletool generates the encryption key from password by 2000 rounds of PBKDF2 with HMAC-SHA-256 using password as salt (:(). diff --git a/build/nsis.install.nsh b/build/nsis.install.nsh index 0ef2409a63..d2c172d351 100644 --- a/build/nsis.install.nsh +++ b/build/nsis.install.nsh @@ -33,7 +33,7 @@ Section "Geth" GETH_IDX SimpleFC::AdvAddRule "Geth outgoing peers (TCP:30303)" "" 6 2 1 2147483647 1 "$INSTDIR\geth.exe" "" "" "Ethereum" "" 30303 "" "" SimpleFC::AdvAddRule "Geth UDP discovery (UDP:30303)" "" 17 2 1 2147483647 1 "$INSTDIR\geth.exe" "" "" "Ethereum" "" 30303 "" "" - # Set default IPC endpoint (https://github.com/ethereum/EIPs/issues/147) + # Set default IPC endpoint (https://github.com/pavelkrolevets/EIPs/issues/147) ${EnvVarUpdate} $0 "ETHEREUM_SOCKET" "R" "HKLM" "\\.\pipe\geth.ipc" ${EnvVarUpdate} $0 "ETHEREUM_SOCKET" "A" "HKLM" "\\.\pipe\geth.ipc" diff --git a/build/nsis.uninstall.nsh b/build/nsis.uninstall.nsh index 6358faa74e..5b9af5c3b7 100644 --- a/build/nsis.uninstall.nsh +++ b/build/nsis.uninstall.nsh @@ -21,7 +21,7 @@ Section "Uninstall" SimpleFC::AdvRemoveRule "Geth outgoing peers (TCP:30303)" SimpleFC::AdvRemoveRule "Geth UDP discovery (UDP:30303)" - # Remove IPC endpoint (https://github.com/ethereum/EIPs/issues/147) + # Remove IPC endpoint (https://github.com/pavelkrolevets/EIPs/issues/147) ${un.EnvVarUpdate} $0 "ETHEREUM_SOCKET" "R" "HKLM" "\\.\pipe\geth.ipc" # Remove install directory from PATH diff --git a/cmd/clef/README.md b/cmd/clef/README.md index 027c22c98f..430eb8f33d 100644 --- a/cmd/clef/README.md +++ b/cmd/clef/README.md @@ -170,7 +170,7 @@ All hex encoded values must be prefixed with `0x`. #### Create new password protected account -The signer will generate a new private key, encrypts it according to [web3 keystore spec](https://github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition) and stores it in the keystore directory. +The signer will generate a new private key, encrypts it according to [web3 keystore spec](https://github.com/pavelkrolevets/wiki/wiki/Web3-Secret-Storage-Definition) and stores it in the keystore directory. The client is responsible for creating a backup of the keystore. If the keystore is lost there is no method of retrieving lost accounts. #### Arguments @@ -423,7 +423,7 @@ Response format. #### Arguments - - account [object]: key in [web3 keystore format](https://github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition) (retrieved with account_export) + - account [object]: key in [web3 keystore format](https://github.com/pavelkrolevets/wiki/wiki/Web3-Secret-Storage-Definition) (retrieved with account_export) #### Result - imported key [object]: @@ -486,7 +486,7 @@ Response - account [address]: export private key that is associated with this account #### Result - - exported key, see [web3 keystore format](https://github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition) for + - exported key, see [web3 keystore format](https://github.com/pavelkrolevets/wiki/wiki/Web3-Secret-Storage-Definition) for more information #### Sample call diff --git a/cmd/puppeth/module_dashboard.go b/cmd/puppeth/module_dashboard.go index 7ded8e01b7..84ba12b70c 100644 --- a/cmd/puppeth/module_dashboard.go +++ b/cmd/puppeth/module_dashboard.go @@ -211,7 +211,7 @@ var dashboardContent = `
ethereumwallet --rpc $HOME/.{{.Network}}/geth.ipc --node-networkid={{.NetworkID}} --node-datadir=$HOME/.{{.Network}}{{if .Ethstats}} --node-ethstats='{{.Ethstats}}'{{end}} --node-bootnodes={{.BootnodesFlat}}


-

You can download the Ethereum Wallet from https://github.com/ethereum/mist/releases.

+

You can download the Ethereum Wallet from https://github.com/pavelkrolevets/mist/releases.

@@ -232,7 +232,7 @@ var dashboardContent = `
mist --rpc $HOME/.{{.Network}}/geth.ipc --node-networkid={{.NetworkID}} --node-datadir=$HOME/.{{.Network}}{{if .Ethstats}} --node-ethstats='{{.Ethstats}}'{{end}} --node-bootnodes={{.BootnodesFlat}}


-

You can download the Mist browser from https://github.com/ethereum/mist/releases.

+

You can download the Mist browser from https://github.com/pavelkrolevets/mist/releases.

@@ -337,7 +337,7 @@ try! node?.start();
eth --config {{.CppGenesis}} --datadir $HOME/.{{.Network}} --peerset "{{.CppBootnodes}}"


-

You can find cpp-ethereum at https://github.com/ethereum/cpp-ethereum/.

+

You can find cpp-ethereum at https://github.com/pavelkrolevets/cpp-ethereum/.

@@ -401,7 +401,7 @@ try! node?.start();
pyethapp -c eth.genesis="$(cat {{.PythonGenesis}})" -c eth.network_id={{.NetworkID}} -c data_dir=$HOME/.config/pyethapp/{{.Network}} -c discovery.bootstrap_nodes="[{{.PythonBootnodes}}]" -c eth.block.HOMESTEAD_FORK_BLKNUM={{.Homestead}} -c eth.block.ANTI_DOS_FORK_BLKNUM={{.Tangerine}} -c eth.block.SPURIOUS_DRAGON_FORK_BLKNUM={{.Spurious}} -c eth.block.METROPOLIS_FORK_BLKNUM={{.Byzantium}} -c eth.block.DAO_FORK_BLKNUM=18446744073709551615 run --console


-

You can find pyethapp at https://github.com/ethereum/pyethapp/.

+

You can find pyethapp at https://github.com/pavelkrolevets/pyethapp/.

diff --git a/common/types_test.go b/common/types_test.go index 7095ccd019..1bfa7eb4ed 100644 --- a/common/types_test.go +++ b/common/types_test.go @@ -126,7 +126,7 @@ func TestAddressHexChecksum(t *testing.T) { Input string Output string }{ - // Test cases from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-55.md#specification + // Test cases from https://github.com/pavelkrolevets/EIPs/blob/master/EIPS/eip-55.md#specification {"0x5aaeb6053f3e94c9b9a09f33669435e7ef1beaed", "0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed"}, {"0xfb6916095ca1df60bb79ce92ce3ea74c37c5d359", "0xfB6916095ca1df60bB79Ce92cE3Ea74c37c5d359"}, {"0xdbf03b407c01e7cd3cbea99509d93f8dddc8c6fb", "0xdbF03B407c01E7cD3CBea99509d93f8DDDC8C6FB"}, @@ -154,7 +154,7 @@ func BenchmarkAddressHex(b *testing.B) { func TestMixedcaseAccount_Address(t *testing.T) { - // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-55.md + // https://github.com/pavelkrolevets/EIPs/blob/master/EIPS/eip-55.md // Note: 0X{checksum_addr} is not valid according to spec above var res []struct { diff --git a/consensus/dpos/api.go b/consensus/dpos/api.go index cc7b8a93db..2748b0efd1 100644 --- a/consensus/dpos/api.go +++ b/consensus/dpos/api.go @@ -17,10 +17,10 @@ package dpos import ( - "github.com/pavelkrolevets/go-ethereum/common" - "github.com/pavelkrolevets/go-ethereum/consensus" - "github.com/pavelkrolevets/go-ethereum/core/types" - "github.com/pavelkrolevets/go-ethereum/rpc" + "github.com/meitu/go-ethereum/common" + "github.com/meitu/go-ethereum/consensus" + "github.com/meitu/go-ethereum/core/types" + "github.com/meitu/go-ethereum/rpc" "math/big" ) diff --git a/consensus/dpos/dpos.go b/consensus/dpos/dpos.go index d8e9f78277..d53d0f8cba 100644 --- a/consensus/dpos/dpos.go +++ b/consensus/dpos/dpos.go @@ -33,9 +33,9 @@ const ( blockInterval = int64(1) epochInterval = int64(86400) - maxValidatorSize = 3 - safeSize = maxValidatorSize*2/3 + 1 - consensusSize = maxValidatorSize*2/3 + 1 + maxValidatorSize = 1 + safeSize = 1 //maxValidatorSize*2/3 + 1 + consensusSize = 1 //maxValidatorSize*2/3 + 1 ) var ( diff --git a/consensus/dpos/dpos_test.go b/consensus/dpos/dpos_test.go index 7f79ace3aa..784fbbce9a 100644 --- a/consensus/dpos/dpos_test.go +++ b/consensus/dpos/dpos_test.go @@ -5,10 +5,10 @@ import ( "encoding/binary" - "github.com/pavelkrolevets/go-ethereum/common" - "github.com/pavelkrolevets/go-ethereum/core/types" - "github.com/pavelkrolevets/go-ethereum/ethdb" - "github.com/pavelkrolevets/go-ethereum/trie" + "github.com/meitu/go-ethereum/common" + "github.com/meitu/go-ethereum/core/types" + "github.com/meitu/go-ethereum/ethdb" + "github.com/meitu/go-ethereum/trie" "github.com/stretchr/testify/assert" ) diff --git a/consensus/dpos/epoch_context.go b/consensus/dpos/epoch_context.go index cbda686c1e..03cf821604 100644 --- a/consensus/dpos/epoch_context.go +++ b/consensus/dpos/epoch_context.go @@ -8,12 +8,12 @@ import ( "math/rand" "sort" - "github.com/pavelkrolevets/go-ethereum/common" - "github.com/pavelkrolevets/go-ethereum/core/state" - "github.com/pavelkrolevets/go-ethereum/core/types" - "github.com/pavelkrolevets/go-ethereum/crypto" - "github.com/pavelkrolevets/go-ethereum/log" - "github.com/pavelkrolevets/go-ethereum/trie" + "github.com/meitu/go-ethereum/common" + "github.com/meitu/go-ethereum/core/state" + "github.com/meitu/go-ethereum/core/types" + "github.com/meitu/go-ethereum/crypto" + "github.com/meitu/go-ethereum/log" + "github.com/meitu/go-ethereum/trie" ) type EpochContext struct { diff --git a/consensus/dpos/epoch_context_test.go b/consensus/dpos/epoch_context_test.go index e8a2d2fde7..8a2fab6589 100644 --- a/consensus/dpos/epoch_context_test.go +++ b/consensus/dpos/epoch_context_test.go @@ -6,11 +6,11 @@ import ( "strings" "testing" - "github.com/pavelkrolevets/go-ethereum/common" - "github.com/pavelkrolevets/go-ethereum/core/state" - "github.com/pavelkrolevets/go-ethereum/core/types" - "github.com/pavelkrolevets/go-ethereum/ethdb" - "github.com/pavelkrolevets/go-ethereum/trie" + "github.com/meitu/go-ethereum/common" + "github.com/meitu/go-ethereum/core/state" + "github.com/meitu/go-ethereum/core/types" + "github.com/meitu/go-ethereum/ethdb" + "github.com/meitu/go-ethereum/trie" "github.com/stretchr/testify/assert" ) diff --git a/consensus/ethash/consensus.go b/consensus/ethash/consensus.go index 63220bb748..fd8095da03 100644 --- a/consensus/ethash/consensus.go +++ b/consensus/ethash/consensus.go @@ -321,7 +321,7 @@ var ( // the difficulty that a new block should have when created at time given the // parent block's time and difficulty. The calculation uses the Byzantium rules. func calcDifficultyByzantium(time uint64, parent *types.Header) *big.Int { - // https://github.com/ethereum/EIPs/issues/100. + // https://github.com/pavelkrolevets/EIPs/issues/100. // algorithm: // diff = (parent_diff + // (parent_diff / 2048 * max((2 if len(parent.uncles) else 1) - ((timestamp - parent.timestamp) // 9), -99)) @@ -356,7 +356,7 @@ func calcDifficultyByzantium(time uint64, parent *types.Header) *big.Int { x.Set(params.MinimumDifficulty) } // calculate a fake block number for the ice-age delay: - // https://github.com/ethereum/EIPs/pull/669 + // https://github.com/pavelkrolevets/EIPs/pull/669 // fake_block_number = max(0, block.number - 3_000_000) fakeBlockNumber := new(big.Int) if parent.Number.Cmp(big2999999) >= 0 { @@ -380,7 +380,7 @@ func calcDifficultyByzantium(time uint64, parent *types.Header) *big.Int { // the difficulty that a new block should have when created at time given the // parent block's time and difficulty. The calculation uses the Homestead rules. func calcDifficultyHomestead(time uint64, parent *types.Header) *big.Int { - // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2.md + // https://github.com/pavelkrolevets/EIPs/blob/master/EIPS/eip-2.md // algorithm: // diff = (parent_diff + // (parent_diff / 2048 * max(1 - (block_timestamp - parent_timestamp) // 10, -99)) diff --git a/contracts/ens/README.md b/contracts/ens/README.md index c09b47e39d..92d1930fc2 100644 --- a/contracts/ens/README.md +++ b/contracts/ens/README.md @@ -2,7 +2,7 @@ ## Usage -Full documentation for the Ethereum Name Service [can be found as EIP 137](https://github.com/ethereum/EIPs/issues/137). +Full documentation for the Ethereum Name Service [can be found as EIP 137](https://github.com/pavelkrolevets/EIPs/issues/137). This package offers a simple binding that streamlines the registration of arbitrary UTF8 domain names to swarm content hashes. ## Development diff --git a/core/types/block.go b/core/types/block.go index a02c049ecf..606f73ff59 100644 --- a/core/types/block.go +++ b/core/types/block.go @@ -25,6 +25,7 @@ import ( "sync/atomic" "time" "unsafe" + "fmt" "github.com/pavelkrolevets/go-ethereum/common" "github.com/pavelkrolevets/go-ethereum/common/hexutil" @@ -70,6 +71,8 @@ func (n *BlockNonce) UnmarshalText(input []byte) error { type Header struct { ParentHash common.Hash `json:"parentHash" gencodec:"required"` UncleHash common.Hash `json:"sha3Uncles" gencodec:"required"` + Validator common.Address `json:"validator" gencodec:"required"` + DposContext *DposContextProto `json:"dposContext" gencodec:"required"` Coinbase common.Address `json:"miner" gencodec:"required"` Root common.Hash `json:"stateRoot" gencodec:"required"` TxHash common.Hash `json:"transactionsRoot" gencodec:"required"` @@ -107,6 +110,7 @@ func (h *Header) HashNoNonce() common.Hash { return rlpHash([]interface{}{ h.ParentHash, h.UncleHash, + h.Validator, h.Coinbase, h.Root, h.TxHash, @@ -159,6 +163,7 @@ type Block struct { // inter-peer block relay. ReceivedAt time.Time ReceivedFrom interface{} + DposContext *DposContext } // DeprecatedTd is an old relic for extracting the TD of a block. It is in the @@ -253,6 +258,11 @@ func CopyHeader(h *Header) *Header { cpy.Extra = make([]byte, len(h.Extra)) copy(cpy.Extra, h.Extra) } + // add dposContextProto to header + cpy.DposContext = &DposContextProto{} + if h.DposContext != nil { + cpy.DposContext = h.DposContext + } return &cpy } @@ -311,6 +321,7 @@ func (b *Block) NumberU64() uint64 { return b.header.Number.Uint64() } func (b *Block) MixDigest() common.Hash { return b.header.MixDigest } func (b *Block) Nonce() uint64 { return binary.BigEndian.Uint64(b.header.Nonce[:]) } func (b *Block) Bloom() Bloom { return b.header.Bloom } +func (b *Block) Validator() common.Address { return b.header.Validator } func (b *Block) Coinbase() common.Address { return b.header.Coinbase } func (b *Block) Root() common.Hash { return b.header.Root } func (b *Block) ParentHash() common.Hash { return b.header.ParentHash } @@ -360,7 +371,10 @@ func (b *Block) WithSeal(header *Header) *Block { header: &cpy, transactions: b.transactions, uncles: b.uncles, + // add dposcontext + DposContext: b.DposContext, } + } // WithBody returns a new block with the given transaction and uncle contents. @@ -388,6 +402,42 @@ func (b *Block) Hash() common.Hash { return v } +func (b *Block) String() string { + str := fmt.Sprintf(`Block(#%v): Size: %v { +MinerHash: %x +%v +Transactions: +%v +Uncles: +%v +} +`, b.Number(), b.Size(), b.header.HashNoNonce(), b.header, b.transactions, b.uncles) + return str +} + +func (h *Header) String() string { + return fmt.Sprintf(`Header(%x): +[ + ParentHash: %x + UncleHash: %x + Validator: %x + Coinbase: %x + Root: %x + TxSha %x + ReceiptSha: %x + DposContext: %x + Bloom: %x + Difficulty: %v + Number: %v + GasLimit: %v + GasUsed: %v + Time: %v + Extra: %s + MixDigest: %x + Nonce: %x +]`, h.Hash(), h.ParentHash, h.UncleHash, h.Validator, h.Coinbase, h.Root, h.TxHash, h.ReceiptHash, h.DposContext, h.Bloom, h.Difficulty, h.Number, h.GasLimit, h.GasUsed, h.Time, h.Extra, h.MixDigest, h.Nonce) +} + type Blocks []*Block type BlockBy func(b1, b2 *Block) bool diff --git a/core/types/dpos_context.go b/core/types/dpos_context.go new file mode 100644 index 0000000000..bd6d1ef3cd --- /dev/null +++ b/core/types/dpos_context.go @@ -0,0 +1,359 @@ +package types + +import ( + "bytes" + "errors" + "fmt" + + "github.com/pavelkrolevets/go-ethereum/common" + "github.com/pavelkrolevets/go-ethereum/crypto/sha3" + "github.com/pavelkrolevets/go-ethereum/ethdb" + "github.com/pavelkrolevets/go-ethereum/rlp" + "github.com/pavelkrolevets/go-ethereum/trie" +) + +type DposContext struct { + epochTrie *trie.Trie + delegateTrie *trie.Trie + voteTrie *trie.Trie + candidateTrie *trie.Trie + mintCntTrie *trie.Trie + + db trie.Database +} + +var ( + epochPrefix = []byte("epoch-") + delegatePrefix = []byte("delegate-") + votePrefix = []byte("vote-") + candidatePrefix = []byte("candidate-") + mintCntPrefix = []byte("mintCnt-") +) + +func NewEpochTrie(root common.Hash, db trie.Database) (*trie.Trie, error) { + return trie.NewTrieWithPrefix(root, epochPrefix, db) +} + +func NewDelegateTrie(root common.Hash, db trie.Database) (*trie.Trie, error) { + return trie.NewTrieWithPrefix(root, delegatePrefix, db) +} + +func NewVoteTrie(root common.Hash, db trie.Database) (*trie.Trie, error) { + return trie.NewTrieWithPrefix(root, votePrefix, db) +} + +func NewCandidateTrie(root common.Hash, db trie.Database) (*trie.Trie, error) { + return trie.NewTrieWithPrefix(root, candidatePrefix, db) +} + +func NewMintCntTrie(root common.Hash, db trie.Database) (*trie.Trie, error) { + return trie.NewTrieWithPrefix(root, mintCntPrefix, db) +} + +func NewDposContext(db trie.Database) (*DposContext, error) { + epochTrie, err := NewEpochTrie(common.Hash{}, db) + if err != nil { + return nil, err + } + delegateTrie, err := NewDelegateTrie(common.Hash{}, db) + if err != nil { + return nil, err + } + voteTrie, err := NewVoteTrie(common.Hash{}, db) + if err != nil { + return nil, err + } + candidateTrie, err := NewCandidateTrie(common.Hash{}, db) + if err != nil { + return nil, err + } + mintCntTrie, err := NewMintCntTrie(common.Hash{}, db) + if err != nil { + return nil, err + } + return &DposContext{ + epochTrie: epochTrie, + delegateTrie: delegateTrie, + voteTrie: voteTrie, + candidateTrie: candidateTrie, + mintCntTrie: mintCntTrie, + db: db, + }, nil +} + +func NewDposContextFromProto(db trie.Database, ctxProto *DposContextProto) (*DposContext, error) { + epochTrie, err := NewEpochTrie(ctxProto.EpochHash, db) + if err != nil { + return nil, err + } + delegateTrie, err := NewDelegateTrie(ctxProto.DelegateHash, db) + if err != nil { + return nil, err + } + voteTrie, err := NewVoteTrie(ctxProto.VoteHash, db) + if err != nil { + return nil, err + } + candidateTrie, err := NewCandidateTrie(ctxProto.CandidateHash, db) + if err != nil { + return nil, err + } + mintCntTrie, err := NewMintCntTrie(ctxProto.MintCntHash, db) + if err != nil { + return nil, err + } + return &DposContext{ + epochTrie: epochTrie, + delegateTrie: delegateTrie, + voteTrie: voteTrie, + candidateTrie: candidateTrie, + mintCntTrie: mintCntTrie, + db: db, + }, nil +} + +func (d *DposContext) Copy() *DposContext { + epochTrie := *d.epochTrie + delegateTrie := *d.delegateTrie + voteTrie := *d.voteTrie + candidateTrie := *d.candidateTrie + mintCntTrie := *d.mintCntTrie + return &DposContext{ + epochTrie: &epochTrie, + delegateTrie: &delegateTrie, + voteTrie: &voteTrie, + candidateTrie: &candidateTrie, + mintCntTrie: &mintCntTrie, + } +} + +func (d *DposContext) Root() (h common.Hash) { + hw := sha3.NewKeccak256() + rlp.Encode(hw, d.epochTrie.Hash()) + rlp.Encode(hw, d.delegateTrie.Hash()) + rlp.Encode(hw, d.candidateTrie.Hash()) + rlp.Encode(hw, d.voteTrie.Hash()) + rlp.Encode(hw, d.mintCntTrie.Hash()) + hw.Sum(h[:0]) + return h +} + +func (d *DposContext) Snapshot() *DposContext { + return d.Copy() +} + +func (d *DposContext) RevertToSnapShot(snapshot *DposContext) { + d.epochTrie = snapshot.epochTrie + d.delegateTrie = snapshot.delegateTrie + d.candidateTrie = snapshot.candidateTrie + d.voteTrie = snapshot.voteTrie + d.mintCntTrie = snapshot.mintCntTrie +} + +func (d *DposContext) FromProto(dcp *DposContextProto) error { + var err error + d.epochTrie, err = NewEpochTrie(dcp.EpochHash, d.db) + if err != nil { + return err + } + d.delegateTrie, err = NewDelegateTrie(dcp.DelegateHash, d.db) + if err != nil { + return err + } + d.candidateTrie, err = NewCandidateTrie(dcp.CandidateHash, d.db) + if err != nil { + return err + } + d.voteTrie, err = NewVoteTrie(dcp.VoteHash, d.db) + if err != nil { + return err + } + d.mintCntTrie, err = NewMintCntTrie(dcp.MintCntHash, d.db) + return err +} + +type DposContextProto struct { + EpochHash common.Hash `json:"epochRoot" gencodec:"required"` + DelegateHash common.Hash `json:"delegateRoot" gencodec:"required"` + CandidateHash common.Hash `json:"candidateRoot" gencodec:"required"` + VoteHash common.Hash `json:"voteRoot" gencodec:"required"` + MintCntHash common.Hash `json:"mintCntRoot" gencodec:"required"` +} + +func (d *DposContext) ToProto() *DposContextProto { + return &DposContextProto{ + EpochHash: d.epochTrie.Hash(), + DelegateHash: d.delegateTrie.Hash(), + CandidateHash: d.candidateTrie.Hash(), + VoteHash: d.voteTrie.Hash(), + MintCntHash: d.mintCntTrie.Hash(), + } +} + +func (p *DposContextProto) Root() (h common.Hash) { + hw := sha3.NewKeccak256() + rlp.Encode(hw, p.EpochHash) + rlp.Encode(hw, p.DelegateHash) + rlp.Encode(hw, p.CandidateHash) + rlp.Encode(hw, p.VoteHash) + rlp.Encode(hw, p.MintCntHash) + hw.Sum(h[:0]) + return h +} + +func (d *DposContext) KickoutCandidate(candidateAddr common.Address) error { + candidate := candidateAddr.Bytes() + err := d.candidateTrie.TryDelete(candidate) + if err != nil { + if _, ok := err.(*trie.MissingNodeError); !ok { + return err + } + } + iter := trie.NewIterator(d.delegateTrie.PrefixIterator(candidate)) + for iter.Next() { + delegator := iter.Value + key := append(candidate, delegator...) + err = d.delegateTrie.TryDelete(key) + if err != nil { + if _, ok := err.(*trie.MissingNodeError); !ok { + return err + } + } + v, err := d.voteTrie.TryGet(delegator) + if err != nil { + if _, ok := err.(*trie.MissingNodeError); !ok { + return err + } + } + if err == nil && bytes.Equal(v, candidate) { + err = d.voteTrie.TryDelete(delegator) + if err != nil { + if _, ok := err.(*trie.MissingNodeError); !ok { + return err + } + } + } + } + return nil +} + +func (d *DposContext) BecomeCandidate(candidateAddr common.Address) error { + candidate := candidateAddr.Bytes() + return d.candidateTrie.TryUpdate(candidate, candidate) +} + +func (d *DposContext) Delegate(delegatorAddr, candidateAddr common.Address) error { + delegator, candidate := delegatorAddr.Bytes(), candidateAddr.Bytes() + + // the candidate must be candidate + candidateInTrie, err := d.candidateTrie.TryGet(candidate) + if err != nil { + return err + } + if candidateInTrie == nil { + return errors.New("invalid candidate to delegate") + } + + // delete old candidate if exists + oldCandidate, err := d.voteTrie.TryGet(delegator) + if err != nil { + if _, ok := err.(*trie.MissingNodeError); !ok { + return err + } + } + if oldCandidate != nil { + d.delegateTrie.Delete(append(oldCandidate, delegator...)) + } + if err = d.delegateTrie.TryUpdate(append(candidate, delegator...), delegator); err != nil { + return err + } + return d.voteTrie.TryUpdate(delegator, candidate) +} + +func (d *DposContext) UnDelegate(delegatorAddr, candidateAddr common.Address) error { + delegator, candidate := delegatorAddr.Bytes(), candidateAddr.Bytes() + + // the candidate must be candidate + candidateInTrie, err := d.candidateTrie.TryGet(candidate) + if err != nil { + return err + } + if candidateInTrie == nil { + return errors.New("invalid candidate to undelegate") + } + + oldCandidate, err := d.voteTrie.TryGet(delegator) + if err != nil { + return err + } + if !bytes.Equal(candidate, oldCandidate) { + return errors.New("mismatch candidate to undelegate") + } + + if err = d.delegateTrie.TryDelete(append(candidate, delegator...)); err != nil { + return err + } + return d.voteTrie.TryDelete(delegator) +} + +func (d *DposContext) CommitTo(dbw trie.DatabaseWriter) (*DposContextProto, error) { + epochRoot, err := d.epochTrie.CommitTo(dbw) + if err != nil { + return nil, err + } + delegateRoot, err := d.delegateTrie.CommitTo(dbw) + if err != nil { + return nil, err + } + voteRoot, err := d.voteTrie.CommitTo(dbw) + if err != nil { + return nil, err + } + candidateRoot, err := d.candidateTrie.CommitTo(dbw) + if err != nil { + return nil, err + } + mintCntRoot, err := d.mintCntTrie.CommitTo(dbw) + if err != nil { + return nil, err + } + return &DposContextProto{ + EpochHash: epochRoot, + DelegateHash: delegateRoot, + VoteHash: voteRoot, + CandidateHash: candidateRoot, + MintCntHash: mintCntRoot, + }, nil +} + +func (d *DposContext) CandidateTrie() *trie.Trie { return d.candidateTrie } +func (d *DposContext) DelegateTrie() *trie.Trie { return d.delegateTrie } +func (d *DposContext) VoteTrie() *trie.Trie { return d.voteTrie } +func (d *DposContext) EpochTrie() *trie.Trie { return d.epochTrie } +func (d *DposContext) MintCntTrie() *trie.Trie { return d.mintCntTrie } +func (d *DposContext) DB() ethdb.Database { return d.db } +func (dc *DposContext) SetEpoch(epoch *trie.Trie) { dc.epochTrie = epoch } +func (dc *DposContext) SetDelegate(delegate *trie.Trie) { dc.delegateTrie = delegate } +func (dc *DposContext) SetVote(vote *trie.Trie) { dc.voteTrie = vote } +func (dc *DposContext) SetCandidate(candidate *trie.Trie) { dc.candidateTrie = candidate } +func (dc *DposContext) SetMintCnt(mintCnt *trie.Trie) { dc.mintCntTrie = mintCnt } + +func (dc *DposContext) GetValidators() ([]common.Address, error) { + var validators []common.Address + key := []byte("validator") + validatorsRLP := dc.epochTrie.Get(key) + if err := rlp.DecodeBytes(validatorsRLP, &validators); err != nil { + return nil, fmt.Errorf("failed to decode validators: %s", err) + } + return validators, nil +} + +func (dc *DposContext) SetValidators(validators []common.Address) error { + key := []byte("validator") + validatorsRLP, err := rlp.EncodeToBytes(validators) + if err != nil { + return fmt.Errorf("failed to encode validators to rlp bytes: %s", err) + } + dc.epochTrie.Update(key, validatorsRLP) + return nil +} diff --git a/core/types/dpos_context_test.go b/core/types/dpos_context_test.go new file mode 100644 index 0000000000..7de8fceb62 --- /dev/null +++ b/core/types/dpos_context_test.go @@ -0,0 +1,178 @@ +package types + +import ( + "testing" + + "github.com/pavelkrolevets/go-ethereum/common" + "github.com/pavelkrolevets/go-ethereum/ethdb" + "github.com/pavelkrolevets/go-ethereum/trie" + "github.com/stretchr/testify/assert" +) + +func TestDposContextSnapshot(t *testing.T) { + db, _ := ethdb.NewMemDatabase() + dposContext, err := NewDposContext(db) + assert.Nil(t, err) + + snapshot := dposContext.Snapshot() + assert.Equal(t, dposContext.Root(), snapshot.Root()) + assert.NotEqual(t, dposContext, snapshot) + + // change dposContext + assert.Nil(t, dposContext.BecomeCandidate(common.HexToAddress("0x44d1ce0b7cb3588bca96151fe1bc05af38f91b6c"))) + assert.NotEqual(t, dposContext.Root(), snapshot.Root()) + + // revert snapshot + dposContext.RevertToSnapShot(snapshot) + assert.Equal(t, dposContext.Root(), snapshot.Root()) + assert.NotEqual(t, dposContext, snapshot) +} + +func TestDposContextBecomeCandidate(t *testing.T) { + candidates := []common.Address{ + common.HexToAddress("0x44d1ce0b7cb3588bca96151fe1bc05af38f91b6e"), + common.HexToAddress("0xa60a3886b552ff9992cfcd208ec1152079e046c2"), + common.HexToAddress("0x4e080e49f62694554871e669aeb4ebe17c4a9670"), + } + db, _ := ethdb.NewMemDatabase() + dposContext, err := NewDposContext(db) + assert.Nil(t, err) + for _, candidate := range candidates { + assert.Nil(t, dposContext.BecomeCandidate(candidate)) + } + + candidateMap := map[common.Address]bool{} + candidateIter := trie.NewIterator(dposContext.candidateTrie.NodeIterator(nil)) + for candidateIter.Next() { + candidateMap[common.BytesToAddress(candidateIter.Value)] = true + } + assert.Equal(t, len(candidates), len(candidateMap)) + for _, candidate := range candidates { + assert.True(t, candidateMap[candidate]) + } +} + +func TestDposContextKickoutCandidate(t *testing.T) { + candidates := []common.Address{ + common.HexToAddress("0x44d1ce0b7cb3588bca96151fe1bc05af38f91b6e"), + common.HexToAddress("0xa60a3886b552ff9992cfcd208ec1152079e046c2"), + common.HexToAddress("0x4e080e49f62694554871e669aeb4ebe17c4a9670"), + } + db, _ := ethdb.NewMemDatabase() + dposContext, err := NewDposContext(db) + assert.Nil(t, err) + for _, candidate := range candidates { + assert.Nil(t, dposContext.BecomeCandidate(candidate)) + assert.Nil(t, dposContext.Delegate(candidate, candidate)) + } + + kickIdx := 1 + assert.Nil(t, dposContext.KickoutCandidate(candidates[kickIdx])) + candidateMap := map[common.Address]bool{} + candidateIter := trie.NewIterator(dposContext.candidateTrie.NodeIterator(nil)) + for candidateIter.Next() { + candidateMap[common.BytesToAddress(candidateIter.Value)] = true + } + voteIter := trie.NewIterator(dposContext.voteTrie.NodeIterator(nil)) + voteMap := map[common.Address]bool{} + for voteIter.Next() { + voteMap[common.BytesToAddress(voteIter.Value)] = true + } + for i, candidate := range candidates { + delegateIter := trie.NewIterator(dposContext.delegateTrie.PrefixIterator(candidate.Bytes())) + if i == kickIdx { + assert.False(t, delegateIter.Next()) + assert.False(t, candidateMap[candidate]) + assert.False(t, voteMap[candidate]) + continue + } + assert.True(t, delegateIter.Next()) + assert.True(t, candidateMap[candidate]) + assert.True(t, voteMap[candidate]) + } +} + +func TestDposContextDelegateAndUnDelegate(t *testing.T) { + candidate := common.HexToAddress("0x44d1ce0b7cb3588bca96151fe1bc05af38f91b6e") + newCandidate := common.HexToAddress("0xa60a3886b552ff9992cfcd208ec1152079e046c2") + delegator := common.HexToAddress("0x4e080e49f62694554871e669aeb4ebe17c4a9670") + db, _ := ethdb.NewMemDatabase() + dposContext, err := NewDposContext(db) + assert.Nil(t, err) + assert.Nil(t, dposContext.BecomeCandidate(candidate)) + assert.Nil(t, dposContext.BecomeCandidate(newCandidate)) + + // delegator delegate to not exist candidate + candidateIter := trie.NewIterator(dposContext.candidateTrie.NodeIterator(nil)) + candidateMap := map[string]bool{} + for candidateIter.Next() { + candidateMap[string(candidateIter.Value)] = true + } + assert.NotNil(t, dposContext.Delegate(delegator, common.HexToAddress("0xab"))) + + // delegator delegate to old candidate + assert.Nil(t, dposContext.Delegate(delegator, candidate)) + delegateIter := trie.NewIterator(dposContext.delegateTrie.PrefixIterator(candidate.Bytes())) + if assert.True(t, delegateIter.Next()) { + assert.Equal(t, append(delegatePrefix, append(candidate.Bytes(), delegator.Bytes()...)...), delegateIter.Key) + assert.Equal(t, delegator, common.BytesToAddress(delegateIter.Value)) + } + voteIter := trie.NewIterator(dposContext.voteTrie.NodeIterator(nil)) + if assert.True(t, voteIter.Next()) { + assert.Equal(t, append(votePrefix, delegator.Bytes()...), voteIter.Key) + assert.Equal(t, candidate, common.BytesToAddress(voteIter.Value)) + } + + // delegator delegate to new candidate + assert.Nil(t, dposContext.Delegate(delegator, newCandidate)) + delegateIter = trie.NewIterator(dposContext.delegateTrie.PrefixIterator(candidate.Bytes())) + assert.False(t, delegateIter.Next()) + delegateIter = trie.NewIterator(dposContext.delegateTrie.PrefixIterator(newCandidate.Bytes())) + if assert.True(t, delegateIter.Next()) { + assert.Equal(t, append(delegatePrefix, append(newCandidate.Bytes(), delegator.Bytes()...)...), delegateIter.Key) + assert.Equal(t, delegator, common.BytesToAddress(delegateIter.Value)) + } + voteIter = trie.NewIterator(dposContext.voteTrie.NodeIterator(nil)) + if assert.True(t, voteIter.Next()) { + assert.Equal(t, append(votePrefix, delegator.Bytes()...), voteIter.Key) + assert.Equal(t, newCandidate, common.BytesToAddress(voteIter.Value)) + } + + // delegator undelegate to not exist candidate + assert.NotNil(t, dposContext.UnDelegate(common.HexToAddress("0x00"), candidate)) + + // delegator undelegate to old candidate + assert.NotNil(t, dposContext.UnDelegate(delegator, candidate)) + + // delegator undelegate to new candidate + assert.Nil(t, dposContext.UnDelegate(delegator, newCandidate)) + delegateIter = trie.NewIterator(dposContext.delegateTrie.PrefixIterator(newCandidate.Bytes())) + assert.False(t, delegateIter.Next()) + voteIter = trie.NewIterator(dposContext.voteTrie.NodeIterator(nil)) + assert.False(t, voteIter.Next()) +} + +func TestDposContextValidators(t *testing.T) { + validators := []common.Address{ + common.HexToAddress("0x44d1ce0b7cb3588bca96151fe1bc05af38f91b6e"), + common.HexToAddress("0xa60a3886b552ff9992cfcd208ec1152079e046c2"), + common.HexToAddress("0x4e080e49f62694554871e669aeb4ebe17c4a9670"), + } + + db, _ := ethdb.NewMemDatabase() + dposContext, err := NewDposContext(db) + assert.Nil(t, err) + + assert.Nil(t, dposContext.SetValidators(validators)) + + result, err := dposContext.GetValidators() + assert.Nil(t, err) + assert.Equal(t, len(validators), len(result)) + validatorMap := map[common.Address]bool{} + for _, validator := range validators { + validatorMap[validator] = true + } + for _, validator := range result { + assert.True(t, validatorMap[validator]) + } +} diff --git a/core/types/transaction_test.go b/core/types/transaction_test.go index fe3c3bec55..4c8d897a5f 100644 --- a/core/types/transaction_test.go +++ b/core/types/transaction_test.go @@ -29,7 +29,7 @@ import ( ) // The values in those tests are from the Transaction Tests -// at github.com/ethereum/tests. +// at github.com/pavelkrolevets/tests. var ( emptyTx = NewTransaction( 0, diff --git a/core/vm/instructions_test.go b/core/vm/instructions_test.go index ae91cca607..3e138c1731 100644 --- a/core/vm/instructions_test.go +++ b/core/vm/instructions_test.go @@ -110,7 +110,7 @@ func TestByteOp(t *testing.T) { } func TestSHL(t *testing.T) { - // Testcases from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-145.md#shl-shift-left + // Testcases from https://github.com/pavelkrolevets/EIPs/blob/master/EIPS/eip-145.md#shl-shift-left tests := []twoOperandTest{ {"0000000000000000000000000000000000000000000000000000000000000001", "00", "0000000000000000000000000000000000000000000000000000000000000001"}, {"0000000000000000000000000000000000000000000000000000000000000001", "01", "0000000000000000000000000000000000000000000000000000000000000002"}, @@ -128,7 +128,7 @@ func TestSHL(t *testing.T) { } func TestSHR(t *testing.T) { - // Testcases from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-145.md#shr-logical-shift-right + // Testcases from https://github.com/pavelkrolevets/EIPs/blob/master/EIPS/eip-145.md#shr-logical-shift-right tests := []twoOperandTest{ {"0000000000000000000000000000000000000000000000000000000000000001", "00", "0000000000000000000000000000000000000000000000000000000000000001"}, {"0000000000000000000000000000000000000000000000000000000000000001", "01", "0000000000000000000000000000000000000000000000000000000000000000"}, @@ -146,7 +146,7 @@ func TestSHR(t *testing.T) { } func TestSAR(t *testing.T) { - // Testcases from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-145.md#sar-arithmetic-shift-right + // Testcases from https://github.com/pavelkrolevets/EIPs/blob/master/EIPS/eip-145.md#sar-arithmetic-shift-right tests := []twoOperandTest{ {"0000000000000000000000000000000000000000000000000000000000000001", "00", "0000000000000000000000000000000000000000000000000000000000000001"}, {"0000000000000000000000000000000000000000000000000000000000000001", "01", "0000000000000000000000000000000000000000000000000000000000000000"}, diff --git a/dashboard/assets.go b/dashboard/assets.go index f3e7cf9815..bbc8508a77 100644 --- a/dashboard/assets.go +++ b/dashboard/assets.go @@ -32727,7 +32727,7 @@ var _bundleJs = []byte((((((((((`!function(modules) { }, _react2.default.createElement("span", { style: _common.styles.light }, "Commit "), _react2.default.createElement("a", { - href: "https://github.com/ethereum/go-ethereum/commit/" + general.commit, + href: "https://github.com/pavelkrolevets/go-ethereum/commit/" + general.commit, target: "_blank", style: { color: "inherit", diff --git a/eth/filters/api.go b/eth/filters/api.go index e9afd4172a..3739a28005 100644 --- a/eth/filters/api.go +++ b/eth/filters/api.go @@ -101,7 +101,7 @@ func (api *PublicFilterAPI) timeoutLoop() { // It is part of the filter package because this filter can be used through the // `eth_getFilterChanges` polling method that is also used for log filters. // -// https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_newpendingtransactionfilter +// https://github.com/pavelkrolevets/wiki/wiki/JSON-RPC#eth_newpendingtransactionfilter func (api *PublicFilterAPI) NewPendingTransactionFilter() rpc.ID { var ( pendingTxs = make(chan []common.Hash) @@ -171,7 +171,7 @@ func (api *PublicFilterAPI) NewPendingTransactions(ctx context.Context) (*rpc.Su // NewBlockFilter creates a filter that fetches blocks that are imported into the chain. // It is part of the filter package since polling goes with eth_getFilterChanges. // -// https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_newblockfilter +// https://github.com/pavelkrolevets/wiki/wiki/JSON-RPC#eth_newblockfilter func (api *PublicFilterAPI) NewBlockFilter() rpc.ID { var ( headers = make(chan *types.Header) @@ -287,7 +287,7 @@ type FilterCriteria ethereum.FilterQuery // // In case "fromBlock" > "toBlock" an error is returned. // -// https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_newfilter +// https://github.com/pavelkrolevets/wiki/wiki/JSON-RPC#eth_newfilter func (api *PublicFilterAPI) NewFilter(crit FilterCriteria) (rpc.ID, error) { logs := make(chan []*types.Log) logsSub, err := api.events.SubscribeLogs(ethereum.FilterQuery(crit), logs) @@ -322,7 +322,7 @@ func (api *PublicFilterAPI) NewFilter(crit FilterCriteria) (rpc.ID, error) { // GetLogs returns logs matching the given argument that are stored within the state. // -// https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getlogs +// https://github.com/pavelkrolevets/wiki/wiki/JSON-RPC#eth_getlogs func (api *PublicFilterAPI) GetLogs(ctx context.Context, crit FilterCriteria) ([]*types.Log, error) { var filter *Filter if crit.BlockHash != nil { @@ -351,7 +351,7 @@ func (api *PublicFilterAPI) GetLogs(ctx context.Context, crit FilterCriteria) ([ // UninstallFilter removes the filter with the given filter id. // -// https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_uninstallfilter +// https://github.com/pavelkrolevets/wiki/wiki/JSON-RPC#eth_uninstallfilter func (api *PublicFilterAPI) UninstallFilter(id rpc.ID) bool { api.filtersMu.Lock() f, found := api.filters[id] @@ -369,7 +369,7 @@ func (api *PublicFilterAPI) UninstallFilter(id rpc.ID) bool { // GetFilterLogs returns the logs for the filter with the given id. // If the filter could not be found an empty array of logs is returned. // -// https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getfilterlogs +// https://github.com/pavelkrolevets/wiki/wiki/JSON-RPC#eth_getfilterlogs func (api *PublicFilterAPI) GetFilterLogs(ctx context.Context, id rpc.ID) ([]*types.Log, error) { api.filtersMu.Lock() f, found := api.filters[id] @@ -410,7 +410,7 @@ func (api *PublicFilterAPI) GetFilterLogs(ctx context.Context, id rpc.ID) ([]*ty // For pending transaction and block filters the result is []common.Hash. // (pending)Log filters return []Log. // -// https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getfilterchanges +// https://github.com/pavelkrolevets/wiki/wiki/JSON-RPC#eth_getfilterchanges func (api *PublicFilterAPI) GetFilterChanges(id rpc.ID) (interface{}, error) { api.filtersMu.Lock() defer api.filtersMu.Unlock() diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 80dbcc8617..690a6a2865 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -1249,7 +1249,7 @@ func (s *PublicTransactionPoolAPI) SendRawTransaction(ctx context.Context, encod // // The account associated with addr must be unlocked. // -// https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sign +// https://github.com/pavelkrolevets/wiki/wiki/JSON-RPC#eth_sign func (s *PublicTransactionPoolAPI) Sign(addr common.Address, data hexutil.Bytes) (hexutil.Bytes, error) { // Look up the wallet containing the requested signer account := accounts.Account{Address: addr} diff --git a/params/config.go b/params/config.go index 7ba6cc91fd..934a847160 100644 --- a/params/config.go +++ b/params/config.go @@ -78,21 +78,34 @@ var ( }, } + DposChainConfig = &ChainConfig{ + ChainID: big.NewInt(1515), + HomesteadBlock: big.NewInt(0), + DAOForkBlock: nil, + DAOForkSupport: false, + EIP150Block: big.NewInt(0), + EIP150Hash: common.Hash{}, + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + + Dpos: &DposConfig{}, + } // AllEthashProtocolChanges contains every protocol change (EIPs) introduced // and accepted by the Ethereum core developers into the Ethash consensus. // // This configuration is intentionally not using keyed fields to force anyone // adding flags to the config to also have to set these fields. - AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil} + AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil, nil} // AllCliqueProtocolChanges contains every protocol change (EIPs) introduced // and accepted by the Ethereum core developers into the Clique consensus. // // This configuration is intentionally not using keyed fields to force anyone // adding flags to the config to also have to set these fields. - AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, &CliqueConfig{Period: 0, Epoch: 30000}} + AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, &CliqueConfig{Period: 0, Epoch: 30000}, nil} - TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil} + TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil, nil} TestRules = TestChainConfig.Rules(new(big.Int)) ) @@ -109,7 +122,7 @@ type ChainConfig struct { DAOForkBlock *big.Int `json:"daoForkBlock,omitempty"` // TheDAO hard-fork switch block (nil = no fork) DAOForkSupport bool `json:"daoForkSupport,omitempty"` // Whether the nodes supports or opposes the DAO hard-fork - // EIP150 implements the Gas price changes (https://github.com/ethereum/EIPs/issues/150) + // EIP150 implements the Gas price changes (https://github.com/pavelkrolevets/EIPs/issues/150) EIP150Block *big.Int `json:"eip150Block,omitempty"` // EIP150 HF block (nil = no fork) EIP150Hash common.Hash `json:"eip150Hash,omitempty"` // EIP150 HF hash (needed for header only clients as only gas pricing changed) @@ -122,6 +135,7 @@ type ChainConfig struct { // Various consensus engines Ethash *EthashConfig `json:"ethash,omitempty"` Clique *CliqueConfig `json:"clique,omitempty"` + Dpos *DposConfig `json:"dpos,omitempty"` } // EthashConfig is the consensus engine configs for proof-of-work based sealing. @@ -143,6 +157,16 @@ func (c *CliqueConfig) String() string { return "clique" } +// DposConfig is the consensus engine configs for delegated proof-of-stake based sealing. +type DposConfig struct { + Validators []common.Address `json:"validators"` // Genesis validator list +} + +// String implements the stringer interface, returning the consensus engine details. +func (d *DposConfig) String() string { + return "dpos" +} + // String implements the fmt.Stringer interface. func (c *ChainConfig) String() string { var engine interface{} @@ -151,6 +175,8 @@ func (c *ChainConfig) String() string { engine = c.Ethash case c.Clique != nil: engine = c.Clique + case c.Dpos !=nil: + engine = c.Dpos default: engine = "unknown" } diff --git a/signer/core/abihelper_test.go b/signer/core/abihelper_test.go index 538ba9bbb7..fd3fa58db6 100644 --- a/signer/core/abihelper_test.go +++ b/signer/core/abihelper_test.go @@ -71,7 +71,7 @@ func TestNewUnpacker(t *testing.T) { [10]byte{49, 50, 51, 52, 53, 54, 55, 56, 57, 48}, common.Hex2Bytes("48656c6c6f2c20776f726c6421"), }, - }, { // https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI#examples + }, { // https://github.com/pavelkrolevets/wiki/wiki/Ethereum-Contract-ABI#examples `[{"type":"function","name":"sam","inputs":[{"type":"bytes"},{"type":"bool"},{"type":"uint256[]"}]}]`, // "dave", true and [1,2,3] "a5643bf20000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000464617665000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003", @@ -139,7 +139,7 @@ func TestCalldataDecoding(t *testing.T) { "42958b5400000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000042", // Too short compareAndApprove "a52c101e00ff0000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000042", - // From https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI + // From https://github.com/pavelkrolevets/wiki/wiki/Ethereum-Contract-ABI // contains a bool with illegal values "a5643bf20000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000001100000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000464617665000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003", } { @@ -151,7 +151,7 @@ func TestCalldataDecoding(t *testing.T) { //Expected success for _, hexdata := range []string{ - // From https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI + // From https://github.com/pavelkrolevets/wiki/wiki/Ethereum-Contract-ABI "a5643bf20000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000464617665000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003", "a52c101e0000000000000000000000000000000000000000000000000000000000000012", "a52c101eFFffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", diff --git a/tests/block_test_util.go b/tests/block_test_util.go index 2a6527714d..4e49c4c467 100644 --- a/tests/block_test_util.go +++ b/tests/block_test_util.go @@ -151,7 +151,7 @@ func (t *BlockTest) genesis(config *params.ChainConfig) *core.Genesis { } } -/* See https://github.com/ethereum/tests/wiki/Blockchain-Tests-II +/* See https://github.com/pavelkrolevets/tests/wiki/Blockchain-Tests-II Whether a block is valid or not is a bit subtle, it's defined by presence of blockHeader, transactions and uncleHeaders fields. If they are missing, the block is diff --git a/tests/state_test_util.go b/tests/state_test_util.go index 26b9109936..3dc64769dd 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -38,7 +38,7 @@ import ( ) // StateTest checks transaction processing without block context. -// See https://github.com/ethereum/EIPs/issues/176 for the test format specification. +// See https://github.com/pavelkrolevets/EIPs/issues/176 for the test format specification. type StateTest struct { json stJSON } @@ -218,7 +218,7 @@ func (tx *stTransaction) toMessage(ps stPostState) (core.Message, error) { dataHex := tx.Data[ps.Indexes.Data] valueHex := tx.Value[ps.Indexes.Value] gasLimit := tx.GasLimit[ps.Indexes.Gas] - // Value, Data hex encoding is messy: https://github.com/ethereum/tests/issues/203 + // Value, Data hex encoding is messy: https://github.com/pavelkrolevets/tests/issues/203 value := new(big.Int) if valueHex != "0x" { v, ok := math.ParseBig256(valueHex) diff --git a/tests/vm_test_util.go b/tests/vm_test_util.go index 1131d1cf28..27dc3ef9e6 100644 --- a/tests/vm_test_util.go +++ b/tests/vm_test_util.go @@ -34,7 +34,7 @@ import ( ) // VMTest checks EVM execution without block or transaction context. -// See https://github.com/ethereum/tests/wiki/VM-Tests for the test format specification. +// See https://github.com/pavelkrolevets/tests/wiki/VM-Tests for the test format specification. type VMTest struct { json vmJSON } diff --git a/trie/database.go b/trie/database.go index 47282ec87b..0345c2788c 100644 --- a/trie/database.go +++ b/trie/database.go @@ -58,6 +58,14 @@ type DatabaseReader interface { Has(key []byte) (bool, error) } +// DatabaseWriter wraps the Put method of a backing store for the trie. +type DatabaseWriter interface { + // Put stores the mapping key->value in the database. + // Implementations must not hold onto the value bytes, the trie + // will reuse the slice across calls to Put. + Put(key, value []byte) error +} + // Database is an intermediate write layer between the trie data structures and // the disk database. The aim is to accumulate trie writes in-memory and only // periodically flush a couple tries to disk, garbage collecting the remainder. diff --git a/trie/iterator.go b/trie/iterator.go index e4379c1c67..8963d4f311 100644 --- a/trie/iterator.go +++ b/trie/iterator.go @@ -573,3 +573,94 @@ func (it *unionIterator) Error() error { } return nil } + +type prefixIterator struct { + prefix []byte + nodeIterator NodeIterator +} + +// newPrefixIterator constructs a NodeIterator, iterates over elements in trie that +// has common prefix. +func newPrefixIterator(trie *Trie, prefix []byte) NodeIterator { + if trie.Hash() == emptyState { + return new(prefixIterator) + } + // nodeIterator will convert prefix to hex + nodeIt := newNodeIterator(trie, prefix) + prefix = keybytesToHex(prefix) + return &prefixIterator{ + nodeIterator: nodeIt, + prefix: prefix[:len(prefix)-1], // remove the hex terminator + } +} + +// hasPrefix return whether the nodeIterator has common prefix +func (it *prefixIterator) hasPrefix() bool { + return bytes.HasPrefix(it.nodeIterator.Path(), it.prefix) +} + +func (it *prefixIterator) Hash() common.Hash { + if it.hasPrefix() { + return it.nodeIterator.Hash() + } + return common.Hash{} +} + +func (it *prefixIterator) Parent() common.Hash { + if it.hasPrefix() { + it.nodeIterator.Parent() + } + return common.Hash{} +} + +func (it *prefixIterator) Leaf() bool { + if it.hasPrefix() { + return it.nodeIterator.Leaf() + } + return false +} + +func (it *prefixIterator) LeafBlob() []byte { + if it.hasPrefix() { + return it.nodeIterator.LeafBlob() + } + return nil +} + +func (it *prefixIterator) LeafKey() []byte { + if it.hasPrefix() { + return it.nodeIterator.LeafKey() + } + return nil +} + +func (it *prefixIterator) Path() []byte { + if it.hasPrefix() { + return it.nodeIterator.Path() + } + return nil +} + +// Next moves the iterator to the next node, returning whether there are any +// further nodes which has common prefix. In case of an internal error this method +// returns false and sets the Error field to the encountered failure. +// If `descend` is false, skips iterating over any subnodes of the current node. +func (it *prefixIterator) Next(descend bool) bool { + if it.nodeIterator.Next(descend) { + if it.hasPrefix() { + return true + } + } + return false +} + +func (it *prefixIterator) Error() error { + return it.nodeIterator.Error() +} + +func (it *prefixIterator) LeafProof() [][]byte { + if it.hasPrefix() { + return it.nodeIterator.LeafProof() + } + return nil +} diff --git a/trie/trie.go b/trie/trie.go index a59802b241..16854bc7ac 100644 --- a/trie/trie.go +++ b/trie/trie.go @@ -25,6 +25,8 @@ import ( "github.com/pavelkrolevets/go-ethereum/crypto" "github.com/pavelkrolevets/go-ethereum/log" "github.com/pavelkrolevets/go-ethereum/metrics" + "github.com/pavelkrolevets/go-ethereum/crypto/sha3" + ) var ( @@ -54,6 +56,10 @@ func CacheUnloads() int64 { return cacheUnloadCounter.Count() } +func init() { + sha3.NewKeccak256().Sum(emptyState[:0]) +} + // LeafCallback is a callback type invoked when a trie operation reaches a leaf // node. It's used by state sync and commit to allow handling external references // between account and storage tries. @@ -65,10 +71,10 @@ type LeafCallback func(leaf []byte, parent common.Hash) error // // Trie is not safe for concurrent use. type Trie struct { - db *Database + db Database root node originalRoot common.Hash - + prefix []byte // Cache generation values. // cachegen increases by one with each commit operation. // new nodes are tagged with the current generation and unloaded @@ -93,14 +99,17 @@ func (t *Trie) newFlag() nodeFlag { // trie is initially empty and does not require a database. Otherwise, // New will panic if db is nil and returns a MissingNodeError if root does // not exist in the database. Accessing the trie loads nodes from db on demand. -func New(root common.Hash, db *Database) (*Trie, error) { - if db == nil { - panic("trie.New called without a database") - } +func New(root common.Hash, db Database) (*Trie, error) { + trie := &Trie{ db: db, originalRoot: root, } + + if db == nil { + panic("trie.New called without a database") + } + if root != (common.Hash{}) && root != emptyRoot { rootnode, err := trie.resolveHash(root[:], nil) if err != nil { @@ -110,6 +119,25 @@ func New(root common.Hash, db *Database) (*Trie, error) { } return trie, nil } +// Creates trie with prefix for dpos content +func NewTrieWithPrefix(root common.Hash, prefix []byte, db Database) (*Trie, error) { + trie, err := New(root, db) + if err != nil { + return nil, err + } + trie.prefix = prefix + return trie, nil +} + + +// PrefixIterator returns an iterator that returns nodes of the trie which has the prefix path specificed +// Iteration starts at the key after the given start key. +func (t *Trie) PrefixIterator(prefix []byte) NodeIterator { + if t.prefix != nil { + prefix = append(t.prefix, prefix...) + } + return newPrefixIterator(t, prefix) +} // NodeIterator returns an iterator that returns nodes of the trie. Iteration starts at // the key after the given start key. diff --git a/vendor/github.com/ethereum/ethash/src/libethash/io.h b/vendor/github.com/ethereum/ethash/src/libethash/io.h index 7a27089c7d..75cdcef7f9 100644 --- a/vendor/github.com/ethereum/ethash/src/libethash/io.h +++ b/vendor/github.com/ethereum/ethash/src/libethash/io.h @@ -38,7 +38,7 @@ extern "C" { // 10 is for maximum number of digits of a uint32_t (for REVISION) // 1 is for - and 16 is for the first 16 hex digits for first 8 bytes of // the seedhash and last 1 is for the null terminating character -// Reference: https://github.com/ethereum/wiki/wiki/Ethash-DAG +// Reference: https://github.com/pavelkrolevets/wiki/wiki/Ethash-DAG #define DAG_MUTABLE_NAME_MAX_SIZE (6 + 10 + 1 + 16 + 1) /// Possible return values of @see ethash_io_prepare enum ethash_io_rc { @@ -80,7 +80,7 @@ enum ethash_io_rc { * data directory. If it does not exist it's created. * @param[in] seedhash The seedhash of the current block number, used in the * naming of the file as can be seen from the spec at: - * https://github.com/ethereum/wiki/wiki/Ethash-DAG + * https://github.com/pavelkrolevets/wiki/wiki/Ethash-DAG * @param[out] output_file If there was no failure then this will point to an open * file descriptor. User is responsible for closing it. * In the case of memo match then the file is open on read @@ -175,7 +175,7 @@ char* ethash_io_create_filename( /** * Gets the default directory name for the DAG depending on the system * - * The spec defining this directory is here: https://github.com/ethereum/wiki/wiki/Ethash-DAG + * The spec defining this directory is here: https://github.com/pavelkrolevets/wiki/wiki/Ethash-DAG * * @param[out] strbuf A string buffer of sufficient size to keep the * null termninated string of the directory name