core/forkid, eth: make forkid a struct, next uint64, enr struct, RLP

This commit is contained in:
Péter Szilágyi 2019-07-03 16:04:51 +03:00
parent 8ad6303a0f
commit 0578240c60
No known key found for this signature in database
GPG key ID: E9AE538CEDF8293D
3 changed files with 85 additions and 83 deletions

View file

@ -20,7 +20,6 @@ package forkid
import ( import (
"encoding/binary" "encoding/binary"
"errors" "errors"
"fmt"
"hash/crc32" "hash/crc32"
"math" "math"
"math/big" "math/big"
@ -45,10 +44,11 @@ var (
ErrLocalIncompatibleOrStale = errors.New("local incompatible or needs update") ErrLocalIncompatibleOrStale = errors.New("local incompatible or needs update")
) )
// ID is a 2x4-byte tuple containing: // ID is a fork identifier as defined by EIP-2124.
// - forkhash: CRC32 checksum of the genesis block and passed fork block numbers type ID struct {
// - forknext: CRC32 checksum of the next fork block number (or 0, if no known) Hash uint32 // CRC32 checksum of the genesis block and passed fork block numbers
type ID [8]byte Next uint64 // Block number of the next upcoming fork, or 0 if no forks are known
}
// NewID calculates the Ethereum fork ID from the chain config and head. // NewID calculates the Ethereum fork ID from the chain config and head.
func NewID(chain *core.BlockChain) ID { func NewID(chain *core.BlockChain) ID {
@ -64,24 +64,20 @@ func NewID(chain *core.BlockChain) ID {
// having to simulate an entire blockchain. // having to simulate an entire blockchain.
func newID(config *params.ChainConfig, genesis common.Hash, head uint64) ID { func newID(config *params.ChainConfig, genesis common.Hash, head uint64) ID {
// Calculate the starting checksum from the genesis hash // Calculate the starting checksum from the genesis hash
forkHash := crc32.ChecksumIEEE(genesis[:]) hash := crc32.ChecksumIEEE(genesis[:])
// Calculate the current fork checksum and the next fork block // Calculate the current fork checksum and the next fork block
var forkNext uint32 var next uint64
for _, fork := range gatherForks(config) { for _, fork := range gatherForks(config) {
if fork <= head { if fork <= head {
// Fork already passed, checksum the previous hash and the fork number // Fork already passed, checksum the previous hash and the fork number
forkHash = checksumUpdate(forkHash, fork) hash = checksumUpdate(hash, fork)
continue continue
} }
forkNext = checksum(fork) next = fork
break break
} }
// Aggregate everything into a single binary blob return ID{Hash: hash, Next: next}
var entry ID
binary.BigEndian.PutUint32(entry[0:], forkHash)
binary.BigEndian.PutUint32(entry[4:], forkNext)
return entry
} }
// NewFilter creates an filter that returns if a fork ID should be rejected or not // NewFilter creates an filter that returns if a fork ID should be rejected or not
@ -104,17 +100,14 @@ func newFilter(config *params.ChainConfig, genesis common.Hash, headfn func() ui
var ( var (
forks = gatherForks(config) forks = gatherForks(config)
sums = make([]uint32, len(forks)+1) // 0th is the genesis sums = make([]uint32, len(forks)+1) // 0th is the genesis
next = make([]uint32, len(forks))
) )
sums[0] = crc32.ChecksumIEEE(genesis[:]) sums[0] = crc32.ChecksumIEEE(genesis[:])
for i, fork := range forks { for i, fork := range forks {
sums[i+1] = checksumUpdate(sums[i], fork) sums[i+1] = checksumUpdate(sums[i], fork)
next[i] = checksum(fork)
} }
// Add two sentries to simplify the fork checks and don't require special // Add two sentries to simplify the fork checks and don't require special
// casing the last one. // casing the last one.
forks = append(forks, math.MaxUint64) // Last fork will never be passed forks = append(forks, math.MaxUint64) // Last fork will never be passed
next = append(next, 0) // Last fork is all 0
// Create a validator that will filter out incompatible chains // Create a validator that will filter out incompatible chains
return func(id ID) error { return func(id ID) error {
@ -134,11 +127,7 @@ func newFilter(config *params.ChainConfig, genesis common.Hash, headfn func() ui
// the remote, but at this current point in time we don't have enough // the remote, but at this current point in time we don't have enough
// information. // information.
// 4. Reject in all other cases. // 4. Reject in all other cases.
var ( head := headfn()
head = headfn()
remoteSum = binary.BigEndian.Uint32(id[0:4])
remoteNext = binary.BigEndian.Uint32(id[4:8])
)
for i, fork := range forks { for i, fork := range forks {
// If our head is beyond this fork, continue to the next (we have a dummy // If our head is beyond this fork, continue to the next (we have a dummy
// fork of maxuint64 as the last item to always fail this check eventually). // fork of maxuint64 as the last item to always fail this check eventually).
@ -147,16 +136,16 @@ func newFilter(config *params.ChainConfig, genesis common.Hash, headfn func() ui
} }
// Found the first unpassed fork block, check if our current state matches // Found the first unpassed fork block, check if our current state matches
// the remote checksum (rule #1). // the remote checksum (rule #1).
if sums[i] == remoteSum { if sums[i] == id.Hash {
// Yay, fork checksum matched, ignore any upcoming fork // Yay, fork checksum matched, ignore any upcoming fork
return nil return nil
} }
// The local and remote nodes are in different forks currently, check if the // The local and remote nodes are in different forks currently, check if the
// remote checksum is a subset of our local forks (rule #2). // remote checksum is a subset of our local forks (rule #2).
for j := 0; j < i; j++ { for j := 0; j < i; j++ {
if sums[j] == remoteSum { if sums[j] == id.Hash {
// Remote checksum is a subset, validate based on the announced next fork // Remote checksum is a subset, validate based on the announced next fork
if next[j] != remoteNext { if forks[j] != id.Next {
return ErrRemoteStale return ErrRemoteStale
} }
return nil return nil
@ -165,7 +154,7 @@ func newFilter(config *params.ChainConfig, genesis common.Hash, headfn func() ui
// Remote chain is not a subset of our local one, check if it's a superset by // Remote chain is not a subset of our local one, check if it's a superset by
// any chance, signalling that we're simply out of sync (rule #3). // any chance, signalling that we're simply out of sync (rule #3).
for j := i + 1; j < len(sums); j++ { for j := i + 1; j < len(sums); j++ {
if sums[j] == remoteSum { if sums[j] == id.Hash {
// Yay, remote checksum is a superset, ignore upcoming forks // Yay, remote checksum is a superset, ignore upcoming forks
return nil return nil
} }
@ -173,7 +162,7 @@ func newFilter(config *params.ChainConfig, genesis common.Hash, headfn func() ui
// No exact, subset or superset match. We are on differing chains, reject. // No exact, subset or superset match. We are on differing chains, reject.
return ErrLocalIncompatibleOrStale return ErrLocalIncompatibleOrStale
} }
log.Error("Impossible fork ID validation", "id", fmt.Sprintf("%x", id)) log.Error("Impossible fork ID validation", "id", id)
return nil // Something's very wrong, accept rather than reject return nil // Something's very wrong, accept rather than reject
} }
} }

View file

@ -17,6 +17,7 @@
package forkid package forkid
import ( import (
"math"
"testing" "testing"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
@ -40,20 +41,20 @@ func TestCreation(t *testing.T) {
params.MainnetChainConfig, params.MainnetChainConfig,
params.MainnetGenesisHash, params.MainnetGenesisHash,
[]testcase{ []testcase{
{0, ID{0xfc, 0x64, 0xec, 0x04, 0xc9, 0x29, 0xf1, 0xc5}}, // Unsynced {0, ID{Hash: 0xfc64ec04, Next: 1150000}}, // Unsynced
{1149999, ID{0xfc, 0x64, 0xec, 0x04, 0xc9, 0x29, 0xf1, 0xc5}}, // Last Frontier block {1149999, ID{Hash: 0xfc64ec04, Next: 1150000}}, // Last Frontier block
{1150000, ID{0x97, 0xc2, 0xc3, 0x4c, 0x2d, 0x10, 0xef, 0x43}}, // First Homestead block {1150000, ID{Hash: 0x97c2c34c, Next: 1920000}}, // First Homestead block
{1919999, ID{0x97, 0xc2, 0xc3, 0x4c, 0x2d, 0x10, 0xef, 0x43}}, // Last Homestead block {1919999, ID{Hash: 0x97c2c34c, Next: 1920000}}, // Last Homestead block
{1920000, ID{0x91, 0xd1, 0xf9, 0x48, 0x44, 0xfe, 0xbd, 0x6b}}, // First DAO block {1920000, ID{Hash: 0x91d1f948, Next: 2463000}}, // First DAO block
{2462999, ID{0x91, 0xd1, 0xf9, 0x48, 0x44, 0xfe, 0xbd, 0x6b}}, // Last DAO block {2462999, ID{Hash: 0x91d1f948, Next: 2463000}}, // Last DAO block
{2463000, ID{0x7a, 0x64, 0xda, 0x13, 0xe3, 0x5d, 0x84, 0xf1}}, // First Tangerine block {2463000, ID{Hash: 0x7a64da13, Next: 2675000}}, // First Tangerine block
{2674999, ID{0x7a, 0x64, 0xda, 0x13, 0xe3, 0x5d, 0x84, 0xf1}}, // Last Tangerine block {2674999, ID{Hash: 0x7a64da13, Next: 2675000}}, // Last Tangerine block
{2675000, ID{0x3e, 0xdd, 0x5b, 0x10, 0x4d, 0xd3, 0x46, 0x54}}, // First Spurious block {2675000, ID{Hash: 0x3edd5b10, Next: 4370000}}, // First Spurious block
{4369999, ID{0x3e, 0xdd, 0x5b, 0x10, 0x4d, 0xd3, 0x46, 0x54}}, // Last Spurious block {4369999, ID{Hash: 0x3edd5b10, Next: 4370000}}, // Last Spurious block
{4370000, ID{0xa0, 0x0b, 0xc3, 0x24, 0xfc, 0xa4, 0x36, 0x40}}, // First Byzantium block {4370000, ID{Hash: 0xa00bc324, Next: 7280000}}, // First Byzantium block
{7279999, ID{0xa0, 0x0b, 0xc3, 0x24, 0xfc, 0xa4, 0x36, 0x40}}, // Last Byzantium block {7279999, ID{Hash: 0xa00bc324, Next: 7280000}}, // Last Byzantium block
{7280000, ID{0x66, 0x8d, 0xb0, 0xaf, 0x00, 0x00, 0x00, 0x00}}, // First and last Constantinople, first Petersburg block {7280000, ID{Hash: 0x668db0af, Next: 0}}, // First and last Constantinople, first Petersburg block
{7987396, ID{0x66, 0x8d, 0xb0, 0xaf, 0x00, 0x00, 0x00, 0x00}}, // Today Petersburg block {7987396, ID{Hash: 0x668db0af, Next: 0}}, // Today Petersburg block
}, },
}, },
// Ropsten test cases // Ropsten test cases
@ -61,16 +62,16 @@ func TestCreation(t *testing.T) {
params.TestnetChainConfig, params.TestnetChainConfig,
params.TestnetGenesisHash, params.TestnetGenesisHash,
[]testcase{ []testcase{
{0, ID{0x30, 0xc7, 0xdd, 0xbc, 0x85, 0xf7, 0x36, 0x77}}, // Unsynced, last Frontier, Homestead and first Tangerine block {0, ID{Hash: 0x30c7ddbc, Next: 10}}, // Unsynced, last Frontier, Homestead and first Tangerine block
{9, ID{0x30, 0xc7, 0xdd, 0xbc, 0x85, 0xf7, 0x36, 0x77}}, // Last Tangerine block {9, ID{Hash: 0x30c7ddbc, Next: 10}}, // Last Tangerine block
{10, ID{0x63, 0x76, 0x01, 0x90, 0xb4, 0xbf, 0x05, 0xc3}}, // First Spurious block {10, ID{Hash: 0x63760190, Next: 1700000}}, // First Spurious block
{1699999, ID{0x63, 0x76, 0x01, 0x90, 0xb4, 0xbf, 0x05, 0xc3}}, // Last Spurious block {1699999, ID{Hash: 0x63760190, Next: 1700000}}, // Last Spurious block
{1700000, ID{0x3e, 0xa1, 0x59, 0xc7, 0x9d, 0xca, 0x62, 0x15}}, // First Byzantium block {1700000, ID{Hash: 0x3ea159c7, Next: 4230000}}, // First Byzantium block
{4229999, ID{0x3e, 0xa1, 0x59, 0xc7, 0x9d, 0xca, 0x62, 0x15}}, // Last Byzantium block {4229999, ID{Hash: 0x3ea159c7, Next: 4230000}}, // Last Byzantium block
{4230000, ID{0x97, 0xb5, 0x44, 0xf3, 0x3e, 0x63, 0x2f, 0x9e}}, // First Constantinople block {4230000, ID{Hash: 0x97b544f3, Next: 4939394}}, // First Constantinople block
{4939393, ID{0x97, 0xb5, 0x44, 0xf3, 0x3e, 0x63, 0x2f, 0x9e}}, // Last Constantinople block {4939393, ID{Hash: 0x97b544f3, Next: 4939394}}, // Last Constantinople block
{4939394, ID{0xd6, 0xe2, 0x14, 0x9b, 0x00, 0x00, 0x00, 0x00}}, // First Petersburg block {4939394, ID{Hash: 0xd6e2149b, Next: 0}}, // First Petersburg block
{5822692, ID{0xd6, 0xe2, 0x14, 0x9b, 0x00, 0x00, 0x00, 0x00}}, // Today Petersburg block {5822692, ID{Hash: 0xd6e2149b, Next: 0}}, // Today Petersburg block
}, },
}, },
// Rinkeby test cases // Rinkeby test cases
@ -78,17 +79,17 @@ func TestCreation(t *testing.T) {
params.RinkebyChainConfig, params.RinkebyChainConfig,
params.RinkebyGenesisHash, params.RinkebyGenesisHash,
[]testcase{ []testcase{
{0, ID{0x3b, 0x8e, 0x06, 0x91, 0x12, 0x25, 0xef, 0xff}}, // Unsynced, last Frontier block {0, ID{Hash: 0x3b8e0691, Next: 1}}, // Unsynced, last Frontier block
{1, ID{0x60, 0x94, 0x92, 0x95, 0x8b, 0x2c, 0xbe, 0x45}}, // First and last Homestead block {1, ID{Hash: 0x60949295, Next: 2}}, // First and last Homestead block
{2, ID{0x8b, 0xde, 0x40, 0xdd, 0xfc, 0x2b, 0x8e, 0xd3}}, // First and last Tangerine block {2, ID{Hash: 0x8bde40dd, Next: 3}}, // First and last Tangerine block
{3, ID{0xcb, 0x3a, 0x64, 0xbb, 0x42, 0x35, 0xd4, 0x51}}, // First Spurious block {3, ID{Hash: 0xcb3a64bb, Next: 1035301}}, // First Spurious block
{1035300, ID{0xcb, 0x3a, 0x64, 0xbb, 0x42, 0x35, 0xd4, 0x51}}, // Last Spurious block {1035300, ID{Hash: 0xcb3a64bb, Next: 1035301}}, // Last Spurious block
{1035301, ID{0x8d, 0x74, 0x8b, 0x57, 0xe8, 0xab, 0xd4, 0x37}}, // First Byzantium block {1035301, ID{Hash: 0x8d748b57, Next: 3660663}}, // First Byzantium block
{3660662, ID{0x8d, 0x74, 0x8b, 0x57, 0xe8, 0xab, 0xd4, 0x37}}, // Last Byzantium block {3660662, ID{Hash: 0x8d748b57, Next: 3660663}}, // Last Byzantium block
{3660663, ID{0xe4, 0x9c, 0xab, 0x14, 0xa5, 0x41, 0x64, 0x45}}, // First Constantinople block {3660663, ID{Hash: 0xe49cab14, Next: 4321234}}, // First Constantinople block
{4321233, ID{0xe4, 0x9c, 0xab, 0x14, 0xa5, 0x41, 0x64, 0x45}}, // Last Constantinople block {4321233, ID{Hash: 0xe49cab14, Next: 4321234}}, // Last Constantinople block
{4321234, ID{0xaf, 0xec, 0x6b, 0x27, 0x00, 0x00, 0x00, 0x00}}, // First Petersburg block {4321234, ID{Hash: 0xafec6b27, Next: 0}}, // First Petersburg block
{4586649, ID{0xaf, 0xec, 0x6b, 0x27, 0x00, 0x00, 0x00, 0x00}}, // Today Petersburg block {4586649, ID{Hash: 0xafec6b27, Next: 0}}, // Today Petersburg block
}, },
}, },
// Goerli test cases // Goerli test cases
@ -96,8 +97,8 @@ func TestCreation(t *testing.T) {
params.GoerliChainConfig, params.GoerliChainConfig,
params.GoerliGenesisHash, params.GoerliGenesisHash,
[]testcase{ []testcase{
{0, ID{0xa3, 0xf5, 0xab, 0x08, 0x00, 0x00, 0x00, 0x00}}, // Unsynced, last Frontier, Homestead, Tangerine, Spurious, Byzantium, Constantinople and first Petersburg block {0, ID{Hash: 0xa3f5ab08, Next: 0}}, // Unsynced, last Frontier, Homestead, Tangerine, Spurious, Byzantium, Constantinople and first Petersburg block
{795329, ID{0xa3, 0xf5, 0xab, 0x08, 0x00, 0x00, 0x00, 0x00}}, // Today Petersburg block {795329, ID{Hash: 0xa3f5ab08, Next: 0}}, // Today Petersburg block
}, },
}, },
} }
@ -119,56 +120,56 @@ func TestValidation(t *testing.T) {
err error err error
}{ }{
// Local is mainnet Petersburg, remote announces the same. No future fork is announced. // Local is mainnet Petersburg, remote announces the same. No future fork is announced.
{7987396, ID{0x66, 0x8d, 0xb0, 0xaf, 0x00, 0x00, 0x00, 0x00}, nil}, {7987396, ID{Hash: 0x668db0af, Next: 0}, nil},
// Local is mainnet Petersburg, remote announces the same. Remote also announces a next fork // Local is mainnet Petersburg, remote announces the same. Remote also announces a next fork
// at block 0xffffffff, but that is uncertain. // at block 0xffffffff, but that is uncertain.
{7987396, ID{0x66, 0x8d, 0xb0, 0xaf, 0xbb, 0x99, 0xff, 0x8a}, nil}, {7987396, ID{Hash: 0x668db0af, Next: math.MaxUint64}, nil},
// Local is mainnet currently in Byzantium only (so it's aware of Petersburg), remote announces // Local is mainnet currently in Byzantium only (so it's aware of Petersburg), remote announces
// also Byzantium, but it's not yet aware of Petersburg (e.g. non updated node before the fork). // also Byzantium, but it's not yet aware of Petersburg (e.g. non updated node before the fork).
// In this case we don't know if Petersburg passed yet or not. // In this case we don't know if Petersburg passed yet or not.
{7279999, ID{0xa0, 0x0b, 0xc3, 0x24, 0x00, 0x00, 0x00, 0x00}, nil}, {7279999, ID{Hash: 0xa00bc324, Next: 0}, nil},
// Local is mainnet currently in Byzantium only (so it's aware of Petersburg), remote announces // Local is mainnet currently in Byzantium only (so it's aware of Petersburg), remote announces
// also Byzantium, and it's also aware of Petersburg (e.g. updated node before the fork). We // also Byzantium, and it's also aware of Petersburg (e.g. updated node before the fork). We
// don't know if Petersburg passed yet (will pass) or not. // don't know if Petersburg passed yet (will pass) or not.
{7279999, ID{0xa0, 0x0b, 0xc3, 0x24, 0xfc, 0xa4, 0x36, 0x40}, nil}, {7279999, ID{Hash: 0xa00bc324, Next: 7280000}, nil},
// Local is mainnet currently in Byzantium only (so it's aware of Petersburg), remote announces // Local is mainnet currently in Byzantium only (so it's aware of Petersburg), remote announces
// also Byzantium, and it's also aware of some random fork (e.g. misconfigured Petersburg). As // also Byzantium, and it's also aware of some random fork (e.g. misconfigured Petersburg). As
// neither forks passed at neither nodes, they may mismatch, but we still connect for now. // neither forks passed at neither nodes, they may mismatch, but we still connect for now.
{7279999, ID{0xa0, 0x0b, 0xc3, 0x24, 0xbb, 0x99, 0xff, 0x8a}, nil}, {7279999, ID{Hash: 0xa00bc324, Next: math.MaxUint64}, nil},
// Local is mainnet Petersburg, remote announces Byzantium + knowledge about Petersburg. Remote // Local is mainnet Petersburg, remote announces Byzantium + knowledge about Petersburg. Remote
// is simply out of sync, accept. // is simply out of sync, accept.
{7987396, ID{0x66, 0x8d, 0xb0, 0xaf, 0xfc, 0xa4, 0x36, 0x40}, nil}, {7987396, ID{Hash: 0x668db0af, Next: 7280000}, nil},
// Local is mainnet Petersburg, remote announces Spurious + knowledge about Byzantium. Remote // Local is mainnet Petersburg, remote announces Spurious + knowledge about Byzantium. Remote
// is definitely out of sync. It may or may not need the Petersburg update, we don't know yet. // is definitely out of sync. It may or may not need the Petersburg update, we don't know yet.
{7987396, ID{0x3e, 0xdd, 0x5b, 0x10, 0x4d, 0xd3, 0x46, 0x54}, nil}, {7987396, ID{Hash: 0x3edd5b10, Next: 4370000}, nil},
// Local is mainnet Byzantium, remote announces Petersburg. Local is out of sync, accept. // Local is mainnet Byzantium, remote announces Petersburg. Local is out of sync, accept.
{7279999, ID{0x66, 0x8d, 0xb0, 0xaf, 0x00, 0x00, 0x00, 0x00}, nil}, {7279999, ID{Hash: 0x668db0af, Next: 0}, nil},
// Local is mainnet Spurious, remote announces Byzantium, but is not aware of Petersburg. Local // Local is mainnet Spurious, remote announces Byzantium, but is not aware of Petersburg. Local
// out of sync. Local also knows about a future fork, but that is uncertain yet. // out of sync. Local also knows about a future fork, but that is uncertain yet.
{4369999, ID{0xa0, 0x0b, 0xc3, 0x24, 0x00, 0x00, 0x00, 0x00}, nil}, {4369999, ID{Hash: 0xa00bc324, Next: 0}, nil},
// Local is mainnet Petersburg. remote announces Byzantium but is not aware of further forks. // Local is mainnet Petersburg. remote announces Byzantium but is not aware of further forks.
// Remote needs software update. // Remote needs software update.
{7987396, ID{0xa0, 0x0b, 0xc3, 0x24, 0x00, 0x00, 0x00, 0x00}, ErrRemoteStale}, {7987396, ID{Hash: 0xa00bc324, Next: 0}, ErrRemoteStale},
// Local is mainnet Petersburg, and isn't aware of more forks. Remote announces Petersburg + // Local is mainnet Petersburg, and isn't aware of more forks. Remote announces Petersburg +
// 0xffffffff. Local needs software update, reject. // 0xffffffff. Local needs software update, reject.
{7987396, ID{0x5c, 0xdd, 0xc0, 0xe1, 0x00, 0x00, 0x00, 0x00}, ErrLocalIncompatibleOrStale}, {7987396, ID{Hash: 0x5cddc0e1, Next: 0}, ErrLocalIncompatibleOrStale},
// Local is mainnet Byzantium, and is aware of Petersburg. Remote announces Petersburg + // Local is mainnet Byzantium, and is aware of Petersburg. Remote announces Petersburg +
// 0xffffffff. Local needs software update, reject. // 0xffffffff. Local needs software update, reject.
{7279999, ID{0x5c, 0xdd, 0xc0, 0xe1, 0x00, 0x00, 0x00, 0x00}, ErrLocalIncompatibleOrStale}, {7279999, ID{Hash: 0x5cddc0e1, Next: 0}, ErrLocalIncompatibleOrStale},
// Local is mainnet Petersburg, remote is Rinkeby Petersburg. // Local is mainnet Petersburg, remote is Rinkeby Petersburg.
{7987396, ID{0xaf, 0xec, 0x6b, 0x27, 0x00, 0x00, 0x00, 0x00}, ErrLocalIncompatibleOrStale}, {7987396, ID{Hash: 0xafec6b27, Next: 0}, ErrLocalIncompatibleOrStale},
} }
for i, tt := range tests { for i, tt := range tests {
filter := newFilter(params.MainnetChainConfig, params.MainnetGenesisHash, func() uint64 { return tt.head }) filter := newFilter(params.MainnetChainConfig, params.MainnetGenesisHash, func() uint64 { return tt.head })

View file

@ -20,15 +20,27 @@ import (
"github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/forkid" "github.com/ethereum/go-ethereum/core/forkid"
"github.com/ethereum/go-ethereum/p2p/enr" "github.com/ethereum/go-ethereum/p2p/enr"
"github.com/ethereum/go-ethereum/rlp"
) )
// ENR is the "eth" Ethereum Node Record, holding the fork id as specified by // ENR is the "eth" Ethereum Node Record, advertising various information useful
// EIP-2124 (https://eips.ethereum.org/EIPS/eip-2124). // for maintaining the Ethereum computer network.
type ENR forkid.ID //
// Whilst only one thing is contained here for now, the ENR is a struct to permit
// future extensibility.
type ENR struct {
ForkID forkid.ID // Fork identifier per EIP-2124
// NewENR calculates the Ethereum network ENR from the fork ID. // Ignore additional fields (for forward compatibility).
Rest []rlp.RawValue `rlp:"tail"`
}
// NewENR calculates the Ethereum network ENR from various information available
// from the chain.
func NewENR(chain *core.BlockChain) ENR { func NewENR(chain *core.BlockChain) ENR {
return ENR(forkid.NewID(chain)) return ENR{
ForkID: forkid.NewID(chain),
}
} }
// ENRKey implements enr.Entry, returning the key for the chain config. // ENRKey implements enr.Entry, returning the key for the chain config.
@ -46,6 +58,6 @@ func NewENRFilter(chain *core.BlockChain) func(r *enr.Record) error {
return nil return nil
} }
// If found, run it across the fork ID validator // If found, run it across the fork ID validator
return filter(forkid.ID(entry)) return filter(entry.ForkID)
} }
} }