github.com/iotexproject/iotex-core@v1.14.1-rc1/blockchain/block/systemlog_test.go (about) 1 // Copyright (c) 2020 IoTeX Foundation 2 // This source code is provided 'as is' and no warranties are given as to title or non-infringement, merchantability 3 // or fitness for purpose and, to the extent permitted by law, all liability for your use of the code is disclaimed. 4 // This source code is governed by Apache License 2.0 that can be found in the LICENSE file. 5 6 package block 7 8 import ( 9 "math/big" 10 "testing" 11 12 "github.com/stretchr/testify/require" 13 14 "github.com/iotexproject/go-pkgs/hash" 15 "github.com/iotexproject/iotex-address/address" 16 "github.com/iotexproject/iotex-proto/golang/iotextypes" 17 18 "github.com/iotexproject/iotex-core/action" 19 "github.com/iotexproject/iotex-core/test/identityset" 20 ) 21 22 var ( 23 _amount = big.NewInt(100) 24 25 _evmLog = &action.TransactionLog{ 26 Sender: identityset.Address(0).String(), 27 Recipient: identityset.Address(1).String(), 28 Amount: _amount, 29 Type: iotextypes.TransactionLogType_IN_CONTRACT_TRANSFER, 30 } 31 _createLog = &action.TransactionLog{ 32 Sender: identityset.Address(0).String(), 33 Recipient: address.StakingBucketPoolAddr, 34 Amount: _amount, 35 Type: iotextypes.TransactionLogType_CREATE_BUCKET, 36 } 37 _depositLog = &action.TransactionLog{ 38 Sender: identityset.Address(0).String(), 39 Recipient: address.StakingBucketPoolAddr, 40 Amount: _amount, 41 Type: iotextypes.TransactionLogType_DEPOSIT_TO_BUCKET, 42 } 43 withdrawLog = &action.TransactionLog{ 44 Sender: address.StakingBucketPoolAddr, 45 Recipient: identityset.Address(0).String(), 46 Amount: _amount, 47 Type: iotextypes.TransactionLogType_WITHDRAW_BUCKET, 48 } 49 selfstakeLog = &action.TransactionLog{ 50 Sender: identityset.Address(0).String(), 51 Recipient: address.StakingBucketPoolAddr, 52 Amount: _amount, 53 Type: iotextypes.TransactionLogType_CANDIDATE_SELF_STAKE, 54 } 55 registerLog = &action.TransactionLog{ 56 Sender: identityset.Address(0).String(), 57 Recipient: address.RewardingPoolAddr, 58 Amount: _amount, 59 Type: iotextypes.TransactionLogType_CANDIDATE_REGISTRATION_FEE, 60 } 61 normalLog = &action.Log{ 62 Address: "io1qnpz47hx5q6r3w876axtrn6yz95d70cjl35r53", 63 Topics: []hash.Hash256{ 64 hash.BytesToHash256(identityset.PrivateKey(0).PublicKey().Hash()), 65 hash.BytesToHash256(identityset.PrivateKey(1).PublicKey().Hash()), 66 }, 67 Data: _amount.Bytes(), 68 } 69 receiptTest = []struct { 70 r *action.Receipt 71 num uint64 72 }{ 73 { 74 // failed receipt 75 &action.Receipt{Status: uint64(iotextypes.ReceiptStatus_Failure)}, 76 0, 77 }, 78 { 79 // success but not transaction log 80 (&action.Receipt{Status: uint64(iotextypes.ReceiptStatus_Success)}).AddLogs(normalLog), 81 0, 82 }, 83 { 84 // contain evm transfer 85 (&action.Receipt{Status: uint64(iotextypes.ReceiptStatus_Success)}).AddTransactionLogs(_evmLog), 86 1, 87 }, 88 { 89 // contain create bucket 90 (&action.Receipt{Status: uint64(iotextypes.ReceiptStatus_Success)}).AddTransactionLogs(_createLog), 91 1, 92 }, 93 { 94 // contain deposit bucket 95 (&action.Receipt{Status: uint64(iotextypes.ReceiptStatus_Success)}).AddTransactionLogs(_depositLog), 96 1, 97 }, 98 { 99 // contain withdraw bucket 100 (&action.Receipt{Status: uint64(iotextypes.ReceiptStatus_Success)}).AddTransactionLogs(withdrawLog), 101 1, 102 }, 103 { 104 // contain candidate self-stake 105 (&action.Receipt{Status: uint64(iotextypes.ReceiptStatus_Success)}).AddTransactionLogs(selfstakeLog), 106 1, 107 }, 108 { 109 // contain candidate register 110 (&action.Receipt{Status: uint64(iotextypes.ReceiptStatus_Success)}).AddTransactionLogs(registerLog), 111 1, 112 }, 113 { 114 // contain all 115 (&action.Receipt{Status: uint64(iotextypes.ReceiptStatus_Success)}).AddTransactionLogs(_evmLog, _createLog, _depositLog, withdrawLog, selfstakeLog, registerLog), 116 6, 117 }, 118 } 119 ) 120 121 func TestReceiptSystemLog(t *testing.T) { 122 r := require.New(t) 123 124 for _, v := range receiptTest { 125 sysLog := ReceiptTransactionLog(v.r) 126 if v.num > 0 { 127 r.Equal(v.r.ActionHash, sysLog.actHash) 128 r.EqualValues(v.num, len(sysLog.txRecords)) 129 logs := v.r.TransactionLogs() 130 for i, rec := range sysLog.txRecords { 131 r.Equal(LogTokenTxRecord(logs[i]), rec) 132 } 133 } else { 134 r.Nil(sysLog) 135 } 136 } 137 138 // can serialize an empty log 139 log := &BlkTransactionLog{} 140 r.Equal([]byte{}, log.Serialize()) 141 } 142 143 func TestSystemLogFromReceipt(t *testing.T) { 144 r := require.New(t) 145 146 blk := Block{} 147 blkLog := blk.TransactionLog() 148 r.Nil(blkLog) 149 blk.Receipts = []*action.Receipt{} 150 blkLog = blk.TransactionLog() 151 r.Nil(blkLog) 152 // normal log is not transaction log 153 blk.Receipts = append(blk.Receipts, (&action.Receipt{Status: uint64(iotextypes.ReceiptStatus_Success)}).AddLogs(normalLog)) 154 blkLog = blk.TransactionLog() 155 r.Nil(blkLog) 156 157 blk.Receipts = blk.Receipts[:0] 158 implicitTransferNum := 0 159 for i := range receiptTest { 160 if receiptTest[i].num > 0 { 161 blk.Receipts = append(blk.Receipts, receiptTest[i].r) 162 implicitTransferNum++ 163 } 164 } 165 blkLog = blk.TransactionLog() 166 r.Equal(implicitTransferNum, len(blkLog.actionLogs)) 167 168 // test serialize/deserialize 169 b := blkLog.Serialize() 170 r.NotNil(b) 171 pb, err := DeserializeSystemLogPb(b) 172 r.NoError(err) 173 174 // verify block systemlog pb message 175 r.EqualValues(implicitTransferNum, len(pb.Logs)) 176 for i, sysLog := range pb.Logs { 177 receipt := blk.Receipts[i] 178 logs := receipt.TransactionLogs() 179 r.Equal(receipt.ActionHash, hash.BytesToHash256(sysLog.ActionHash)) 180 r.EqualValues(len(logs), sysLog.NumTransactions) 181 r.Equal(len(logs), len(sysLog.Transactions)) 182 for i, tx := range sysLog.Transactions { 183 // verify token tx record 184 rec := &TokenTxRecord{ 185 amount: tx.Amount, 186 sender: tx.Sender, 187 recipient: tx.Recipient, 188 typ: tx.Type, 189 } 190 r.Equal(LogTokenTxRecord(logs[i]), rec) 191 } 192 } 193 }