diff --git a/core/types/qi_tx.go b/core/types/qi_tx.go index 94860b839d..11ac6dd1b9 100644 --- a/core/types/qi_tx.go +++ b/core/types/qi_tx.go @@ -10,8 +10,8 @@ import ( type QiTx struct { ChainID *big.Int // replay protection - TxIn TxIns - TxOut TxOuts + TxIn TxIns `json:"txIns"` + TxOut TxOuts `json:"txOuts"` Signature *schnorr.Signature diff --git a/core/types/utxo.go b/core/types/utxo.go index 772b574202..a992b45551 100644 --- a/core/types/utxo.go +++ b/core/types/utxo.go @@ -71,8 +71,8 @@ func (txIns *TxIns) ProtoDecode(protoTxIns *ProtoTxIns) error { // TxIn defines a Qi transaction input type TxIn struct { - PreviousOutPoint OutPoint - PubKey []byte + PreviousOutPoint OutPoint `json:"previousOutPoint"` + PubKey []byte `json:"pubKey"` } func (txIn TxIn) ProtoEncode() (*ProtoTxIn, error) { @@ -99,8 +99,8 @@ func (txIn *TxIn) ProtoDecode(protoTxIn *ProtoTxIn) error { // OutPoint defines a Qi data type that is used to track previous outputs type OutPoint struct { - TxHash common.Hash - Index uint16 + TxHash common.Hash `json:"txHash"` + Index uint16 `json:"index"` } func (outPoint OutPoint) Key() string { diff --git a/internal/quaiapi/quai_api.go b/internal/quaiapi/quai_api.go index 1b01d4ed6a..ca351cbeb8 100644 --- a/internal/quaiapi/quai_api.go +++ b/internal/quaiapi/quai_api.go @@ -493,7 +493,7 @@ func (s *PublicBlockChainQuaiAPI) EstimateGas(ctx context.Context, args Transact // BaseFee returns the base fee for a tx to be included in the next block. // If txType is set to "true" returns the Quai base fee in units of Wei. // If txType is set to "false" returns the Qi base fee in units of Qit. -func (s *PublicBlockChainQuaiAPI) BaseFee(ctx context.Context, txType bool) (*big.Int, error) { +func (s *PublicBlockChainQuaiAPI) BaseFee(ctx context.Context, txType bool) (*hexutil.Big, error) { header := s.b.CurrentBlock() if header == nil { return nil, errors.New("no header available") @@ -505,7 +505,7 @@ func (s *PublicBlockChainQuaiAPI) BaseFee(ctx context.Context, txType bool) (*bi } if txType { - return misc.CalcBaseFee(chainCfg, header), nil + return (*hexutil.Big)(misc.CalcBaseFee(chainCfg, header)), nil } else { // Use the prime terminus if we have it lastPrime, err := s.b.HeaderByHash(ctx, header.PrimeTerminus()) @@ -516,16 +516,16 @@ func (s *PublicBlockChainQuaiAPI) BaseFee(ctx context.Context, txType bool) (*bi qiBaseFee := misc.QuaiToQi(lastPrime.WorkObjectHeader(), quaiBaseFee) if qiBaseFee.Cmp(big.NewInt(0)) == 0 { // Minimum base fee is 1 qit or smallest unit - return types.Denominations[0], nil + return (*hexutil.Big)(types.Denominations[0]), nil } else { - return qiBaseFee, nil + return (*hexutil.Big)(qiBaseFee), nil } } } // EstimateFeeForQi returns an estimate of the amount of Qi in qits needed to execute the // given transaction against the current pending block. -func (s *PublicBlockChainQuaiAPI) EstimateFeeForQi(ctx context.Context, args TransactionArgs) (*big.Int, error) { +func (s *PublicBlockChainQuaiAPI) EstimateFeeForQi(ctx context.Context, args TransactionArgs) (*hexutil.Big, error) { // Estimate the gas gas, err := args.CalculateQiTxGas(s.b.NodeLocation()) if err != nil { @@ -551,9 +551,10 @@ func (s *PublicBlockChainQuaiAPI) EstimateFeeForQi(ctx context.Context, args Tra feeInQi := misc.QuaiToQi(lastPrime.WorkObjectHeader(), feeInQuai) if feeInQi.Cmp(big.NewInt(0)) == 0 { // Minimum fee is 1 qit or smallest unit - return types.Denominations[0], nil + return (*hexutil.Big)(types.Denominations[0]), nil } - return feeInQi, nil + log.Global.Infof("Estimated fee: %s\n", feeInQi.String()) + return (*hexutil.Big)(feeInQi), nil } // RPCMarshalBlock converts the given block to the RPC output which depends on fullTx. If inclTx is true transactions are @@ -861,7 +862,7 @@ func (s *PublicBlockChainQuaiAPI) GetProtocolExpansionNumber() int { } // Calculate the amount of Quai that Qi can be converted to. Expect the current Header and the Qi amount in "qits", returns the quai amount in "its" -func (s *PublicBlockChainQuaiAPI) QiRateAtBlock(ctx context.Context, blockRef interface{}, qiAmount uint64) *big.Int { +func (s *PublicBlockChainQuaiAPI) QiRateAtBlock(ctx context.Context, blockRef interface{}, qiAmount uint64) *hexutil.Big { var header *types.WorkObject var err error switch b := blockRef.(type) { @@ -874,11 +875,11 @@ func (s *PublicBlockChainQuaiAPI) QiRateAtBlock(ctx context.Context, blockRef in return nil } - return misc.QiToQuai(header.WorkObjectHeader(), new(big.Int).SetUint64(qiAmount)) + return (*hexutil.Big)(misc.QiToQuai(header.WorkObjectHeader(), new(big.Int).SetUint64(qiAmount))) } // Calculate the amount of Qi that Quai can be converted to. Expect the current Header and the Quai amount in "its", returns the Qi amount in "qits" -func (s *PublicBlockChainQuaiAPI) QuaiRateAtBlock(ctx context.Context, blockRef interface{}, quaiAmount uint64) *big.Int { +func (s *PublicBlockChainQuaiAPI) QuaiRateAtBlock(ctx context.Context, blockRef interface{}, quaiAmount uint64) *hexutil.Big { var header *types.WorkObject var err error switch b := blockRef.(type) { @@ -891,7 +892,7 @@ func (s *PublicBlockChainQuaiAPI) QuaiRateAtBlock(ctx context.Context, blockRef return nil } - return misc.QuaiToQi(header.WorkObjectHeader(), new(big.Int).SetUint64(quaiAmount)) + return (*hexutil.Big)(misc.QuaiToQi(header.WorkObjectHeader(), new(big.Int).SetUint64(quaiAmount))) } func (s *PublicBlockChainQuaiAPI) CalcOrder(ctx context.Context, raw hexutil.Bytes) (hexutil.Uint, error) { diff --git a/quaiclient/ethclient/ethclient.go b/quaiclient/ethclient/ethclient.go index 02dc93c4ed..13f3d2005c 100644 --- a/quaiclient/ethclient/ethclient.go +++ b/quaiclient/ethclient/ethclient.go @@ -477,6 +477,49 @@ func (ec *Client) EstimateGas(ctx context.Context, msg quai.CallMsg) (uint64, er return uint64(hex), nil } +type TransactionArgs struct { + From *common.Address `json:"from"` + To *common.Address `json:"to"` + Gas *hexutil.Uint64 `json:"gas"` + GasPrice *hexutil.Big `json:"gasPrice"` + MaxFeePerGas *hexutil.Big `json:"maxFeePerGas"` + MaxPriorityFeePerGas *hexutil.Big `json:"maxPriorityFeePerGas"` + Value *hexutil.Big `json:"value"` + Nonce *hexutil.Uint64 `json:"nonce"` + + // We accept "data" and "input" for backwards-compatibility reasons. + // "input" is the newer name and should be preferred by clients. + Data *hexutil.Bytes `json:"data"` + Input *hexutil.Bytes `json:"input"` + + // Introduced by AccessListTxType transaction. + AccessList *types.AccessList `json:"accessList,omitempty"` + ChainID *hexutil.Big `json:"chainId,omitempty"` + + // Support for Qi (UTXO) transaction + TxIn types.TxIns `json:"txIn,omitempty"` + TxOut types.TxOuts `json:"txOut,omitempty"` + TxType uint8 `json:"txType,omitempty"` +} + +// EstimateGas tries to estimate the gas needed to execute a specific transaction based on +// the current pending state of the backend blockchain. There is no guarantee that this is +// the true gas limit requirement as other transactions may be added or removed by miners, +// but it should provide a basis for setting a reasonable default. +func (ec *Client) EstimateFeeForQi(ctx context.Context, tx *types.Transaction) (*big.Int, error) { + args := TransactionArgs{ + TxIn: tx.TxIn(), + TxOut: tx.TxOut(), + TxType: types.QiTxType, + } + var result hexutil.Big + err := ec.c.CallContext(ctx, &result, "quai_estimateFeeForQi", args) + if err != nil { + return nil, err + } + return (*big.Int)(&result), nil +} + // SendTransaction injects a signed transaction into the pending pool for execution. // // If the transaction was a contract creation use the TransactionReceipt method to get the