create new func penalties for hard fork

This commit is contained in:
parmarrushabh 2019-02-19 17:25:31 +05:30
parent a479343cc7
commit 147e1f0baf
7 changed files with 95 additions and 264 deletions

View file

@ -1,5 +1,7 @@
package common
import "math/big"
const (
RewardMasterPercent = 40
RewardVoterPercent = 50
@ -14,7 +16,15 @@ const (
LimitPenaltyEpoch = 4
BlocksPerYear = uint64(15768000)
LimitThresholdNonceInQueue = 10
MinGasPrice = 2500
DefaultMinGasPrice = 2500
MergeSignRange = 15
RangeReturnSigner = 150
MinimunMinerBlockPerEpoch = 1
)
var TIP2019Block = big.NewInt(1050000)
var TIPSigning = big.NewInt(3000000)
var IsTestnet bool = false
var StoreRewardFolder string
var RollbackHash Hash
var MinGasPrice int64

View file

@ -42,6 +42,7 @@ import (
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/rpc"
"github.com/hashicorp/golang-lru"
)
const (
@ -209,7 +210,7 @@ func ecrecover(header *types.Header, sigcache *lru.ARCCache) (common.Address, er
// Ethereum testnet following the Ropsten attacks.
type XDPoS struct {
config *params.XDPoSConfig // Consensus engine configuration parameters
db ethdb.Database // Database to store and retrieve snapshot checkpoints
db ethdb.Database // Database to store and retrieve snapshot checkpoints
recents *lru.ARCCache // Snapshots for recent block to speed up reorgs
signatures *lru.ARCCache // Signatures of recent blocks to speed up mining
@ -922,7 +923,7 @@ func (c *XDPoS) Seal(chain consensus.ChainReader, block *types.Block, stop <-cha
if limit := uint64(2); number < limit || seen > number-limit {
// Only take into account the non-epoch blocks
if number%c.config.Epoch != 0 {
log.Info("len(masternodes)", len(masternodes), "number", number, "limit", limit, "seen", seen, "recent", recent.String(), "snap.Recents", snap.Recents)
log.Info("Length of MasterNodes", "len(masternodes)", len(masternodes), "number", number, "limit", limit, "seen", seen, "recent", recent.String(), "snap.Recents", snap.Recents)
log.Info("Signed recently, must wait for others")
<-stop
return nil, nil

View file

@ -374,7 +374,7 @@ func CalculateRewardForSigner(chainReward *big.Int, signers map[common.Address]*
}
// Get candidate owner by address.
func GetCandidatesOwnerBySigner(validator *contractValidator.Kyc, signerAddr common.Address) common.Address {
func GetCandidatesOwnerBySigner(validator *contractValidator.XDCValidator, signerAddr common.Address) common.Address {
owner := signerAddr
opts := new(bind.CallOpts)
owner, err := validator.GetCandidateOwner(opts, signerAddr)
@ -387,7 +387,7 @@ func GetCandidatesOwnerBySigner(validator *contractValidator.Kyc, signerAddr com
}
// Calculate reward for holders.
func CalculateRewardForHolders(foudationWalletAddr common.Address, validator *contractValidator.Kyc, state *state.StateDB, signer common.Address, calcReward *big.Int) (error, map[common.Address]*big.Int) {
func CalculateRewardForHolders(foudationWalletAddr common.Address, validator *contractValidator.XDCValidator, state *state.StateDB, signer common.Address, calcReward *big.Int) (error, map[common.Address]*big.Int) {
rewards, err := GetRewardBalancesRate(foudationWalletAddr, signer, calcReward, validator)
if err != nil {
return err, nil
@ -401,7 +401,7 @@ func CalculateRewardForHolders(foudationWalletAddr common.Address, validator *co
}
// Get reward balance rates for master node, founder and holders.
func GetRewardBalancesRate(foudationWalletAddr common.Address, masterAddr common.Address, totalReward *big.Int, validator *contractValidator.Kyc) (map[common.Address]*big.Int, error) {
func GetRewardBalancesRate(foudationWalletAddr common.Address, masterAddr common.Address, totalReward *big.Int, validator *contractValidator.XDCValidator) (map[common.Address]*big.Int, error) {
owner := GetCandidatesOwnerBySigner(validator, masterAddr)
balances := make(map[common.Address]*big.Int)
rewardMaster := new(big.Int).Mul(totalReward, new(big.Int).SetInt64(common.RewardMasterPercent))

View file

@ -46,7 +46,7 @@ import (
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/trie"
lru "github.com/hashicorp/golang-lru"
"github.com/hashicorp/golang-lru"
"gopkg.in/karalabe/cookiejar.v2/collections/prque"
)
@ -1833,7 +1833,7 @@ func (bc *BlockChain) UpdateM1() error {
return err
}
addr := common.HexToAddress(common.MasternodeVotingSMC)
validator, err := contractValidator.NewKyc(addr, client)
validator, err := contractValidator.NewXDCValidator(addr, client)
if err != nil {
return err
}

View file

@ -30,13 +30,12 @@ import (
"time"
"bytes"
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/consensus/XDPoS"
"github.com/ethereum/go-ethereum/consensus/ethash"
"github.com/ethereum/go-ethereum/consensus/XDPoS"
"github.com/ethereum/go-ethereum/contracts"
"github.com/ethereum/go-ethereum/contracts/validator/contract"
"github.com/ethereum/go-ethereum/core"
@ -324,7 +323,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
return err, nil
}
// Get validator.
validator, err := contract.NewKyc(common.HexToAddress(common.MasternodeVotingSMC), client)
validator, err := contract.NewXDCValidator(common.HexToAddress(common.MasternodeVotingSMC), client)
if err != nil {
log.Error("Fail get instance of XDC Validator", "error", err)
return err, nil

View file

@ -44,17 +44,10 @@ import (
"github.com/ethereum/go-ethereum/rpc"
"github.com/syndtr/goleveldb/leveldb"
"github.com/syndtr/goleveldb/leveldb/util"
contractValidator "github.com/ethereum/go-ethereum/contracts/validator/contract"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
)
const (
defaultGasPrice = 50 * params.Shannon
// statuses of candidates
statusMasternode = "MASTERNODE"
statusSlashed = "SLASHED"
statusProposed = "PROPOSED"
defaultGasPrice = 50 * params.Shannon
)
// PublicEthereumAPI provides an API to access Ethereum related information.
@ -501,7 +494,13 @@ func (s *PublicBlockChainAPI) BlockNumber() *big.Int {
// BlockNumber returns the block number of the chain head.
func (s *PublicBlockChainAPI) GetRewardByHash(hash common.Hash) map[string]interface{} {
return s.b.GetRewardByHash(hash)
if c, ok := s.b.GetEngine().(*XDPoS.XDPoS); ok {
rewards := c.GetRewards(hash)
if rewards != nil {
return rewards
}
}
return make(map[string]interface{})
}
// GetBalance returns the amount of wei for the given address in the state of the
@ -615,175 +614,6 @@ func (s *PublicBlockChainAPI) GetStorageAt(ctx context.Context, address common.A
return res[:], state.Error()
}
func (s *PublicBlockChainAPI) GetBlockSignersByHash(ctx context.Context, blockHash common.Hash) ([]common.Address, error) {
block, err := s.b.GetBlock(ctx, blockHash)
if err != nil || block == nil {
return []common.Address{}, err
}
masternodes, err := s.GetMasternodes(ctx, block)
if err != nil || len(masternodes) == 0 {
log.Error("Failed to get masternodes", "err", err, "len(masternodes)", len(masternodes))
return []common.Address{}, err
}
return s.rpcOutputBlockSigners(block, ctx, masternodes)
}
func (s *PublicBlockChainAPI) GetBlockSignersByNumber(ctx context.Context, blockNumber rpc.BlockNumber) ([]common.Address, error) {
block, err := s.b.BlockByNumber(ctx, blockNumber)
if err != nil || block == nil {
return []common.Address{}, err
}
masternodes, err := s.GetMasternodes(ctx, block)
if err != nil || len(masternodes) == 0 {
log.Error("Failed to get masternodes", "err", err, "len(masternodes)", len(masternodes))
return []common.Address{}, err
}
return s.rpcOutputBlockSigners(block, ctx, masternodes)
}
func (s *PublicBlockChainAPI) GetBlockFinalityByHash(ctx context.Context, blockHash common.Hash) (int32, error) {
block, err := s.b.GetBlock(ctx, blockHash)
if err != nil || block == nil {
return int32(0), err
}
masternodes, err := s.GetMasternodes(ctx, block)
if err != nil || len(masternodes) == 0 {
log.Error("Failed to get masternodes", "err", err, "len(masternodes)", len(masternodes))
return int32(0), err
}
blockSigners, err := s.rpcOutputBlockSigners(block, ctx, masternodes)
if err != nil {
return int32(0), err
}
return int32(100 * len(blockSigners) / len(masternodes)), err
}
func (s *PublicBlockChainAPI) GetBlockFinalityByNumber(ctx context.Context, blockNumber rpc.BlockNumber) (int32, error) {
block, err := s.b.BlockByNumber(ctx, blockNumber)
if err != nil || block == nil {
return int32(0), err
}
masternodes, err := s.GetMasternodes(ctx, block)
if err != nil || len(masternodes) == 0 {
log.Error("Failed to get masternodes", "err", err, "len(masternodes)", len(masternodes))
return int32(0), err
}
blockSigners, err := s.rpcOutputBlockSigners(block, ctx, masternodes)
if err != nil {
return int32(0), err
}
return int32(100 * len(blockSigners) / len(masternodes)), err
}
// GetMasternodes returns masternodes set at the starting block of epoch of the given block
func (s *PublicBlockChainAPI) GetMasternodes(ctx context.Context, b *types.Block) ([]common.Address, error) {
var masternodes []common.Address
if b.Number().Int64() >= 0 {
curBlockNumber := b.Number().Uint64()
prevBlockNumber := curBlockNumber + (common.MergeSignRange - (curBlockNumber % common.MergeSignRange))
latestBlockNumber := s.b.CurrentBlock().Number().Uint64()
if prevBlockNumber >= latestBlockNumber || !s.b.ChainConfig().IsTIP2019(b.Number()) {
prevBlockNumber = curBlockNumber
}
if engine, ok := s.b.GetEngine().(*XDPoS.XDPoS); ok {
// Get block epoc latest.
lastCheckpointNumber := prevBlockNumber - (prevBlockNumber % s.b.ChainConfig().XDPoS.Epoch)
prevCheckpointBlock, _ := s.b.BlockByNumber(ctx, rpc.BlockNumber(lastCheckpointNumber))
if prevCheckpointBlock != nil {
masternodes = engine.GetMasternodesFromCheckpointHeader(prevCheckpointBlock.Header(), curBlockNumber, s.b.ChainConfig().XDPoS.Epoch)
}
} else {
log.Error("Undefined XDPoS consensus engine")
}
}
return masternodes, nil
}
// GetCandidateStatus returns status of the given candidate at a specified epochNumber
func (s *PublicBlockChainAPI) GetCandidateStatus(ctx context.Context, coinbaseAddress common.Address, epochNumber rpc.EpochNumber) (string, error) {
var (
block *types.Block
masternodes, penaltyList, candidates, proposedList []common.Address
penalties []byte
err error
)
block = s.b.CurrentBlock()
epoch := s.b.ChainConfig().XDPoS.Epoch
// TODO: we currently support the latest epoch only
//if epochNumber == rpc.LatestEpochNumber {
// block = s.b.CurrentBlock()
//} else {
// checkpointNumber := rpc.BlockNumber((uint64(epochNumber) - 1) * epoch)
// if checkpointNumber < 0 {
// checkpointNumber = 0
// }
// block, err = s.b.BlockByNumber(ctx, checkpointNumber)
// if err != nil || block == nil {
// return "", err
// }
//}
blockNum := block.Number().Uint64()
masternodes, err = s.GetMasternodes(ctx, block)
if err != nil || len(masternodes) == 0 {
log.Error("Failed to get masternodes", "err", err, "len(masternodes)", len(masternodes))
return "", err
}
for _, masternode := range masternodes {
if coinbaseAddress == masternode {
return statusMasternode, nil
}
}
// look up recent checkpoint headers to get penalty list
for i := 0; i <= common.LimitPenaltyEpoch; i++ {
if blockNum > uint64(i) * epoch {
blockCheckpointNumber := rpc.BlockNumber(blockNum - (blockNum % epoch) - (uint64(i) * epoch))
blockCheckpoint, err := s.b.BlockByNumber(ctx, blockCheckpointNumber)
if err != nil {
log.Error("Failed to get block by number", "num", blockCheckpointNumber, "err", err)
continue
}
penalties = append(penalties, blockCheckpoint.Penalties()...)
}
}
if len(penalties) > 0 {
penaltyList = common.ExtractAddressFromBytes(penalties)
for _, pen := range penaltyList {
if coinbaseAddress == pen {
return statusSlashed, nil
}
}
}
// read smart contract to get candidate list
client, err := s.b.GetIPCClient()
if err != nil {
return "", err
}
addr := common.HexToAddress(common.MasternodeVotingSMC)
validator, err := contractValidator.NewXDCValidator(addr, client)
if err != nil {
return "", err
}
opts := new(bind.CallOpts)
candidates, err = validator.GetCandidates(opts)
if err != nil {
return "", err
}
// exclude masternodes
proposedList = common.RemoveItemFromArray(candidates, masternodes)
// exclude penalties
proposedList = common.RemoveItemFromArray(proposedList, penaltyList)
for _, proposed := range proposedList {
if coinbaseAddress == proposed {
return statusProposed, nil
}
}
return "", nil
}
// CallArgs represents the arguments for a call.
type CallArgs struct {
From common.Address `json:"from"`
@ -1030,55 +860,46 @@ func (s *PublicBlockChainAPI) rpcOutputBlock(b *types.Block, inclTx bool, fullTx
uncleHashes[i] = uncle.Hash()
}
fields["uncles"] = uncleHashes
return fields, nil
}
func (s *PublicBlockChainAPI) rpcOutputBlockSigners(b *types.Block, ctx context.Context, masternodes []common.Address) ([]common.Address, error) {
// Get signers for block.
client, err := s.b.GetIPCClient()
if err != nil {
log.Error("Fail to connect IPC client for block status", "error", err)
return []common.Address{}, err
}
var signers []common.Address
var filterSigners []common.Address
finality := int32(0)
if b.Number().Int64() > 0 {
curBlockNumber := b.Number().Uint64()
prevBlockNumber := curBlockNumber + (common.MergeSignRange - (curBlockNumber % common.MergeSignRange))
latestBlockNumber := s.b.CurrentBlock().Number().Uint64()
if prevBlockNumber >= latestBlockNumber || !s.b.ChainConfig().IsTIP2019(b.Number()) {
prevBlockNumber = curBlockNumber
addrBlockSigner := common.HexToAddress(common.BlockSigners)
signers, err = contracts.GetSignersFromContract(addrBlockSigner, client, b.Hash())
if err != nil {
log.Error("Fail to get signers from block signer SC.", "error", err)
}
if engine, ok := s.b.GetEngine().(*XDPoS.XDPoS); ok {
prevBlock, err := s.b.BlockByNumber(ctx, rpc.BlockNumber(prevBlockNumber))
if err != nil {
log.Error("Fail to get previous block", "error", err)
return []common.Address{}, err
}
addrBlockSigner := common.HexToAddress(common.BlockSigners)
signers, err = contracts.GetSignersByExecutingEVM(addrBlockSigner, client, prevBlock.Hash())
if err != nil {
log.Error("Fail to get signers from block signer SC.", "error", err)
return []common.Address{}, err
}
validator, _ := engine.RecoverValidator(b.Header())
creator, _ := engine.RecoverSigner(b.Header())
signers = append(signers, validator)
signers = append(signers, creator)
for _, masternode := range masternodes {
for _, signer := range signers {
if signer == masternode {
filterSigners = append(filterSigners, masternode)
break
// Get block epoc latest.
if s.b.ChainConfig().XDPoS != nil {
engine := s.b.GetEngine()
lastCheckpointNumber := rpc.BlockNumber(b.Number().Uint64() - (b.Number().Uint64() % s.b.ChainConfig().XDPoS.Epoch))
prevCheckpointBlock, _ := s.b.BlockByNumber(ctx, lastCheckpointNumber)
if prevCheckpointBlock != nil {
masternodes := engine.(*XDPoS.XDPoS).GetMasternodesFromCheckpointHeader(prevCheckpointBlock.Header(), b.Number().Uint64(), s.b.ChainConfig().XDPoS.Epoch)
countFinality := 0
for _, masternode := range masternodes {
for _, signer := range signers {
if signer == masternode {
countFinality++
filterSigners = append(filterSigners, masternode)
break
}
}
}
finality = int32(countFinality * 100 / len(masternodes))
}
} else {
log.Error("Undefined XDPoS consensus engine")
}
}
return filterSigners, nil
fields["signers"] = filterSigners
fields["finality"] = finality
return fields, nil
}
// RPCTransaction represents a transaction that will serialize to the RPC representation of a transaction
@ -1711,4 +1532,4 @@ func (s *PublicNetAPI) PeerCount() hexutil.Uint {
// Version returns the current ethereum protocol version.
func (s *PublicNetAPI) Version() string {
return fmt.Sprintf("%d", s.networkVersion)
}
}

View file

@ -27,63 +27,63 @@ import (
var indices = []string{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f", "[17]"}
type Node interface {
type node interface {
fstring(string) string
Cache() (HashNode, bool)
cache() (hashNode, bool)
canUnload(cachegen, cachelimit uint16) bool
}
type (
FullNode struct {
Children [17]Node // Actual trie node data to encode/decode (needs custom encoder)
fullNode struct {
Children [17]node // Actual trie node data to encode/decode (needs custom encoder)
flags nodeFlag
}
ShortNode struct {
shortNode struct {
Key []byte
Val Node
Val node
flags nodeFlag
}
HashNode []byte
ValueNode []byte
hashNode []byte
valueNode []byte
)
// EncodeRLP encodes a full node into the consensus RLP format.
func (n *FullNode) EncodeRLP(w io.Writer) error {
func (n *fullNode) EncodeRLP(w io.Writer) error {
return rlp.Encode(w, n.Children)
}
func (n *FullNode) copy() *FullNode { copy := *n; return &copy }
func (n *ShortNode) copy() *ShortNode { copy := *n; return &copy }
func (n *fullNode) copy() *fullNode { copy := *n; return &copy }
func (n *shortNode) copy() *shortNode { copy := *n; return &copy }
// nodeFlag contains caching-related metadata about a node.
type nodeFlag struct {
hash HashNode // cached hash of the node (may be nil)
hash hashNode // cached hash of the node (may be nil)
gen uint16 // cache generation counter
dirty bool // whether the node has changes that must be written to the database
}
// canUnload tells whether a Node can be unloaded.
// canUnload tells whether a node can be unloaded.
func (n *nodeFlag) canUnload(cachegen, cachelimit uint16) bool {
return !n.dirty && cachegen-n.gen >= cachelimit
}
func (n *FullNode) canUnload(gen, limit uint16) bool { return n.flags.canUnload(gen, limit) }
func (n *ShortNode) canUnload(gen, limit uint16) bool { return n.flags.canUnload(gen, limit) }
func (n HashNode) canUnload(uint16, uint16) bool { return false }
func (n ValueNode) canUnload(uint16, uint16) bool { return false }
func (n *fullNode) canUnload(gen, limit uint16) bool { return n.flags.canUnload(gen, limit) }
func (n *shortNode) canUnload(gen, limit uint16) bool { return n.flags.canUnload(gen, limit) }
func (n hashNode) canUnload(uint16, uint16) bool { return false }
func (n valueNode) canUnload(uint16, uint16) bool { return false }
func (n *FullNode) Cache() (HashNode, bool) { return n.flags.hash, n.flags.dirty }
func (n *ShortNode) Cache() (HashNode, bool) { return n.flags.hash, n.flags.dirty }
func (n HashNode) Cache() (HashNode, bool) { return nil, true }
func (n ValueNode) Cache() (HashNode, bool) { return nil, true }
func (n *fullNode) cache() (hashNode, bool) { return n.flags.hash, n.flags.dirty }
func (n *shortNode) cache() (hashNode, bool) { return n.flags.hash, n.flags.dirty }
func (n hashNode) cache() (hashNode, bool) { return nil, true }
func (n valueNode) cache() (hashNode, bool) { return nil, true }
// Pretty printing.
func (n *FullNode) String() string { return n.fstring("") }
func (n *ShortNode) String() string { return n.fstring("") }
func (n HashNode) String() string { return n.fstring("") }
func (n ValueNode) String() string { return n.fstring("") }
func (n *fullNode) String() string { return n.fstring("") }
func (n *shortNode) String() string { return n.fstring("") }
func (n hashNode) String() string { return n.fstring("") }
func (n valueNode) String() string { return n.fstring("") }
func (n *FullNode) fstring(ind string) string {
func (n *fullNode) fstring(ind string) string {
resp := fmt.Sprintf("[\n%s ", ind)
for i, node := range n.Children {
if node == nil {
@ -94,17 +94,17 @@ func (n *FullNode) fstring(ind string) string {
}
return resp + fmt.Sprintf("\n%s] ", ind)
}
func (n *ShortNode) fstring(ind string) string {
func (n *shortNode) fstring(ind string) string {
return fmt.Sprintf("{%x: %v} ", n.Key, n.Val.fstring(ind+" "))
}
func (n HashNode) fstring(ind string) string {
func (n hashNode) fstring(ind string) string {
return fmt.Sprintf("<%x> ", []byte(n))
}
func (n ValueNode) fstring(ind string) string {
func (n valueNode) fstring(ind string) string {
return fmt.Sprintf("%x ", []byte(n))
}
func MustDecodeNode(hash, buf []byte, cachegen uint16) Node {
func mustDecodeNode(hash, buf []byte, cachegen uint16) node {
n, err := decodeNode(hash, buf, cachegen)
if err != nil {
panic(fmt.Sprintf("node %x: %v", hash, err))
@ -113,7 +113,7 @@ func MustDecodeNode(hash, buf []byte, cachegen uint16) Node {
}
// decodeNode parses the RLP encoding of a trie node.
func decodeNode(hash, buf []byte, cachegen uint16) (Node, error) {
func decodeNode(hash, buf []byte, cachegen uint16) (node, error) {
if len(buf) == 0 {
return nil, io.ErrUnexpectedEOF
}
@ -133,7 +133,7 @@ func decodeNode(hash, buf []byte, cachegen uint16) (Node, error) {
}
}
func decodeShort(hash, buf, elems []byte, cachegen uint16) (Node, error) {
func decodeShort(hash, buf, elems []byte, cachegen uint16) (node, error) {
kbuf, rest, err := rlp.SplitString(elems)
if err != nil {
return nil, err
@ -146,17 +146,17 @@ func decodeShort(hash, buf, elems []byte, cachegen uint16) (Node, error) {
if err != nil {
return nil, fmt.Errorf("invalid value node: %v", err)
}
return &ShortNode{key, append(ValueNode{}, val...), flag}, nil
return &shortNode{key, append(valueNode{}, val...), flag}, nil
}
r, _, err := decodeRef(rest, cachegen)
if err != nil {
return nil, wrapError(err, "val")
}
return &ShortNode{key, r, flag}, nil
return &shortNode{key, r, flag}, nil
}
func decodeFull(hash, buf, elems []byte, cachegen uint16) (*FullNode, error) {
n := &FullNode{flags: nodeFlag{hash: hash, gen: cachegen}}
func decodeFull(hash, buf, elems []byte, cachegen uint16) (*fullNode, error) {
n := &fullNode{flags: nodeFlag{hash: hash, gen: cachegen}}
for i := 0; i < 16; i++ {
cld, rest, err := decodeRef(elems, cachegen)
if err != nil {
@ -169,14 +169,14 @@ func decodeFull(hash, buf, elems []byte, cachegen uint16) (*FullNode, error) {
return n, err
}
if len(val) > 0 {
n.Children[16] = append(ValueNode{}, val...)
n.Children[16] = append(valueNode{}, val...)
}
return n, nil
}
const hashLen = len(common.Hash{})
func decodeRef(buf []byte, cachegen uint16) (Node, []byte, error) {
func decodeRef(buf []byte, cachegen uint16) (node, []byte, error) {
kind, val, rest, err := rlp.Split(buf)
if err != nil {
return nil, buf, err
@ -195,7 +195,7 @@ func decodeRef(buf []byte, cachegen uint16) (Node, []byte, error) {
// empty node
return nil, rest, nil
case kind == rlp.String && len(val) == 32:
return append(HashNode{}, val...), rest, nil
return append(hashNode{}, val...), rest, nil
default:
return nil, nil, fmt.Errorf("invalid RLP string size %d (want 0 or 32)", len(val))
}
@ -221,4 +221,4 @@ func wrapError(err error, ctx string) error {
func (err *decodeError) Error() string {
return fmt.Sprintf("%v (decode path: %s)", err.what, strings.Join(err.stack, "<-"))
}
}