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

Introducing base fee + hard fork logic #933

Merged
merged 32 commits into from
Jan 30, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
2e97a1a
feat: add the dynamic fee tx and support for typed txs
paologalligit Nov 29, 2024
47ce11b
test: add tests for txpool and logdb
paologalligit Dec 2, 2024
492ac99
refactor: split builder into legacy and dynFee builder
paologalligit Dec 3, 2024
297cb4e
test: add more tests including dynamic fee txs
paologalligit Dec 5, 2024
985417c
test: add tests for legacy and dynamic tx builder
paologalligit Dec 5, 2024
18f6cad
test: add more dynFee txs to tests
paologalligit Dec 18, 2024
8be755e
refactor: merge tx builder into one builder
paologalligit Jan 9, 2025
c183504
refactor: add MustBuild to tx builder and fix error
paologalligit Jan 23, 2025
edcfcd7
refactor: move hashWithoutNonce to concrete tx implementation
paologalligit Jan 23, 2025
3658676
feat: add the dynamic fee tx and support for typed txs
paologalligit Nov 29, 2024
620e4e2
feat: add baseFee to header struct
paologalligit Dec 6, 2024
e15a48f
test: add more header tests
paologalligit Dec 9, 2024
e8b2745
fix: replace header type in baseFee calc
paologalligit Dec 12, 2024
7b42d92
refactor: use the extension struct to include the baseFee instead of …
paologalligit Dec 16, 2024
13ca58e
feat: add galactica fork
paologalligit Dec 17, 2024
9af7b02
feat: add header check for galactica fork
paologalligit Dec 17, 2024
d539df7
feat: add checks for new galactica header
paologalligit Dec 18, 2024
5f626ca
clean
paologalligit Jan 3, 2025
a882555
test: add baseFee tests with consecutive empty and full blocks
paologalligit Jan 3, 2025
0dd1585
fix: revert go.mod
paologalligit Jan 7, 2025
92e0cd3
fix: clean code
paologalligit Jan 7, 2025
f7cf6dc
feat: include baseFee when Galactica fork enebled + tests
paologalligit Jan 7, 2025
458dab6
style: fix lowercase
paologalligit Jan 8, 2025
0f6c4f7
test: fix test
paologalligit Jan 10, 2025
0baeeb0
test: add validate block tests
paologalligit Jan 14, 2025
12d81ae
fix: go.mod file
paologalligit Jan 14, 2025
57860c9
fix: base fee tests
paologalligit Jan 15, 2025
422defb
tests: add more dyn fee tx tests
paologalligit Jan 24, 2025
6790e11
fix: rebase conflicts
paologalligit Jan 24, 2025
47454ff
fix: remove check on gas limit block header before galactica
paologalligit Jan 24, 2025
4617f3b
fixes as per review
paologalligit Jan 29, 2025
83d5be9
test: refactor block builder test
paologalligit Jan 29, 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
1 change: 1 addition & 0 deletions api/accounts/accounts.go
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@ func (a *Accounts) batchCall(
Time: header.Timestamp(),
GasLimit: header.GasLimit(),
TotalScore: header.TotalScore(),
BaseFee: header.BaseFee(),
},
a.forkConfig)
results = make(BatchCallResults, 0)
Expand Down
2 changes: 2 additions & 0 deletions api/blocks/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ type JSONBlockSummary struct {
Signer thor.Address `json:"signer"`
IsTrunk bool `json:"isTrunk"`
IsFinalized bool `json:"isFinalized"`
BaseFee *big.Int `json:"baseFee,omitempty"`
}

type JSONRawBlockSummary struct {
Expand Down Expand Up @@ -120,6 +121,7 @@ func buildJSONBlockSummary(summary *chain.BlockSummary, isTrunk bool, isFinalize
COM: header.COM(),
IsTrunk: isTrunk,
IsFinalized: isFinalized,
BaseFee: summary.Header.BaseFee(),
}
}

Expand Down
1 change: 1 addition & 0 deletions api/debug/debug.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@ func (d *Debug) traceCall(ctx context.Context, tracer tracers.Tracer, header *bl
Time: header.Timestamp(),
GasLimit: header.GasLimit(),
TotalScore: header.TotalScore(),
BaseFee: header.BaseFee(),
},
d.forkConfig)

Expand Down
120 changes: 81 additions & 39 deletions api/transactions/transactions_benchmark_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,13 @@ import (
)

var (
cachedAccounts []genesis.DevAccount
once sync.Once
blockCount = 1_000
cachedAccounts []genesis.DevAccount
once sync.Once
blockCount = 1_000
createManyTxFuncs = []func(signerPK *ecdsa.PrivateKey, thorChain *testchain.Chain) (tx.Transactions, error){
createManyClausesPerTxLegacy,
createManyClausesPerTxDynFee,
}
)

