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 }