github.com/klaytn/klaytn@v1.12.1/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  }