mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-27 23:26:44 +00:00
london fork (#260)
* london fork changes * Update version.go * burn contract address
This commit is contained in:
parent
8dd6f59bbc
commit
7115b84b7a
8 changed files with 396 additions and 31 deletions
4
Makefile
4
Makefile
|
|
@ -50,8 +50,8 @@ ios:
|
|||
|
||||
test: all
|
||||
# $(GORUN) build/ci.go test
|
||||
go test github.com/ethereum/go-ethereum/consensus/bor
|
||||
go test github.com/ethereum/go-ethereum/tests/bor
|
||||
go test github.com/ethereum/go-ethereum/consensus/bor -v
|
||||
go test github.com/ethereum/go-ethereum/tests/bor -v
|
||||
|
||||
lint: ## Run linters.
|
||||
$(GORUN) build/ci.go lint
|
||||
|
|
|
|||
|
|
@ -182,12 +182,12 @@ func encodeSigHeader(w io.Writer, header *types.Header) {
|
|||
func CalcProducerDelay(number uint64, succession int, c *params.BorConfig) uint64 {
|
||||
// When the block is the first block of the sprint, it is expected to be delayed by `producerDelay`.
|
||||
// That is to allow time for block propagation in the last sprint
|
||||
delay := c.Period
|
||||
delay := c.CalculatePeriod(number)
|
||||
if number%c.Sprint == 0 {
|
||||
delay = c.ProducerDelay
|
||||
}
|
||||
if succession > 0 {
|
||||
delay += uint64(succession) * c.BackupMultiplier
|
||||
delay += uint64(succession) * c.CalculateBackupMultiplier(number)
|
||||
}
|
||||
return delay
|
||||
}
|
||||
|
|
@ -353,6 +353,11 @@ func (c *Bor) verifyHeader(chain consensus.ChainHeaderReader, header *types.Head
|
|||
return errInvalidDifficulty
|
||||
}
|
||||
}
|
||||
// Verify that the gas limit is <= 2^63-1
|
||||
cap := uint64(0x7fffffffffffffff)
|
||||
if header.GasLimit > cap {
|
||||
return fmt.Errorf("invalid gasLimit: have %v, max %v", header.GasLimit, cap)
|
||||
}
|
||||
// If all checks passed, validate any special fields for hard forks
|
||||
if err := misc.VerifyForkHashes(chain.Config(), header, false); err != nil {
|
||||
return err
|
||||
|
|
@ -396,7 +401,24 @@ func (c *Bor) verifyCascadingFields(chain consensus.ChainHeaderReader, header *t
|
|||
return consensus.ErrUnknownAncestor
|
||||
}
|
||||
|
||||
if parent.Time+c.config.Period > header.Time {
|
||||
// Verify that the gasUsed is <= gasLimit
|
||||
if header.GasUsed > header.GasLimit {
|
||||
return fmt.Errorf("invalid gasUsed: have %d, gasLimit %d", header.GasUsed, header.GasLimit)
|
||||
}
|
||||
if !chain.Config().IsLondon(header.Number) {
|
||||
// Verify BaseFee not present before EIP-1559 fork.
|
||||
if header.BaseFee != nil {
|
||||
return fmt.Errorf("invalid baseFee before fork: have %d, want <nil>", header.BaseFee)
|
||||
}
|
||||
if err := misc.VerifyGaslimit(parent.GasLimit, header.GasLimit); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if err := misc.VerifyEip1559Header(chain.Config(), parent, header); err != nil {
|
||||
// Verify the header's EIP-1559 attributes.
|
||||
return err
|
||||
}
|
||||
|
||||
if parent.Time+c.config.CalculatePeriod(number) > header.Time {
|
||||
return ErrInvalidTimestamp
|
||||
}
|
||||
|
||||
|
|
@ -791,7 +813,7 @@ func (c *Bor) Seal(chain consensus.ChainHeaderReader, block *types.Block, result
|
|||
return errUnknownBlock
|
||||
}
|
||||
// For 0-period chains, refuse to seal empty blocks (no reward but would spin sealing)
|
||||
if c.config.Period == 0 && len(block.Transactions()) == 0 {
|
||||
if c.config.CalculatePeriod(number) == 0 && len(block.Transactions()) == 0 {
|
||||
log.Info("Sealing paused, waiting for transactions")
|
||||
return nil
|
||||
}
|
||||
|
|
@ -819,7 +841,7 @@ func (c *Bor) Seal(chain consensus.ChainHeaderReader, block *types.Block, result
|
|||
// Sweet, the protocol permits us to sign the block, wait for our time
|
||||
delay := time.Unix(int64(header.Time), 0).Sub(time.Now()) // nolint: gosimple
|
||||
// wiggle was already accounted for in header.Time, this is just for logging
|
||||
wiggle := time.Duration(successionNumber) * time.Duration(c.config.BackupMultiplier) * time.Second
|
||||
wiggle := time.Duration(successionNumber) * time.Duration(c.config.CalculateBackupMultiplier(number)) * time.Second
|
||||
|
||||
// Sign all the things!
|
||||
sighash, err := signFn(accounts.Account{Address: signer}, accounts.MimetypeBor, BorRLP(header))
|
||||
|
|
|
|||
|
|
@ -337,6 +337,11 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
|
|||
effectiveTip = cmath.BigMin(st.gasTipCap, new(big.Int).Sub(st.gasFeeCap, st.evm.Context.BaseFee))
|
||||
}
|
||||
amount := new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed()), effectiveTip)
|
||||
if london {
|
||||
burntContractAddress := common.HexToAddress(st.evm.ChainConfig().Bor.CalculateBurntContract(st.evm.Context.BlockNumber.Uint64()))
|
||||
burnAmount := new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed()), st.evm.Context.BaseFee)
|
||||
st.state.AddBalance(burntContractAddress, burnAmount)
|
||||
}
|
||||
st.state.AddBalance(st.evm.Context.Coinbase, amount)
|
||||
output1 := new(big.Int).SetBytes(input1.Bytes())
|
||||
output2 := new(big.Int).SetBytes(input2.Bytes())
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ func (s *PublicBlockChainAPI) appendRPCMarshalBorTransaction(ctx context.Context
|
|||
if borTx != nil {
|
||||
formattedTxs := fields["transactions"].([]interface{})
|
||||
if fullTx {
|
||||
marshalledTx := newRPCTransaction(borTx, blockHash, blockNumber, txIndex, nil, s.b.ChainConfig())
|
||||
marshalledTx := newRPCTransaction(borTx, blockHash, blockNumber, txIndex, block.BaseFee(), s.b.ChainConfig())
|
||||
// newRPCTransaction calculates hash based on RLP of the transaction data.
|
||||
// In case of bor block tx, we need simple derived tx hash (same as function argument) instead of RLP hash
|
||||
marshalledTx.Hash = txHash
|
||||
|
|
|
|||
122
params/config.go
122
params/config.go
|
|
@ -20,6 +20,8 @@ import (
|
|||
"encoding/binary"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"sort"
|
||||
"strconv"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"golang.org/x/crypto/sha3"
|
||||
|
|
@ -222,6 +224,40 @@ var (
|
|||
Threshold: 2,
|
||||
}
|
||||
|
||||
// BorTestChainConfig contains the chain parameters to run a node on the Test network.
|
||||
BorTestChainConfig = &ChainConfig{
|
||||
ChainID: big.NewInt(80001),
|
||||
HomesteadBlock: big.NewInt(0),
|
||||
DAOForkBlock: nil,
|
||||
DAOForkSupport: true,
|
||||
EIP150Hash: common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"),
|
||||
EIP150Block: big.NewInt(0),
|
||||
EIP155Block: big.NewInt(0),
|
||||
EIP158Block: big.NewInt(0),
|
||||
ByzantiumBlock: big.NewInt(0),
|
||||
ConstantinopleBlock: big.NewInt(0),
|
||||
PetersburgBlock: big.NewInt(0),
|
||||
IstanbulBlock: big.NewInt(0),
|
||||
MuirGlacierBlock: big.NewInt(0),
|
||||
BerlinBlock: big.NewInt(0),
|
||||
LondonBlock: big.NewInt(0),
|
||||
Bor: &BorConfig{
|
||||
Period: map[string]uint64{
|
||||
"0": 2,
|
||||
},
|
||||
ProducerDelay: 6,
|
||||
Sprint: 64,
|
||||
BackupMultiplier: map[string]uint64{
|
||||
"0": 2,
|
||||
},
|
||||
ValidatorContract: "0x0000000000000000000000000000000000001000",
|
||||
StateReceiverContract: "0x0000000000000000000000000000000000001001",
|
||||
BurntContract: map[string]string{
|
||||
"0": "0x00000000000000000000000000000000000000000",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// MumbaiChainConfig contains the chain parameters to run a node on the Mumbai test network.
|
||||
MumbaiChainConfig = &ChainConfig{
|
||||
ChainID: big.NewInt(80001),
|
||||
|
|
@ -238,13 +274,21 @@ var (
|
|||
IstanbulBlock: big.NewInt(2722000),
|
||||
MuirGlacierBlock: big.NewInt(2722000),
|
||||
BerlinBlock: big.NewInt(13996000),
|
||||
LondonBlock: big.NewInt(22640000),
|
||||
Bor: &BorConfig{
|
||||
Period: 2,
|
||||
ProducerDelay: 6,
|
||||
Sprint: 64,
|
||||
BackupMultiplier: 2,
|
||||
Period: map[string]uint64{
|
||||
"0": 2,
|
||||
},
|
||||
ProducerDelay: 6,
|
||||
Sprint: 64,
|
||||
BackupMultiplier: map[string]uint64{
|
||||
"0": 2,
|
||||
},
|
||||
ValidatorContract: "0x0000000000000000000000000000000000001000",
|
||||
StateReceiverContract: "0x0000000000000000000000000000000000001001",
|
||||
BurntContract: map[string]string{
|
||||
"22640000": "0x70bcA57F4579f58670aB2d18Ef16e02C17553C38",
|
||||
},
|
||||
BlockAlloc: map[string]interface{}{
|
||||
// write as interface since that is how it is decoded in genesis
|
||||
"22244000": map[string]interface{}{
|
||||
|
|
@ -272,11 +316,16 @@ var (
|
|||
IstanbulBlock: big.NewInt(3395000),
|
||||
MuirGlacierBlock: big.NewInt(3395000),
|
||||
BerlinBlock: big.NewInt(14750000),
|
||||
LondonBlock: big.NewInt(0), // TODO - Add london fork block
|
||||
Bor: &BorConfig{
|
||||
Period: 2,
|
||||
ProducerDelay: 6,
|
||||
Sprint: 64,
|
||||
BackupMultiplier: 2,
|
||||
Period: map[string]uint64{
|
||||
"0": 2,
|
||||
},
|
||||
ProducerDelay: 6,
|
||||
Sprint: 64,
|
||||
BackupMultiplier: map[string]uint64{
|
||||
"0": 2,
|
||||
},
|
||||
ValidatorContract: "0x0000000000000000000000000000000000001000",
|
||||
StateReceiverContract: "0x0000000000000000000000000000000000001001",
|
||||
OverrideStateSyncRecords: map[string]int{
|
||||
|
|
@ -290,6 +339,9 @@ var (
|
|||
"14953792": 0,
|
||||
"14953856": 0,
|
||||
},
|
||||
BurntContract: map[string]string{
|
||||
"0": "0x0000000000000000000000000000000000000000",
|
||||
}, // TODO add london fork contract and block
|
||||
BlockAlloc: map[string]interface{}{
|
||||
// write as interface since that is how it is decoded in genesis
|
||||
"22156660": map[string]interface{}{
|
||||
|
|
@ -426,15 +478,15 @@ func (c *CliqueConfig) String() string {
|
|||
|
||||
// BorConfig is the consensus engine configs for Matic bor based sealing.
|
||||
type BorConfig struct {
|
||||
Period uint64 `json:"period"` // Number of seconds between blocks to enforce
|
||||
ProducerDelay uint64 `json:"producerDelay"` // Number of seconds delay between two producer interval
|
||||
Sprint uint64 `json:"sprint"` // Epoch length to proposer
|
||||
BackupMultiplier uint64 `json:"backupMultiplier"` // Backup multiplier to determine the wiggle time
|
||||
ValidatorContract string `json:"validatorContract"` // Validator set contract
|
||||
StateReceiverContract string `json:"stateReceiverContract"` // State receiver contract
|
||||
|
||||
Period map[string]uint64 `json:"period"` // Number of seconds between blocks to enforce
|
||||
ProducerDelay uint64 `json:"producerDelay"` // Number of seconds delay between two producer interval
|
||||
Sprint uint64 `json:"sprint"` // Epoch length to proposer
|
||||
BackupMultiplier map[string]uint64 `json:"backupMultiplier"` // Backup multiplier to determine the wiggle time
|
||||
ValidatorContract string `json:"validatorContract"` // Validator set contract
|
||||
StateReceiverContract string `json:"stateReceiverContract"` // State receiver contract
|
||||
OverrideStateSyncRecords map[string]int `json:"overrideStateSyncRecords"` // override state records count
|
||||
BlockAlloc map[string]interface{} `json:"blockAlloc"`
|
||||
BurntContract map[string]string `json:"burntContract"` // governance contract where the token will be sent to and burnt in london fork
|
||||
}
|
||||
|
||||
// String implements the stringer interface, returning the consensus engine details.
|
||||
|
|
@ -442,6 +494,46 @@ func (b *BorConfig) String() string {
|
|||
return "bor"
|
||||
}
|
||||
|
||||
func (c *BorConfig) CalculateBackupMultiplier(number uint64) uint64 {
|
||||
return c.calculateBorConfigHelper(c.BackupMultiplier, number)
|
||||
}
|
||||
|
||||
func (c *BorConfig) CalculatePeriod(number uint64) uint64 {
|
||||
return c.calculateBorConfigHelper(c.Period, number)
|
||||
}
|
||||
|
||||
func (c *BorConfig) calculateBorConfigHelper(field map[string]uint64, number uint64) uint64 {
|
||||
keys := make([]string, 0, len(field))
|
||||
for k := range field {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
for i := 0; i < len(keys)-1; i++ {
|
||||
valUint, _ := strconv.ParseUint(keys[i], 10, 64)
|
||||
valUintNext, _ := strconv.ParseUint(keys[i+1], 10, 64)
|
||||
if number > valUint && number < valUintNext {
|
||||
return field[keys[i]]
|
||||
}
|
||||
}
|
||||
return field[keys[len(keys)-1]]
|
||||
}
|
||||
|
||||
func (c *BorConfig) CalculateBurntContract(number uint64) string {
|
||||
keys := make([]string, 0, len(c.BurntContract))
|
||||
for k := range c.BurntContract {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
for i := 0; i < len(keys)-1; i++ {
|
||||
valUint, _ := strconv.ParseUint(keys[i], 10, 64)
|
||||
valUintNext, _ := strconv.ParseUint(keys[i+1], 10, 64)
|
||||
if number > valUint && number < valUintNext {
|
||||
return c.BurntContract[keys[i]]
|
||||
}
|
||||
}
|
||||
return c.BurntContract[keys[len(keys)-1]]
|
||||
}
|
||||
|
||||
// String implements the fmt.Stringer interface.
|
||||
func (c *ChainConfig) String() string {
|
||||
var engine interface{}
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@ import (
|
|||
const (
|
||||
VersionMajor = 0 // Major version component of the current release
|
||||
VersionMinor = 2 // Minor version component of the current release
|
||||
VersionPatch = 12 // Patch version component of the current release
|
||||
VersionMeta = "stable" // Version metadata to append to the version string
|
||||
VersionPatch = 13 // Patch version component of the current release
|
||||
VersionMeta = "beta" // Version metadata to append to the version string
|
||||
)
|
||||
|
||||
// Version holds the textual version string.
|
||||
|
|
|
|||
|
|
@ -7,14 +7,18 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/consensus/bor"
|
||||
"github.com/ethereum/go-ethereum/consensus/ethash"
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/core/vm"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/ethereum/go-ethereum/tests/bor/mocks"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
@ -268,3 +272,233 @@ func getSampleEventRecord(t *testing.T) *bor.EventRecordWithTime {
|
|||
_eventRecords[0].Time = time.Unix(1, 0)
|
||||
return _eventRecords[0]
|
||||
}
|
||||
|
||||
// TestEIP1559Transition tests the following:
|
||||
//
|
||||
// 1. A transaction whose gasFeeCap is greater than the baseFee is valid.
|
||||
// 2. Gas accounting for access lists on EIP-1559 transactions is correct.
|
||||
// 3. Only the transaction's tip will be received by the coinbase.
|
||||
// 4. The transaction sender pays for both the tip and baseFee.
|
||||
// 5. The coinbase receives only the partially realized tip when
|
||||
// gasFeeCap - gasTipCap < baseFee.
|
||||
// 6. Legacy transaction behave as expected (e.g. gasPrice = gasFeeCap = gasTipCap).
|
||||
func TestEIP1559Transition(t *testing.T) {
|
||||
var (
|
||||
aa = common.HexToAddress("0x000000000000000000000000000000000000aaaa")
|
||||
|
||||
// Generate a canonical chain to act as the main dataset
|
||||
db = rawdb.NewMemoryDatabase()
|
||||
engine = ethash.NewFaker()
|
||||
|
||||
// A sender who makes transactions, has some funds
|
||||
key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
||||
key2, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
|
||||
key3, _ = crypto.HexToECDSA("225171aed3793cba1c029832886d69785b7e77a54a44211226b447aa2d16b058")
|
||||
|
||||
addr1 = crypto.PubkeyToAddress(key1.PublicKey)
|
||||
addr2 = crypto.PubkeyToAddress(key2.PublicKey)
|
||||
addr3 = crypto.PubkeyToAddress(key3.PublicKey)
|
||||
funds = new(big.Int).Mul(common.Big1, big.NewInt(params.Ether))
|
||||
gspec = &core.Genesis{
|
||||
Config: params.BorTestChainConfig,
|
||||
Alloc: core.GenesisAlloc{
|
||||
addr1: {Balance: funds},
|
||||
addr2: {Balance: funds},
|
||||
addr3: {Balance: funds},
|
||||
// The address 0xAAAA sloads 0x00 and 0x01
|
||||
aa: {
|
||||
Code: []byte{
|
||||
byte(vm.PC),
|
||||
byte(vm.PC),
|
||||
byte(vm.SLOAD),
|
||||
byte(vm.SLOAD),
|
||||
},
|
||||
Nonce: 0,
|
||||
Balance: big.NewInt(0),
|
||||
},
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
gspec.Config.BerlinBlock = common.Big0
|
||||
gspec.Config.LondonBlock = common.Big0
|
||||
genesis := gspec.MustCommit(db)
|
||||
signer := types.LatestSigner(gspec.Config)
|
||||
|
||||
blocks, _ := core.GenerateChain(gspec.Config, genesis, engine, db, 1, func(i int, b *core.BlockGen) {
|
||||
b.SetCoinbase(common.Address{1})
|
||||
// One transaction to 0xAAAA
|
||||
accesses := types.AccessList{types.AccessTuple{
|
||||
Address: aa,
|
||||
StorageKeys: []common.Hash{{0}},
|
||||
}}
|
||||
|
||||
txdata := &types.DynamicFeeTx{
|
||||
ChainID: gspec.Config.ChainID,
|
||||
Nonce: 0,
|
||||
To: &aa,
|
||||
Gas: 30000,
|
||||
GasFeeCap: newGwei(5),
|
||||
GasTipCap: big.NewInt(2),
|
||||
AccessList: accesses,
|
||||
Data: []byte{},
|
||||
}
|
||||
tx := types.NewTx(txdata)
|
||||
tx, _ = types.SignTx(tx, signer, key1)
|
||||
|
||||
b.AddTx(tx)
|
||||
})
|
||||
|
||||
diskdb := rawdb.NewMemoryDatabase()
|
||||
gspec.MustCommit(diskdb)
|
||||
|
||||
chain, err := core.NewBlockChain(diskdb, nil, gspec.Config, engine, vm.Config{}, nil, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create tester chain: %v", err)
|
||||
}
|
||||
if n, err := chain.InsertChain(blocks); err != nil {
|
||||
t.Fatalf("block %d: failed to insert into chain: %v", n, err)
|
||||
}
|
||||
|
||||
block := chain.GetBlockByNumber(1)
|
||||
|
||||
// 1+2: Ensure EIP-1559 access lists are accounted for via gas usage.
|
||||
expectedGas := params.TxGas + params.TxAccessListAddressGas + params.TxAccessListStorageKeyGas +
|
||||
vm.GasQuickStep*2 + params.WarmStorageReadCostEIP2929 + params.ColdSloadCostEIP2929
|
||||
if block.GasUsed() != expectedGas {
|
||||
t.Fatalf("incorrect amount of gas spent: expected %d, got %d", expectedGas, block.GasUsed())
|
||||
}
|
||||
|
||||
state, _ := chain.State()
|
||||
|
||||
// 3: Ensure that miner received only the tx's tip.
|
||||
actual := state.GetBalance(block.Coinbase())
|
||||
expected := new(big.Int).Add(
|
||||
new(big.Int).SetUint64(block.GasUsed()*block.Transactions()[0].GasTipCap().Uint64()),
|
||||
ethash.ConstantinopleBlockReward,
|
||||
)
|
||||
if actual.Cmp(expected) != 0 {
|
||||
t.Fatalf("miner balance incorrect: expected %d, got %d", expected, actual)
|
||||
}
|
||||
|
||||
// check burnt contract balance
|
||||
actual = state.GetBalance(common.HexToAddress(params.BorTestChainConfig.Bor.CalculateBurntContract(block.NumberU64())))
|
||||
expected = new(big.Int).Mul(new(big.Int).SetUint64(block.GasUsed()), block.BaseFee())
|
||||
burntContractBalance := expected
|
||||
if actual.Cmp(expected) != 0 {
|
||||
t.Fatalf("burnt contract balance incorrect: expected %d, got %d", expected, actual)
|
||||
}
|
||||
|
||||
// 4: Ensure the tx sender paid for the gasUsed * (tip + block baseFee).
|
||||
actual = new(big.Int).Sub(funds, state.GetBalance(addr1))
|
||||
expected = new(big.Int).SetUint64(block.GasUsed() * (block.Transactions()[0].GasTipCap().Uint64() + block.BaseFee().Uint64()))
|
||||
if actual.Cmp(expected) != 0 {
|
||||
t.Fatalf("sender balance incorrect: expected %d, got %d", expected, actual)
|
||||
}
|
||||
|
||||
blocks, _ = core.GenerateChain(gspec.Config, block, engine, db, 1, func(i int, b *core.BlockGen) {
|
||||
b.SetCoinbase(common.Address{2})
|
||||
|
||||
txdata := &types.LegacyTx{
|
||||
Nonce: 0,
|
||||
To: &aa,
|
||||
Gas: 30000,
|
||||
GasPrice: newGwei(5),
|
||||
}
|
||||
tx := types.NewTx(txdata)
|
||||
tx, _ = types.SignTx(tx, signer, key2)
|
||||
|
||||
b.AddTx(tx)
|
||||
})
|
||||
|
||||
if n, err := chain.InsertChain(blocks); err != nil {
|
||||
t.Fatalf("block %d: failed to insert into chain: %v", n, err)
|
||||
}
|
||||
|
||||
block = chain.GetBlockByNumber(2)
|
||||
state, _ = chain.State()
|
||||
effectiveTip := block.Transactions()[0].GasTipCap().Uint64() - block.BaseFee().Uint64()
|
||||
|
||||
// 6+5: Ensure that miner received only the tx's effective tip.
|
||||
actual = state.GetBalance(block.Coinbase())
|
||||
expected = new(big.Int).Add(
|
||||
new(big.Int).SetUint64(block.GasUsed()*effectiveTip),
|
||||
ethash.ConstantinopleBlockReward,
|
||||
)
|
||||
if actual.Cmp(expected) != 0 {
|
||||
t.Fatalf("miner balance incorrect: expected %d, got %d", expected, actual)
|
||||
}
|
||||
|
||||
// check burnt contract balance
|
||||
actual = state.GetBalance(common.HexToAddress(params.BorTestChainConfig.Bor.CalculateBurntContract(block.NumberU64())))
|
||||
expected = new(big.Int).Add(burntContractBalance, new(big.Int).Mul(new(big.Int).SetUint64(block.GasUsed()), block.BaseFee()))
|
||||
burntContractBalance = expected
|
||||
if actual.Cmp(expected) != 0 {
|
||||
t.Fatalf("burnt contract balance incorrect: expected %d, got %d", expected, actual)
|
||||
}
|
||||
|
||||
// 4: Ensure the tx sender paid for the gasUsed * (effectiveTip + block baseFee).
|
||||
actual = new(big.Int).Sub(funds, state.GetBalance(addr2))
|
||||
expected = new(big.Int).SetUint64(block.GasUsed() * (effectiveTip + block.BaseFee().Uint64()))
|
||||
if actual.Cmp(expected) != 0 {
|
||||
t.Fatalf("sender balance incorrect: expected %d, got %d", expected, actual)
|
||||
}
|
||||
|
||||
blocks, _ = core.GenerateChain(gspec.Config, block, engine, db, 1, func(i int, b *core.BlockGen) {
|
||||
b.SetCoinbase(common.Address{3})
|
||||
|
||||
txdata := &types.LegacyTx{
|
||||
Nonce: 0,
|
||||
To: &aa,
|
||||
Gas: 30000,
|
||||
GasPrice: newGwei(5),
|
||||
}
|
||||
tx := types.NewTx(txdata)
|
||||
tx, _ = types.SignTx(tx, signer, key3)
|
||||
|
||||
b.AddTx(tx)
|
||||
|
||||
accesses := types.AccessList{types.AccessTuple{
|
||||
Address: aa,
|
||||
StorageKeys: []common.Hash{{0}},
|
||||
}}
|
||||
|
||||
txdata2 := &types.DynamicFeeTx{
|
||||
ChainID: gspec.Config.ChainID,
|
||||
Nonce: 1,
|
||||
To: &aa,
|
||||
Gas: 30000,
|
||||
GasFeeCap: newGwei(5),
|
||||
GasTipCap: big.NewInt(2),
|
||||
AccessList: accesses,
|
||||
Data: []byte{},
|
||||
}
|
||||
tx = types.NewTx(txdata2)
|
||||
tx, _ = types.SignTx(tx, signer, key3)
|
||||
|
||||
b.AddTx(tx)
|
||||
|
||||
})
|
||||
|
||||
if n, err := chain.InsertChain(blocks); err != nil {
|
||||
t.Fatalf("block %d: failed to insert into chain: %v", n, err)
|
||||
}
|
||||
|
||||
block = chain.GetBlockByNumber(3)
|
||||
state, _ = chain.State()
|
||||
|
||||
// check burnt contract balance
|
||||
actual = state.GetBalance(common.HexToAddress(params.BorTestChainConfig.Bor.CalculateBurntContract(block.NumberU64())))
|
||||
burntAmount := new(big.Int).Mul(
|
||||
block.BaseFee(),
|
||||
big.NewInt(int64(block.GasUsed())),
|
||||
)
|
||||
expected = new(big.Int).Add(burntContractBalance, burntAmount)
|
||||
if actual.Cmp(expected) != 0 {
|
||||
t.Fatalf("burnt contract balance incorrect: expected %d, got %d", expected, actual)
|
||||
}
|
||||
}
|
||||
|
||||
func newGwei(n int64) *big.Int {
|
||||
return new(big.Int).Mul(big.NewInt(n), big.NewInt(params.GWei))
|
||||
}
|
||||
|
|
|
|||
18
tests/bor/testdata/genesis.json
vendored
18
tests/bor/testdata/genesis.json
vendored
|
|
@ -8,13 +8,25 @@
|
|||
"eip158Block": 0,
|
||||
"byzantiumBlock": 0,
|
||||
"constantinopleBlock": 0,
|
||||
"petersburgBlock": 0,
|
||||
"istanbulBlock": 0,
|
||||
"muirGlacierBlock": 0,
|
||||
"berlinBlock": 0,
|
||||
"londonBlock": 10,
|
||||
"bor": {
|
||||
"period": 1,
|
||||
"period": {
|
||||
"0": 1
|
||||
},
|
||||
"producerDelay": 4,
|
||||
"sprint": 4,
|
||||
"backupMultiplier": 1,
|
||||
"backupMultiplier": {
|
||||
"0": 1
|
||||
},
|
||||
"validatorContract": "0x0000000000000000000000000000000000001000",
|
||||
"stateReceiverContract": "0x0000000000000000000000000000000000001001"
|
||||
"stateReceiverContract": "0x0000000000000000000000000000000000001001",
|
||||
"burntContract": {
|
||||
"0": "0x0000000000000000000000000000000000000000"
|
||||
}
|
||||
}
|
||||
},
|
||||
"nonce": "0x0",
|
||||
|
|
|
|||
Loading…
Reference in a new issue