changed ethdb.Database to trie.Database

This commit is contained in:
pavelkrolevets 2018-08-09 12:47:24 +08:00
parent 1c075dd0a1
commit fb640ddeac
36 changed files with 823 additions and 83 deletions

2
.gitmodules vendored
View file

@ -1,3 +1,3 @@
[submodule "tests"]
path = tests/testdata
url = https://github.com/ethereum/tests
url = https://github.com/pavelkrolevets/tests

View file

@ -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

View file

@ -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.

View file

@ -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

View file

@ -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 (

View file

@ -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
*/

View file

@ -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 (:().

View file

@ -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"

View file

@ -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

View file

@ -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

View file

@ -211,7 +211,7 @@ var dashboardContent = `
<pre>ethereumwallet --rpc $HOME/.{{.Network}}/geth.ipc --node-networkid={{.NetworkID}} --node-datadir=$HOME/.{{.Network}}{{if .Ethstats}} --node-ethstats='{{.Ethstats}}'{{end}} --node-bootnodes={{.BootnodesFlat}}</pre>
<p>
<br/>
<p>You can download the Ethereum Wallet from <a href="https://github.com/ethereum/mist/releases" target="about:blank">https://github.com/ethereum/mist/releases</a>.</p>
<p>You can download the Ethereum Wallet from <a href="https://github.com/pavelkrolevets/mist/releases" target="about:blank">https://github.com/pavelkrolevets/mist/releases</a>.</p>
</div>
</div>
</div>
@ -232,7 +232,7 @@ var dashboardContent = `
<pre>mist --rpc $HOME/.{{.Network}}/geth.ipc --node-networkid={{.NetworkID}} --node-datadir=$HOME/.{{.Network}}{{if .Ethstats}} --node-ethstats='{{.Ethstats}}'{{end}} --node-bootnodes={{.BootnodesFlat}}</pre>
<p>
<br/>
<p>You can download the Mist browser from <a href="https://github.com/ethereum/mist/releases" target="about:blank">https://github.com/ethereum/mist/releases</a>.</p>
<p>You can download the Mist browser from <a href="https://github.com/pavelkrolevets/mist/releases" target="about:blank">https://github.com/pavelkrolevets/mist/releases</a>.</p>
</div>
</div>
</div>
@ -337,7 +337,7 @@ try! node?.start();
<pre>eth --config {{.CppGenesis}} --datadir $HOME/.{{.Network}} --peerset "{{.CppBootnodes}}"</pre>
</p>
<br/>
<p>You can find cpp-ethereum at <a href="https://github.com/ethereum/cpp-ethereum/" target="about:blank">https://github.com/ethereum/cpp-ethereum/</a>.</p>
<p>You can find cpp-ethereum at <a href="https://github.com/pavelkrolevets/cpp-ethereum/" target="about:blank">https://github.com/pavelkrolevets/cpp-ethereum/</a>.</p>
</div>
</div>
</div>
@ -401,7 +401,7 @@ try! node?.start();
<pre>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</pre>
</p>
<br/>
<p>You can find pyethapp at <a href="https://github.com/ethereum/pyethapp/" target="about:blank">https://github.com/ethereum/pyethapp/</a>.</p>
<p>You can find pyethapp at <a href="https://github.com/pavelkrolevets/pyethapp/" target="about:blank">https://github.com/pavelkrolevets/pyethapp/</a>.</p>
</div>
</div>
</div>

View file

@ -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 {

View file

@ -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"
)

View file

@ -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 (

View file

@ -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"
)

View file

@ -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 {

View file

@ -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"
)

View file

@ -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))

View file

@ -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

View file

@ -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

359
core/types/dpos_context.go Normal file
View file

@ -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
}

View file

@ -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])
}
}

View file

@ -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,

View file

@ -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"},

View file

@ -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",

View file

@ -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()

View file

@ -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}

View file

@ -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"
}

View file

@ -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",

View file

@ -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

View file

@ -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)

View file

@ -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
}

View file

@ -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.

View file

@ -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
}

View file

@ -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.

View file

@ -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