Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add the dynamic fee tx and support for typed txs #903

Merged
merged 22 commits into from
Jan 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
e6630db
feat: add the dynamic fee tx and support for typed txs
paologalligit Nov 29, 2024
fafe9a5
refactor: returning maxFeePerGas or mas uint8 as gasPriceCoef for dyn…
paologalligit Dec 2, 2024
27f54fb
test: add mempool tests with dynFeeTxs type
paologalligit Dec 2, 2024
72e6012
test: add tests for txpool and logdb
paologalligit Dec 2, 2024
080ac25
test: add transactions test
paologalligit Dec 3, 2024
b5a6506
refactor: split builder into legacy and dynFee builder
paologalligit Dec 3, 2024
8cfc6f0
test: add more tests including dynamic fee txs
paologalligit Dec 5, 2024
f937500
style: fix linting
paologalligit Dec 5, 2024
4d236da
fix: switch to LegacyBuilder
paologalligit Dec 5, 2024
1a468a5
test: add more tests
paologalligit Dec 5, 2024
bcb20e3
test: add tests for legacy and dynamic tx builder
paologalligit Dec 5, 2024
135b14c
test: add dynFee tx in initBlockServer test
paologalligit Dec 6, 2024
2d12bf4
test: add dynFee tx in tests initializations function
paologalligit Dec 6, 2024
e5bf58d
feat: replace rlp.EncodeToBytes with the new tx MarshalBinary
paologalligit Dec 17, 2024
267fd43
refactor: change tx type codes
paologalligit Dec 17, 2024
8422b55
test: add more dynFee txs to tests
paologalligit Dec 18, 2024
dcbfd44
Rebase to master
paologalligit Dec 19, 2024
724d391
feat: differentiate legacy and dyn fee json response
paologalligit Dec 20, 2024
8a375f1
refactor: merge tx builder into one builder
paologalligit Jan 9, 2025
316917a
refactor: add MustBuild to tx builder and fix error
paologalligit Jan 23, 2025
3eec5f4
refactor: move hashWithoutNonce to concrete tx implementation
paologalligit Jan 23, 2025
ddf656a
fix: use MarshalBinary to encode/decode a tx instead of encodeRLP
paologalligit Jan 24, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 8 additions & 12 deletions api/accounts/accounts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ func initAccountServer(t *testing.T, enabledDeprecated bool) {
genesisBlock = thorChain.GenesisBlock()
claTransfer := tx.NewClause(&addr).WithValue(value)
claDeploy := tx.NewClause(nil).WithData(bytecode)
transaction := buildTxWithClauses(thorChain.Repo().ChainTag(), claTransfer, claDeploy)
transaction := buildTxWithClauses(tx.LegacyTxType, thorChain.Repo().ChainTag(), claTransfer, claDeploy)
contractAddr = thor.CreateContractAddress(transaction.ID(), 1, 0)
method := "set"
abi, _ := ABI.New([]byte(abiJSON))
Expand All @@ -296,7 +296,7 @@ func initAccountServer(t *testing.T, enabledDeprecated bool) {
t.Fatal(err)
}
claCall := tx.NewClause(&contractAddr).WithData(input)
transactionCall := buildTxWithClauses(thorChain.Repo().ChainTag(), claCall)
transactionCall := buildTxWithClauses(tx.DynamicFeeTxType, thorChain.Repo().ChainTag(), claCall)
require.NoError(t,
thorChain.MintTransactions(
genesis.DevAccounts()[0],
Expand All @@ -312,17 +312,13 @@ func initAccountServer(t *testing.T, enabledDeprecated bool) {
ts = httptest.NewServer(router)
}

func buildTxWithClauses(chaiTag byte, clauses ...*tx.Clause) *tx.Transaction {
builder := new(tx.Builder).
ChainTag(chaiTag).
func buildTxWithClauses(txType int, chainTag byte, clauses ...*tx.Clause) *tx.Transaction {
trx := tx.NewTxBuilder(txType).
ChainTag(chainTag).
Expiration(10).
Gas(1000000)
for _, c := range clauses {
builder.Clause(c)
}

trx := builder.Build()

Gas(1000000).
Clauses(clauses).
MustBuild()
return tx.MustSign(trx, genesis.DevAccounts()[0].PrivateKey)
}

Expand Down
38 changes: 24 additions & 14 deletions api/blocks/blocks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -230,20 +230,30 @@ func initBlockServer(t *testing.T) {

addr := thor.BytesToAddress([]byte("to"))
cla := tx.NewClause(&addr).WithValue(big.NewInt(10000))
trx := tx.MustSign(
new(tx.Builder).
ChainTag(thorChain.Repo().ChainTag()).
GasPriceCoef(1).
Expiration(10).
Gas(21000).
Nonce(1).
Clause(cla).
BlockRef(tx.NewBlockRef(0)).
Build(),
genesis.DevAccounts()[0].PrivateKey,
)

require.NoError(t, thorChain.MintTransactions(genesis.DevAccounts()[0], trx))
legacyTx := tx.NewTxBuilder(tx.LegacyTxType).
ChainTag(thorChain.Repo().ChainTag()).
GasPriceCoef(1).
Expiration(10).
Gas(21000).
Nonce(1).
Clause(cla).
BlockRef(tx.NewBlockRef(0)).
MustBuild()
legacyTx = tx.MustSign(legacyTx, genesis.DevAccounts()[0].PrivateKey)

dynFeeTx := tx.NewTxBuilder(tx.DynamicFeeTxType).
ChainTag(thorChain.Repo().ChainTag()).
MaxFeePerGas(big.NewInt(100000)).
MaxPriorityFeePerGas(big.NewInt(100)).
Expiration(10).
Gas(21000).
Nonce(2).
Clause(cla).
BlockRef(tx.NewBlockRef(0)).
MustBuild()
dynFeeTx = tx.MustSign(dynFeeTx, genesis.DevAccounts()[0].PrivateKey)

require.NoError(t, thorChain.MintTransactions(genesis.DevAccounts()[0], legacyTx, dynFeeTx))

allBlocks, err := thorChain.GetAllBlocks()
require.NoError(t, err)
Expand Down
74 changes: 42 additions & 32 deletions api/blocks/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
package blocks

import (
"math/big"

"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/common/math"
"github.com/vechain/thor/v2/chain"
Expand Down Expand Up @@ -67,18 +69,20 @@ type JSONOutput struct {
}

type JSONEmbeddedTx struct {
ID thor.Bytes32 `json:"id"`
ChainTag byte `json:"chainTag"`
BlockRef string `json:"blockRef"`
Expiration uint32 `json:"expiration"`
Clauses []*JSONClause `json:"clauses"`
GasPriceCoef uint8 `json:"gasPriceCoef"`
Gas uint64 `json:"gas"`
Origin thor.Address `json:"origin"`
Delegator *thor.Address `json:"delegator"`
Nonce math.HexOrDecimal64 `json:"nonce"`
DependsOn *thor.Bytes32 `json:"dependsOn"`
Size uint32 `json:"size"`
ID thor.Bytes32 `json:"id"`
ChainTag byte `json:"chainTag"`
BlockRef string `json:"blockRef"`
Expiration uint32 `json:"expiration"`
Clauses []*JSONClause `json:"clauses"`
GasPriceCoef uint8 `json:"gasPriceCoef"`
MaxFeePerGas *big.Int `json:"maxFeePerGas,omitempty"`
MaxPriorityFeePerGas *big.Int `json:"maxPriorityFeePerGas,omitempty"`
Gas uint64 `json:"gas"`
Origin thor.Address `json:"origin"`
Delegator *thor.Address `json:"delegator"`
Nonce math.HexOrDecimal64 `json:"nonce"`
DependsOn *thor.Bytes32 `json:"dependsOn"`
Size uint32 `json:"size"`

// receipt part
GasUsed uint64 `json:"gasUsed"`
Expand Down Expand Up @@ -148,13 +152,13 @@ func buildJSONOutput(txID thor.Bytes32, index uint32, c *tx.Clause, o *tx.Output

func buildJSONEmbeddedTxs(txs tx.Transactions, receipts tx.Receipts) []*JSONEmbeddedTx {
jTxs := make([]*JSONEmbeddedTx, 0, len(txs))
for itx, tx := range txs {
for itx, trx := range txs {
receipt := receipts[itx]

clauses := tx.Clauses()
blockRef := tx.BlockRef()
origin, _ := tx.Origin()
delegator, _ := tx.Delegator()
clauses := trx.Clauses()
blockRef := trx.BlockRef()
origin, _ := trx.Origin()
delegator, _ := trx.Delegator()

jcs := make([]*JSONClause, 0, len(clauses))
jos := make([]*JSONOutput, 0, len(receipt.Outputs))
Expand All @@ -166,31 +170,37 @@ func buildJSONEmbeddedTxs(txs tx.Transactions, receipts tx.Receipts) []*JSONEmbe
hexutil.Encode(c.Data()),
})
if !receipt.Reverted {
jos = append(jos, buildJSONOutput(tx.ID(), uint32(i), c, receipt.Outputs[i]))
jos = append(jos, buildJSONOutput(trx.ID(), uint32(i), c, receipt.Outputs[i]))
}
}

jTxs = append(jTxs, &JSONEmbeddedTx{
ID: tx.ID(),
ChainTag: tx.ChainTag(),
BlockRef: hexutil.Encode(blockRef[:]),
Expiration: tx.Expiration(),
Clauses: jcs,
GasPriceCoef: tx.GasPriceCoef(),
Gas: tx.Gas(),
Origin: origin,
Delegator: delegator,
Nonce: math.HexOrDecimal64(tx.Nonce()),
DependsOn: tx.DependsOn(),
Size: uint32(tx.Size()),
embedTx := &JSONEmbeddedTx{
ID: trx.ID(),
ChainTag: trx.ChainTag(),
BlockRef: hexutil.Encode(blockRef[:]),
Expiration: trx.Expiration(),
Clauses: jcs,
Gas: trx.Gas(),
Origin: origin,
Delegator: delegator,
Nonce: math.HexOrDecimal64(trx.Nonce()),
DependsOn: trx.DependsOn(),
Size: uint32(trx.Size()),

GasUsed: receipt.GasUsed,
GasPayer: receipt.GasPayer,
Paid: (*math.HexOrDecimal256)(receipt.Paid),
Reward: (*math.HexOrDecimal256)(receipt.Reward),
Reverted: receipt.Reverted,
Outputs: jos,
})
}
if trx.Type() == tx.LegacyTxType {
otherview marked this conversation as resolved.
Show resolved Hide resolved
embedTx.GasPriceCoef = trx.GasPriceCoef()
} else {
embedTx.MaxFeePerGas = trx.MaxFeePerGas()
embedTx.MaxPriorityFeePerGas = trx.MaxPriorityFeePerGas()
}
jTxs = append(jTxs, embedTx)
}
return jTxs
}
25 changes: 20 additions & 5 deletions api/debug/debug_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -541,16 +541,16 @@ func initDebugServer(t *testing.T) {

// Adding an empty clause transaction to the block to cover the case of
// scanning multiple txs before getting the right one
noClausesTx := new(tx.Builder).
noClausesTx := tx.NewTxBuilder(tx.LegacyTxType).
ChainTag(thorChain.Repo().ChainTag()).
Expiration(10).
Gas(21000).
Build()
MustBuild()
noClausesTx = tx.MustSign(noClausesTx, genesis.DevAccounts()[0].PrivateKey)

cla := tx.NewClause(&addr).WithValue(big.NewInt(10000))
cla2 := tx.NewClause(&addr).WithValue(big.NewInt(10000))
transaction = new(tx.Builder).
transaction = tx.NewTxBuilder(tx.LegacyTxType).
ChainTag(thorChain.Repo().ChainTag()).
GasPriceCoef(1).
Expiration(10).
Expand All @@ -559,10 +559,25 @@ func initDebugServer(t *testing.T) {
Clause(cla).
Clause(cla2).
BlockRef(tx.NewBlockRef(0)).
Build()
MustBuild()
transaction = tx.MustSign(transaction, genesis.DevAccounts()[0].PrivateKey)

require.NoError(t, thorChain.MintTransactions(genesis.DevAccounts()[0], transaction, noClausesTx))
dynFeeTx := tx.NewTxBuilder(tx.DynamicFeeTxType).
ChainTag(thorChain.Repo().ChainTag()).
Expiration(10).
Gas(21000).
MaxFeePerGas(big.NewInt(1000)).
MaxPriorityFeePerGas(big.NewInt(100000)).
Nonce(1).
Clause(cla).
BlockRef(tx.NewBlockRef(0)).
MustBuild()
dynFeeTx = tx.MustSign(
dynFeeTx,
genesis.DevAccounts()[0].PrivateKey,
)

require.NoError(t, thorChain.MintTransactions(genesis.DevAccounts()[0], transaction, noClausesTx, dynFeeTx))
require.NoError(t, thorChain.MintTransactions(genesis.DevAccounts()[0]))

allBlocks, err := thorChain.GetAllBlocks()
Expand Down
10 changes: 5 additions & 5 deletions api/subscriptions/block_reader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,26 +64,26 @@ func initChain(t *testing.T) *testchain.Chain {

addr := thor.BytesToAddress([]byte("to"))
cla := tx.NewClause(&addr).WithValue(big.NewInt(10000))
tr := new(tx.Builder).
tr := tx.NewTxBuilder(tx.LegacyTxType).
ChainTag(thorChain.Repo().ChainTag()).
GasPriceCoef(1).
Expiration(10).
Gas(21000).
Nonce(1).
Clause(cla).
BlockRef(tx.NewBlockRef(0)).
Build()
MustBuild()
tr = tx.MustSign(tr, genesis.DevAccounts()[0].PrivateKey)

txDeploy := new(tx.Builder).
txDeploy := tx.NewTxBuilder(tx.DynamicFeeTxType).
ChainTag(thorChain.Repo().ChainTag()).
GasPriceCoef(1).
MaxFeePerGas(big.NewInt(1)).
Expiration(100).
Gas(1_000_000).
Nonce(3).
Clause(tx.NewClause(nil).WithData(common.Hex2Bytes(eventcontract.HexBytecode))).
BlockRef(tx.NewBlockRef(0)).
Build()
MustBuild()
sigTxDeploy, err := crypto.Sign(txDeploy.SigningHash().Bytes(), genesis.DevAccounts()[1].PrivateKey)
require.NoError(t, err)
txDeploy = txDeploy.WithSignature(sigTxDeploy)
Expand Down
45 changes: 23 additions & 22 deletions api/subscriptions/pending_tx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ func TestPendingTx_DispatchLoop(t *testing.T) {
p.Subscribe(txCh)

// Add a new tx to the mempool
transaction := createTx(repo, 0)
transaction := createTx(repo, 0, tx.LegacyTxType)
txPool.AddLocal(transaction)

// Start the dispatch loop
Expand All @@ -113,7 +113,7 @@ func TestPendingTx_DispatchLoop(t *testing.T) {
p.Unsubscribe(txCh)

// Add another tx to the mempool
tx2 := createTx(repo, 1)
tx2 := createTx(repo, 1, tx.DynamicFeeTxType)
txPool.AddLocal(tx2)

// Assert that the channel did not receive the second transaction
Expand Down Expand Up @@ -147,24 +147,6 @@ func addNewBlock(repo *chain.Repository, stater *state.Stater, b0 *block.Block,
}
}

func createTx(repo *chain.Repository, addressNumber uint) *tx.Transaction {
addr := thor.BytesToAddress([]byte("to"))
cla := tx.NewClause(&addr).WithValue(big.NewInt(10000))

return tx.MustSign(
new(tx.Builder).
ChainTag(repo.ChainTag()).
GasPriceCoef(1).
Expiration(1000).
Gas(21000).
Nonce(uint64(datagen.RandInt())).
Clause(cla).
BlockRef(tx.NewBlockRef(0)).
Build(),
genesis.DevAccounts()[addressNumber].PrivateKey,
)
}

func TestPendingTx_NoWriteAfterUnsubscribe(t *testing.T) {
// Arrange
thorChain := initChain(t)
Expand All @@ -183,7 +165,7 @@ func TestPendingTx_NoWriteAfterUnsubscribe(t *testing.T) {

done := make(chan struct{})
// Attempt to write a new transaction
trx := createTx(thorChain.Repo(), 0)
trx := createTx(thorChain.Repo(), 0, tx.LegacyTxType)
assert.NotPanics(t, func() {
p.dispatch(trx, done) // dispatch should not panic after unsubscribe
}, "Dispatching after unsubscribe should not panic")
Expand Down Expand Up @@ -221,7 +203,7 @@ func TestPendingTx_UnsubscribeOnWebSocketClose(t *testing.T) {
defer ws.Close()

// Add a transaction
trx := createTx(thorChain.Repo(), 0)
trx := createTx(thorChain.Repo(), 0, tx.LegacyTxType)
txPool.AddLocal(trx)

// Wait to receive transaction
Expand All @@ -242,3 +224,22 @@ func TestPendingTx_UnsubscribeOnWebSocketClose(t *testing.T) {
require.Equal(t, len(sub.pendingTx.listeners), 0)
sub.pendingTx.mu.Unlock()
}

func createTx(repo *chain.Repository, addressNumber uint, txType int) *tx.Transaction {
addr := thor.BytesToAddress([]byte("to"))
cla := tx.NewClause(&addr).WithValue(big.NewInt(10000))

trx := tx.NewTxBuilder(txType).
ChainTag(repo.ChainTag()).
GasPriceCoef(1).
Expiration(1000).
Gas(21000).
Nonce(uint64(datagen.RandInt())).
Clause(cla).
BlockRef(tx.NewBlockRef(0)).
MustBuild()
return tx.MustSign(
trx,
genesis.DevAccounts()[addressNumber].PrivateKey,
)
}
Loading
Loading