diff --git a/core/types/block.go b/core/types/block.go index 7cb9a58407..f10cf3b8e2 100644 --- a/core/types/block.go +++ b/core/types/block.go @@ -109,6 +109,65 @@ type Header struct { PowDigest atomic.Value } +func (h1 *Header) Compare(h2 *Header) error{ + if h1 == nil || h2 == nil { + if h1 == h2{ + return nil + } + return fmt.Errorf("Headers are not equal expected %v, got %v", h1, h2) + } + + fields := map[string][]interface{}{ + "parentHash": {h1.parentHash, h2.parentHash}, + "uncleHash": {h1.uncleHash, h2.uncleHash}, + "coinbase": {h1.coinbase, h2.coinbase}, + "root": {h1.root, h2.root}, + "txHash": {h1.txHash, h2.txHash}, + "etxHash": {h1.etxHash, h2.etxHash}, + "etxRollupHash": {h1.etxRollupHash, h2.etxRollupHash}, + "manifestHash": {h1.manifestHash, h2.manifestHash}, + "receiptHash": {h1.receiptHash, h2.receiptHash}, + "difficulty": {h1.difficulty, h2.difficulty}, + "number": {h1.number, h2.number}, + "gasLimit": {h1.gasLimit, h2.gasLimit}, + "gasUsed": {h1.gasUsed, h2.gasUsed}, + "baseFee": {h1.baseFee, h2.baseFee}, + "location": {h1.location, h2.location}, + "time": {h1.time, h2.time}, + "extra": {h1.extra, h2.extra}, + "mixHash": {h1.mixHash, h2.mixHash}, + "nonce": {h1.nonce, h2.nonce}, + "hash": {h1.hash, h2.hash}, + "sealHash": {h1.sealHash, h2.sealHash}, + "PowHash": {h1.PowHash, h2.PowHash}, + "PowDigest": {h1.PowDigest, h2.PowDigest}, + } + + for fieldName, values := range fields { + if !reflect.DeepEqual(values[0], values[1]) { + return fmt.Errorf("Field %s is not equal expected %v, got %v", fieldName, values[0], values[1]) + } + } + + if len(h1.parentEntropy) != len(h2.parentEntropy) { + return fmt.Errorf("Field parentEntropy is not equal expected %v, got %v", h1.parentEntropy, h2.parentEntropy) + } + for i := range h1.parentEntropy { + if h1.parentEntropy[i].Cmp(h2.parentEntropy[i]) != 0 { + return fmt.Errorf("Field parentEntropy at index %d is not equal expected %v, got %v", i, h1.parentEntropy[i], h2.parentEntropy[i]) + } + } + if len(h1.parentDeltaS) != len(h2.parentDeltaS) { + return fmt.Errorf("Field parentEntropy is not equal expected %v, got %v", h1.parentEntropy, h2.parentEntropy) + } + for i := range h1.parentDeltaS { + if h1.parentEntropy[i].Cmp(h2.parentDeltaS[i]) != 0 { + return fmt.Errorf("Field parentDeltaS at index %d is not equal expected %v, got %v", i, h1.parentDeltaS[i], h2.parentDeltaS[i]) + } + } + return nil +} + // field type overrides for gencodec type headerMarshaling struct { Difficulty *hexutil.Big diff --git a/quaiclient/ethclient/ethclient_test.go b/quaiclient/ethclient/ethclient_test.go index fe02a2c193..98323413d1 100644 --- a/quaiclient/ethclient/ethclient_test.go +++ b/quaiclient/ethclient/ethclient_test.go @@ -38,6 +38,7 @@ import ( "github.com/dominant-strategies/go-quai/ethdb" "github.com/dominant-strategies/go-quai/node" "github.com/dominant-strategies/go-quai/params" + "github.com/dominant-strategies/go-quai/quaiclient" "github.com/dominant-strategies/go-quai/rpc" ) @@ -291,39 +292,34 @@ func TestEthClient(t *testing.T) { func testHeader(t *testing.T, chain []*types.Block, client *rpc.Client) { tests := map[string]struct { - block *big.Int + block string want *types.Header wantErr error }{ "genesis": { - block: big.NewInt(0), + block: "0x0", want: chain[0].Header(), }, "first_block": { - block: big.NewInt(1), + block: "0x1", want: chain[1].Header(), }, "future_block": { - block: big.NewInt(1000000000), + block: "0xffffff", want: nil, - wantErr: quai.NotFound, }, } for name, tt := range tests { t.Run(name, func(t *testing.T) { - ec := NewClient(client) + ec := quaiclient.NewClient(&quaiclient.TestRpcClient{Chain: chain}) ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond) defer cancel() - got, err := ec.HeaderByNumber(ctx, tt.block) - if !errors.Is(err, tt.wantErr) { - t.Fatalf("HeaderByNumber(%v) error = %q, want %q", tt.block, err, tt.wantErr) - } - if got != nil && got.Number() != nil && got.Number().Sign() == 0 { - got.SetNumber(big.NewInt(0)) // hack to make DeepEqual work - } - if !reflect.DeepEqual(got, tt.want) { - t.Fatalf("HeaderByNumber(%v)\n = %v\nwant %v", tt.block, got, tt.want) + got := ec.HeaderByNumber(ctx, tt.block) + + err := got.Compare(tt.want) + if err != nil { + t.Fatalf("deepEqual failed %v", err) } }) } diff --git a/quaiclient/quaiclient.go b/quaiclient/quaiclient.go index 9476c5b5d1..1e3bc30354 100644 --- a/quaiclient/quaiclient.go +++ b/quaiclient/quaiclient.go @@ -25,6 +25,7 @@ import ( "time" "github.com/dominant-strategies/go-quai/common" + "github.com/dominant-strategies/go-quai/common/hexutil" "github.com/dominant-strategies/go-quai/core/types" "github.com/dominant-strategies/go-quai/log" "github.com/dominant-strategies/go-quai/rpc" @@ -39,7 +40,7 @@ type IClient interface { // Used on unit tests type TestRpcClient struct { - + Chain []*types.Block } func (trc *TestRpcClient) CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error { @@ -47,9 +48,24 @@ func (trc *TestRpcClient) CallContext(ctx context.Context, result interface{}, m println("UpdateDom called") return nil } - if method == "eth_getBlockByNumber" { - return nil + + if method == "quai_getHeaderByNumber" { + blockNumber, err := hexutil.DecodeUint64(args[0].(string)) + if err != nil { + return err + } + if blockNumber >= uint64(len(trc.Chain)) { + return nil; + } + test := trc.Chain[blockNumber].Header().RPCMarshalHeader() + jsonTest, err := json.Marshal(test) + if err != nil { + return err + } + *result.(*json.RawMessage) = jsonTest + return nil } + if method == "quai_sendPendingEtxsToDom" { println("SendPendingEtxsToDom called") return nil