func getCachedAccounts(b *testing.B) []genesis.DevAccount {
Expand All @@ -56,28 +60,29 @@ func BenchmarkFetchTx_RealDB_RandomSigners_ManyClausesPerTx(b *testing.B) {
// create state accounts
accounts := getCachedAccounts(b)

// randomly pick a signer for signing the transactions
randomSignerFunc := randomPickSignerFunc(accounts, createManyClausesPerTx)
for _, createManyClausesPerTx := range createManyTxFuncs { // randomly pick a signer for signing the transactions
randomSignerFunc := randomPickSignerFunc(accounts, createManyClausesPerTx)

// create test db - will be automagically removed when the benchmark ends
db, err := openTempMainDB(b.TempDir())
require.NoError(b, err)
// create test db - will be automagically removed when the benchmark ends
db, err := openTempMainDB(b.TempDir())
require.NoError(b, err)

// create blocks
newChain, transactions := createPackedChain(b, db, blockCount, accounts, randomSignerFunc)
// create blocks
newChain, transactions := createPackedChain(b, db, blockCount, accounts, randomSignerFunc)

// shuffle the transaction into a randomized order
randomizedTransactions := shuffleSlice(transactions)
b.Logf("About to process %d txs", len(randomizedTransactions))
// shuffle the transaction into a randomized order
randomizedTransactions := shuffleSlice(transactions)
b.Logf("About to process %d txs", len(randomizedTransactions))

// run the benchmarks
b.Run("getTransaction", func(b *testing.B) {
benchmarkGetTransaction(b, newChain, randomizedTransactions)
})
// run the benchmarks
b.Run("getTransaction", func(b *testing.B) {
benchmarkGetTransaction(b, newChain, randomizedTransactions)
})

b.Run("getReceipt", func(b *testing.B) {
benchmarkGetReceipt(b, newChain, randomizedTransactions)
})
b.Run("getReceipt", func(b *testing.B) {
benchmarkGetReceipt(b, newChain, randomizedTransactions)
})
}
}

func BenchmarkFetchTx_RealDB_RandomSigners_OneClausePerTx(b *testing.B) {
Expand Down Expand Up @@ -109,27 +114,27 @@ func BenchmarkFetchTx_RealDB_RandomSigners_OneClausePerTx(b *testing.B) {
}

func BenchmarkFetchTx_RandomSigners_ManyClausesPerTx(b *testing.B) {
// create state accounts
accounts := getCachedAccounts(b)
for _, createManyClausesPerTx := range createManyTxFuncs { // create state accounts
accounts := getCachedAccounts(b)
// randomly pick a signer for signing the transactions
randomSignerFunc := randomPickSignerFunc(accounts, createManyClausesPerTx)

// randomly pick a signer for signing the transactions
randomSignerFunc := randomPickSignerFunc(accounts, createManyClausesPerTx)
// create blocks
newChain, transactions := createPackedChain(b, muxdb.NewMem(), blockCount, accounts, randomSignerFunc)

// create blocks
newChain, transactions := createPackedChain(b, muxdb.NewMem(), blockCount, accounts, randomSignerFunc)
// shuffle the transaction into a randomized order
randomizedTransactions := shuffleSlice(transactions)
b.Logf("About to process %d txs", len(randomizedTransactions))

// shuffle the transaction into a randomized order
randomizedTransactions := shuffleSlice(transactions)
b.Logf("About to process %d txs", len(randomizedTransactions))

// run the benchmarks
b.Run("getTransaction", func(b *testing.B) {
benchmarkGetTransaction(b, newChain, randomizedTransactions)
})
// run the benchmarks
b.Run("getTransaction", func(b *testing.B) {
benchmarkGetTransaction(b, newChain, randomizedTransactions)
})

b.Run("getReceipt", func(b *testing.B) {
benchmarkGetReceipt(b, newChain, randomizedTransactions)
})
b.Run("getReceipt", func(b *testing.B) {
benchmarkGetReceipt(b, newChain, randomizedTransactions)
})
}
}

func BenchmarkFetchTx_RandomSigners_OneClausePerTx(b *testing.B) {
Expand Down Expand Up @@ -233,9 +238,15 @@ func createOneClausePerTx(signerPK *ecdsa.PrivateKey, thorChain *testchain.Chain
for gasUsed < 9_500_000 {
toAddr := datagen.RandAddress()
cla := tx.NewClause(&toAddr).WithValue(big.NewInt(10000))
transaction := tx.NewTxBuilder(tx.LegacyTxType).
b := tx.NewTxBuilder(tx.LegacyTxType)
if gasUsed%2 == 0 {
b = tx.NewTxBuilder(tx.DynamicFeeTxType)
}
transaction := b.
ChainTag(thorChain.Repo().ChainTag()).
GasPriceCoef(1).
MaxFeePerGas(big.NewInt(1000000)).
MaxPriorityFeePerGas(big.NewInt(100)).
Expiration(math.MaxUint32 - 1).
Gas(21_000).
Nonce(uint64(datagen.RandInt())).
Expand All @@ -255,7 +266,7 @@ func createOneClausePerTx(signerPK *ecdsa.PrivateKey, thorChain *testchain.Chain
return transactions, nil
}

func createManyClausesPerTx(signerPK *ecdsa.PrivateKey, thorChain *testchain.Chain) (tx.Transactions, error) {
func createManyClausesPerTxLegacy(signerPK *ecdsa.PrivateKey, thorChain *testchain.Chain) (tx.Transactions, error) {
var transactions tx.Transactions
gasUsed := uint64(0)
txGas := uint64(42_000)
Expand Down Expand Up @@ -285,6 +296,37 @@ func createManyClausesPerTx(signerPK *ecdsa.PrivateKey, thorChain *testchain.Cha
return transactions, nil
}

func createManyClausesPerTxDynFee(signerPK *ecdsa.PrivateKey, thorChain *testchain.Chain) (tx.Transactions, error) {
var transactions tx.Transactions
gasUsed := uint64(0)
txGas := uint64(42_000)

transactionBuilder := tx.NewTxBuilder(tx.DynamicFeeTxType).
ChainTag(thorChain.Repo().ChainTag()).
MaxFeePerGas(big.NewInt(1000000)).
MaxPriorityFeePerGas(big.NewInt(100)).
Expiration(math.MaxUint32 - 1).
Nonce(uint64(datagen.RandInt())).
BlockRef(tx.NewBlockRef(0))

for ; gasUsed < 9_500_000; gasUsed += txGas {
toAddr := datagen.RandAddress()
transactionBuilder.Clause(tx.NewClause(&toAddr).WithValue(big.NewInt(10000)))
}

transaction := transactionBuilder.Gas(gasUsed).MustBuild()

sig, err := crypto.Sign(transaction.SigningHash().Bytes(), signerPK)
if err != nil {
return nil, err
}
transaction = transaction.WithSignature(sig)

transactions = append(transactions, transaction)

return transactions, nil
}

func packTxsIntoBlock(thorChain *testchain.Chain, proposerAccount *genesis.DevAccount, parentBlk *block.Block, transactions tx.Transactions) (*block.Block, error) {
p := packer.New(thorChain.Repo(), thorChain.Stater(), proposerAccount.Address, &proposerAccount.Address, thorChain.GetForkConfig())

Expand Down
8 changes: 8 additions & 0 deletions block/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
package block

import (
"math/big"

"github.com/vechain/thor/v2/thor"
"github.com/vechain/thor/v2/tx"
)
Expand Down Expand Up @@ -88,6 +90,12 @@ func (b *Builder) COM() *Builder {
return b
}

// BaseFee sets base fee.
func (b *Builder) BaseFee(baseFee *big.Int) *Builder {
b.headerBody.Extension.BaseFee = baseFee
return b
}

// Build build a block object.
func (b *Builder) Build() *Block {
header := Header{body: b.headerBody}
Expand Down
71 changes: 71 additions & 0 deletions block/builder_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// Copyright (c) 2024 The VeChainThor developers

// Distributed under the GNU Lesser General Public License v3.0 software license, see the accompanying
// file LICENSE or <https://www.gnu.org/licenses/lgpl-3.0.html>

package block

import (
"math/big"
"testing"

"github.com/stretchr/testify/assert"
"github.com/vechain/thor/v2/thor"
"github.com/vechain/thor/v2/tx"
)

func TestBuilder_Build(t *testing.T) {
builder := &Builder{}

id := thor.Bytes32{1, 2, 3}
builder.ParentID(id)

ts := uint64(1234567890)
builder.Timestamp(ts)

score := uint64(100)
builder.TotalScore(score)

limit := uint64(5000)
builder.GasLimit(limit)

used := uint64(3000)
builder.GasUsed(used)

addr := thor.Address{1, 2, 3}
builder.Beneficiary(addr)

hash := thor.Bytes32{1, 2, 3}
builder.StateRoot(hash)

builder.ReceiptsRoot(hash)
tr := tx.NewTxBuilder(tx.LegacyTxType).MustBuild()

builder.Transaction(tr)
features := tx.Features(0x01)

builder.TransactionFeatures(features)
alpha := []byte{1, 2, 3}

builder.Alpha(alpha)
builder.COM()

baseFee := big.NewInt(1000)
builder.BaseFee(baseFee)

b := builder.Build()

assert.Equal(t, id, b.header.ParentID())
assert.Equal(t, ts, b.header.Timestamp())
assert.Equal(t, score, b.header.TotalScore())
assert.Equal(t, limit, b.header.GasLimit())
assert.Equal(t, used, b.header.GasUsed())
assert.Equal(t, addr, b.header.Beneficiary())
assert.Equal(t, hash, b.header.StateRoot())
assert.Equal(t, hash, b.header.ReceiptsRoot())
assert.Contains(t, b.Transactions(), tr)
assert.Equal(t, features, b.header.TxsFeatures())
assert.Equal(t, alpha, b.header.Alpha())
assert.True(t, b.header.COM())
assert.Equal(t, baseFee, b.header.BaseFee())
}
Loading
Loading