Skip to content

Commit a5a4fa7

Browse files
authored
all: use uint256 in state (#28598)
This change makes use of uin256 to represent balance in state. It touches primarily upon statedb, stateobject and state processing, trying to avoid changes in transaction pools, core types, rpc and tracers.
1 parent 819a497 commit a5a4fa7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+353
-337
lines changed

cmd/evm/internal/t8ntool/execution.go

+5-4
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import (
3636
"github.com/ethereum/go-ethereum/params"
3737
"github.com/ethereum/go-ethereum/rlp"
3838
"github.com/ethereum/go-ethereum/trie"
39+
"github.com/holiman/uint256"
3940
"golang.org/x/crypto/sha3"
4041
)
4142

@@ -308,15 +309,15 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
308309
reward.Sub(reward, new(big.Int).SetUint64(ommer.Delta))
309310
reward.Mul(reward, blockReward)
310311
reward.Div(reward, big.NewInt(8))
311-
statedb.AddBalance(ommer.Address, reward)
312+
statedb.AddBalance(ommer.Address, uint256.MustFromBig(reward))
312313
}
313-
statedb.AddBalance(pre.Env.Coinbase, minerReward)
314+
statedb.AddBalance(pre.Env.Coinbase, uint256.MustFromBig(minerReward))
314315
}
315316
// Apply withdrawals
316317
for _, w := range pre.Env.Withdrawals {
317318
// Amount is in gwei, turn into wei
318319
amount := new(big.Int).Mul(new(big.Int).SetUint64(w.Amount), big.NewInt(params.GWei))
319-
statedb.AddBalance(w.Address, amount)
320+
statedb.AddBalance(w.Address, uint256.MustFromBig(amount))
320321
}
321322
// Commit block
322323
root, err := statedb.Commit(vmContext.BlockNumber.Uint64(), chainConfig.IsEIP158(vmContext.BlockNumber))
@@ -359,7 +360,7 @@ func MakePreState(db ethdb.Database, accounts core.GenesisAlloc) *state.StateDB
359360
for addr, a := range accounts {
360361
statedb.SetCode(addr, a.Code)
361362
statedb.SetNonce(addr, a.Nonce)
362-
statedb.SetBalance(addr, a.Balance)
363+
statedb.SetBalance(addr, uint256.MustFromBig(a.Balance))
363364
for k, v := range a.Storage {
364365
statedb.SetState(addr, k, v)
365366
}

cmd/evm/internal/t8ntool/transition.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ func (g Alloc) OnAccount(addr *common.Address, dumpAccount state.DumpAccount) {
280280
if addr == nil {
281281
return
282282
}
283-
balance, _ := new(big.Int).SetString(dumpAccount.Balance, 10)
283+
balance, _ := new(big.Int).SetString(dumpAccount.Balance, 0)
284284
var storage map[common.Hash]common.Hash
285285
if dumpAccount.Storage != nil {
286286
storage = make(map[common.Hash]common.Hash)

common/big.go

+7-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,11 @@
1616

1717
package common
1818

19-
import "math/big"
19+
import (
20+
"math/big"
21+
22+
"github.com/holiman/uint256"
23+
)
2024

2125
// Common big integers often used
2226
var (
@@ -27,4 +31,6 @@ var (
2731
Big32 = big.NewInt(32)
2832
Big256 = big.NewInt(256)
2933
Big257 = big.NewInt(257)
34+
35+
U2560 = uint256.NewInt(0)
3036
)

consensus/beacon/consensus.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import (
3030
"github.com/ethereum/go-ethereum/params"
3131
"github.com/ethereum/go-ethereum/rpc"
3232
"github.com/ethereum/go-ethereum/trie"
33+
"github.com/holiman/uint256"
3334
)
3435

3536
// Proof-of-stake protocol constants.
@@ -355,8 +356,8 @@ func (beacon *Beacon) Finalize(chain consensus.ChainHeaderReader, header *types.
355356
// Withdrawals processing.
356357
for _, w := range withdrawals {
357358
// Convert amount from gwei to wei.
358-
amount := new(big.Int).SetUint64(w.Amount)
359-
amount = amount.Mul(amount, big.NewInt(params.GWei))
359+
amount := new(uint256.Int).SetUint64(w.Amount)
360+
amount = amount.Mul(amount, uint256.NewInt(params.GWei))
360361
state.AddBalance(w.Address, amount)
361362
}
362363
// No block reward which is issued by consensus layer instead.

consensus/ethash/consensus.go

+16-13
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,17 @@ import (
3333
"github.com/ethereum/go-ethereum/params"
3434
"github.com/ethereum/go-ethereum/rlp"
3535
"github.com/ethereum/go-ethereum/trie"
36+
"github.com/holiman/uint256"
3637
"golang.org/x/crypto/sha3"
3738
)
3839

3940
// Ethash proof-of-work protocol constants.
4041
var (
41-
FrontierBlockReward = big.NewInt(5e+18) // Block reward in wei for successfully mining a block
42-
ByzantiumBlockReward = big.NewInt(3e+18) // Block reward in wei for successfully mining a block upward from Byzantium
43-
ConstantinopleBlockReward = big.NewInt(2e+18) // Block reward in wei for successfully mining a block upward from Constantinople
44-
maxUncles = 2 // Maximum number of uncles allowed in a single block
45-
allowedFutureBlockTimeSeconds = int64(15) // Max seconds from current time allowed for blocks, before they're considered future blocks
42+
FrontierBlockReward = uint256.NewInt(5e+18) // Block reward in wei for successfully mining a block
43+
ByzantiumBlockReward = uint256.NewInt(3e+18) // Block reward in wei for successfully mining a block upward from Byzantium
44+
ConstantinopleBlockReward = uint256.NewInt(2e+18) // Block reward in wei for successfully mining a block upward from Constantinople
45+
maxUncles = 2 // Maximum number of uncles allowed in a single block
46+
allowedFutureBlockTimeSeconds = int64(15) // Max seconds from current time allowed for blocks, before they're considered future blocks
4647

4748
// calcDifficultyEip5133 is the difficulty adjustment algorithm as specified by EIP 5133.
4849
// It offsets the bomb a total of 11.4M blocks.
@@ -562,8 +563,8 @@ func (ethash *Ethash) SealHash(header *types.Header) (hash common.Hash) {
562563

563564
// Some weird constants to avoid constant memory allocs for them.
564565
var (
565-
big8 = big.NewInt(8)
566-
big32 = big.NewInt(32)
566+
u256_8 = uint256.NewInt(8)
567+
u256_32 = uint256.NewInt(32)
567568
)
568569

569570
// AccumulateRewards credits the coinbase of the given block with the mining
@@ -579,16 +580,18 @@ func accumulateRewards(config *params.ChainConfig, state *state.StateDB, header
579580
blockReward = ConstantinopleBlockReward
580581
}
581582
// Accumulate the rewards for the miner and any included uncles
582-
reward := new(big.Int).Set(blockReward)
583-
r := new(big.Int)
583+
reward := new(uint256.Int).Set(blockReward)
584+
r := new(uint256.Int)
585+
hNum, _ := uint256.FromBig(header.Number)
584586
for _, uncle := range uncles {
585-
r.Add(uncle.Number, big8)
586-
r.Sub(r, header.Number)
587+
uNum, _ := uint256.FromBig(uncle.Number)
588+
r.AddUint64(uNum, 8)
589+
r.Sub(r, hNum)
587590
r.Mul(r, blockReward)
588-
r.Div(r, big8)
591+
r.Div(r, u256_8)
589592
state.AddBalance(uncle.Coinbase, r)
590593

591-
r.Div(blockReward, big32)
594+
r.Div(blockReward, u256_32)
592595
reward.Add(reward, r)
593596
}
594597
state.AddBalance(header.Coinbase, reward)

consensus/misc/dao.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"github.com/ethereum/go-ethereum/core/state"
2525
"github.com/ethereum/go-ethereum/core/types"
2626
"github.com/ethereum/go-ethereum/params"
27+
"github.com/holiman/uint256"
2728
)
2829

2930
var (
@@ -81,6 +82,6 @@ func ApplyDAOHardFork(statedb *state.StateDB) {
8182
// Move every DAO account and extra-balance account funds into the refund contract
8283
for _, addr := range params.DAODrainList() {
8384
statedb.AddBalance(params.DAORefundContract, statedb.GetBalance(addr))
84-
statedb.SetBalance(addr, new(big.Int))
85+
statedb.SetBalance(addr, new(uint256.Int))
8586
}
8687
}

core/blockchain_test.go

+11-10
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import (
4040
"github.com/ethereum/go-ethereum/ethdb"
4141
"github.com/ethereum/go-ethereum/params"
4242
"github.com/ethereum/go-ethereum/trie"
43+
"github.com/holiman/uint256"
4344
)
4445

4546
// So we can deterministically seed different blockchains
@@ -3567,7 +3568,7 @@ func testInitThenFailCreateContract(t *testing.T, scheme string) {
35673568
defer chain.Stop()
35683569

35693570
statedb, _ := chain.State()
3570-
if got, exp := statedb.GetBalance(aa), big.NewInt(100000); got.Cmp(exp) != 0 {
3571+
if got, exp := statedb.GetBalance(aa), uint256.NewInt(100000); got.Cmp(exp) != 0 {
35713572
t.Fatalf("Genesis err, got %v exp %v", got, exp)
35723573
}
35733574
// First block tries to create, but fails
@@ -3577,7 +3578,7 @@ func testInitThenFailCreateContract(t *testing.T, scheme string) {
35773578
t.Fatalf("block %d: failed to insert into chain: %v", block.NumberU64(), err)
35783579
}
35793580
statedb, _ = chain.State()
3580-
if got, exp := statedb.GetBalance(aa), big.NewInt(100000); got.Cmp(exp) != 0 {
3581+
if got, exp := statedb.GetBalance(aa), uint256.NewInt(100000); got.Cmp(exp) != 0 {
35813582
t.Fatalf("block %d: got %v exp %v", block.NumberU64(), got, exp)
35823583
}
35833584
}
@@ -3763,17 +3764,17 @@ func testEIP1559Transition(t *testing.T, scheme string) {
37633764
state, _ := chain.State()
37643765

37653766
// 3: Ensure that miner received only the tx's tip.
3766-
actual := state.GetBalance(block.Coinbase())
3767+
actual := state.GetBalance(block.Coinbase()).ToBig()
37673768
expected := new(big.Int).Add(
37683769
new(big.Int).SetUint64(block.GasUsed()*block.Transactions()[0].GasTipCap().Uint64()),
3769-
ethash.ConstantinopleBlockReward,
3770+
ethash.ConstantinopleBlockReward.ToBig(),
37703771
)
37713772
if actual.Cmp(expected) != 0 {
37723773
t.Fatalf("miner balance incorrect: expected %d, got %d", expected, actual)
37733774
}
37743775

37753776
// 4: Ensure the tx sender paid for the gasUsed * (tip + block baseFee).
3776-
actual = new(big.Int).Sub(funds, state.GetBalance(addr1))
3777+
actual = new(big.Int).Sub(funds, state.GetBalance(addr1).ToBig())
37773778
expected = new(big.Int).SetUint64(block.GasUsed() * (block.Transactions()[0].GasTipCap().Uint64() + block.BaseFee().Uint64()))
37783779
if actual.Cmp(expected) != 0 {
37793780
t.Fatalf("sender balance incorrect: expected %d, got %d", expected, actual)
@@ -3803,17 +3804,17 @@ func testEIP1559Transition(t *testing.T, scheme string) {
38033804
effectiveTip := block.Transactions()[0].GasTipCap().Uint64() - block.BaseFee().Uint64()
38043805

38053806
// 6+5: Ensure that miner received only the tx's effective tip.
3806-
actual = state.GetBalance(block.Coinbase())
3807+
actual = state.GetBalance(block.Coinbase()).ToBig()
38073808
expected = new(big.Int).Add(
38083809
new(big.Int).SetUint64(block.GasUsed()*effectiveTip),
3809-
ethash.ConstantinopleBlockReward,
3810+
ethash.ConstantinopleBlockReward.ToBig(),
38103811
)
38113812
if actual.Cmp(expected) != 0 {
38123813
t.Fatalf("miner balance incorrect: expected %d, got %d", expected, actual)
38133814
}
38143815

38153816
// 4: Ensure the tx sender paid for the gasUsed * (effectiveTip + block baseFee).
3816-
actual = new(big.Int).Sub(funds, state.GetBalance(addr2))
3817+
actual = new(big.Int).Sub(funds, state.GetBalance(addr2).ToBig())
38173818
expected = new(big.Int).SetUint64(block.GasUsed() * (effectiveTip + block.BaseFee().Uint64()))
38183819
if actual.Cmp(expected) != 0 {
38193820
t.Fatalf("sender balance incorrect: expected %d, got %d", expected, actual)
@@ -4628,14 +4629,14 @@ func TestEIP3651(t *testing.T) {
46284629
state, _ := chain.State()
46294630

46304631
// 3: Ensure that miner received only the tx's tip.
4631-
actual := state.GetBalance(block.Coinbase())
4632+
actual := state.GetBalance(block.Coinbase()).ToBig()
46324633
expected := new(big.Int).SetUint64(block.GasUsed() * block.Transactions()[0].GasTipCap().Uint64())
46334634
if actual.Cmp(expected) != 0 {
46344635
t.Fatalf("miner balance incorrect: expected %d, got %d", expected, actual)
46354636
}
46364637

46374638
// 4: Ensure the tx sender paid for the gasUsed * (tip + block baseFee).
4638-
actual = new(big.Int).Sub(funds, state.GetBalance(addr1))
4639+
actual = new(big.Int).Sub(funds, state.GetBalance(addr1).ToBig())
46394640
expected = new(big.Int).SetUint64(block.GasUsed() * (block.Transactions()[0].GasTipCap().Uint64() + block.BaseFee().Uint64()))
46404641
if actual.Cmp(expected) != 0 {
46414642
t.Fatalf("sender balance incorrect: expected %d, got %d", expected, actual)

core/chain_makers.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import (
3232
"github.com/ethereum/go-ethereum/ethdb"
3333
"github.com/ethereum/go-ethereum/params"
3434
"github.com/ethereum/go-ethereum/trie"
35+
"github.com/holiman/uint256"
3536
)
3637

3738
// BlockGen creates blocks for testing.
@@ -157,7 +158,7 @@ func (b *BlockGen) AddTxWithVMConfig(tx *types.Transaction, config vm.Config) {
157158
}
158159

159160
// GetBalance returns the balance of the given address at the generated block.
160-
func (b *BlockGen) GetBalance(addr common.Address) *big.Int {
161+
func (b *BlockGen) GetBalance(addr common.Address) *uint256.Int {
161162
return b.statedb.GetBalance(addr)
162163
}
163164

core/evm.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"github.com/ethereum/go-ethereum/consensus/misc/eip4844"
2525
"github.com/ethereum/go-ethereum/core/types"
2626
"github.com/ethereum/go-ethereum/core/vm"
27+
"github.com/holiman/uint256"
2728
)
2829

2930
// ChainContext supports retrieving headers and consensus parameters from the
@@ -129,12 +130,12 @@ func GetHashFn(ref *types.Header, chain ChainContext) func(n uint64) common.Hash
129130

130131
// CanTransfer checks whether there are enough funds in the address' account to make a transfer.
131132
// This does not take the necessary gas in to account to make the transfer valid.
132-
func CanTransfer(db vm.StateDB, addr common.Address, amount *big.Int) bool {
133+
func CanTransfer(db vm.StateDB, addr common.Address, amount *uint256.Int) bool {
133134
return db.GetBalance(addr).Cmp(amount) >= 0
134135
}
135136

136137
// Transfer subtracts amount from sender and adds amount to recipient using the given Db
137-
func Transfer(db vm.StateDB, sender, recipient common.Address, amount *big.Int) {
138+
func Transfer(db vm.StateDB, sender, recipient common.Address, amount *uint256.Int) {
138139
db.SubBalance(sender, amount)
139140
db.AddBalance(recipient, amount)
140141
}

core/genesis.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import (
3838
"github.com/ethereum/go-ethereum/rlp"
3939
"github.com/ethereum/go-ethereum/trie"
4040
"github.com/ethereum/go-ethereum/trie/triedb/pathdb"
41+
"github.com/holiman/uint256"
4142
)
4243

4344
//go:generate go run github.com/fjl/gencodec -type Genesis -field-override genesisSpecMarshaling -out gen_genesis.go
@@ -142,7 +143,7 @@ func (ga *GenesisAlloc) hash(isVerkle bool) (common.Hash, error) {
142143
}
143144
for addr, account := range *ga {
144145
if account.Balance != nil {
145-
statedb.AddBalance(addr, account.Balance)
146+
statedb.AddBalance(addr, uint256.MustFromBig(account.Balance))
146147
}
147148
statedb.SetCode(addr, account.Code)
148149
statedb.SetNonce(addr, account.Nonce)
@@ -163,7 +164,7 @@ func (ga *GenesisAlloc) flush(db ethdb.Database, triedb *trie.Database, blockhas
163164
}
164165
for addr, account := range *ga {
165166
if account.Balance != nil {
166-
statedb.AddBalance(addr, account.Balance)
167+
statedb.AddBalance(addr, uint256.MustFromBig(account.Balance))
167168
}
168169
statedb.SetCode(addr, account.Code)
169170
statedb.SetNonce(addr, account.Nonce)

core/state/journal.go

+3-4
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,8 @@
1717
package state
1818

1919
import (
20-
"math/big"
21-
2220
"github.com/ethereum/go-ethereum/common"
21+
"github.com/holiman/uint256"
2322
)
2423

2524
// journalEntry is a modification entry in the state change journal that can be
@@ -103,13 +102,13 @@ type (
103102
selfDestructChange struct {
104103
account *common.Address
105104
prev bool // whether account had already self-destructed
106-
prevbalance *big.Int
105+
prevbalance *uint256.Int
107106
}
108107

109108
// Changes to individual accounts.
110109
balanceChange struct {
111110
account *common.Address
112-
prev *big.Int
111+
prev *uint256.Int
113112
}
114113
nonceChange struct {
115114
account *common.Address

0 commit comments

Comments
 (0)