github.com/amazechain/amc@v0.1.3/common/block/block.go (about) 1 // Copyright 2022 The AmazeChain Authors 2 // This file is part of the AmazeChain library. 3 // 4 // The AmazeChain 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 AmazeChain 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 AmazeChain library. If not, see <http://www.gnu.org/licenses/>. 16 17 package block 18 19 import ( 20 "fmt" 21 "github.com/amazechain/amc/api/protocol/types_pb" 22 "github.com/amazechain/amc/common/hash" 23 "github.com/amazechain/amc/common/transaction" 24 "github.com/amazechain/amc/common/types" 25 "github.com/amazechain/amc/utils" 26 "github.com/holiman/uint256" 27 "google.golang.org/protobuf/proto" 28 "strings" 29 "sync/atomic" 30 "time" 31 ) 32 33 //type writeCounter types.StorageSize 34 // 35 //func (c *writeCounter) Write(b []byte) (int, error) { 36 // *c += writeCounter(len(b)) 37 // return len(b), nil 38 //} 39 40 type Block struct { 41 header *Header 42 body *Body 43 44 hash atomic.Value 45 size atomic.Value 46 47 ReceiveAt time.Time 48 ReceivedFrom interface{} 49 } 50 51 type Verify struct { 52 Address types.Address 53 PublicKey types.PublicKey 54 } 55 56 func (v *Verify) ToProtoMessage() proto.Message { 57 var pbVerifier types_pb.Verifier 58 pbVerifier.Address = utils.ConvertAddressToH160(v.Address) 59 pbVerifier.PublicKey = utils.ConvertPublicKeyToH384(v.PublicKey) 60 return &pbVerifier 61 } 62 63 func (v *Verify) FromProtoMessage(pbVerifier *types_pb.Verifier) *Verify { 64 v.Address = utils.ConvertH160toAddress(pbVerifier.Address) 65 v.PublicKey = utils.ConvertH384ToPublicKey(pbVerifier.PublicKey) 66 return v 67 } 68 69 type Reward struct { 70 Address types.Address 71 Amount *uint256.Int 72 } 73 74 type Rewards []*Reward 75 76 func (r Rewards) Len() int { 77 return len(r) 78 } 79 80 func (r Rewards) Less(i, j int) bool { 81 return strings.Compare(r[i].Address.String(), r[j].Address.String()) > 0 82 } 83 84 func (r Rewards) Swap(i, j int) { 85 r[i], r[j] = r[j], r[i] 86 } 87 88 func (r *Reward) ToProtoMessage() proto.Message { 89 var pbReward types_pb.Reward 90 pbReward.Address = utils.ConvertAddressToH160(r.Address) 91 pbReward.Amount = utils.ConvertUint256IntToH256(r.Amount) 92 return &pbReward 93 } 94 95 func (r *Reward) FromProtoMessage(pbReward *types_pb.Reward) *Reward { 96 r.Address = utils.ConvertH160toAddress(pbReward.Address) 97 r.Amount = utils.ConvertH256ToUint256Int(pbReward.Amount) 98 return r 99 } 100 101 func (b *Block) Transactions() []*transaction.Transaction { 102 if b.body != nil { 103 return b.body.Transactions() 104 } 105 106 return nil 107 } 108 109 func (b *Block) StateRoot() types.Hash { 110 return b.header.Root 111 } 112 113 func (b *Block) Hash() types.Hash { 114 return b.Header().Hash() 115 } 116 117 func (b *Block) Marshal() ([]byte, error) { 118 bpBlock := b.ToProtoMessage() 119 return proto.Marshal(bpBlock) 120 } 121 122 func (b *Block) Unmarshal(data []byte) error { 123 var pBlock types_pb.Block 124 if err := proto.Unmarshal(data, &pBlock); err != nil { 125 return err 126 } 127 if err := b.FromProtoMessage(&pBlock); err != nil { 128 return err 129 } 130 return nil 131 } 132 133 // NewBlock creates a new block. The input data is copied, 134 // changes to header and to the field values will not affect the 135 // block. 136 // 137 // The values of TxHash, UncleHash, ReceiptHash and Bloom in header 138 // are ignored and set to values derived from the given txs, uncles 139 // and receipts. 140 func NewBlock(h IHeader, txs []*transaction.Transaction) IBlock { 141 142 block := &Block{ 143 header: CopyHeader(h.(*Header)), 144 body: &Body{Txs: txs}, 145 ReceiveAt: time.Now(), 146 ReceivedFrom: nil, 147 } 148 return block 149 } 150 151 func NewBlockFromReceipt(h IHeader, txs []*transaction.Transaction, uncles []IHeader, receipts []*Receipt, reward []*Reward) IBlock { 152 153 block := &Block{ 154 header: CopyHeader(h.(*Header)), 155 body: &Body{Txs: txs, Rewards: CopyReward(reward)}, 156 ReceiveAt: time.Now(), 157 ReceivedFrom: nil, 158 } 159 //if len(receipts) > 0 { 160 // print(receipts) 161 //} 162 163 block.header.Bloom = CreateBloom(receipts) 164 block.header.TxHash = hash.DeriveSha(transaction.Transactions(txs)) 165 block.header.ReceiptHash = hash.DeriveSha(Receipts(receipts)) 166 167 return block 168 } 169 170 func (b *Block) Header() IHeader { 171 return CopyHeader(b.header) 172 } 173 174 func (b *Block) Body() IBody { 175 return b.body 176 } 177 178 func (b *Block) Number64() *uint256.Int { 179 return b.header.Number 180 } 181 182 func (b *Block) BaseFee64() *uint256.Int { 183 return b.header.BaseFee 184 } 185 186 func (b *Block) Difficulty() *uint256.Int { 187 return b.header.Difficulty 188 } 189 190 func (b *Block) Time() uint64 { 191 return b.header.Time 192 } 193 194 func (b *Block) GasLimit() uint64 { 195 return b.header.GasLimit 196 } 197 198 func (b *Block) GasUsed() uint64 { 199 return b.header.GasUsed 200 } 201 202 func (b *Block) Nonce() uint64 { 203 return b.header.Nonce.Uint64() 204 } 205 206 func (b *Block) Coinbase() types.Address { 207 return b.header.Coinbase 208 } 209 210 func (b *Block) ParentHash() types.Hash { 211 return b.header.ParentHash 212 } 213 214 func (b *Block) TxHash() types.Hash { 215 return b.header.TxHash 216 } 217 218 func (b *Block) WithSeal(header IHeader) *Block { 219 b.header = CopyHeader(header.(*Header)) 220 return b 221 } 222 223 func (b *Block) Transaction(hash types.Hash) *transaction.Transaction { 224 return nil 225 } 226 227 func (b *Block) ToProtoMessage() proto.Message { 228 pbHeader := b.header.ToProtoMessage() 229 pbBody := b.body.ToProtoMessage() 230 pBlock := types_pb.Block{ 231 Header: pbHeader.(*types_pb.Header), 232 Body: pbBody.(*types_pb.Body), 233 } 234 235 return &pBlock 236 } 237 238 func (b *Block) FromProtoMessage(message proto.Message) error { 239 var ( 240 pBlock *types_pb.Block 241 header Header 242 body Body 243 ok bool 244 ) 245 246 if pBlock, ok = message.(*types_pb.Block); !ok { 247 return fmt.Errorf("type conversion failure") 248 } 249 250 if err := header.FromProtoMessage(pBlock.Header); err != nil { 251 return err 252 } 253 254 if err := body.FromProtoMessage(pBlock.Body); err != nil { 255 return err 256 } 257 258 b.header = &header 259 b.body = &body 260 b.ReceiveAt = time.Now() 261 return nil 262 } 263 264 func (b *Block) SendersToTxs(senders []types.Address) { 265 //todo 266 } 267 268 func (b *Block) Uncles() []*Header { 269 return nil 270 }