github.com/klaytn/klaytn@v1.12.1/node/sc/kas/anchor_test.go (about)

     1  // Copyright 2020 The klaytn Authors
     2  // This file is part of the klaytn library.
     3  //
     4  // The klaytn 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 klaytn 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 klaytn library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package kas
    18  
    19  import (
    20  	"bytes"
    21  	"encoding/json"
    22  	"errors"
    23  	"io"
    24  	"math/big"
    25  	"math/rand"
    26  	"net/http"
    27  	"strconv"
    28  	"testing"
    29  
    30  	"github.com/golang/mock/gomock"
    31  	"github.com/klaytn/klaytn/blockchain/types"
    32  	"github.com/klaytn/klaytn/common"
    33  	"github.com/klaytn/klaytn/crypto"
    34  	"github.com/klaytn/klaytn/node/sc/kas/mocks"
    35  	"github.com/stretchr/testify/assert"
    36  )
    37  
    38  var errTest = errors.New("test error")
    39  
    40  func testAnchorData() *types.AnchoringDataInternalType0 {
    41  	return &types.AnchoringDataInternalType0{
    42  		BlockHash:     common.HexToHash("0"),
    43  		TxHash:        common.HexToHash("1"),
    44  		ParentHash:    common.HexToHash("2"),
    45  		ReceiptHash:   common.HexToHash("3"),
    46  		StateRootHash: common.HexToHash("4"),
    47  		BlockNumber:   big.NewInt(5),
    48  		BlockCount:    big.NewInt(6),
    49  		TxCount:       big.NewInt(7),
    50  	}
    51  }
    52  
    53  func _TestExampleSendRequest(t *testing.T) {
    54  	url := "http://anchor-api.dev.klaytn.com/v1/anchor"
    55  	xChainId := "1001"
    56  	user := ""
    57  	pwd := ""
    58  
    59  	operator := common.HexToAddress("0xFC6A9Fe8a71F7bB576070a7fe408AFdE8E3d4819")
    60  
    61  	// Anchor Data
    62  	anchorData := testAnchorData()
    63  
    64  	kasConfig := &KASConfig{
    65  		Url:          url,
    66  		XChainId:     xChainId,
    67  		User:         user,
    68  		Pwd:          pwd,
    69  		Operator:     operator,
    70  		Anchor:       true,
    71  		AnchorPeriod: 1,
    72  	}
    73  
    74  	kasAnchor := NewKASAnchor(kasConfig, nil, nil)
    75  
    76  	payload := dataToPayload(anchorData)
    77  	res, err := kasAnchor.sendRequest(payload)
    78  	assert.NoError(t, err)
    79  
    80  	result, err := json.Marshal(res)
    81  	assert.NoError(t, err)
    82  
    83  	t.Log(string(result))
    84  }
    85  
    86  func TestSendRequest(t *testing.T) {
    87  	config := KASConfig{}
    88  	anchor := NewKASAnchor(&config, nil, nil)
    89  	ctrl := gomock.NewController(t)
    90  	defer ctrl.Finish()
    91  	m := mocks.NewMockHTTPClient(ctrl)
    92  	anchor.client = m
    93  
    94  	anchorData := testAnchorData()
    95  	pl := dataToPayload(anchorData)
    96  
    97  	// OK case
    98  	{
    99  		expectedRes := http.Response{Status: strconv.Itoa(http.StatusOK)}
   100  		expectedRespBody := respBody{
   101  			Code: 0,
   102  		}
   103  		bodyBytes, _ := json.Marshal(expectedRespBody)
   104  		expectedRes.Body = io.NopCloser(bytes.NewReader(bodyBytes))
   105  		expectedRes.StatusCode = http.StatusOK
   106  
   107  		m.EXPECT().Do(gomock.Any()).Times(1).Return(&expectedRes, nil)
   108  		resp, err := anchor.sendRequest(pl)
   109  
   110  		assert.NoError(t, err)
   111  		assert.Equal(t, expectedRespBody.Code, resp.Code)
   112  	}
   113  
   114  	// Error case
   115  	{
   116  		m.EXPECT().Do(gomock.Any()).Times(1).Return(nil, errTest)
   117  		resp, err := anchor.sendRequest(pl)
   118  
   119  		assert.Error(t, errTest, err)
   120  		assert.Nil(t, resp)
   121  	}
   122  }
   123  
   124  func TestDataToPayload(t *testing.T) {
   125  	anchorData := testAnchorData()
   126  	pl := dataToPayload(anchorData)
   127  	assert.Equal(t, anchorData.BlockNumber.String(), pl.Id)
   128  	assert.Equal(t, *anchorData, pl.AnchoringDataInternalType0)
   129  }
   130  
   131  func TestBlockToAnchoringDataInternalType0(t *testing.T) {
   132  	testBlockToAnchoringDataInternalType0(t, 1)
   133  	testBlockToAnchoringDataInternalType0(t, 7)
   134  	testBlockToAnchoringDataInternalType0(t, 100)
   135  }
   136  
   137  func testBlockToAnchoringDataInternalType0(t *testing.T, period uint64) {
   138  	random := rand.New(rand.NewSource(0))
   139  
   140  	config := KASConfig{
   141  		Anchor:       true,
   142  		AnchorPeriod: period,
   143  	}
   144  
   145  	ctrl := gomock.NewController(t)
   146  	defer ctrl.Finish()
   147  	bc := mocks.NewMockBlockChain(ctrl)
   148  
   149  	anchor := NewKASAnchor(&config, nil, bc)
   150  	testBlkN := uint64(100)
   151  	pastCnt := [100]uint64{}
   152  	txCnt := uint64(0)
   153  
   154  	for blkNum := uint64(0); blkNum < testBlkN; blkNum++ {
   155  		// Gen random block
   156  		header := &types.Header{Number: big.NewInt(int64(blkNum))}
   157  		block := types.NewBlockWithHeader(header)
   158  		txNum := random.Uint64() % 10
   159  		txs, _ := genTransactions(txNum)
   160  		body := &types.Body{Transactions: txs}
   161  		block = block.WithBody(body.Transactions)
   162  
   163  		// update blockchain mock
   164  		bc.EXPECT().GetBlockByNumber(blkNum).Return(block).AnyTimes()
   165  
   166  		// call target func
   167  		result := anchor.blockToAnchoringDataInternalType0(block)
   168  
   169  		// calc expected value
   170  		txCnt -= pastCnt[blkNum%anchor.kasConfig.AnchorPeriod]
   171  		pastCnt[blkNum%anchor.kasConfig.AnchorPeriod] = txNum
   172  		txCnt += txNum
   173  
   174  		// compare result
   175  		assert.Equal(t, txCnt, result.TxCount.Uint64(), "blkNum:%v", blkNum)
   176  	}
   177  }
   178  
   179  func genTransactions(n uint64) (types.Transactions, error) {
   180  	key, _ := crypto.GenerateKey()
   181  	addr := crypto.PubkeyToAddress(key.PublicKey)
   182  	signer := types.LatestSignerForChainID(big.NewInt(18))
   183  
   184  	txs := types.Transactions{}
   185  
   186  	for i := uint64(0); i < n; i++ {
   187  		tx, _ := types.SignTx(
   188  			types.NewTransaction(0, addr,
   189  				big.NewInt(int64(n)), 0, big.NewInt(int64(n)), nil), signer, key)
   190  
   191  		txs = append(txs, tx)
   192  	}
   193  
   194  	return txs, nil
   195  }