Skip to content
This repository has been archived by the owner on Jul 23, 2024. It is now read-only.

Commit

Permalink
Supports dynamic base fee in the common architecture features
Browse files Browse the repository at this point in the history
  • Loading branch information
jimni1222 committed Jun 23, 2022
1 parent 1f5c930 commit 7de3b90
Show file tree
Hide file tree
Showing 27 changed files with 680 additions and 44 deletions.
55 changes: 47 additions & 8 deletions packages/caver-core-method/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,7 @@ const buildSendRequestFunc = (defer, sendSignedTx, sendTxCallback) => (payload,
return method.requestManager.send(payload, sendTxCallback)
}

const buildSendFunc = (method, isSendTx) => (...args) => {
const buildSendFunc = (method, isSendTx) => async (...args) => {
const defer = utils.promiEvent(!isSendTx)
const payload = method.toPayload(args)

Expand All @@ -459,27 +459,66 @@ const buildSendFunc = (method, isSendTx) => (...args) => {

const isGasPriceInputMissing = isSendTx && _.isObject(payload.params[0]) && payload.params[0].gasPrice === undefined

// If gasPrice input is missing, call getGasPrice rpc
if (!isGasPriceInputMissing) {
// The TxTypeEthereumDynamicFee transaction does not use the gasPrice field,
// so we need to check `maxPriorityFeePerGas` and `maxFeePerGas` field instead of `gasPrice`.
const isDynamicFeeTx = payload.params[0].type === TX_TYPE_STRING.TxTypeEthereumDynamicFee
const filledDynamicGasFeeTx =
isDynamicFeeTx && payload.params[0].maxPriorityFeePerGas !== undefined && payload.params[0].maxFeePerGas !== undefined

// If gasPrice is missing, have to fill gasPrice field before sending tx
if (!isGasPriceInputMissing || filledDynamicGasFeeTx) {
sendRequest(payload, method)
return defer.eventEmitter
}

const getHeader = new Method({
name: 'getHeader',
call: 'klay_getHeaderByNumber',
params: 1,
}).createFunction(method.requestManager)

const getGasPrice = new Method({
name: 'getGasPrice',
call: 'klay_gasPrice',
params: 0,
}).createFunction(method.requestManager)

getGasPrice((err, gasPrice) => {
const getMaxPriorityFeePerGas = new Method({
name: 'getMaxPriorityFeePerGas',
call: 'klay_maxPriorityFeePerGas',
params: 0,
}).createFunction(method.requestManager)

const header = await getHeader('latest')
const bf = utils.hexToNumber(header.baseFeePerGas || '0x0')

// The baseFeePerGas is bigger than 0 means that Klaytn uses dynamic gas price.
if (bf > 0) {
if (!isDynamicFeeTx) {
payload.params[0].gasPrice = bf * 2
} else {
// If maxFeePerGas is undefined, set maxFeePerGas with `baseFee * 2`.
payload.params[0].maxFeePerGas = payload.params[0].maxFeePerGas || bf * 2
// If maxPriorityFeePerGas is undefined, call `klay_maxPriorityFeePerGas`.
if (payload.params[0].maxPriorityFeePerGas === undefined) {
const maxPriorityFeePerGas = await getMaxPriorityFeePerGas()
payload.params[0].maxPriorityFeePerGas = maxPriorityFeePerGas
}
}
} else {
// If baseFeePerGas is not defined or 0, we need to use unit price for the `gasPrice` field.
const gp = await getGasPrice()
// The TxTypeEthereumDynamicFee transaction does not use the gasPrice field,
// so the gas price default is not set for TxTypeEthereumDynamicFee.
if (payload.params[0].type !== TX_TYPE_STRING.TxTypeEthereumDynamicFee) {
payload.params[0].gasPrice = gasPrice || payload.params[0].gasPrice
if (!isDynamicFeeTx) {
payload.params[0].gasPrice = payload.params[0].gasPrice || gp
} else {
payload.params[0].maxPriorityFeePerGas = payload.params[0].maxPriorityFeePerGas || gp
payload.params[0].maxFeePerGas = payload.params[0].maxFeePerGas || gp
}
sendRequest(payload, method)
})
}

sendRequest(payload, method)
/**
* attaching `.on('receipt')` is possible by returning defer.eventEmitter
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ class AbstractTransaction {
* Calls `klay_chainID` klay rpc call.
*
* @example
* const result = tx.getChainId()
* const result = await tx.getChainId()
*
* @return {string} chain id
*/
Expand All @@ -166,11 +166,40 @@ class AbstractTransaction {
return chainId
}

/**
* Returns a suggested gas price to use in the transaction.
* If `baseFee` is bigger than `0` in the header,
* then returns `baseFee * 2`.
* If not, calls `klay_gasPrice` to return unit price of the gas.
*
* @example
* const result = await tx.getSuggestedGasPrice()
*
* @return {string} gas price
*/
async getSuggestedGasPrice() {
const bfStr = await this.getBaseFee()
const baseFee = utils.hexToNumber(bfStr)

let suggestedGasPrice
if (baseFee > 0) {
// After hard KIP-71 fork, set gasPrice (or maxFeePerGas) with baseFee * 2
suggestedGasPrice = baseFee * 2
suggestedGasPrice = utils.toHex(suggestedGasPrice)
} else {
// Before hard KIP-71 fork, set gasPrice (or maxFeePerGas) with gas unit price
suggestedGasPrice = await this.klaytnCall.getGasPrice()
}
return suggestedGasPrice
}

/**
* Calls `klay_gasPrice` klay rpc call.
* Note that when Klaytn network use dynamic gas fee,
* you need to use `tx.getSuggestedGasPrice` function in the gasPrice field.
*
* @example
* const result = tx.getGasPrice()
* const result = await tx.getGasPrice()
*
* @return {string} gas price
*/
Expand All @@ -183,7 +212,7 @@ class AbstractTransaction {
* Calls `klay_getTransactionCount` klay rpc call.
*
* @example
* const result = tx.getNonce('0x{from address}')
* const result = await tx.getNonce('0x{from address}')
*
* @return {string} nonce
*/
Expand All @@ -194,22 +223,23 @@ class AbstractTransaction {

/**
* Calls `klay_getHeaderByNumber` klay rpc call to get `baseFeePerGas` in header.
* If `baseFeePerGas` is not existed, returns '0x0'.
*
* @example
* const result = tx.getBaseFee()
* const result = await tx.getBaseFee()
*
* @return {string} base fee
*/
async getBaseFee() {
const header = await this.klaytnCall.getHeaderByNumber('latest')
return header.baseFeePerGas
return header.baseFeePerGas || '0x0'
}

/**
* Calls `klay_maxPriorityFeePerGas` klay rpc call.
*
* @example
* const result = tx.getMaxPriorityFeePerGas()
* const result = await tx.getMaxPriorityFeePerGas()
*
* @return {string} suggested max priority fee per gas
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ class AccountUpdate extends AbstractTransaction {
async fillTransaction() {
const [chainId, gasPrice, nonce] = await Promise.all([
isNot(this.chainId) ? this.getChainId() : this.chainId,
isNot(this.gasPrice) ? this.getGasPrice() : this.gasPrice,
isNot(this.gasPrice) ? this.getSuggestedGasPrice() : this.gasPrice,
isNot(this.nonce) ? this.getNonce(this.from) : this.nonce,
])

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ class FeeDelegatedAccountUpdate extends AbstractFeeDelegatedTransaction {
async fillTransaction() {
const [chainId, gasPrice, nonce] = await Promise.all([
isNot(this.chainId) ? this.getChainId() : this.chainId,
isNot(this.gasPrice) ? this.getGasPrice() : this.gasPrice,
isNot(this.gasPrice) ? this.getSuggestedGasPrice() : this.gasPrice,
isNot(this.nonce) ? this.getNonce(this.from) : this.nonce,
])

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ class FeeDelegatedAccountUpdateWithRatio extends AbstractFeeDelegatedWithRatioTr
async fillTransaction() {
const [chainId, gasPrice, nonce] = await Promise.all([
isNot(this.chainId) ? this.getChainId() : this.chainId,
isNot(this.gasPrice) ? this.getGasPrice() : this.gasPrice,
isNot(this.gasPrice) ? this.getSuggestedGasPrice() : this.gasPrice,
isNot(this.nonce) ? this.getNonce(this.from) : this.nonce,
])

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ class Cancel extends AbstractTransaction {
async fillTransaction() {
const [chainId, gasPrice, nonce] = await Promise.all([
isNot(this.chainId) ? this.getChainId() : this.chainId,
isNot(this.gasPrice) ? this.getGasPrice() : this.gasPrice,
isNot(this.gasPrice) ? this.getSuggestedGasPrice() : this.gasPrice,
isNot(this.nonce) ? this.getNonce(this.from) : this.nonce,
])

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ class FeeDelegatedCancel extends AbstractFeeDelegatedTransaction {
async fillTransaction() {
const [chainId, gasPrice, nonce] = await Promise.all([
isNot(this.chainId) ? this.getChainId() : this.chainId,
isNot(this.gasPrice) ? this.getGasPrice() : this.gasPrice,
isNot(this.gasPrice) ? this.getSuggestedGasPrice() : this.gasPrice,
isNot(this.nonce) ? this.getNonce(this.from) : this.nonce,
])

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ class FeeDelegatedCancelWithRatio extends AbstractFeeDelegatedWithRatioTransacti
async fillTransaction() {
const [chainId, gasPrice, nonce] = await Promise.all([
isNot(this.chainId) ? this.getChainId() : this.chainId,
isNot(this.gasPrice) ? this.getGasPrice() : this.gasPrice,
isNot(this.gasPrice) ? this.getSuggestedGasPrice() : this.gasPrice,
isNot(this.nonce) ? this.getNonce(this.from) : this.nonce,
])

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ class ChainDataAnchoring extends AbstractTransaction {
async fillTransaction() {
const [chainId, gasPrice, nonce] = await Promise.all([
isNot(this.chainId) ? this.getChainId() : this.chainId,
isNot(this.gasPrice) ? this.getGasPrice() : this.gasPrice,
isNot(this.gasPrice) ? this.getSuggestedGasPrice() : this.gasPrice,
isNot(this.nonce) ? this.getNonce(this.from) : this.nonce,
])

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ class FeeDelegatedChainDataAnchoring extends AbstractFeeDelegatedTransaction {
async fillTransaction() {
const [chainId, gasPrice, nonce] = await Promise.all([
isNot(this.chainId) ? this.getChainId() : this.chainId,
isNot(this.gasPrice) ? this.getGasPrice() : this.gasPrice,
isNot(this.gasPrice) ? this.getSuggestedGasPrice() : this.gasPrice,
isNot(this.nonce) ? this.getNonce(this.from) : this.nonce,
])

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ class FeeDelegatedChainDataAnchoringWithRatio extends AbstractFeeDelegatedWithRa
async fillTransaction() {
const [chainId, gasPrice, nonce] = await Promise.all([
isNot(this.chainId) ? this.getChainId() : this.chainId,
isNot(this.gasPrice) ? this.getGasPrice() : this.gasPrice,
isNot(this.gasPrice) ? this.getSuggestedGasPrice() : this.gasPrice,
isNot(this.nonce) ? this.getNonce(this.from) : this.nonce,
])

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,7 @@ class EthereumAccessList extends AbstractTransaction {
async fillTransaction() {
const [chainId, gasPrice, nonce] = await Promise.all([
isNot(this.chainId) ? this.getChainId() : this.chainId,
isNot(this.gasPrice) ? this.getGasPrice() : this.gasPrice,
isNot(this.gasPrice) ? this.getSuggestedGasPrice() : this.gasPrice,
isNot(this.nonce) ? this.getNonce(this.from) : this.nonce,
])

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -390,21 +390,17 @@ class EthereumDynamicFee extends AbstractTransaction {
async fillTransaction() {
const isNotMaxPriorityFeePerGas = isNot(this.maxPriorityFeePerGas)
const isNotMaxFeePerGas = isNot(this.maxFeePerGas)
const [chainId, maxPriorityFeePerGas, nonce, baseFee] = await Promise.all([
const [chainId, maxPriorityFeePerGas, nonce, maxFeePerGas] = await Promise.all([
isNot(this.chainId) ? this.getChainId() : this.chainId,
isNotMaxPriorityFeePerGas ? this.getMaxPriorityFeePerGas() : this.maxPriorityFeePerGas,
isNot(this.nonce) ? this.getNonce(this.from) : this.nonce,
isNotMaxPriorityFeePerGas || isNotMaxFeePerGas ? this.getBaseFee() : undefined,
isNotMaxFeePerGas ? this.getSuggestedGasPrice() : this.maxFeePerGas,
])

this.chainId = chainId
this.nonce = nonce
this.maxPriorityFeePerGas = maxPriorityFeePerGas

// Set maxFeePerGas with `block.baseFeePerGas.mul(2).add(maxPriorityFeePerGas)`
if (isNotMaxFeePerGas) {
this.maxFeePerGas = utils.hexToNumber(baseFee) * 2 + utils.hexToNumber(this.maxPriorityFeePerGas)
}
this.maxFeePerGas = maxFeePerGas
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ class LegacyTransaction extends AbstractTransaction {
async fillTransaction() {
const [chainId, gasPrice, nonce] = await Promise.all([
isNot(this.chainId) ? this.getChainId() : this.chainId,
isNot(this.gasPrice) ? this.getGasPrice() : this.gasPrice,
isNot(this.gasPrice) ? this.getSuggestedGasPrice() : this.gasPrice,
isNot(this.nonce) ? this.getNonce(this.from) : this.nonce,
])

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ class FeeDelegatedSmartContractDeploy extends AbstractFeeDelegatedTransaction {
async fillTransaction() {
const [chainId, gasPrice, nonce] = await Promise.all([
isNot(this.chainId) ? this.getChainId() : this.chainId,
isNot(this.gasPrice) ? this.getGasPrice() : this.gasPrice,
isNot(this.gasPrice) ? this.getSuggestedGasPrice() : this.gasPrice,
isNot(this.nonce) ? this.getNonce(this.from) : this.nonce,
])

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ class FeeDelegatedSmartContractDeployWithRatio extends AbstractFeeDelegatedWithR
async fillTransaction() {
const [chainId, gasPrice, nonce] = await Promise.all([
isNot(this.chainId) ? this.getChainId() : this.chainId,
isNot(this.gasPrice) ? this.getGasPrice() : this.gasPrice,
isNot(this.gasPrice) ? this.getSuggestedGasPrice() : this.gasPrice,
isNot(this.nonce) ? this.getNonce(this.from) : this.nonce,
])

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ class SmartContractDeploy extends AbstractTransaction {
async fillTransaction() {
const [chainId, gasPrice, nonce] = await Promise.all([
isNot(this.chainId) ? this.getChainId() : this.chainId,
isNot(this.gasPrice) ? this.getGasPrice() : this.gasPrice,
isNot(this.gasPrice) ? this.getSuggestedGasPrice() : this.gasPrice,
isNot(this.nonce) ? this.getNonce(this.from) : this.nonce,
])

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ class FeeDelegatedSmartContractExecution extends AbstractFeeDelegatedTransaction
async fillTransaction() {
const [chainId, gasPrice, nonce] = await Promise.all([
isNot(this.chainId) ? this.getChainId() : this.chainId,
isNot(this.gasPrice) ? this.getGasPrice() : this.gasPrice,
isNot(this.gasPrice) ? this.getSuggestedGasPrice() : this.gasPrice,
isNot(this.nonce) ? this.getNonce(this.from) : this.nonce,
])

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ class FeeDelegatedSmartContractExecutionWithRatio extends AbstractFeeDelegatedWi
async fillTransaction() {
const [chainId, gasPrice, nonce] = await Promise.all([
isNot(this.chainId) ? this.getChainId() : this.chainId,
isNot(this.gasPrice) ? this.getGasPrice() : this.gasPrice,
isNot(this.gasPrice) ? this.getSuggestedGasPrice() : this.gasPrice,
isNot(this.nonce) ? this.getNonce(this.from) : this.nonce,
])

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ class SmartContractExecution extends AbstractTransaction {
async fillTransaction() {
const [chainId, gasPrice, nonce] = await Promise.all([
isNot(this.chainId) ? this.getChainId() : this.chainId,
isNot(this.gasPrice) ? this.getGasPrice() : this.gasPrice,
isNot(this.gasPrice) ? this.getSuggestedGasPrice() : this.gasPrice,
isNot(this.nonce) ? this.getNonce(this.from) : this.nonce,
])

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ class FeeDelegatedValueTransfer extends AbstractFeeDelegatedTransaction {
async fillTransaction() {
const [chainId, gasPrice, nonce] = await Promise.all([
isNot(this.chainId) ? this.getChainId() : this.chainId,
isNot(this.gasPrice) ? this.getGasPrice() : this.gasPrice,
isNot(this.gasPrice) ? this.getSuggestedGasPrice() : this.gasPrice,
isNot(this.nonce) ? this.getNonce(this.from) : this.nonce,
])

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ class FeeDelegatedValueTransferWithRatio extends AbstractFeeDelegatedWithRatioTr
async fillTransaction() {
const [chainId, gasPrice, nonce] = await Promise.all([
isNot(this.chainId) ? this.getChainId() : this.chainId,
isNot(this.gasPrice) ? this.getGasPrice() : this.gasPrice,
isNot(this.gasPrice) ? this.getSuggestedGasPrice() : this.gasPrice,
isNot(this.nonce) ? this.getNonce(this.from) : this.nonce,
])

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ class ValueTransfer extends AbstractTransaction {
async fillTransaction() {
const [chainId, gasPrice, nonce] = await Promise.all([
isNot(this.chainId) ? this.getChainId() : this.chainId,
isNot(this.gasPrice) ? this.getGasPrice() : this.gasPrice,
isNot(this.gasPrice) ? this.getSuggestedGasPrice() : this.gasPrice,
isNot(this.nonce) ? this.getNonce(this.from) : this.nonce,
])

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ class FeeDelegatedValueTransferMemo extends AbstractFeeDelegatedTransaction {
async fillTransaction() {
const [chainId, gasPrice, nonce] = await Promise.all([
isNot(this.chainId) ? this.getChainId() : this.chainId,
isNot(this.gasPrice) ? this.getGasPrice() : this.gasPrice,
isNot(this.gasPrice) ? this.getSuggestedGasPrice() : this.gasPrice,
isNot(this.nonce) ? this.getNonce(this.from) : this.nonce,
])

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ class FeeDelegatedValueTransferMemoWithRatio extends AbstractFeeDelegatedWithRat
async fillTransaction() {
const [chainId, gasPrice, nonce] = await Promise.all([
isNot(this.chainId) ? this.getChainId() : this.chainId,
isNot(this.gasPrice) ? this.getGasPrice() : this.gasPrice,
isNot(this.gasPrice) ? this.getSuggestedGasPrice() : this.gasPrice,
isNot(this.nonce) ? this.getNonce(this.from) : this.nonce,
])

Expand Down
Loading

0 comments on commit 7de3b90

Please sign in to comment.