Skip to content

Commit

Permalink
processing txs
Browse files Browse the repository at this point in the history
  • Loading branch information
otherview committed Nov 22, 2024
1 parent a277482 commit 9189474
Show file tree
Hide file tree
Showing 2 changed files with 162 additions and 26 deletions.
187 changes: 161 additions & 26 deletions cmd/thor/node/node_benchmark_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,24 @@ package node

import (
"crypto/ecdsa"
"fmt"
"github.com/ethereum/go-ethereum/crypto"
"github.com/stretchr/testify/require"
"github.com/vechain/thor/v2/bft"
"github.com/vechain/thor/v2/block"
"github.com/vechain/thor/v2/chain"
"github.com/vechain/thor/v2/genesis"
"github.com/vechain/thor/v2/runtime"
"github.com/vechain/thor/v2/state"
"github.com/vechain/thor/v2/test/datagen"
"github.com/vechain/thor/v2/test/testchain"
"github.com/vechain/thor/v2/thor"
"github.com/vechain/thor/v2/trie"
"github.com/vechain/thor/v2/tx"
"github.com/vechain/thor/v2/vrf"
"github.com/vechain/thor/v2/xenv"
"math"
"math/big"
"testing"
)

Expand Down Expand Up @@ -42,10 +50,10 @@ func BenchmarkProcessBlock(b *testing.B) {
stater,
nil, // logDB (optional)
nil,
"", // txStashPath
nil, // communicator
1000000, // targetGasLimit
true, // skipLogs
"", // txStashPath
nil, // communicator
10_000_000, // targetGasLimit
true, // skipLogs
forkConfig,
)

