This commit is contained in:
parmarrushabh 2019-02-24 17:40:26 +05:30
parent 147e1f0baf
commit 1b13b3a305
10 changed files with 134 additions and 230 deletions

View file

@ -74,8 +74,10 @@ SUBCOMMANDS:
func init() { func init() {
cli.AppHelpTemplate = `{{.Name}} {{if .Flags}}[global options] {{end}}command{{if .Flags}} [command options]{{end}} [arguments...] cli.AppHelpTemplate = `{{.Name}} {{if .Flags}}[global options] {{end}}command{{if .Flags}} [command options]{{end}} [arguments...]
VERSION: VERSION:
{{.Version}} {{.Version}}
COMMANDS: COMMANDS:
{{range .Commands}}{{.Name}}{{with .ShortName}}, {{.}}{{end}}{{ "\t" }}{{.Usage}} {{range .Commands}}{{.Name}}{{with .ShortName}}, {{.}}{{end}}{{ "\t" }}{{.Usage}}
{{end}}{{if .Flags}} {{end}}{{if .Flags}}
@ -110,12 +112,6 @@ func NewApp(gitCommit, usage string) *cli.App {
// are the same for all commands. // are the same for all commands.
var ( var (
// XDC flags.
RollbackFlag = cli.StringFlag{
Name: "rollback",
Usage: "Rollback chain at hash",
Value: "",
}
// General settings // General settings
AnnounceTxsFlag = cli.BoolFlag{ AnnounceTxsFlag = cli.BoolFlag{
Name: "announce-txs", Name: "announce-txs",
@ -745,9 +741,9 @@ func setIPC(ctx *cli.Context, cfg *node.Config) {
} }
} }
// MakeDatabaseHandles raises out the number of allowed file handles per process // makeDatabaseHandles raises out the number of allowed file handles per process
// for XDC and returns half of the allowance to assign to the database. // for XDC and returns half of the allowance to assign to the database.
func MakeDatabaseHandles() int { func makeDatabaseHandles() int {
limit, err := fdlimit.Current() limit, err := fdlimit.Current()
if err != nil { if err != nil {
Fatalf("Failed to retrieve file descriptor allowance: %v", err) Fatalf("Failed to retrieve file descriptor allowance: %v", err)
@ -1064,7 +1060,7 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) {
if ctx.GlobalIsSet(CacheFlag.Name) || ctx.GlobalIsSet(CacheDatabaseFlag.Name) { if ctx.GlobalIsSet(CacheFlag.Name) || ctx.GlobalIsSet(CacheDatabaseFlag.Name) {
cfg.DatabaseCache = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheDatabaseFlag.Name) / 100 cfg.DatabaseCache = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheDatabaseFlag.Name) / 100
} }
cfg.DatabaseHandles = MakeDatabaseHandles() cfg.DatabaseHandles = makeDatabaseHandles()
if gcmode := ctx.GlobalString(GCModeFlag.Name); gcmode != "full" && gcmode != "archive" { if gcmode := ctx.GlobalString(GCModeFlag.Name); gcmode != "full" && gcmode != "archive" {
Fatalf("--%s must be either 'full' or 'archive'", GCModeFlag.Name) Fatalf("--%s must be either 'full' or 'archive'", GCModeFlag.Name)
@ -1091,9 +1087,9 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) {
cfg.EnablePreimageRecording = ctx.GlobalBool(VMEnableDebugFlag.Name) cfg.EnablePreimageRecording = ctx.GlobalBool(VMEnableDebugFlag.Name)
} }
if ctx.GlobalIsSet(StoreRewardFlag.Name) { if ctx.GlobalIsSet(StoreRewardFlag.Name) {
common.StoreRewardFolder = filepath.Join(stack.DataDir(), "XDC", "rewards") cfg.StoreRewardFolder = filepath.Join(stack.DataDir(), "XDC", "rewards")
if _, err := os.Stat(common.StoreRewardFolder); os.IsNotExist(err) { if _, err := os.Stat(cfg.StoreRewardFolder); os.IsNotExist(err) {
os.Mkdir(common.StoreRewardFolder, os.ModePerm) os.Mkdir(cfg.StoreRewardFolder, os.ModePerm)
} }
} }
// Override any default configs for hard coded networks. // Override any default configs for hard coded networks.
@ -1210,7 +1206,7 @@ func SetupNetwork(ctx *cli.Context) {
func MakeChainDatabase(ctx *cli.Context, stack *node.Node) ethdb.Database { func MakeChainDatabase(ctx *cli.Context, stack *node.Node) ethdb.Database {
var ( var (
cache = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheDatabaseFlag.Name) / 100 cache = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheDatabaseFlag.Name) / 100
handles = MakeDatabaseHandles() handles = makeDatabaseHandles()
) )
name := "chaindata" name := "chaindata"
if ctx.GlobalBool(LightModeFlag.Name) { if ctx.GlobalBool(LightModeFlag.Name) {
@ -1260,7 +1256,6 @@ func MakeChain(ctx *cli.Context, stack *node.Node) (chain *core.BlockChain, chai
DatasetsOnDisk: eth.DefaultConfig.Ethash.DatasetsOnDisk, DatasetsOnDisk: eth.DefaultConfig.Ethash.DatasetsOnDisk,
}) })
} }
Fatalf("Only support XDPoS consensus")
} }
if gcmode := ctx.GlobalString(GCModeFlag.Name); gcmode != "full" && gcmode != "archive" { if gcmode := ctx.GlobalString(GCModeFlag.Name); gcmode != "full" && gcmode != "archive" {
Fatalf("--%s must be either 'full' or 'archive'", GCModeFlag.Name) Fatalf("--%s must be either 'full' or 'archive'", GCModeFlag.Name)
@ -1320,4 +1315,4 @@ func MigrateFlags(action func(ctx *cli.Context) error) func(*cli.Context) error
} }
return action(ctx) return action(ctx)
} }
} }

File diff suppressed because one or more lines are too long

View file

