github.com/core-coin/go-core/v2@v2.1.9/xcb/energyprice/energyprice_test.go (about)

     1  // Copyright 2023 by the Authors
     2  // This file is part of the go-core library.
     3  //
     4  // The go-core library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser 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  // The go-core library 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 Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-core library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package energyprice
    18  
    19  import (
    20  	"context"
    21  	"math"
    22  	"math/big"
    23  	"testing"
    24  
    25  	"github.com/core-coin/go-core/v2/consensus/cryptore"
    26  
    27  	"github.com/core-coin/go-core/v2/common"
    28  	"github.com/core-coin/go-core/v2/core"
    29  	"github.com/core-coin/go-core/v2/core/rawdb"
    30  	"github.com/core-coin/go-core/v2/core/types"
    31  	"github.com/core-coin/go-core/v2/core/vm"
    32  	"github.com/core-coin/go-core/v2/crypto"
    33  	"github.com/core-coin/go-core/v2/params"
    34  	"github.com/core-coin/go-core/v2/rpc"
    35  )
    36  
    37  type testBackend struct {
    38  	chain *core.BlockChain
    39  }
    40  
    41  func (b *testBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) {
    42  	if number == rpc.LatestBlockNumber {
    43  		return b.chain.CurrentBlock().Header(), nil
    44  	}
    45  	return b.chain.GetHeaderByNumber(uint64(number)), nil
    46  }
    47  
    48  func (b *testBackend) BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error) {
    49  	if number == rpc.LatestBlockNumber {
    50  		return b.chain.CurrentBlock(), nil
    51  	}
    52  	return b.chain.GetBlockByNumber(uint64(number)), nil
    53  }
    54  
    55  func (b *testBackend) ChainConfig() *params.ChainConfig {
    56  	return b.chain.Config()
    57  }
    58  
    59  func newTestBackend(t *testing.T) *testBackend {
    60  	var (
    61  		key, _ = crypto.UnmarshalPrivateKeyHex("89bdfaa2b6f9c30b94ee98fec96c58ff8507fabf49d36a6267e6cb5516eaa2a9e854eccc041f9f67e109d0eb4f653586855355c5b2b87bb313")
    62  		gspec  = &core.Genesis{
    63  			Config: params.MainnetChainConfig,
    64  			Alloc:  core.GenesisAlloc{key.Address(): {Balance: big.NewInt(math.MaxInt64)}},
    65  		}
    66  		signer = types.NewNucleusSigner(gspec.Config.NetworkID)
    67  	)
    68  	engine := cryptore.NewFaker()
    69  	db := rawdb.NewMemoryDatabase()
    70  	genesis, _ := gspec.Commit(db)
    71  
    72  	address, err := common.HexToAddress("cb4900000133700000deadbeef000000000000000000")
    73  	if err != nil {
    74  		t.Error(err)
    75  	}
    76  	// Generate testing blocks
    77  	blocks, _ := core.GenerateChain(params.MainnetChainConfig, genesis, engine, db, 32, func(i int, b *core.BlockGen) {
    78  		b.SetCoinbase(common.Address{1})
    79  		tx, err := types.SignTx(types.NewTransaction(b.TxNonce(key.Address()), address, big.NewInt(100), 21000, big.NewInt(int64(i+1)*params.Nucle), nil), signer, key)
    80  		if err != nil {
    81  			t.Fatalf("failed to create tx: %v", err)
    82  		}
    83  		b.AddTx(tx)
    84  	})
    85  	// Construct testing chain
    86  	diskdb := rawdb.NewMemoryDatabase()
    87  	gspec.Commit(diskdb)
    88  	chain, err := core.NewBlockChain(diskdb, nil, params.MainnetChainConfig, engine, vm.Config{}, nil, nil)
    89  	if err != nil {
    90  		t.Fatalf("Failed to create local chain, %v", err)
    91  	}
    92  	chain.InsertChain(blocks)
    93  	return &testBackend{chain: chain}
    94  }
    95  
    96  func (b *testBackend) CurrentHeader() *types.Header {
    97  	return b.chain.CurrentHeader()
    98  }
    99  
   100  func (b *testBackend) GetBlockByNumber(number uint64) *types.Block {
   101  	return b.chain.GetBlockByNumber(number)
   102  }
   103  
   104  func TestSuggestPrice(t *testing.T) {
   105  	config := Config{
   106  		Blocks:     3,
   107  		Percentile: 60,
   108  		Default:    big.NewInt(params.Nucle),
   109  	}
   110  	backend := newTestBackend(t)
   111  	oracle := NewOracle(backend, config)
   112  
   113  	// The energy price sampled is: 32G, 31G, 30G, 29G, 28G, 27G
   114  	got, err := oracle.SuggestPrice(context.Background())
   115  	if err != nil {
   116  		t.Fatalf("Failed to retrieve recommended energy price: %v", err)
   117  	}
   118  	expect := big.NewInt(params.Nucle * int64(30))
   119  	if got.Cmp(expect) != 0 {
   120  		t.Fatalf("Energy price mismatch, want %d, got %d", expect, got)
   121  	}
   122  }