github.com/theQRL/go-zond@v0.2.1/cmd/devp2p/internal/zondtest/chain.go (about)

     1  // Copyright 2020 The go-ethereum Authors
     2  // This file is part of go-ethereum.
     3  //
     4  // go-ethereum is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // go-ethereum is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU General Public License
    15  // along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package zondtest
    18  
    19  // TODO(now.youtrack.cloud/issue/TGZ-6)
    20  /*
    21  import (
    22  	"compress/gzip"
    23  	"encoding/json"
    24  	"errors"
    25  	"fmt"
    26  	"io"
    27  	"os"
    28  	"strings"
    29  
    30  	"github.com/theQRL/go-zond/common"
    31  	"github.com/theQRL/go-zond/core"
    32  	"github.com/theQRL/go-zond/core/forkid"
    33  	"github.com/theQRL/go-zond/core/types"
    34  	"github.com/theQRL/go-zond/params"
    35  	"github.com/theQRL/go-zond/rlp"
    36  	"github.com/theQRL/go-zond/zond/protocols/zond"
    37  )
    38  
    39  type Chain struct {
    40  	genesis     core.Genesis
    41  	blocks      []*types.Block
    42  	chainConfig *params.ChainConfig
    43  }
    44  
    45  // Len returns the length of the chain.
    46  func (c *Chain) Len() int {
    47  	return len(c.blocks)
    48  }
    49  
    50  func (c *Chain) RootAt(height int) common.Hash {
    51  	if height < c.Len() {
    52  		return c.blocks[height].Root()
    53  	}
    54  	return common.Hash{}
    55  }
    56  
    57  // ForkID gets the fork id of the chain.
    58  func (c *Chain) ForkID() forkid.ID {
    59  	return forkid.NewID(c.chainConfig, c.blocks[0], uint64(c.Len()), c.blocks[0].Time())
    60  }
    61  
    62  // Shorten returns a copy chain of a desired height from the imported
    63  func (c *Chain) Shorten(height int) *Chain {
    64  	blocks := make([]*types.Block, height)
    65  	copy(blocks, c.blocks[:height])
    66  
    67  	config := *c.chainConfig
    68  	return &Chain{
    69  		blocks:      blocks,
    70  		chainConfig: &config,
    71  	}
    72  }
    73  
    74  // Head returns the chain head.
    75  func (c *Chain) Head() *types.Block {
    76  	return c.blocks[c.Len()-1]
    77  }
    78  
    79  // GetHeaders returns the headers base on a zondGetPacketHeadersPacket.
    80  func (c *Chain) GetHeaders(req *zond.GetBlockHeadersPacket) ([]*types.Header, error) {
    81  	if req.Amount < 1 {
    82  		return nil, errors.New("no block headers requested")
    83  	}
    84  
    85  	headers := make([]*types.Header, req.Amount)
    86  	var blockNumber uint64
    87  
    88  	// range over blocks to check if our chain has the requested header
    89  	for _, block := range c.blocks {
    90  		if block.Hash() == req.Origin.Hash || block.Number().Uint64() == req.Origin.Number {
    91  			headers[0] = block.Header()
    92  			blockNumber = block.Number().Uint64()
    93  		}
    94  	}
    95  	if headers[0] == nil {
    96  		return nil, fmt.Errorf("no headers found for given origin number %v, hash %v", req.Origin.Number, req.Origin.Hash)
    97  	}
    98  
    99  	if req.Reverse {
   100  		for i := 1; i < int(req.Amount); i++ {
   101  			blockNumber -= (1 - req.Skip)
   102  			headers[i] = c.blocks[blockNumber].Header()
   103  		}
   104  
   105  		return headers, nil
   106  	}
   107  
   108  	for i := 1; i < int(req.Amount); i++ {
   109  		blockNumber += (1 + req.Skip)
   110  		headers[i] = c.blocks[blockNumber].Header()
   111  	}
   112  
   113  	return headers, nil
   114  }
   115  
   116  // loadChain takes the given chain.rlp file, and decodes and returns
   117  // the blocks from the file.
   118  func loadChain(chainfile string, genesis string) (*Chain, error) {
   119  	gen, err := loadGenesis(genesis)
   120  	if err != nil {
   121  		return nil, err
   122  	}
   123  	gblock := gen.ToBlock()
   124  
   125  	blocks, err := blocksFromFile(chainfile, gblock)
   126  	if err != nil {
   127  		return nil, err
   128  	}
   129  
   130  	c := &Chain{genesis: gen, blocks: blocks, chainConfig: gen.Config}
   131  	return c, nil
   132  }
   133  
   134  func loadGenesis(genesisFile string) (core.Genesis, error) {
   135  	chainConfig, err := os.ReadFile(genesisFile)
   136  	if err != nil {
   137  		return core.Genesis{}, err
   138  	}
   139  	var gen core.Genesis
   140  	if err := json.Unmarshal(chainConfig, &gen); err != nil {
   141  		return core.Genesis{}, err
   142  	}
   143  	return gen, nil
   144  }
   145  
   146  func blocksFromFile(chainfile string, gblock *types.Block) ([]*types.Block, error) {
   147  	// Load chain.rlp.
   148  	fh, err := os.Open(chainfile)
   149  	if err != nil {
   150  		return nil, err
   151  	}
   152  	defer fh.Close()
   153  	var reader io.Reader = fh
   154  	if strings.HasSuffix(chainfile, ".gz") {
   155  		if reader, err = gzip.NewReader(reader); err != nil {
   156  			return nil, err
   157  		}
   158  	}
   159  	stream := rlp.NewStream(reader, 0)
   160  	var blocks = make([]*types.Block, 1)
   161  	blocks[0] = gblock
   162  	for i := 0; ; i++ {
   163  		var b types.Block
   164  		if err := stream.Decode(&b); err == io.EOF {
   165  			break
   166  		} else if err != nil {
   167  			return nil, fmt.Errorf("at block index %d: %v", i, err)
   168  		}
   169  		if b.NumberU64() != uint64(i+1) {
   170  			return nil, fmt.Errorf("block at index %d has wrong number %d", i, b.NumberU64())
   171  		}
   172  		blocks = append(blocks, &b)
   173  	}
   174  	return blocks, nil
   175  }
   176  */