github.com/bigzoro/my_simplechain@v0.0.0-20240315012955-8ad0a2a29bb9/ethclient/ethclient_test.go (about)

     1  // Copyright 2016 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum 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-ethereum 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-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package ethclient
    18  
    19  import (
    20  	"context"
    21  	"crypto/ecdsa"
    22  	"errors"
    23  	"fmt"
    24  	"github.com/bigzoro/my_simplechain/rlp"
    25  	"golang.org/x/crypto/sha3"
    26  	"io/ioutil"
    27  	"math/big"
    28  	"reflect"
    29  	"testing"
    30  	"time"
    31  
    32  	"github.com/bigzoro/my_simplechain"
    33  	"github.com/bigzoro/my_simplechain/common"
    34  	"github.com/bigzoro/my_simplechain/consensus/ethash"
    35  	"github.com/bigzoro/my_simplechain/consensus/scrypt"
    36  	"github.com/bigzoro/my_simplechain/core"
    37  	"github.com/bigzoro/my_simplechain/core/rawdb"
    38  	"github.com/bigzoro/my_simplechain/core/types"
    39  	"github.com/bigzoro/my_simplechain/crypto"
    40  	"github.com/bigzoro/my_simplechain/eth"
    41  	"github.com/bigzoro/my_simplechain/node"
    42  	"github.com/bigzoro/my_simplechain/params"
    43  )
    44  
    45  // Verify that Client implements the ethereum interfaces.
    46  var (
    47  	_ = simplechain.ChainReader(&Client{})
    48  	_ = simplechain.TransactionReader(&Client{})
    49  	_ = simplechain.ChainStateReader(&Client{})
    50  	_ = simplechain.ChainSyncReader(&Client{})
    51  	_ = simplechain.ContractCaller(&Client{})
    52  	_ = simplechain.GasEstimator(&Client{})
    53  	_ = simplechain.GasPricer(&Client{})
    54  	_ = simplechain.LogFilterer(&Client{})
    55  	_ = simplechain.PendingStateReader(&Client{})
    56  	// _ = simplechain.PendingStateEventer(&Client{})
    57  	_ = simplechain.PendingContractCaller(&Client{})
    58  )
    59  
    60  func TestToFilterArg(t *testing.T) {
    61  	blockHashErr := fmt.Errorf("cannot specify both BlockHash and FromBlock/ToBlock")
    62  	addresses := []common.Address{
    63  		common.HexToAddress("0xD36722ADeC3EdCB29c8e7b5a47f352D701393462"),
    64  	}
    65  	blockHash := common.HexToHash(
    66  		"0xeb94bb7d78b73657a9d7a99792413f50c0a45c51fc62bdcb08a53f18e9a2b4eb",
    67  	)
    68  
    69  	for _, testCase := range []struct {
    70  		name   string
    71  		input  simplechain.FilterQuery
    72  		output interface{}
    73  		err    error
    74  	}{
    75  		{
    76  			"without BlockHash",
    77  			simplechain.FilterQuery{
    78  				Addresses: addresses,
    79  				FromBlock: big.NewInt(1),
    80  				ToBlock:   big.NewInt(2),
    81  				Topics:    [][]common.Hash{},
    82  			},
    83  			map[string]interface{}{
    84  				"address":   addresses,
    85  				"fromBlock": "0x1",
    86  				"toBlock":   "0x2",
    87  				"topics":    [][]common.Hash{},
    88  			},
    89  			nil,
    90  		},
    91  		{
    92  			"with nil fromBlock and nil toBlock",
    93  			simplechain.FilterQuery{
    94  				Addresses: addresses,
    95  				Topics:    [][]common.Hash{},
    96  			},
    97  			map[string]interface{}{
    98  				"address":   addresses,
    99  				"fromBlock": "0x0",
   100  				"toBlock":   "latest",
   101  				"topics":    [][]common.Hash{},
   102  			},
   103  			nil,
   104  		},
   105  		{
   106  			"with blockhash",
   107  			simplechain.FilterQuery{
   108  				Addresses: addresses,
   109  				BlockHash: &blockHash,
   110  				Topics:    [][]common.Hash{},
   111  			},
   112  			map[string]interface{}{
   113  				"address":   addresses,
   114  				"blockHash": blockHash,
   115  				"topics":    [][]common.Hash{},
   116  			},
   117  			nil,
   118  		},
   119  		{
   120  			"with blockhash and from block",
   121  			simplechain.FilterQuery{
   122  				Addresses: addresses,
   123  				BlockHash: &blockHash,
   124  				FromBlock: big.NewInt(1),
   125  				Topics:    [][]common.Hash{},
   126  			},
   127  			nil,
   128  			blockHashErr,
   129  		},
   130  		{
   131  			"with blockhash and to block",
   132  			simplechain.FilterQuery{
   133  				Addresses: addresses,
   134  				BlockHash: &blockHash,
   135  				ToBlock:   big.NewInt(1),
   136  				Topics:    [][]common.Hash{},
   137  			},
   138  			nil,
   139  			blockHashErr,
   140  		},
   141  		{
   142  			"with blockhash and both from / to block",
   143  			simplechain.FilterQuery{
   144  				Addresses: addresses,
   145  				BlockHash: &blockHash,
   146  				FromBlock: big.NewInt(1),
   147  				ToBlock:   big.NewInt(2),
   148  				Topics:    [][]common.Hash{},
   149  			},
   150  			nil,
   151  			blockHashErr,
   152  		},
   153  	} {
   154  		t.Run(testCase.name, func(t *testing.T) {
   155  			output, err := toFilterArg(testCase.input)
   156  			if (testCase.err == nil) != (err == nil) {
   157  				t.Fatalf("expected error %v but got %v", testCase.err, err)
   158  			}
   159  			if testCase.err != nil {
   160  				if testCase.err.Error() != err.Error() {
   161  					t.Fatalf("expected error %v but got %v", testCase.err, err)
   162  				}
   163  			} else if !reflect.DeepEqual(testCase.output, output) {
   164  				t.Fatalf("expected filter arg %v but got %v", testCase.output, output)
   165  			}
   166  		})
   167  	}
   168  }
   169  
   170  var (
   171  	testKey, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   172  	testAddr    = crypto.PubkeyToAddress(testKey.PublicKey)
   173  	testBalance = big.NewInt(2e10)
   174  )
   175  
   176  func newTestBackend(t *testing.T) (*node.Node, []*types.Block) {
   177  	// Generate test chain.
   178  	genesis, blocks := generateTestChain()
   179  
   180  	// Start SimpleService service.
   181  	var ethservice *eth.SimpleService
   182  	n, err := node.New(&node.Config{})
   183  	n.Register(func(ctx *node.ServiceContext) (node.Service, error) {
   184  		config := &eth.Config{Genesis: genesis}
   185  		config.Ethash.PowMode = ethash.ModeFake
   186  		ethservice, err = eth.New(ctx, config)
   187  		return ethservice, err
   188  	})
   189  
   190  	// Import the test chain.
   191  	if err := n.Start(); err != nil {
   192  		t.Fatalf("can't start test node: %v", err)
   193  	}
   194  
   195  	if _, err := ethservice.BlockChain().InsertChain(blocks[1:]); err != nil {
   196  		t.Fatalf("can't import test blocks: %v", err)
   197  	}
   198  	return n, blocks
   199  }
   200  
   201  func generateTestChain() (*core.Genesis, []*types.Block) {
   202  	db := rawdb.NewMemoryDatabase()
   203  	config := params.AllScryptProtocolChanges
   204  	genesis := &core.Genesis{
   205  		Config:    config,
   206  		Alloc:     core.GenesisAlloc{testAddr: {Balance: testBalance}},
   207  		ExtraData: []byte("test genesis"),
   208  		Timestamp: 9000,
   209  	}
   210  	generate := func(i int, g *core.BlockGen) {
   211  		g.OffsetTime(5)
   212  		g.SetExtra([]byte("test"))
   213  	}
   214  	gblock := genesis.ToBlock(db)
   215  	engine := scrypt.NewFaker()
   216  	blocks, _ := core.GenerateChain(config, gblock, engine, db, 1, generate)
   217  	blocks = append([]*types.Block{gblock}, blocks...)
   218  	return genesis, blocks
   219  }
   220  
   221  func TestHeader(t *testing.T) {
   222  	backend, chain := newTestBackend(t)
   223  	client, _ := backend.Attach()
   224  	defer backend.Stop()
   225  	defer client.Close()
   226  
   227  	tests := map[string]struct {
   228  		block   *big.Int
   229  		want    *types.Header
   230  		wantErr error
   231  	}{
   232  		"genesis": {
   233  			block: big.NewInt(0),
   234  			want:  chain[0].Header(),
   235  		},
   236  		"first_block": {
   237  			block: big.NewInt(1),
   238  			want:  chain[1].Header(),
   239  		},
   240  		"future_block": {
   241  			block: big.NewInt(1000000000),
   242  			want:  nil,
   243  		},
   244  	}
   245  	for name, tt := range tests {
   246  		t.Run(name, func(t *testing.T) {
   247  			ec := NewClient(client)
   248  			ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
   249  			defer cancel()
   250  
   251  			got, err := ec.HeaderByNumber(ctx, tt.block)
   252  			if tt.wantErr != nil && (err == nil || err.Error() != tt.wantErr.Error()) {
   253  				t.Fatalf("HeaderByNumber(%v) error = %q, want %q", tt.block, err, tt.wantErr)
   254  			}
   255  			if got != nil && got.Number.Sign() == 0 {
   256  				got.Number = big.NewInt(0) // hack to make DeepEqual work
   257  			}
   258  			if !reflect.DeepEqual(got, tt.want) {
   259  				t.Fatalf("HeaderByNumber(%v)\n   = %v\nwant %v", tt.block, got, tt.want)
   260  			}
   261  		})
   262  	}
   263  }
   264  
   265  func TestBalanceAt(t *testing.T) {
   266  	backend, _ := newTestBackend(t)
   267  	client, _ := backend.Attach()
   268  	defer backend.Stop()
   269  	defer client.Close()
   270  
   271  	tests := map[string]struct {
   272  		account common.Address
   273  		block   *big.Int
   274  		want    *big.Int
   275  		wantErr error
   276  	}{
   277  		"valid_account": {
   278  			account: testAddr,
   279  			block:   big.NewInt(1),
   280  			want:    testBalance,
   281  		},
   282  		"non_existent_account": {
   283  			account: common.Address{1},
   284  			block:   big.NewInt(1),
   285  			want:    big.NewInt(0),
   286  		},
   287  		"future_block": {
   288  			account: testAddr,
   289  			block:   big.NewInt(1000000000),
   290  			want:    big.NewInt(0),
   291  			wantErr: errors.New("header not found"),
   292  		},
   293  	}
   294  	for name, tt := range tests {
   295  		t.Run(name, func(t *testing.T) {
   296  			ec := NewClient(client)
   297  			ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
   298  			defer cancel()
   299  
   300  			got, err := ec.BalanceAt(ctx, tt.account, tt.block)
   301  			if tt.wantErr != nil && (err == nil || err.Error() != tt.wantErr.Error()) {
   302  				t.Fatalf("BalanceAt(%x, %v) error = %q, want %q", tt.account, tt.block, err, tt.wantErr)
   303  			}
   304  			if got.Cmp(tt.want) != 0 {
   305  				t.Fatalf("BalanceAt(%x, %v) = %v, want %v", tt.account, tt.block, got, tt.want)
   306  			}
   307  		})
   308  	}
   309  }
   310  
   311  func TestTransactionInBlockInterrupted(t *testing.T) {
   312  	backend, _ := newTestBackend(t)
   313  	client, _ := backend.Attach()
   314  	defer backend.Stop()
   315  	defer client.Close()
   316  
   317  	ec := NewClient(client)
   318  	ctx, cancel := context.WithCancel(context.Background())
   319  	cancel()
   320  	tx, err := ec.TransactionInBlock(ctx, common.Hash{1}, 1)
   321  	if tx != nil {
   322  		t.Fatal("transaction should be nil")
   323  	}
   324  	if err == nil {
   325  		t.Fatal("error should not be nil")
   326  	}
   327  }
   328  
   329  func TestChainID(t *testing.T) {
   330  	backend, _ := newTestBackend(t)
   331  	client, _ := backend.Attach()
   332  	defer backend.Stop()
   333  	defer client.Close()
   334  	ec := NewClient(client)
   335  
   336  	id, err := ec.ChainID(context.Background())
   337  	if err != nil {
   338  		t.Fatalf("unexpected error: %v", err)
   339  	}
   340  	if id == nil || id.Cmp(params.AllScryptProtocolChanges.ChainID) != 0 {
   341  		t.Fatalf("ChainID returned wrong number: %+v", id)
   342  	}
   343  }
   344  func rlpHash(x interface{}) (h common.Hash) {
   345  	hw := sha3.NewLegacyKeccak256()
   346  	rlp.Encode(hw, x)
   347  	hw.Sum(h[:0])
   348  	return h
   349  }
   350  
   351  func ConvertKey(priKeyHash string) (*ecdsa.PrivateKey, common.Address, error) {
   352  	priKey, err := crypto.HexToECDSA(priKeyHash)
   353  	if err != nil {
   354  		return nil, common.Address{}, err
   355  	}
   356  	pubKey := priKey.Public().(*ecdsa.PublicKey)
   357  	addr := crypto.PubkeyToAddress(*pubKey)
   358  	return priKey, addr, nil
   359  }
   360  func TestClient_SendCertificateRevocationList(t *testing.T) {
   361  	filename := "/Users/daminyang/cademo/node/node-0/tls/crls/crl.pem"
   362  	data, err := ioutil.ReadFile(filename)
   363  	if err != nil {
   364  		t.Error(err)
   365  		return
   366  	}
   367  	url := "http://127.0.0.1:7545"
   368  	rpcClient, err := Dial(url, "", "", nil)
   369  	if err != nil {
   370  		t.Error(err)
   371  		return
   372  	}
   373  	prv, addr, err := ConvertKey("d7c7b25c9ff7f1e10167c41b4a521e63922425df6243a0712ce74e7994b91427")
   374  	if err != nil {
   375  		fmt.Println(err)
   376  		return
   377  	}
   378  	fmt.Println("addr", addr.String())
   379  	hash := rlpHash(data)
   380  
   381  	signature, err := crypto.Sign(hash[:], prv)
   382  	if err != nil {
   383  		fmt.Println(err)
   384  		return
   385  	}
   386  
   387  	err = rpcClient.SendCertificateRevocationList(context.Background(), data, signature)
   388  	if err != nil {
   389  		t.Error(err)
   390  		return
   391  	}
   392  
   393  }