@ -3715,13 +3715,6 @@ var inputBlockNumberFormatter = function (blockNumber) {
return utils.toHex(blockNumber); return utils.toHex(blockNumber);
}; };
var inputEpochNumberFormatter = function (epochNumber) {
if (epochNumber === undefined || epochNumber === "latest") {
return "latest";
}
return utils.toHex(epochNumber);
};
/** /**
* Formats the input of a transaction and converts all values to HEX * Formats the input of a transaction and converts all values to HEX
* *
@ -3847,22 +3840,6 @@ var outputBlockFormatter = function(block) {
return block; return block;
}; };
/**
* Formats the output of a blockSigner list
*
* @method outputBlockFormatter
* @param {Object} blockSigners
* @returns {Object}
*/
var outputBlockSignersFormatter = function(blockSigners) {
if (utils.isArray(blockSigners)) {
blockSigners.forEach(function(item){
if(!utils.isString(item))
return formatOutputAddress(item);
});
}
return blockSigners;
};
/** /**
* Formats the output of a log * Formats the output of a log
@ -3973,7 +3950,6 @@ var outputSyncingFormatter = function(result) {
module.exports = { module.exports = {
inputDefaultBlockNumberFormatter: inputDefaultBlockNumberFormatter, inputDefaultBlockNumberFormatter: inputDefaultBlockNumberFormatter,
inputBlockNumberFormatter: inputBlockNumberFormatter, inputBlockNumberFormatter: inputBlockNumberFormatter,
inputEpochNumberFormatter: inputEpochNumberFormatter,
inputCallFormatter: inputCallFormatter, inputCallFormatter: inputCallFormatter,
inputTransactionFormatter: inputTransactionFormatter, inputTransactionFormatter: inputTransactionFormatter,
inputAddressFormatter: inputAddressFormatter, inputAddressFormatter: inputAddressFormatter,
@ -3982,7 +3958,6 @@ module.exports = {
outputTransactionFormatter: outputTransactionFormatter, outputTransactionFormatter: outputTransactionFormatter,
outputTransactionReceiptFormatter: outputTransactionReceiptFormatter, outputTransactionReceiptFormatter: outputTransactionReceiptFormatter,
outputBlockFormatter: outputBlockFormatter, outputBlockFormatter: outputBlockFormatter,
outputBlockSignersFormatter: outputBlockSignersFormatter,
outputLogFormatter: outputLogFormatter, outputLogFormatter: outputLogFormatter,
outputPostFormatter: outputPostFormatter, outputPostFormatter: outputPostFormatter,
outputSyncingFormatter: outputSyncingFormatter outputSyncingFormatter: outputSyncingFormatter
@ -5235,14 +5210,6 @@ var blockCall = function (args) {
return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? "eth_getBlockByHash" : "eth_getBlockByNumber"; return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? "eth_getBlockByHash" : "eth_getBlockByNumber";
}; };
var blockSignersCall = function (args) {
return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? "eth_getBlockSignersByHash" : "eth_getBlockSignersByNumber";
};
var blockFinalityCall = function (args) {
return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? "eth_getBlockFinalityByHash" : "eth_getBlockFinalityByNumber";
};
var transactionFromBlockCall = function (args) { var transactionFromBlockCall = function (args) {
return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? 'eth_getTransactionByBlockHashAndIndex' : 'eth_getTransactionByBlockNumberAndIndex'; return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? 'eth_getTransactionByBlockHashAndIndex' : 'eth_getTransactionByBlockNumberAndIndex';
}; };
@ -5330,22 +5297,6 @@ var methods = function () {
outputFormatter: formatters.outputBlockFormatter outputFormatter: formatters.outputBlockFormatter
}); });
var getBlockSigners = new Method({
name: 'getBlockSigners',
call: blockSignersCall,
params: 1,
inputFormatter: [formatters.inputBlockNumberFormatter],
outputFormatter: formatters.outputBlockSignersFormatter
});
var getBlockFinality = new Method({
name: 'getBlockFinality',
call: blockFinalityCall,
params: 1,
inputFormatter: [formatters.inputBlockNumberFormatter],
outputFormatter: formatters.formatOutputInt
});
var getUncle = new Method({ var getUncle = new Method({
name: 'getUncle', name: 'getUncle',
call: uncleCall, call: uncleCall,
@ -5480,20 +5431,11 @@ var methods = function () {
params: 0 params: 0
}); });
var getCandidateStatus = new Method({
name: 'getCandidateStatus',
call: 'eth_getCandidateStatus',
params: 2,
inputFormatter: [formatters.inputAddressFormatter, formatters.inputEpochNumberFormatter]
});
return [ return [
getBalance, getBalance,
getStorageAt, getStorageAt,
getCode, getCode,
getBlock, getBlock,
getBlockSigners,
getBlockFinality,
getCandidateStatus,
getUncle, getUncle,
getCompilers, getCompilers,
getBlockTransactionCount, getBlockTransactionCount,

View file

@ -117,13 +117,11 @@ type ServerCodec interface {
} }
type BlockNumber int64 type BlockNumber int64
type EpochNumber int64
const ( const (
PendingBlockNumber = BlockNumber(-2) PendingBlockNumber = BlockNumber(-2)
LatestBlockNumber = BlockNumber(-1) LatestBlockNumber = BlockNumber(-1)
EarliestBlockNumber = BlockNumber(0) EarliestBlockNumber = BlockNumber(0)
LatestEpochNumber = EpochNumber(-1)
) )
// UnmarshalJSON parses the given JSON fragment into a BlockNumber. It supports: // UnmarshalJSON parses the given JSON fragment into a BlockNumber. It supports:
@ -133,7 +131,11 @@ const (
// - an invalid block number error when the given argument isn't a known strings // - an invalid block number error when the given argument isn't a known strings
// - an out of range error when the given block number is either too little or too large // - an out of range error when the given block number is either too little or too large
func (bn *BlockNumber) UnmarshalJSON(data []byte) error { func (bn *BlockNumber) UnmarshalJSON(data []byte) error {
input := trimData(data) input := strings.TrimSpace(string(data))
if len(input) >= 2 && input[0] == '"' && input[len(input)-1] == '"' {
input = input[1 : len(input)-1]
}
switch input { switch input {
case "earliest": case "earliest":
*bn = EarliestBlockNumber *bn = EarliestBlockNumber
@ -161,34 +163,3 @@ func (bn *BlockNumber) UnmarshalJSON(data []byte) error {
func (bn BlockNumber) Int64() int64 { func (bn BlockNumber) Int64() int64 {
return (int64)(bn) return (int64)(bn)
} }
func (e *EpochNumber) UnmarshalJSON(data []byte) error {
input := trimData(data)
if input == "latest" {
*e = LatestEpochNumber
return nil
}
eNum, err := hexutil.DecodeUint64(input)
if err != nil {
return err
}
if eNum > math.MaxInt64 {
return fmt.Errorf("EpochNumber too high")
}
*e = EpochNumber(eNum)
return nil
}
func (e EpochNumber) Int64() int64 {
return (int64)(e)
}
func trimData(data []byte) string {
input := strings.TrimSpace(string(data))
if len(input) >= 2 && input[0] == '"' && input[len(input)-1] == '"' {
input = input[1 : len(input)-1]
}
return input
}

View file

@ -53,9 +53,9 @@ func returnHasherToPool(h *hasher) {
// hash collapses a node down into a hash node, also returning a copy of the // hash collapses a node down into a hash node, also returning a copy of the
// original node initialized with the computed hash to replace the original one. // original node initialized with the computed hash to replace the original one.
func (h *hasher) hash(n Node, db *Database, force bool) (Node, Node, error) { func (h *hasher) hash(n node, db *Database, force bool) (node, node, error) {
// If we're not storing the node, just hashing, use available cached data // If we're not storing the node, just hashing, use available cached data
if hash, dirty := n.Cache(); hash != nil { if hash, dirty := n.cache(); hash != nil {
if db == nil { if db == nil {
return hash, n, nil return hash, n, nil
} }
@ -72,23 +72,23 @@ func (h *hasher) hash(n Node, db *Database, force bool) (Node, Node, error) {
// Trie not processed yet or needs storage, walk the children // Trie not processed yet or needs storage, walk the children
collapsed, cached, err := h.hashChildren(n, db) collapsed, cached, err := h.hashChildren(n, db)
if err != nil { if err != nil {
return HashNode{}, n, err return hashNode{}, n, err
} }
hashed, err := h.store(collapsed, db, force) hashed, err := h.store(collapsed, db, force)
if err != nil { if err != nil {
return HashNode{}, n, err return hashNode{}, n, err
} }
// Cache the hash of the node for later reuse and remove // Cache the hash of the node for later reuse and remove
// the dirty flag in commit mode. It's fine to assign these values directly // the dirty flag in commit mode. It's fine to assign these values directly
// without copying the node first because hashChildren copies it. // without copying the node first because hashChildren copies it.
cachedHash, _ := hashed.(HashNode) cachedHash, _ := hashed.(hashNode)
switch cn := cached.(type) { switch cn := cached.(type) {
case *ShortNode: case *shortNode:
cn.flags.hash = cachedHash cn.flags.hash = cachedHash
if db != nil { if db != nil {
cn.flags.dirty = false cn.flags.dirty = false
} }
case *FullNode: case *fullNode:
cn.flags.hash = cachedHash cn.flags.hash = cachedHash
if db != nil { if db != nil {
cn.flags.dirty = false cn.flags.dirty = false
@ -100,28 +100,28 @@ func (h *hasher) hash(n Node, db *Database, force bool) (Node, Node, error) {
// hashChildren replaces the children of a node with their hashes if the encoded // hashChildren replaces the children of a node with their hashes if the encoded
// size of the child is larger than a hash, returning the collapsed node as well // size of the child is larger than a hash, returning the collapsed node as well
// as a replacement for the original node with the child hashes cached in. // as a replacement for the original node with the child hashes cached in.
func (h *hasher) hashChildren(original Node, db *Database) (Node, Node, error) { func (h *hasher) hashChildren(original node, db *Database) (node, node, error) {
var err error var err error
switch n := original.(type) { switch n := original.(type) {
case *ShortNode: case *shortNode:
// Hash the short Node's child, caching the newly hashed subtree // Hash the short node's child, caching the newly hashed subtree
collapsed, cached := n.copy(), n.copy() collapsed, cached := n.copy(), n.copy()
collapsed.Key = hexToCompact(n.Key) collapsed.Key = hexToCompact(n.Key)
cached.Key = common.CopyBytes(n.Key) cached.Key = common.CopyBytes(n.Key)
if _, ok := n.Val.(ValueNode); !ok { if _, ok := n.Val.(valueNode); !ok {
collapsed.Val, cached.Val, err = h.hash(n.Val, db, false) collapsed.Val, cached.Val, err = h.hash(n.Val, db, false)
if err != nil { if err != nil {
return original, original, err return original, original, err
} }
} }
if collapsed.Val == nil { if collapsed.Val == nil {
collapsed.Val = ValueNode(nil) // Ensure that nil children are encoded as empty strings. collapsed.Val = valueNode(nil) // Ensure that nil children are encoded as empty strings.
} }
return collapsed, cached, nil return collapsed, cached, nil
case *FullNode: case *fullNode:
// Hash the full node's children, caching the newly hashed subtrees // Hash the full node's children, caching the newly hashed subtrees
collapsed, cached := n.copy(), n.copy() collapsed, cached := n.copy(), n.copy()
@ -132,12 +132,12 @@ func (h *hasher) hashChildren(original Node, db *Database) (Node, Node, error) {
return original, original, err return original, original, err
} }
} else { } else {
collapsed.Children[i] = ValueNode(nil) // Ensure that nil children are encoded as empty strings. collapsed.Children[i] = valueNode(nil) // Ensure that nil children are encoded as empty strings.
} }
} }
cached.Children[16] = n.Children[16] cached.Children[16] = n.Children[16]
if collapsed.Children[16] == nil { if collapsed.Children[16] == nil {
collapsed.Children[16] = ValueNode(nil) collapsed.Children[16] = valueNode(nil)
} }
return collapsed, cached, nil return collapsed, cached, nil
@ -150,9 +150,9 @@ func (h *hasher) hashChildren(original Node, db *Database) (Node, Node, error) {
// store hashes the node n and if we have a storage layer specified, it writes // store hashes the node n and if we have a storage layer specified, it writes
// the key/value pair to it and tracks any node->child references as well as any // the key/value pair to it and tracks any node->child references as well as any
// node->external trie references. // node->external trie references.
func (h *hasher) store(n Node, db *Database, force bool) (Node, error) { func (h *hasher) store(n node, db *Database, force bool) (node, error) {
// Don't store hashes or empty nodes. // Don't store hashes or empty nodes.
if _, isHash := n.(HashNode); n == nil || isHash { if _, isHash := n.(hashNode); n == nil || isHash {
return n, nil return n, nil
} }
// Generate the RLP encoding of the node // Generate the RLP encoding of the node
@ -164,11 +164,11 @@ func (h *hasher) store(n Node, db *Database, force bool) (Node, error) {
return n, nil // Nodes smaller than 32 bytes are stored inside their parent return n, nil // Nodes smaller than 32 bytes are stored inside their parent
} }
// Larger nodes are replaced by their hash and stored in the database. // Larger nodes are replaced by their hash and stored in the database.
hash, _ := n.Cache() hash, _ := n.cache()
if hash == nil { if hash == nil {
h.sha.Reset() h.sha.Reset()
h.sha.Write(h.tmp.Bytes()) h.sha.Write(h.tmp.Bytes())
hash = HashNode(h.sha.Sum(nil)) hash = hashNode(h.sha.Sum(nil))
} }
if db != nil { if db != nil {
// We are pooling the trie nodes into an intermediate memory cache // We are pooling the trie nodes into an intermediate memory cache
@ -179,13 +179,13 @@ func (h *hasher) store(n Node, db *Database, force bool) (Node, error) {
// Track all direct parent->child node references // Track all direct parent->child node references
switch n := n.(type) { switch n := n.(type) {
case *ShortNode: case *shortNode:
if child, ok := n.Val.(HashNode); ok { if child, ok := n.Val.(hashNode); ok {
db.reference(common.BytesToHash(child), hash) db.reference(common.BytesToHash(child), hash)
} }
case *FullNode: case *fullNode:
for i := 0; i < 16; i++ { for i := 0; i < 16; i++ {
if child, ok := n.Children[i].(HashNode); ok { if child, ok := n.Children[i].(hashNode); ok {
db.reference(common.BytesToHash(child), hash) db.reference(common.BytesToHash(child), hash)
} }
} }
@ -195,13 +195,13 @@ func (h *hasher) store(n Node, db *Database, force bool) (Node, error) {
// Track external references from account->storage trie // Track external references from account->storage trie
if h.onleaf != nil { if h.onleaf != nil {
switch n := n.(type) { switch n := n.(type) {
case *ShortNode: case *shortNode:
if child, ok := n.Val.(ValueNode); ok { if child, ok := n.Val.(valueNode); ok {
h.onleaf(child, hash) h.onleaf(child, hash)
} }
case *FullNode: case *fullNode:
for i := 0; i < 16; i++ { for i := 0; i < 16; i++ {
if child, ok := n.Children[i].(ValueNode); ok { if child, ok := n.Children[i].(valueNode); ok {
h.onleaf(child, hash) h.onleaf(child, hash)
} }
} }
@ -209,4 +209,4 @@ func (h *hasher) store(n Node, db *Database, force bool) (Node, error) {
} }
} }
return hash, nil return hash, nil
} }

View file

@ -20,6 +20,7 @@ import (
"bytes" "bytes"
"container/heap" "container/heap"
"errors" "errors"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
) )
@ -59,7 +60,6 @@ type NodeIterator interface {
// Next moves the iterator to the next node. If the parameter is false, any child // Next moves the iterator to the next node. If the parameter is false, any child
// nodes will be skipped. // nodes will be skipped.
Next(bool) bool Next(bool) bool
// Error returns the error status of the iterator. // Error returns the error status of the iterator.
Error() error Error() error
@ -86,7 +86,7 @@ type NodeIterator interface {
// trie, which can be resumed at a later invocation. // trie, which can be resumed at a later invocation.
type nodeIteratorState struct { type nodeIteratorState struct {
hash common.Hash // Hash of the node being iterated (nil if not standalone) hash common.Hash // Hash of the node being iterated (nil if not standalone)
node Node // Trie node being iterated node node // Trie node being iterated
parent common.Hash // Hash of the first full ancestor node (nil if current is the root) parent common.Hash // Hash of the first full ancestor node (nil if current is the root)
index int // Child to be processed next index int // Child to be processed next
pathlen int // Length of the path to this node pathlen int // Length of the path to this node
@ -112,7 +112,7 @@ func (e seekError) Error() string {
return "seek error: " + e.err.Error() return "seek error: " + e.err.Error()
} }
func NewNodeIterator(trie *Trie, start []byte) NodeIterator { func newNodeIterator(trie *Trie, start []byte) NodeIterator {
if trie.Hash() == emptyState { if trie.Hash() == emptyState {
return new(nodeIterator) return new(nodeIterator)
} }
@ -141,7 +141,7 @@ func (it *nodeIterator) Leaf() bool {
func (it *nodeIterator) LeafBlob() []byte { func (it *nodeIterator) LeafBlob() []byte {
if len(it.stack) > 0 { if len(it.stack) > 0 {
if node, ok := it.stack[len(it.stack)-1].node.(ValueNode); ok { if node, ok := it.stack[len(it.stack)-1].node.(valueNode); ok {
return []byte(node) return []byte(node)
} }
} }
@ -150,7 +150,7 @@ func (it *nodeIterator) LeafBlob() []byte {
func (it *nodeIterator) LeafKey() []byte { func (it *nodeIterator) LeafKey() []byte {
if len(it.stack) > 0 { if len(it.stack) > 0 {
if _, ok := it.stack[len(it.stack)-1].node.(ValueNode); ok { if _, ok := it.stack[len(it.stack)-1].node.(valueNode); ok {
return hexToKeybytes(it.path) return hexToKeybytes(it.path)
} }
} }
@ -250,7 +250,7 @@ func (it *nodeIterator) peek(descend bool) (*nodeIteratorState, *int, []byte, er
} }
func (st *nodeIteratorState) resolve(tr *Trie, path []byte) error { func (st *nodeIteratorState) resolve(tr *Trie, path []byte) error {
if hash, ok := st.node.(HashNode); ok { if hash, ok := st.node.(hashNode); ok {
resolved, err := tr.resolveHash(hash, path) resolved, err := tr.resolveHash(hash, path)
if err != nil { if err != nil {
return err return err
@ -263,12 +263,12 @@ func (st *nodeIteratorState) resolve(tr *Trie, path []byte) error {
func (it *nodeIterator) nextChild(parent *nodeIteratorState, ancestor common.Hash) (*nodeIteratorState, []byte, bool) { func (it *nodeIterator) nextChild(parent *nodeIteratorState, ancestor common.Hash) (*nodeIteratorState, []byte, bool) {
switch node := parent.node.(type) { switch node := parent.node.(type) {
case *FullNode: case *fullNode:
// Full Node, move to the first non-nil child. // Full node, move to the first non-nil child.
for i := parent.index + 1; i < len(node.Children); i++ { for i := parent.index + 1; i < len(node.Children); i++ {
child := node.Children[i] child := node.Children[i]
if child != nil { if child != nil {
hash, _ := child.Cache() hash, _ := child.cache()
state := &nodeIteratorState{ state := &nodeIteratorState{
hash: common.BytesToHash(hash), hash: common.BytesToHash(hash),
node: child, node: child,
@ -281,10 +281,10 @@ func (it *nodeIterator) nextChild(parent *nodeIteratorState, ancestor common.Has
return state, path, true return state, path, true
} }
} }
case *ShortNode: case *shortNode:
// Short node, return the pointer singleton child // Short node, return the pointer singleton child
if parent.index < 0 { if parent.index < 0 {
hash, _ := node.Val.Cache() hash, _ := node.Val.cache()
state := &nodeIteratorState{ state := &nodeIteratorState{
hash: common.BytesToHash(hash), hash: common.BytesToHash(hash),
node: node.Val, node: node.Val,
@ -525,4 +525,4 @@ func (it *unionIterator) Error() error {
} }
} }
return nil return nil
} }

View file

@ -37,11 +37,11 @@ import (
func (t *Trie) Prove(key []byte, fromLevel uint, proofDb ethdb.Putter) error { func (t *Trie) Prove(key []byte, fromLevel uint, proofDb ethdb.Putter) error {
// Collect all nodes on the path to key. // Collect all nodes on the path to key.
key = keybytesToHex(key) key = keybytesToHex(key)
nodes := []Node{} nodes := []node{}
tn := t.root tn := t.root
for len(key) > 0 && tn != nil { for len(key) > 0 && tn != nil {
switch n := tn.(type) { switch n := tn.(type) {
case *ShortNode: case *shortNode:
if len(key) < len(n.Key) || !bytes.Equal(n.Key, key[:len(n.Key)]) { if len(key) < len(n.Key) || !bytes.Equal(n.Key, key[:len(n.Key)]) {
// The trie doesn't contain the key. // The trie doesn't contain the key.
tn = nil tn = nil
@ -50,11 +50,11 @@ func (t *Trie) Prove(key []byte, fromLevel uint, proofDb ethdb.Putter) error {
key = key[len(n.Key):] key = key[len(n.Key):]
} }
nodes = append(nodes, n) nodes = append(nodes, n)
case *FullNode: case *fullNode:
tn = n.Children[key[0]] tn = n.Children[key[0]]
key = key[1:] key = key[1:]
nodes = append(nodes, n) nodes = append(nodes, n)
case HashNode: case hashNode:
var err error var err error
tn, err = t.resolveHash(n, nil) tn, err = t.resolveHash(n, nil)
if err != nil { if err != nil {
@ -71,7 +71,7 @@ func (t *Trie) Prove(key []byte, fromLevel uint, proofDb ethdb.Putter) error {
// if encoding doesn't work and we're not writing to any database. // if encoding doesn't work and we're not writing to any database.
n, _, _ = hasher.hashChildren(n, nil) n, _, _ = hasher.hashChildren(n, nil)
hn, _ := hasher.store(n, nil, false) hn, _ := hasher.store(n, nil, false)
if hash, ok := hn.(HashNode); ok || i == 0 { if hash, ok := hn.(hashNode); ok || i == 0 {
// If the node's database encoding is a hash (or is the // If the node's database encoding is a hash (or is the
// root node), it becomes a proof element. // root node), it becomes a proof element.
if fromLevel > 0 { if fromLevel > 0 {
@ -119,35 +119,35 @@ func VerifyProof(rootHash common.Hash, key []byte, proofDb DatabaseReader) (valu
case nil: case nil:
// The trie doesn't contain the key. // The trie doesn't contain the key.
return nil, nil, i return nil, nil, i
case HashNode: case hashNode:
key = keyrest key = keyrest
copy(wantHash[:], cld) copy(wantHash[:], cld)
case ValueNode: case valueNode:
return cld, nil, i + 1 return cld, nil, i + 1
} }
} }
} }
func get(tn Node, key []byte) ([]byte, Node) { func get(tn node, key []byte) ([]byte, node) {
for { for {
switch n := tn.(type) { switch n := tn.(type) {
case *ShortNode: case *shortNode:
if len(key) < len(n.Key) || !bytes.Equal(n.Key, key[:len(n.Key)]) { if len(key) < len(n.Key) || !bytes.Equal(n.Key, key[:len(n.Key)]) {
return nil, nil return nil, nil
} }
tn = n.Val tn = n.Val
key = key[len(n.Key):] key = key[len(n.Key):]
case *FullNode: case *fullNode:
tn = n.Children[key[0]] tn = n.Children[key[0]]
key = key[1:] key = key[1:]
case HashNode: case hashNode:
return key, n return key, n
case nil: case nil:
return key, nil return key, nil
case ValueNode: case valueNode:
return nil, n return nil, n
default: default:
panic(fmt.Sprintf("%T: invalid node: %v", tn, tn)) panic(fmt.Sprintf("%T: invalid node: %v", tn, tn))
} }
} }
} }

View file

@ -248,21 +248,21 @@ func (s *TrieSync) schedule(req *request) {
// children retrieves all the missing children of a state trie entry for future // children retrieves all the missing children of a state trie entry for future
// retrieval scheduling. // retrieval scheduling.
func (s *TrieSync) children(req *request, object Node) ([]*request, error) { func (s *TrieSync) children(req *request, object node) ([]*request, error) {
// Gather all the children of the node, irrelevant whether known or not // Gather all the children of the node, irrelevant whether known or not
type child struct { type child struct {
node Node node node
depth int depth int
} }
children := []child{} children := []child{}
switch node := (object).(type) { switch node := (object).(type) {
case *ShortNode: case *shortNode:
children = []child{{ children = []child{{
node: node.Val, node: node.Val,
depth: req.depth + len(node.Key), depth: req.depth + len(node.Key),
}} }}
case *FullNode: case *fullNode:
for i := 0; i < 17; i++ { for i := 0; i < 17; i++ {
if node.Children[i] != nil { if node.Children[i] != nil {
children = append(children, child{ children = append(children, child{
@ -279,14 +279,14 @@ func (s *TrieSync) children(req *request, object Node) ([]*request, error) {
for _, child := range children { for _, child := range children {
// Notify any external watcher of a new key/value node // Notify any external watcher of a new key/value node
if req.callback != nil { if req.callback != nil {
if node, ok := (child.node).(ValueNode); ok { if node, ok := (child.node).(valueNode); ok {
if err := req.callback(node, req.hash); err != nil { if err := req.callback(node, req.hash); err != nil {
return nil, err return nil, err
} }
} }
} }
// If the child references another node, resolve or schedule // If the child references another node, resolve or schedule
if node, ok := (child.node).(HashNode); ok { if node, ok := (child.node).(hashNode); ok {
// Try to resolve the node from the local database // Try to resolve the node from the local database
hash := common.BytesToHash(node) hash := common.BytesToHash(node)
if _, ok := s.membatch.batch[hash]; ok { if _, ok := s.membatch.batch[hash]; ok {
@ -327,4 +327,4 @@ func (s *TrieSync) commit(req *request) (err error) {
} }
} }
return nil return nil
} }

View file

@ -66,7 +66,7 @@ type LeafCallback func(leaf []byte, parent common.Hash) error
// Trie is not safe for concurrent use. // Trie is not safe for concurrent use.
type Trie struct { type Trie struct {
db *Database db *Database
root Node root node
originalRoot common.Hash originalRoot common.Hash
// Cache generation values. // Cache generation values.
@ -114,7 +114,7 @@ func New(root common.Hash, db *Database) (*Trie, error) {
// NodeIterator returns an iterator that returns nodes of the trie. Iteration starts at // NodeIterator returns an iterator that returns nodes of the trie. Iteration starts at
// the key after the given start key. // the key after the given start key.
func (t *Trie) NodeIterator(start []byte) NodeIterator { func (t *Trie) NodeIterator(start []byte) NodeIterator {
return NewNodeIterator(t, start) return newNodeIterator(t, start)
} }
// Get returns the value for key stored in the trie. // Get returns the value for key stored in the trie.
@ -139,13 +139,13 @@ func (t *Trie) TryGet(key []byte) ([]byte, error) {
return value, err return value, err
} }
func (t *Trie) tryGet(origNode Node, key []byte, pos int) (value []byte, newnode Node, didResolve bool, err error) { func (t *Trie) tryGet(origNode node, key []byte, pos int) (value []byte, newnode node, didResolve bool, err error) {
switch n := (origNode).(type) { switch n := (origNode).(type) {
case nil: case nil:
return nil, nil, false, nil return nil, nil, false, nil
case ValueNode: case valueNode:
return n, n, false, nil return n, n, false, nil
case *ShortNode: case *shortNode:
if len(key)-pos < len(n.Key) || !bytes.Equal(n.Key, key[pos:pos+len(n.Key)]) { if len(key)-pos < len(n.Key) || !bytes.Equal(n.Key, key[pos:pos+len(n.Key)]) {
// key not found in trie // key not found in trie
return nil, n, false, nil return nil, n, false, nil
@ -157,7 +157,7 @@ func (t *Trie) tryGet(origNode Node, key []byte, pos int) (value []byte, newnode
n.flags.gen = t.cachegen n.flags.gen = t.cachegen
} }
return value, n, didResolve, err return value, n, didResolve, err
case *FullNode: case *fullNode:
value, newnode, didResolve, err = t.tryGet(n.Children[key[pos]], key, pos+1) value, newnode, didResolve, err = t.tryGet(n.Children[key[pos]], key, pos+1)
if err == nil && didResolve { if err == nil && didResolve {
n = n.copy() n = n.copy()
@ -165,7 +165,7 @@ func (t *Trie) tryGet(origNode Node, key []byte, pos int) (value []byte, newnode
n.Children[key[pos]] = newnode n.Children[key[pos]] = newnode
} }
return value, n, didResolve, err return value, n, didResolve, err
case HashNode: case hashNode:
child, err := t.resolveHash(n, key[:pos]) child, err := t.resolveHash(n, key[:pos])
if err != nil { if err != nil {
return nil, n, true, err return nil, n, true, err
@ -200,7 +200,7 @@ func (t *Trie) Update(key, value []byte) {
func (t *Trie) TryUpdate(key, value []byte) error { func (t *Trie) TryUpdate(key, value []byte) error {
k := keybytesToHex(key) k := keybytesToHex(key)
if len(value) != 0 { if len(value) != 0 {
_, n, err := t.insert(t.root, nil, k, ValueNode(value)) _, n, err := t.insert(t.root, nil, k, valueNode(value))
if err != nil { if err != nil {
return err return err
} }
@ -215,15 +215,15 @@ func (t *Trie) TryUpdate(key, value []byte) error {
return nil return nil
} }
func (t *Trie) insert(n Node, prefix, key []byte, value Node) (bool, Node, error) { func (t *Trie) insert(n node, prefix, key []byte, value node) (bool, node, error) {
if len(key) == 0 { if len(key) == 0 {
if v, ok := n.(ValueNode); ok { if v, ok := n.(valueNode); ok {
return !bytes.Equal(v, value.(ValueNode)), value, nil return !bytes.Equal(v, value.(valueNode)), value, nil
} }
return true, value, nil return true, value, nil
} }
switch n := n.(type) { switch n := n.(type) {
case *ShortNode: case *shortNode:
matchlen := prefixLen(key, n.Key) matchlen := prefixLen(key, n.Key)
// If the whole key matches, keep this short node as is // If the whole key matches, keep this short node as is
// and only update the value. // and only update the value.
@ -232,10 +232,10 @@ func (t *Trie) insert(n Node, prefix, key []byte, value Node) (bool, Node, error
if !dirty || err != nil { if !dirty || err != nil {
return false, n, err return false, n, err
} }
return true, &ShortNode{n.Key, nn, t.newFlag()}, nil return true, &shortNode{n.Key, nn, t.newFlag()}, nil
} }
// Otherwise branch out at the index where they differ. // Otherwise branch out at the index where they differ.
branch := &FullNode{flags: t.newFlag()} branch := &fullNode{flags: t.newFlag()}
var err error var err error
_, branch.Children[n.Key[matchlen]], err = t.insert(nil, append(prefix, n.Key[:matchlen+1]...), n.Key[matchlen+1:], n.Val) _, branch.Children[n.Key[matchlen]], err = t.insert(nil, append(prefix, n.Key[:matchlen+1]...), n.Key[matchlen+1:], n.Val)
if err != nil { if err != nil {
@ -250,9 +250,9 @@ func (t *Trie) insert(n Node, prefix, key []byte, value Node) (bool, Node, error
return true, branch, nil return true, branch, nil
} }
// Otherwise, replace it with a short node leading up to the branch. // Otherwise, replace it with a short node leading up to the branch.
return true, &ShortNode{key[:matchlen], branch, t.newFlag()}, nil return true, &shortNode{key[:matchlen], branch, t.newFlag()}, nil
case *FullNode: case *fullNode:
dirty, nn, err := t.insert(n.Children[key[0]], append(prefix, key[0]), key[1:], value) dirty, nn, err := t.insert(n.Children[key[0]], append(prefix, key[0]), key[1:], value)
if !dirty || err != nil { if !dirty || err != nil {
return false, n, err return false, n, err
@ -263,9 +263,9 @@ func (t *Trie) insert(n Node, prefix, key []byte, value Node) (bool, Node, error
return true, n, nil return true, n, nil
case nil: case nil:
return true, &ShortNode{key, value, t.newFlag()}, nil return true, &shortNode{key, value, t.newFlag()}, nil
case HashNode: case hashNode:
// We've hit a part of the trie that isn't loaded yet. Load // We've hit a part of the trie that isn't loaded yet. Load
// the node and insert into it. This leaves all child nodes on // the node and insert into it. This leaves all child nodes on
// the path to the value in the trie. // the path to the value in the trie.
@ -306,9 +306,9 @@ func (t *Trie) TryDelete(key []byte) error {
// delete returns the new root of the trie with key deleted. // delete returns the new root of the trie with key deleted.
// It reduces the trie to minimal form by simplifying // It reduces the trie to minimal form by simplifying
// nodes on the way up after deleting recursively. // nodes on the way up after deleting recursively.
func (t *Trie) delete(n Node, prefix, key []byte) (bool, Node, error) { func (t *Trie) delete(n node, prefix, key []byte) (bool, node, error) {
switch n := n.(type) { switch n := n.(type) {
case *ShortNode: case *shortNode:
matchlen := prefixLen(key, n.Key) matchlen := prefixLen(key, n.Key)
if matchlen < len(n.Key) { if matchlen < len(n.Key) {
return false, n, nil // don't replace n on mismatch return false, n, nil // don't replace n on mismatch
@ -325,19 +325,19 @@ func (t *Trie) delete(n Node, prefix, key []byte) (bool, Node, error) {
return false, n, err return false, n, err
} }
switch child := child.(type) { switch child := child.(type) {
case *ShortNode: case *shortNode:
// Deleting from the subtrie reduced it to another // Deleting from the subtrie reduced it to another
// short node. Merge the nodes to avoid creating a // short node. Merge the nodes to avoid creating a
// shortNode{..., shortNode{...}}. Use concat (which // shortNode{..., shortNode{...}}. Use concat (which
// always creates a new slice) instead of append to // always creates a new slice) instead of append to
// avoid modifying n.Key since it might be shared with // avoid modifying n.Key since it might be shared with
// other nodes. // other nodes.
return true, &ShortNode{concat(n.Key, child.Key...), child.Val, t.newFlag()}, nil return true, &shortNode{concat(n.Key, child.Key...), child.Val, t.newFlag()}, nil
default: default:
return true, &ShortNode{n.Key, child, t.newFlag()}, nil return true, &shortNode{n.Key, child, t.newFlag()}, nil
} }
case *FullNode: case *fullNode:
dirty, nn, err := t.delete(n.Children[key[0]], append(prefix, key[0]), key[1:]) dirty, nn, err := t.delete(n.Children[key[0]], append(prefix, key[0]), key[1:])
if !dirty || err != nil { if !dirty || err != nil {
return false, n, err return false, n, err
@ -368,7 +368,7 @@ func (t *Trie) delete(n Node, prefix, key []byte) (bool, Node, error) {
} }
if pos >= 0 { if pos >= 0 {
if pos != 16 { if pos != 16 {
// If the remaining entry is a short node, it replaces // If the remaining entry is a short node, it replaces
// n and its key gets the missing nibble tacked to the // n and its key gets the missing nibble tacked to the
// front. This avoids creating an invalid // front. This avoids creating an invalid
// shortNode{..., shortNode{...}}. Since the entry // shortNode{..., shortNode{...}}. Since the entry
@ -378,25 +378,25 @@ func (t *Trie) delete(n Node, prefix, key []byte) (bool, Node, error) {
if err != nil { if err != nil {
return false, nil, err return false, nil, err
} }
if cnode, ok := cnode.(*ShortNode); ok { if cnode, ok := cnode.(*shortNode); ok {
k := append([]byte{byte(pos)}, cnode.Key...) k := append([]byte{byte(pos)}, cnode.Key...)
return true, &ShortNode{k, cnode.Val, t.newFlag()}, nil return true, &shortNode{k, cnode.Val, t.newFlag()}, nil
} }
} }
// Otherwise, n is replaced by a one-nibble short node // Otherwise, n is replaced by a one-nibble short node
// containing the child. // containing the child.
return true, &ShortNode{[]byte{byte(pos)}, n.Children[pos], t.newFlag()}, nil return true, &shortNode{[]byte{byte(pos)}, n.Children[pos], t.newFlag()}, nil
} }
// n still contains at least two values and cannot be reduced. // n still contains at least two values and cannot be reduced.
return true, n, nil return true, n, nil
case ValueNode: case valueNode:
return true, nil, nil return true, nil, nil
case nil: case nil:
return false, nil, nil return false, nil, nil
case HashNode: case hashNode:
// We've hit a part of the trie that isn't loaded yet. Load // We've hit a part of the trie that isn't loaded yet. Load
// the node and delete from it. This leaves all child nodes on // the node and delete from it. This leaves all child nodes on
// the path to the value in the trie. // the path to the value in the trie.
@ -422,14 +422,14 @@ func concat(s1 []byte, s2 ...byte) []byte {
return r return r
} }
func (t *Trie) resolve(n Node, prefix []byte) (Node, error) { func (t *Trie) resolve(n node, prefix []byte) (node, error) {
if n, ok := n.(HashNode); ok { if n, ok := n.(hashNode); ok {
return t.resolveHash(n, prefix) return t.resolveHash(n, prefix)
} }
return n, nil return n, nil
} }
func (t *Trie) resolveHash(n HashNode, prefix []byte) (Node, error) { func (t *Trie) resolveHash(n hashNode, prefix []byte) (node, error) {
cacheMissCounter.Inc(1) cacheMissCounter.Inc(1)
hash := common.BytesToHash(n) hash := common.BytesToHash(n)
@ -438,7 +438,7 @@ func (t *Trie) resolveHash(n HashNode, prefix []byte) (Node, error) {
if err != nil || enc == nil { if err != nil || enc == nil {
return nil, &MissingNodeError{NodeHash: hash, Path: prefix} return nil, &MissingNodeError{NodeHash: hash, Path: prefix}
} }
return MustDecodeNode(n, enc, t.cachegen), nil return mustDecodeNode(n, enc, t.cachegen), nil
} }
// Root returns the root hash of the trie. // Root returns the root hash of the trie.
@ -450,7 +450,7 @@ func (t *Trie) Root() []byte { return t.Hash().Bytes() }
func (t *Trie) Hash() common.Hash { func (t *Trie) Hash() common.Hash {
hash, cached, _ := t.hashRoot(nil, nil) hash, cached, _ := t.hashRoot(nil, nil)
t.root = cached t.root = cached
return common.BytesToHash(hash.(HashNode)) return common.BytesToHash(hash.(hashNode))
} }
// Commit writes all nodes to the trie's memory database, tracking the internal // Commit writes all nodes to the trie's memory database, tracking the internal
@ -465,14 +465,14 @@ func (t *Trie) Commit(onleaf LeafCallback) (root common.Hash, err error) {
} }
t.root = cached t.root = cached
t.cachegen++ t.cachegen++
return common.BytesToHash(hash.(HashNode)), nil return common.BytesToHash(hash.(hashNode)), nil
} }
func (t *Trie) hashRoot(db *Database, onleaf LeafCallback) (Node, Node, error) { func (t *Trie) hashRoot(db *Database, onleaf LeafCallback) (node, node, error) {
if t.root == nil { if t.root == nil {
return HashNode(emptyRoot.Bytes()), nil, nil return hashNode(emptyRoot.Bytes()), nil, nil
} }
h := newHasher(t.cachegen, t.cachelimit, onleaf) h := newHasher(t.cachegen, t.cachelimit, onleaf)
defer returnHasherToPool(h) defer returnHasherToPool(h)
return h.hash(t.root, db, true) return h.hash(t.root, db, true)
} }

View file

@ -469,14 +469,14 @@ func runRandTest(rt randTest) bool {
return true return true
} }
func checkCacheInvariant(n, parent Node, parentCachegen uint16, parentDirty bool, depth int) error { func checkCacheInvariant(n, parent node, parentCachegen uint16, parentDirty bool, depth int) error {
var children []Node var children []node
var flag nodeFlag var flag nodeFlag
switch n := n.(type) { switch n := n.(type) {
case *ShortNode: case *shortNode:
flag = n.flags flag = n.flags
children = []Node{n.Val} children = []node{n.Val}
case *FullNode: case *fullNode:
flag = n.flags flag = n.flags
children = n.Children[:] children = n.Children[:]
default: default:
@ -615,4 +615,4 @@ func updateString(trie *Trie, k, v string) {
func deleteString(trie *Trie, k string) { func deleteString(trie *Trie, k string) {
trie.Delete([]byte(k)) trie.Delete([]byte(k))
} }