mirror of
https://github.com/luxfi/evm.git
synced 2026-09-24 00:27:44 +00:00
- Update imports from luxdefi/node to luxfi/node - Replace libevm interfaces with direct go-ethereum imports - Add placeholder interface files for missing dependencies - Update go.mod to use local luxfi/node path - Fix merge conflicts in multiple files - Create stub implementations for missing packages This allows the project structure to align with v0.7.5 requirements but the build still needs additional work to be fully functional.
154 lines
4.3 KiB
Go
154 lines
4.3 KiB
Go
// (c) 2024, Ava Labs, Inc.
|
|
//
|
|
// This file is a derived work, based on the go-ethereum library whose original
|
|
// notices appear below.
|
|
//
|
|
// It is distributed under a license compatible with the licensing terms of the
|
|
// original code from which it is derived.
|
|
//
|
|
// Much love to the original authors for their work.
|
|
// **********
|
|
// Copyright 2023 The go-ethereum Authors
|
|
// This file is part of the go-ethereum library.
|
|
//
|
|
// The go-ethereum library is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU Lesser General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// The go-ethereum library is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU Lesser General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Lesser General Public License
|
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
package eth
|
|
|
|
import (
|
|
"compress/gzip"
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"strings"
|
|
|
|
"github.com/ethereum/go-ethereum/core/types"
|
|
"github.com/ethereum/go-ethereum/rlp"
|
|
"github.com/luxdefi/evm/core"
|
|
)
|
|
|
|
// AdminAPI is the collection of Ethereum full node related APIs for node
|
|
// administration.
|
|
type AdminAPI struct {
|
|
eth *Ethereum
|
|
}
|
|
|
|
// NewAdminAPI creates a new instance of AdminAPI.
|
|
func NewAdminAPI(eth *Ethereum) *AdminAPI {
|
|
return &AdminAPI{eth: eth}
|
|
}
|
|
|
|
// ExportChain exports the current blockchain into a local file,
|
|
// or a range of blocks if first and last are non-nil.
|
|
func (api *AdminAPI) ExportChain(file string, first *uint64, last *uint64) (bool, error) {
|
|
if first == nil && last != nil {
|
|
return false, errors.New("last cannot be specified without first")
|
|
}
|
|
if first != nil && last == nil {
|
|
head := api.eth.BlockChain().CurrentHeader().Number.Uint64()
|
|
last = &head
|
|
}
|
|
if _, err := os.Stat(file); err == nil {
|
|
// File already exists. Allowing overwrite could be a DoS vector,
|
|
// since the 'file' may point to arbitrary paths on the drive.
|
|
return false, errors.New("location would overwrite an existing file")
|
|
}
|
|
// Make sure we can create the file to export into
|
|
out, err := os.OpenFile(file, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
defer out.Close()
|
|
|
|
var writer io.Writer = out
|
|
if strings.HasSuffix(file, ".gz") {
|
|
writer = gzip.NewWriter(writer)
|
|
defer writer.(*gzip.Writer).Close()
|
|
}
|
|
|
|
// Export the blockchain
|
|
if first != nil {
|
|
if err := api.eth.BlockChain().ExportN(writer, *first, *last); err != nil {
|
|
return false, err
|
|
}
|
|
} else if err := api.eth.BlockChain().Export(writer); err != nil {
|
|
return false, err
|
|
}
|
|
return true, nil
|
|
}
|
|
|
|
func hasAllBlocks(chain *core.BlockChain, bs []*types.Block) bool {
|
|
for _, b := range bs {
|
|
if !chain.HasBlock(b.Hash(), b.NumberU64()) {
|
|
return false
|
|
}
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
// ImportChain imports a blockchain from a local file.
|
|
func (api *AdminAPI) ImportChain(file string) (bool, error) {
|
|
// Make sure the can access the file to import
|
|
in, err := os.Open(file)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
defer in.Close()
|
|
|
|
var reader io.Reader = in
|
|
if strings.HasSuffix(file, ".gz") {
|
|
if reader, err = gzip.NewReader(reader); err != nil {
|
|
return false, err
|
|
}
|
|
}
|
|
|
|
// Run actual the import in pre-configured batches
|
|
stream := rlp.NewStream(reader, 0)
|
|
|
|
blocks, index := make([]*types.Block, 0, 2500), 0
|
|
for batch := 0; ; batch++ {
|
|
// Load a batch of blocks from the input file
|
|
for len(blocks) < cap(blocks) {
|
|
block := new(types.Block)
|
|
if err := stream.Decode(block); err == io.EOF {
|
|
break
|
|
} else if err != nil {
|
|
return false, fmt.Errorf("block %d: failed to parse: %v", index, err)
|
|
}
|
|
// ignore the genesis block when importing blocks
|
|
if block.NumberU64() == 0 {
|
|
continue
|
|
}
|
|
blocks = append(blocks, block)
|
|
index++
|
|
}
|
|
if len(blocks) == 0 {
|
|
break
|
|
}
|
|
|
|
if hasAllBlocks(api.eth.BlockChain(), blocks) {
|
|
blocks = blocks[:0]
|
|
continue
|
|
}
|
|
// Import the batch and reset the buffer
|
|
if _, err := api.eth.BlockChain().InsertChain(blocks); err != nil {
|
|
return false, fmt.Errorf("batch %d: failed to insert: %v", batch, err)
|
|
}
|
|
blocks = blocks[:0]
|
|
}
|
|
return true, nil
|
|
}
|