github.com/klaytn/klaytn@v1.10.2/blockchain/types/anchoring_data.go (about) 1 // Copyright 2019 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 types 18 19 import ( 20 "encoding/json" 21 "errors" 22 "fmt" 23 "math/big" 24 25 "github.com/klaytn/klaytn/common" 26 "github.com/klaytn/klaytn/rlp" 27 ) 28 29 const ( 30 AnchoringDataType0 uint8 = 0 31 AnchoringJSONDataType uint8 = 128 32 ) 33 34 var errUnknownAnchoringTxType = errors.New("unknown anchoring tx type") 35 36 type AnchoringDataInternal interface { 37 GetBlockHash() common.Hash 38 GetBlockNumber() *big.Int 39 } 40 41 type AnchoringData struct { 42 Type uint8 43 Data []byte 44 } 45 46 // AnchoringDataLegacy is an old anchoring type that does not support an data type. 47 type AnchoringDataLegacy struct { 48 BlockHash common.Hash `json:"blockHash"` 49 TxHash common.Hash `json:"transactionsRoot"` 50 ParentHash common.Hash `json:"parentHash"` 51 ReceiptHash common.Hash `json:"receiptsRoot"` 52 StateRootHash common.Hash `json:"stateRoot"` 53 BlockNumber *big.Int `json:"blockNumber"` 54 } 55 56 func (data *AnchoringDataLegacy) GetBlockHash() common.Hash { 57 return data.BlockHash 58 } 59 60 func (data *AnchoringDataLegacy) GetBlockNumber() *big.Int { 61 return data.BlockNumber 62 } 63 64 type AnchoringDataInternalType0 struct { 65 BlockHash common.Hash `json:"blockHash"` 66 TxHash common.Hash `json:"transactionsRoot"` 67 ParentHash common.Hash `json:"parentHash"` 68 ReceiptHash common.Hash `json:"receiptsRoot"` 69 StateRootHash common.Hash `json:"stateRoot"` 70 BlockNumber *big.Int `json:"blockNumber"` 71 BlockCount *big.Int `json:"blockCount"` 72 TxCount *big.Int `json:"txCount"` 73 } 74 75 func (data *AnchoringDataInternalType0) GetBlockHash() common.Hash { 76 return data.BlockHash 77 } 78 79 func (data *AnchoringDataInternalType0) GetBlockNumber() *big.Int { 80 return data.BlockNumber 81 } 82 83 func NewAnchoringDataType0(block *Block, blockCount uint64, txCount uint64) (*AnchoringData, error) { 84 data := &AnchoringDataInternalType0{ 85 block.Hash(), 86 block.Header().TxHash, 87 block.Header().ParentHash, 88 block.Header().ReceiptHash, 89 block.Header().Root, 90 block.Header().Number, 91 new(big.Int).SetUint64(blockCount), 92 new(big.Int).SetUint64(txCount), 93 } 94 encodedCCTxData, err := rlp.EncodeToBytes(data) 95 if err != nil { 96 return nil, err 97 } 98 return &AnchoringData{AnchoringDataType0, encodedCCTxData}, nil 99 } 100 101 func NewAnchoringJSONDataType(v interface{}) (*AnchoringData, error) { 102 encoded, err := json.Marshal(v) 103 if err != nil { 104 return nil, err 105 } 106 return &AnchoringData{AnchoringJSONDataType, encoded}, nil 107 } 108 109 // DecodeAnchoringData decodes an anchoring data used by main and sub bridges. 110 func DecodeAnchoringData(data []byte) (AnchoringDataInternal, error) { 111 anchoringData := new(AnchoringData) 112 if err := rlp.DecodeBytes(data, anchoringData); err != nil { 113 anchoringDataLegacy := new(AnchoringDataLegacy) 114 if err := rlp.DecodeBytes(data, anchoringDataLegacy); err != nil { 115 return nil, err 116 } 117 logger.Trace("decoded legacy anchoring tx", "blockNum", anchoringDataLegacy.GetBlockNumber().String(), "blockHash", anchoringDataLegacy.GetBlockHash().String(), "txHash", anchoringDataLegacy.TxHash.String()) 118 return anchoringDataLegacy, nil 119 } 120 if anchoringData.Type == AnchoringDataType0 { 121 anchoringDataInternal := new(AnchoringDataInternalType0) 122 if err := rlp.DecodeBytes(anchoringData.Data, anchoringDataInternal); err != nil { 123 return nil, err 124 } 125 logger.Trace("decoded type0 anchoring tx", "blockNum", anchoringDataInternal.BlockNumber.String(), "blockHash", anchoringDataInternal.BlockHash.String(), "txHash", anchoringDataInternal.TxHash.String(), "txCount", anchoringDataInternal.TxCount) 126 return anchoringDataInternal, nil 127 } 128 return nil, errUnknownAnchoringTxType 129 } 130 131 // DecodeAnchoringDataToJSON decodes an anchoring data. 132 func DecodeAnchoringDataToJSON(data []byte) (interface{}, error) { 133 anchoringData := new(AnchoringData) 134 if err := rlp.DecodeBytes(data, anchoringData); err != nil { 135 anchoringDataLegacy := new(AnchoringDataLegacy) 136 if err := rlp.DecodeBytes(data, anchoringDataLegacy); err != nil { 137 return nil, err 138 } 139 return anchoringDataLegacy, nil 140 } 141 if anchoringData.Type == AnchoringDataType0 { 142 anchoringDataInternal := new(AnchoringDataInternalType0) 143 if err := rlp.DecodeBytes(anchoringData.Data, anchoringDataInternal); err != nil { 144 return nil, err 145 } 146 return anchoringDataInternal, nil 147 } 148 if anchoringData.Type == AnchoringJSONDataType { 149 var v map[string]interface{} 150 if err := json.Unmarshal(anchoringData.Data, &v); err != nil { 151 return nil, err 152 } 153 return v, nil 154 } 155 return nil, fmt.Errorf("%w type=%v", errUnknownAnchoringTxType, anchoringData.Type) 156 }