Expand All @@ -55,40 +63,87 @@ func BenchmarkProcessBlock(b *testing.B) {
stats := &blockStats{}

// Helper function to create sequential blocks
createMockBlock := func(parentBlock *block.Block, txCount int, gasUsed uint64) *block.Block {
builder := &block.Builder{}
builder.ParentID(parentBlock.Header().ID())
builder.Timestamp(parentBlock.Header().Timestamp() + 100)
builder.GasLimit(10_000_000)
builder.TotalScore(parentBlock.Header().TotalScore() + 1)
builder.GasUsed(gasUsed)
builder.TransactionFeatures(1)
builder.ReceiptsRoot(tx.Receipts{}.RootHash())

// sending money to random account expands the trie leaves
// ( ooc the trie accounts leaves have the contract storage inside of them)
root := trie.Root{
Hash: parentBlock.Header().StateRoot(),
createMockBlock := func(parentBlock *block.Block, currentChain *testchain.Chain) *block.Block {
executionChain := currentChain.Repo().NewBestChain()
fmt.Println(currentChain.Repo().BestBlockSummary().Header.ID().String())
executionStater := currentChain.Stater()
executionState := executionStater.NewState(trie.Root{
Hash: previousBlock.Header().StateRoot(),
Ver: trie.Version{
Major: parentBlock.Header().Number(),
Major: previousBlock.Header().Number(),
Minor: 0,
},
})
execEngine := newExecutionEngine(currentChain, parentBlock, executionChain, executionState)

builder := new(block.Builder)

var receipts tx.Receipts
gasUsed := uint64(0)
for gasUsed < 9_500_000 {
toAddr := datagen.RandAddress()
cla := tx.NewClause(&toAddr).WithValue(big.NewInt(10000))
transaction := new(tx.Builder).
ChainTag(currentChain.Repo().ChainTag()).
GasPriceCoef(1).
Expiration(math.MaxUint32 - 1).
Gas(21_000).
Nonce(uint64(datagen.RandInt())).
Clause(cla).
BlockRef(tx.NewBlockRef(0)).
Build()

sig, err := crypto.Sign(transaction.SigningHash().Bytes(), genesis.DevAccounts()[0].PrivateKey)
require.NoError(b, err)
transaction = transaction.WithSignature(sig)
builder.Transaction(transaction)

// calculate the receipt hash root
receipt, err := execEngine.rt.ExecuteTransaction(transaction)
require.NoError(b, err)
receipts = append(receipts, receipt)

gasUsed += 21_000 // Gas per transaction
}

prevblockRoot := trie.Root{
Hash: previousBlock.Header().StateRoot(),
Ver: trie.Version{
Major: previousBlock.Header().Number(),
Minor: 0,
},
}
stage, err := thorChain.Stater().NewState(root).Stage(trie.Version{Major: parentBlock.Header().Number(), Minor: 0})
fmt.Println("PrevBlock StateRoot: ", prevblockRoot.Hash.String())

stage, err := executionState.Stage(trie.Version{Major: parentBlock.Header().Number() + 1, Minor: 0})
require.NoError(b, err)
stateRoot, err := stage.Commit()
fmt.Println("Mocked StateRoot: ", stateRoot.String())
require.NoError(b, err)

stateRoot := stage.Hash()
builder.StateRoot(stateRoot)
builder.ParentID(parentBlock.Header().ID()).
Timestamp(parentBlock.Header().Timestamp() + 100).
GasLimit(10_000_000).
TotalScore(parentBlock.Header().TotalScore() + 1).
TransactionFeatures(1).
GasUsed(gasUsed).
ReceiptsRoot(receipts.RootHash()).
StateRoot(stateRoot)

blk, err := signWithKey(parentBlock, builder, privateKey, forkConfig)
blk, err := signWithKeyAndBuild(parentBlock, builder, privateKey, forkConfig)
require.NoError(b, err)

require.NoError(b, currentChain.Repo().AddBlock(blk, receipts, 0, true))
return blk
}

// pre-alloc blocks
var blocks []*block.Block
for i := 0; i < 10_000; i++ {
mockBlock := createMockBlock(previousBlock, 100, 0) // 100 transactions, 500,000 gas used
currentChain, err := testchain.NewIntegrationTestChain()
require.NoError(b, err)

for i := 0; i < 10; i++ {
mockBlock := createMockBlock(previousBlock, currentChain)
blocks = append(blocks, mockBlock)
previousBlock = mockBlock
}
Expand All @@ -106,7 +161,7 @@ func BenchmarkProcessBlock(b *testing.B) {
}
}

func signWithKey(parentBlk *block.Block, builder *block.Builder, pk *ecdsa.PrivateKey, forkConfig thor.ForkConfig) (*block.Block, error) {
func signWithKeyAndBuild(parentBlk *block.Block, builder *block.Builder, pk *ecdsa.PrivateKey, forkConfig thor.ForkConfig) (*block.Block, error) {
h := builder.Build().Header()

if h.Number() >= forkConfig.VIP214 {
Expand Down Expand Up @@ -148,3 +203,83 @@ func signWithKey(parentBlk *block.Block, builder *block.Builder, pk *ecdsa.Priva
return blk.WithSignature(sig), nil
}
}

type executionEngined struct {
rt *runtime.Runtime
}

func newExecutionEngine(
thorChain *testchain.Chain,
parentBlk *block.Block,
executionChain *chain.Chain,
executionState *state.State,
) *executionEngined {
signer, err := parentBlk.Header().Signer()
if err != nil {
panic(err)
}
return &executionEngined{
rt: runtime.New(
executionChain,
executionState,
&xenv.BlockContext{
Beneficiary: parentBlk.Header().Beneficiary(),
Signer: signer,
Number: parentBlk.Header().Number(),
Time: parentBlk.Header().Timestamp(),
GasLimit: parentBlk.Header().GasLimit(),
TotalScore: parentBlk.Header().TotalScore(),
},
thorChain.GetForkConfig()),
}
}

//func BuildBlock(stater *state.Stater) (blk *block.Block, events tx.Events, transfers tx.Transfers, err error) {
// state := stater.NewState(trie.Root{})
//
// for _, proc := range b.stateProcs {
// if err := proc(state); err != nil {
// return nil, nil, nil, errors.Wrap(err, "state process")
// }
// }
//
// rt := runtime.New(nil, state, &xenv.BlockContext{
// Time: b.timestamp,
// GasLimit: b.gasLimit,
// }, b.forkConfig)
//
// for _, call := range b.calls {
// exec, _ := rt.PrepareClause(call.clause, 0, math.MaxUint64, &xenv.TransactionContext{
// Origin: call.caller,
// })
// out, _, err := exec()
// if err != nil {
// return nil, nil, nil, errors.Wrap(err, "call")
// }
// if out.VMErr != nil {
// return nil, nil, nil, errors.Wrap(out.VMErr, "vm")
// }
// events = append(events, out.Events...)
// transfers = append(transfers, out.Transfers...)
// }
//
// stage, err := state.Stage(trie.Version{})
// if err != nil {
// return nil, nil, nil, errors.Wrap(err, "stage")
// }
// stateRoot, err := stage.Commit()
// if err != nil {
// return nil, nil, nil, errors.Wrap(err, "commit state")
// }
//
// parentID := thor.Bytes32{0xff, 0xff, 0xff, 0xff} //so, genesis number is 0
// copy(parentID[4:], b.extraData[:])
//
// return new(block.Builder).
// ParentID(parentID).
// Timestamp(b.timestamp).
// GasLimit(b.gasLimit).
// StateRoot(stateRoot).
// ReceiptsRoot(tx.Transactions(nil).RootHash()).
// Build(), events, transfers, nil
//}
1 change: 1 addition & 0 deletions consensus/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ func New(repo *chain.Repository, stater *state.Stater, forkConfig thor.ForkConfi
func (c *Consensus) Process(parentSummary *chain.BlockSummary, blk *block.Block, nowTimestamp uint64, blockConflicts uint32) (*state.Stage, tx.Receipts, error) {
header := blk.Header()
state := c.stater.NewState(parentSummary.Root())
fmt.Println("Consensus StateRoot: ", parentSummary.Root().Hash.String())

var features tx.Features
if header.Number() >= c.forkConfig.VIP191 {
Expand Down

0 comments on commit 9189474

Please sign in to comment.