github.com/amazechain/amc@v0.1.3/internal/api/block_args.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 api
    18  
    19  import (
    20  	"github.com/amazechain/amc/common"
    21  	"github.com/amazechain/amc/common/block"
    22  	"github.com/amazechain/amc/common/hash"
    23  	"github.com/amazechain/amc/common/hexutil"
    24  	"github.com/amazechain/amc/common/transaction"
    25  	"github.com/amazechain/amc/common/types"
    26  	mvm_types "github.com/amazechain/amc/internal/avm/types"
    27  	"github.com/holiman/uint256"
    28  	"math/big"
    29  )
    30  
    31  func RPCMarshalBlock(block block.IBlock, chain common.IBlockChain, inclTx bool, fullTx bool) (map[string]interface{}, error) {
    32  	fields := RPCMarshalHeader(block.Header())
    33  
    34  	if inclTx {
    35  		formatTx := func(tx *transaction.Transaction) (interface{}, error) {
    36  			hash := tx.Hash()
    37  			return mvm_types.FromAmcHash(hash), nil
    38  		}
    39  		if fullTx {
    40  			formatTx = func(tx *transaction.Transaction) (interface{}, error) {
    41  				hash := tx.Hash()
    42  				return newRPCTransactionFromBlockHash(block, hash), nil
    43  			}
    44  		}
    45  		txs := block.Transactions()
    46  		transactions := make([]interface{}, len(txs))
    47  		var err error
    48  		for i, tx := range txs {
    49  			if transactions[i], err = formatTx(tx); err != nil {
    50  				return nil, err
    51  			}
    52  		}
    53  		fields["transactions"] = transactions
    54  
    55  		// verifiers
    56  		verifiers := make([]interface{}, len(block.Body().Verifier()))
    57  		for i, verifier := range block.Body().Verifier() {
    58  			verifiers[i] = verifier
    59  		}
    60  		fields["verifier"] = verifiers
    61  
    62  		// reward todo
    63  		type RPCReward struct {
    64  			Address types.Address
    65  			Amount  *uint256.Int
    66  		}
    67  		rewards := make([]*RPCReward, len(block.Body().Reward()))
    68  		for i, reward := range block.Body().Reward() {
    69  			rewards[i] = &RPCReward{
    70  				reward.Address,
    71  				reward.Amount,
    72  			}
    73  		}
    74  		fields["rewards"] = rewards
    75  
    76  		td := chain.GetTd(block.Hash(), block.Number64())
    77  		if td == nil {
    78  			td = new(uint256.Int)
    79  		}
    80  		fields["totalDifficulty"] = (*hexutil.Big)(td.ToBig())
    81  
    82  	}
    83  	// POA
    84  	uncleHashes := make([]types.Hash, 0)
    85  	fields["uncles"] = uncleHashes
    86  
    87  	return fields, nil
    88  }
    89  
    90  // newRPCTransactionFromBlockHash returns a transaction that will serialize to the RPC representation.
    91  func newRPCTransactionFromBlockHash(b block.IBlock, findHash types.Hash) *RPCTransaction {
    92  	for idx, tx := range b.Transactions() {
    93  		hash := tx.Hash()
    94  		if hash == findHash {
    95  			return newRPCTransactionFromBlockIndex(b, uint64(idx))
    96  		}
    97  	}
    98  	return nil
    99  }
   100  
   101  // newRPCTransactionFromBlockIndex returns a transaction that will serialize to the RPC representation.
   102  func newRPCTransactionFromBlockIndex(b block.IBlock, index uint64) *RPCTransaction {
   103  	txs := b.Transactions()
   104  	if index >= uint64(len(txs)) {
   105  		return nil
   106  	}
   107  	return newRPCTransaction(txs[index], b.Hash(), b.Number64().Uint64(), index, big.NewInt(baseFee))
   108  }
   109  
   110  // RPCMarshalHeader converts the given header to the RPC output .
   111  func RPCMarshalHeader(head block.IHeader) map[string]interface{} {
   112  	header := head.(*block.Header)
   113  	ethHeader := mvm_types.FromAmcHeader(head)
   114  
   115  	result := map[string]interface{}{
   116  		"number":           (*hexutil.Big)(head.Number64().ToBig()),
   117  		"hash":             mvm_types.FromAmcHash(header.Hash()),
   118  		"parentHash":       mvm_types.FromAmcHash(header.ParentHash),
   119  		"nonce":            header.Nonce,
   120  		"mixHash":          mvm_types.FromAmcHash(header.MixDigest),
   121  		"sha3Uncles":       mvm_types.FromAmcHash(hash.EmptyUncleHash),
   122  		"miner":            mvm_types.FromAmcAddress(&header.Coinbase),
   123  		"difficulty":       (*hexutil.Big)(header.Difficulty.ToBig()),
   124  		"extraData":        hexutil.Bytes(header.Extra),
   125  		"size":             hexutil.Uint64(ethHeader.Size()),
   126  		"gasLimit":         hexutil.Uint64(header.GasLimit),
   127  		"gasUsed":          hexutil.Uint64(header.GasUsed),
   128  		"timestamp":        hexutil.Uint64(header.Time),
   129  		"transactionsRoot": mvm_types.FromAmcHash(header.TxHash),
   130  		"receiptsRoot":     mvm_types.FromAmcHash(header.ReceiptHash),
   131  		"logsBloom":        ethHeader.Bloom,
   132  		"stateRoot":        mvm_types.FromAmcHash(header.Root),
   133  		"signature":        header.Signature,
   134  	}
   135  
   136  	if header.BaseFee != nil {
   137  		result["baseFeePerGas"] = (*hexutil.Big)(header.BaseFee.ToBig())
   138  	}
   139  
   140  	return result
   141  }