mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-27 15:16:43 +00:00
Merge branch 'ethereum:master' into build/go1.24.2
This commit is contained in:
commit
aff3a47092
6 changed files with 142 additions and 39 deletions
|
|
@ -219,3 +219,15 @@ func (r *Reader) FindAll(want uint16) ([]*Entry, error) {
|
||||||
off += int64(headerSize + length)
|
off += int64(headerSize + length)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SkipN skips `n` entries starting from `offset` and returns the new offset.
|
||||||
|
func (r *Reader) SkipN(offset int64, n uint64) (int64, error) {
|
||||||
|
for i := uint64(0); i < n; i++ {
|
||||||
|
length, err := r.LengthAt(offset)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
offset += length
|
||||||
|
}
|
||||||
|
return offset, nil
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ func ReadDir(dir, network string) ([]string, error) {
|
||||||
}
|
}
|
||||||
parts := strings.Split(entry.Name(), "-")
|
parts := strings.Split(entry.Name(), "-")
|
||||||
if len(parts) != 3 || parts[0] != network {
|
if len(parts) != 3 || parts[0] != network {
|
||||||
// invalid era1 filename, skip
|
// Invalid era1 filename, skip.
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if epoch, err := strconv.ParseUint(parts[1], 10, 64); err != nil {
|
if epoch, err := strconv.ParseUint(parts[1], 10, 64); err != nil {
|
||||||
|
|
@ -126,6 +126,29 @@ func (e *Era) Close() error {
|
||||||
return e.f.Close()
|
return e.f.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetHeaderByNumber returns the header for the given block number.
|
||||||
|
func (e *Era) GetHeaderByNumber(num uint64) (*types.Header, error) {
|
||||||
|
if e.m.start > num || e.m.start+e.m.count <= num {
|
||||||
|
return nil, errors.New("out-of-bounds")
|
||||||
|
}
|
||||||
|
off, err := e.readOffset(num)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read and decompress header.
|
||||||
|
r, _, err := newSnappyReader(e.s, TypeCompressedHeader, off)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var header types.Header
|
||||||
|
if err := rlp.Decode(r, &header); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &header, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetBlockByNumber returns the block for the given block number.
|
||||||
func (e *Era) GetBlockByNumber(num uint64) (*types.Block, error) {
|
func (e *Era) GetBlockByNumber(num uint64) (*types.Block, error) {
|
||||||
if e.m.start > num || e.m.start+e.m.count <= num {
|
if e.m.start > num || e.m.start+e.m.count <= num {
|
||||||
return nil, errors.New("out-of-bounds")
|
return nil, errors.New("out-of-bounds")
|
||||||
|
|
@ -154,6 +177,34 @@ func (e *Era) GetBlockByNumber(num uint64) (*types.Block, error) {
|
||||||
return types.NewBlockWithHeader(&header).WithBody(body), nil
|
return types.NewBlockWithHeader(&header).WithBody(body), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetReceiptsByNumber returns the receipts for the given block number.
|
||||||
|
func (e *Era) GetReceiptsByNumber(num uint64) (types.Receipts, error) {
|
||||||
|
if e.m.start > num || e.m.start+e.m.count <= num {
|
||||||
|
return nil, errors.New("out-of-bounds")
|
||||||
|
}
|
||||||
|
off, err := e.readOffset(num)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip over header and body.
|
||||||
|
off, err = e.s.SkipN(off, 2)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read and decompress receipts.
|
||||||
|
r, _, err := newSnappyReader(e.s, TypeCompressedReceipts, off)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var receipts types.Receipts
|
||||||
|
if err := rlp.Decode(r, &receipts); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return receipts, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Accumulator reads the accumulator entry in the Era1 file.
|
// Accumulator reads the accumulator entry in the Era1 file.
|
||||||
func (e *Era) Accumulator() (common.Hash, error) {
|
func (e *Era) Accumulator() (common.Hash, error) {
|
||||||
entry, err := e.s.Find(TypeAccumulator)
|
entry, err := e.s.Find(TypeAccumulator)
|
||||||
|
|
@ -187,13 +238,10 @@ func (e *Era) InitialTD() (*big.Int, error) {
|
||||||
}
|
}
|
||||||
off += n
|
off += n
|
||||||
|
|
||||||
// Skip over next two records.
|
// Skip over header and body.
|
||||||
for i := 0; i < 2; i++ {
|
off, err = e.s.SkipN(off, 2)
|
||||||
length, err := e.s.LengthAt(off)
|
if err != nil {
|
||||||
if err != nil {
|
return nil, err
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
off += length
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read total difficulty after first block.
|
// Read total difficulty after first block.
|
||||||
|
|
|
||||||
|
|
@ -18,12 +18,15 @@ package era
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"math/big"
|
"math/big"
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
)
|
)
|
||||||
|
|
||||||
type testchain struct {
|
type testchain struct {
|
||||||
|
|
@ -48,9 +51,9 @@ func TestEra1Builder(t *testing.T) {
|
||||||
chain = testchain{}
|
chain = testchain{}
|
||||||
)
|
)
|
||||||
for i := 0; i < 128; i++ {
|
for i := 0; i < 128; i++ {
|
||||||
chain.headers = append(chain.headers, []byte{byte('h'), byte(i)})
|
chain.headers = append(chain.headers, mustEncode(&types.Header{Number: big.NewInt(int64(i))}))
|
||||||
chain.bodies = append(chain.bodies, []byte{byte('b'), byte(i)})
|
chain.bodies = append(chain.bodies, mustEncode(&types.Body{Transactions: []*types.Transaction{types.NewTransaction(0, common.Address{byte(i)}, nil, 0, nil, nil)}}))
|
||||||
chain.receipts = append(chain.receipts, []byte{byte('r'), byte(i)})
|
chain.receipts = append(chain.receipts, mustEncode(&types.Receipts{{CumulativeGasUsed: uint64(i)}}))
|
||||||
chain.tds = append(chain.tds, big.NewInt(int64(i)))
|
chain.tds = append(chain.tds, big.NewInt(int64(i)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -91,13 +94,25 @@ func TestEra1Builder(t *testing.T) {
|
||||||
t.Fatalf("unexpected error %v", it.Error())
|
t.Fatalf("unexpected error %v", it.Error())
|
||||||
}
|
}
|
||||||
// Check headers.
|
// Check headers.
|
||||||
header, err := io.ReadAll(it.Header)
|
rawHeader, err := io.ReadAll(it.Header)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("error reading header from iterator: %v", err)
|
||||||
|
}
|
||||||
|
if !bytes.Equal(rawHeader, chain.headers[i]) {
|
||||||
|
t.Fatalf("mismatched header: want %s, got %s", chain.headers[i], rawHeader)
|
||||||
|
}
|
||||||
|
header, err := e.GetHeaderByNumber(i)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("error reading header: %v", err)
|
t.Fatalf("error reading header: %v", err)
|
||||||
}
|
}
|
||||||
if !bytes.Equal(header, chain.headers[i]) {
|
encHeader, err := rlp.EncodeToBytes(header)
|
||||||
t.Fatalf("mismatched header: want %s, got %s", chain.headers[i], header)
|
if err != nil {
|
||||||
|
t.Fatalf("error encoding header: %v", err)
|
||||||
}
|
}
|
||||||
|
if !bytes.Equal(encHeader, chain.headers[i]) {
|
||||||
|
t.Fatalf("mismatched header: want %s, got %s", chain.headers[i], encHeader)
|
||||||
|
}
|
||||||
|
|
||||||
// Check bodies.
|
// Check bodies.
|
||||||
body, err := io.ReadAll(it.Body)
|
body, err := io.ReadAll(it.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -106,13 +121,25 @@ func TestEra1Builder(t *testing.T) {
|
||||||
if !bytes.Equal(body, chain.bodies[i]) {
|
if !bytes.Equal(body, chain.bodies[i]) {
|
||||||
t.Fatalf("mismatched body: want %s, got %s", chain.bodies[i], body)
|
t.Fatalf("mismatched body: want %s, got %s", chain.bodies[i], body)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check receipts.
|
// Check receipts.
|
||||||
receipts, err := io.ReadAll(it.Receipts)
|
rawReceipts, err := io.ReadAll(it.Receipts)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("error reading receipts from iterator: %v", err)
|
||||||
|
}
|
||||||
|
if !bytes.Equal(rawReceipts, chain.receipts[i]) {
|
||||||
|
t.Fatalf("mismatched receipts: want %s, got %s", chain.receipts[i], rawReceipts)
|
||||||
|
}
|
||||||
|
receipts, err := e.GetReceiptsByNumber(i)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("error reading receipts: %v", err)
|
t.Fatalf("error reading receipts: %v", err)
|
||||||
}
|
}
|
||||||
if !bytes.Equal(receipts, chain.receipts[i]) {
|
encReceipts, err := rlp.EncodeToBytes(receipts)
|
||||||
t.Fatalf("mismatched receipts: want %s, got %s", chain.receipts[i], receipts)
|
if err != nil {
|
||||||
|
t.Fatalf("error encoding receipts: %v", err)
|
||||||
|
}
|
||||||
|
if !bytes.Equal(encReceipts, chain.receipts[i]) {
|
||||||
|
t.Fatalf("mismatched receipts: want %s, got %s", chain.receipts[i], encReceipts)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check total difficulty.
|
// Check total difficulty.
|
||||||
|
|
@ -144,3 +171,11 @@ func TestEraFilename(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func mustEncode(obj any) []byte {
|
||||||
|
b, err := rlp.EncodeToBytes(obj)
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Sprintf("failed in encode obj: %v", err))
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,9 @@ func (n *pmp) AddMapping(protocol string, extport, intport int, name string, lif
|
||||||
if lifetime <= 0 {
|
if lifetime <= 0 {
|
||||||
return 0, errors.New("lifetime must not be <= 0")
|
return 0, errors.New("lifetime must not be <= 0")
|
||||||
}
|
}
|
||||||
|
if extport == 0 {
|
||||||
|
extport = intport
|
||||||
|
}
|
||||||
// Note order of port arguments is switched between our
|
// Note order of port arguments is switched between our
|
||||||
// AddMapping and the client's AddPortMapping.
|
// AddMapping and the client's AddPortMapping.
|
||||||
res, err := n.c.AddPortMapping(strings.ToLower(protocol), intport, extport, int(lifetime/time.Second))
|
res, err := n.c.AddPortMapping(strings.ToLower(protocol), intport, extport, int(lifetime/time.Second))
|
||||||
|
|
|
||||||
|
|
@ -86,15 +86,15 @@ func (n *upnp) AddMapping(protocol string, extport, intport int, desc string, li
|
||||||
}
|
}
|
||||||
protocol = strings.ToUpper(protocol)
|
protocol = strings.ToUpper(protocol)
|
||||||
lifetimeS := uint32(lifetime / time.Second)
|
lifetimeS := uint32(lifetime / time.Second)
|
||||||
n.DeleteMapping(protocol, extport, intport)
|
|
||||||
|
|
||||||
err = n.withRateLimit(func() error {
|
if extport == 0 {
|
||||||
return n.client.AddPortMapping("", uint16(extport), protocol, uint16(intport), ip.String(), true, desc, lifetimeS)
|
extport = intport
|
||||||
})
|
} else {
|
||||||
if err == nil {
|
// Only delete port mapping if the external port was already used by geth.
|
||||||
return uint16(extport), nil
|
n.DeleteMapping(protocol, extport, intport)
|
||||||
}
|
}
|
||||||
// Try addAnyPortMapping if mapping specified port didn't work.
|
|
||||||
|
// Try to add port mapping, preferring the specified external port.
|
||||||
err = n.withRateLimit(func() error {
|
err = n.withRateLimit(func() error {
|
||||||
p, err := n.addAnyPortMapping(protocol, extport, intport, ip, desc, lifetimeS)
|
p, err := n.addAnyPortMapping(protocol, extport, intport, ip, desc, lifetimeS)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
|
@ -105,18 +105,28 @@ func (n *upnp) AddMapping(protocol string, extport, intport int, desc string, li
|
||||||
return uint16(extport), err
|
return uint16(extport), err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// addAnyPortMapping tries to add a port mapping with the specified external port.
|
||||||
|
// If the external port is already in use, it will try to assign another port.
|
||||||
func (n *upnp) addAnyPortMapping(protocol string, extport, intport int, ip net.IP, desc string, lifetimeS uint32) (uint16, error) {
|
func (n *upnp) addAnyPortMapping(protocol string, extport, intport int, ip net.IP, desc string, lifetimeS uint32) (uint16, error) {
|
||||||
if client, ok := n.client.(*internetgateway2.WANIPConnection2); ok {
|
if client, ok := n.client.(*internetgateway2.WANIPConnection2); ok {
|
||||||
return client.AddAnyPortMapping("", uint16(extport), protocol, uint16(intport), ip.String(), true, desc, lifetimeS)
|
return client.AddAnyPortMapping("", uint16(extport), protocol, uint16(intport), ip.String(), true, desc, lifetimeS)
|
||||||
}
|
}
|
||||||
// It will retry with a random port number if the client does
|
// For IGDv1 and v1 services we should first try to add with extport.
|
||||||
// not support AddAnyPortMapping.
|
|
||||||
extport = n.randomPort()
|
|
||||||
err := n.client.AddPortMapping("", uint16(extport), protocol, uint16(intport), ip.String(), true, desc, lifetimeS)
|
err := n.client.AddPortMapping("", uint16(extport), protocol, uint16(intport), ip.String(), true, desc, lifetimeS)
|
||||||
if err != nil {
|
if err == nil {
|
||||||
return 0, err
|
return uint16(extport), nil
|
||||||
}
|
}
|
||||||
return uint16(extport), nil
|
|
||||||
|
// If above fails, we retry with a random port.
|
||||||
|
// We retry several times because of possible port conflicts.
|
||||||
|
for i := 0; i < 3; i++ {
|
||||||
|
extport = n.randomPort()
|
||||||
|
err := n.client.AddPortMapping("", uint16(extport), protocol, uint16(intport), ip.String(), true, desc, lifetimeS)
|
||||||
|
if err == nil {
|
||||||
|
return uint16(extport), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *upnp) randomPort() int {
|
func (n *upnp) randomPort() int {
|
||||||
|
|
|
||||||
|
|
@ -150,14 +150,9 @@ func (srv *Server) portMappingLoop() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
external := m.port
|
log := newLogger(m.protocol, m.extPort, m.port)
|
||||||
if m.extPort != 0 {
|
|
||||||
external = m.extPort
|
|
||||||
}
|
|
||||||
log := newLogger(m.protocol, external, m.port)
|
|
||||||
|
|
||||||
log.Trace("Attempting port mapping")
|
log.Trace("Attempting port mapping")
|
||||||
p, err := srv.NAT.AddMapping(m.protocol, external, m.port, m.name, portMapDuration)
|
p, err := srv.NAT.AddMapping(m.protocol, m.extPort, m.port, m.name, portMapDuration)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debug("Couldn't add port mapping", "err", err)
|
log.Debug("Couldn't add port mapping", "err", err)
|
||||||
m.extPort = 0
|
m.extPort = 0
|
||||||
|
|
@ -167,8 +162,8 @@ func (srv *Server) portMappingLoop() {
|
||||||
// It was mapped!
|
// It was mapped!
|
||||||
m.extPort = int(p)
|
m.extPort = int(p)
|
||||||
m.nextTime = srv.clock.Now().Add(portMapRefreshInterval)
|
m.nextTime = srv.clock.Now().Add(portMapRefreshInterval)
|
||||||
if external != m.extPort {
|
log = newLogger(m.protocol, m.extPort, m.port)
|
||||||
log = newLogger(m.protocol, m.extPort, m.port)
|
if m.port != m.extPort {
|
||||||
log.Info("NAT mapped alternative port")
|
log.Info("NAT mapped alternative port")
|
||||||
} else {
|
} else {
|
||||||
log.Info("NAT mapped port")
|
log.Info("NAT mapped port")
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue