Skip to content

Commit

Permalink
feat: update base gas price on solo (#722)
Browse files Browse the repository at this point in the history
* feat: update base gas price on solo

* minor update

* fix: base gas price

* add test and panic on error

* refactor: resolve PR comments

* update error message

* add license header

* fix: force pack block & update logs
  • Loading branch information
darrenvechain authored May 13, 2024
1 parent 4fa7366 commit caf4f36
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 3 deletions.
75 changes: 72 additions & 3 deletions cmd/thor/solo/solo.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,18 @@ package solo
import (
"context"
"fmt"
"math/big"
"math/rand"
"time"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/common/mclock"
"github.com/ethereum/go-ethereum/crypto"
"github.com/inconshreveable/log15"
"github.com/pkg/errors"
"github.com/vechain/thor/v2/block"
"github.com/vechain/thor/v2/builtin"
"github.com/vechain/thor/v2/chain"
"github.com/vechain/thor/v2/cmd/thor/bandwidth"
"github.com/vechain/thor/v2/co"
Expand All @@ -27,11 +32,15 @@ import (
"github.com/vechain/thor/v2/txpool"
)

var log = log15.New("pkg", "solo")
var (
log = log15.New("pkg", "solo")
baseGasPrice = big.NewInt(1e13)
)

// Solo mode is the standalone client without p2p server
type Solo struct {
repo *chain.Repository
stater *state.Stater
txPool *txpool.TxPool
packer *packer.Packer
logDB *logdb.LogDB
Expand All @@ -54,6 +63,7 @@ func New(
) *Solo {
return &Solo{
repo: repo,
stater: stater,
txPool: txPool,
packer: packer.New(
repo,
Expand All @@ -77,12 +87,16 @@ func (s *Solo) Run(ctx context.Context) error {
goes.Wait()
}()

log.Info("prepared to pack block")

if err := s.init(); err != nil {
return err
}

goes.Go(func() {
s.loop(ctx)
})

log.Info("prepared to pack block")

return nil
}

Expand Down Expand Up @@ -196,3 +210,58 @@ func (s *Solo) packing(pendingTxs tx.Transactions, onDemand bool) error {

return nil
}

// The init function initializes the chain parameters.
func (s *Solo) init() error {
best := s.repo.BestBlockSummary()
newState := s.stater.NewState(best.Header.StateRoot(), best.Header.Number(), best.Conflicts, best.SteadyNum)
currentBGP, err := builtin.Params.Native(newState).Get(thor.KeyBaseGasPrice)
if err != nil {
return errors.WithMessage(err, "failed to get the current base gas price")
}
if currentBGP == baseGasPrice {
return nil
}

method, found := builtin.Params.ABI.MethodByName("set")
if !found {
return errors.New("Params ABI: set method not found")
}

data, err := method.EncodeInput(thor.KeyBaseGasPrice, baseGasPrice)
if err != nil {
return err
}

clause := tx.NewClause(&builtin.Params.Address).WithData(data)
baseGasePriceTx, err := s.newTx([]*tx.Clause{clause}, genesis.DevAccounts()[0])
if err != nil {
return err
}

if !s.onDemand {
// wait for the next block interval if not on-demand
time.Sleep(time.Duration(10-time.Now().Unix()%10) * time.Second)
}

return s.packing(tx.Transactions{baseGasePriceTx}, false)
}

// newTx builds and signs a new transaction from the given clauses
func (s *Solo) newTx(clauses []*tx.Clause, from genesis.DevAccount) (*tx.Transaction, error) {
builder := new(tx.Builder).ChainTag(s.repo.ChainTag())
for _, c := range clauses {
builder.Clause(c)
}

newTx := builder.BlockRef(tx.NewBlockRef(0)).
Expiration(math.MaxUint32).
Nonce(rand.Uint64()).
DependsOn(nil).
Gas(1_000_000).
Build()

sig, err := crypto.Sign(newTx.SigningHash().Bytes(), from.PrivateKey)

return newTx.WithSignature(sig), err
}
48 changes: 48 additions & 0 deletions cmd/thor/solo/solo_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// 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 solo

import (
"testing"
"time"

"github.com/stretchr/testify/assert"
"github.com/vechain/thor/v2/builtin"
"github.com/vechain/thor/v2/chain"
"github.com/vechain/thor/v2/genesis"
"github.com/vechain/thor/v2/logdb"
"github.com/vechain/thor/v2/muxdb"
"github.com/vechain/thor/v2/state"
"github.com/vechain/thor/v2/thor"
"github.com/vechain/thor/v2/txpool"
)

func newSolo() *Solo {
db := muxdb.NewMem()
stater := state.NewStater(db)
gene := genesis.NewDevnet()
logDb, _ := logdb.NewMem()
b, _, _, _ := gene.Build(stater)
repo, _ := chain.NewRepository(db, b)
mempool := txpool.New(repo, stater, txpool.Options{Limit: 10000, LimitPerAccount: 16, MaxLifetime: 10 * time.Minute})

return New(repo, stater, logDb, mempool, 0, true, false, thor.ForkConfig{})
}

func TestInitSolo(t *testing.T) {
solo := newSolo()

// init solo -> this should mine a block with the gas price tx
err := solo.init()
assert.Nil(t, err)

// check the gas price
best := solo.repo.BestBlockSummary()
newState := solo.stater.NewState(best.Header.StateRoot(), best.Header.Number(), best.Conflicts, best.SteadyNum)
currentBGP, err := builtin.Params.Native(newState).Get(thor.KeyBaseGasPrice)
assert.Nil(t, err)
assert.Equal(t, baseGasPrice, currentBGP)
}

0 comments on commit caf4f36

Please sign in to comment.