github.com/iotexproject/iotex-core@v1.14.1-rc1/blockchain/block/systemlog.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 "github.com/iotexproject/go-pkgs/hash" 10 "github.com/iotexproject/iotex-proto/golang/iotextypes" 11 "go.uber.org/zap" 12 "google.golang.org/protobuf/proto" 13 14 "github.com/iotexproject/iotex-core/action" 15 "github.com/iotexproject/iotex-core/pkg/log" 16 "github.com/iotexproject/iotex-core/pkg/util/byteutil" 17 ) 18 19 // transaction log definitions 20 type ( 21 // TokenTxRecord is a token transaction record 22 TokenTxRecord struct { 23 amount string 24 sender string 25 recipient string 26 typ iotextypes.TransactionLogType 27 } 28 29 // TransactionLog is transaction log in one action 30 TransactionLog struct { 31 actHash hash.Hash256 32 txRecords []*TokenTxRecord 33 } 34 35 // BlkTransactionLog is transaction log in one block 36 BlkTransactionLog struct { 37 actionLogs []*TransactionLog 38 } 39 ) 40 41 // NewTransactionLog creates a new TransactionLog 42 func NewTransactionLog(actHash hash.Hash256, records []*TokenTxRecord) *TransactionLog { 43 if len(records) == 0 { 44 return nil 45 } 46 47 return &TransactionLog{ 48 actHash: actHash, 49 txRecords: records, 50 } 51 } 52 53 // NewTokenTxRecord creates a new TokenTxRecord 54 func NewTokenTxRecord(typ iotextypes.TransactionLogType, amount, sender, recipient string) *TokenTxRecord { 55 rec := TokenTxRecord{ 56 amount: amount, 57 sender: sender, 58 recipient: recipient, 59 typ: typ, 60 } 61 return &rec 62 } 63 64 // DeserializeSystemLogPb parse the byte stream into TransactionLogs Pb message 65 func DeserializeSystemLogPb(buf []byte) (*iotextypes.TransactionLogs, error) { 66 pb := &iotextypes.TransactionLogs{} 67 if err := proto.Unmarshal(buf, pb); err != nil { 68 return nil, err 69 } 70 return pb, nil 71 } 72 73 // Serialize returns a serialized byte stream for BlkTransactionLog 74 func (log *BlkTransactionLog) Serialize() []byte { 75 return byteutil.Must(proto.Marshal(log.toProto())) 76 } 77 78 func (log *BlkTransactionLog) toProto() *iotextypes.TransactionLogs { 79 if len(log.actionLogs) == 0 { 80 return &iotextypes.TransactionLogs{} 81 } 82 83 sysLog := iotextypes.TransactionLogs{} 84 for _, l := range log.actionLogs { 85 if log := l.Proto(); log != nil { 86 sysLog.Logs = append(sysLog.Logs, log) 87 } 88 } 89 90 if len(sysLog.Logs) == 0 { 91 return nil 92 } 93 return &sysLog 94 } 95 96 // Proto returns the pb message 97 func (log *TransactionLog) Proto() *iotextypes.TransactionLog { 98 if len(log.txRecords) == 0 { 99 return nil 100 } 101 102 actionLog := iotextypes.TransactionLog{ 103 ActionHash: log.actHash[:], 104 Transactions: []*iotextypes.TransactionLog_Transaction{}, 105 } 106 for _, l := range log.txRecords { 107 if record := l.toProto(); record != nil { 108 actionLog.Transactions = append(actionLog.Transactions, record) 109 actionLog.NumTransactions++ 110 } 111 } 112 113 if actionLog.NumTransactions == 0 { 114 return nil 115 } 116 return &actionLog 117 } 118 119 func (log *TokenTxRecord) toProto() *iotextypes.TransactionLog_Transaction { 120 return &iotextypes.TransactionLog_Transaction{ 121 Amount: log.amount, 122 Sender: log.sender, 123 Recipient: log.recipient, 124 Type: log.typ, 125 } 126 } 127 128 // ReceiptTransactionLog generates transaction log from receipt 129 func ReceiptTransactionLog(r *action.Receipt) *TransactionLog { 130 if r == nil || len(r.TransactionLogs()) == 0 { 131 return nil 132 } 133 134 actionLog := TransactionLog{ 135 actHash: r.ActionHash, 136 txRecords: []*TokenTxRecord{}, 137 } 138 for _, log := range r.TransactionLogs() { 139 if record := LogTokenTxRecord(log); record != nil { 140 actionLog.txRecords = append(actionLog.txRecords, record) 141 } 142 } 143 144 if len(actionLog.txRecords) == 0 { 145 return nil 146 } 147 return &actionLog 148 } 149 150 // LogTokenTxRecord generates token transaction record from log 151 func LogTokenTxRecord(l *action.TransactionLog) *TokenTxRecord { 152 if l == nil { 153 return nil 154 } 155 if l.Amount.Sign() < 0 { 156 log.L().Panic("Negative amount transaction log.", zap.Any("TransactionLog", l)) 157 } 158 159 return &TokenTxRecord{ 160 sender: l.Sender, 161 recipient: l.Recipient, 162 amount: l.Amount.String(), 163 typ: l.Type, 164 } 165 }