Skip to content

Commit

Permalink
e3: faster apply (erigontech#6970)
Browse files Browse the repository at this point in the history
  • Loading branch information
AskAlexSharov authored Feb 27, 2023
1 parent daf1522 commit 4b4d271
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 3 deletions.
13 changes: 10 additions & 3 deletions core/state/rw_v3.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ type StateV3 struct {
sizeEstimate int
txsDone *atomic2.Uint64
finished atomic2.Bool

applyPrevAccountBuf []byte // buffer for ApplyState. Doesn't need mutex because Apply is single-threaded
}

func NewStateV3() *StateV3 {
Expand All @@ -54,6 +56,8 @@ func NewStateV3() *StateV3 {
kv.PlainContractCode: btree2.NewMap[string, []byte](128),
},
txsDone: atomic2.NewUint64(0),

applyPrevAccountBuf: make([]byte, 128),
}
rs.receiveWork = sync.NewCond(&rs.queueLock)
return rs
Expand Down Expand Up @@ -238,7 +242,8 @@ func (rs *StateV3) appplyState1(roTx kv.Tx, txTask *exec22.TxTask, agg *libstate
copy(addr1, addr)
binary.BigEndian.PutUint64(addr1[len(addr):], original.Incarnation)

prev := accounts.SerialiseV3(original)
prev := rs.applyPrevAccountBuf[:accounts.SerialiseV3Len(original)]
accounts.SerialiseV3To(original, prev)
if err := agg.AddAccountPrev(addr, prev); err != nil {
return err
}
Expand Down Expand Up @@ -336,6 +341,7 @@ func (rs *StateV3) appplyState(roTx kv.Tx, txTask *exec22.TxTask, agg *libstate.
rs.lock.Lock()
defer rs.lock.Unlock()

var a accounts.Account
for addr, increase := range txTask.BalanceIncreaseSet {
increase := increase
addrBytes := addr.Bytes()
Expand All @@ -347,13 +353,14 @@ func (rs *StateV3) appplyState(roTx kv.Tx, txTask *exec22.TxTask, agg *libstate.
return err
}
}
var a accounts.Account
a.Reset()
if err := a.DecodeForStorage(enc0); err != nil {
return err
}
if len(enc0) > 0 {
// Need to convert before balance increase
enc0 = accounts.SerialiseV3(&a)
prev := rs.applyPrevAccountBuf[:accounts.SerialiseV3Len(&a)]
accounts.SerialiseV3To(&a, prev)
}
a.Balance.Add(&a.Balance, &increase)
var enc1 []byte
Expand Down
66 changes: 66 additions & 0 deletions core/types/accounts/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -718,3 +718,69 @@ func SerialiseV3(a *Account) []byte {
}
return value
}

func SerialiseV3Len(a *Account) (l int) {
l++
if a.Nonce > 0 {
l += (bits.Len64(a.Nonce) + 7) / 8
}
l++
if !a.Balance.IsZero() {
l += a.Balance.ByteLen()
}
l++
if !a.IsEmptyCodeHash() {
l += 32
}
l++
if a.Incarnation > 0 {
l += (bits.Len64(a.Incarnation) + 7) / 8
}
return l
}
func SerialiseV3To(a *Account, value []byte) {
pos := 0
if a.Nonce == 0 {
value[pos] = 0
pos++
} else {
nonceBytes := (bits.Len64(a.Nonce) + 7) / 8
value[pos] = byte(nonceBytes)
var nonce = a.Nonce
for i := nonceBytes; i > 0; i-- {
value[pos+i] = byte(nonce)
nonce >>= 8
}
pos += nonceBytes + 1
}
if a.Balance.IsZero() {
value[pos] = 0
pos++
} else {
balanceBytes := a.Balance.ByteLen()
value[pos] = byte(balanceBytes)
pos++
a.Balance.WriteToSlice(value[pos : pos+balanceBytes])
pos += balanceBytes
}
if a.IsEmptyCodeHash() {
value[pos] = 0
pos++
} else {
value[pos] = 32
pos++
copy(value[pos:pos+32], a.CodeHash[:])
pos += 32
}
if a.Incarnation == 0 {
value[pos] = 0
} else {
incBytes := (bits.Len64(a.Incarnation) + 7) / 8
value[pos] = byte(incBytes)
var inc = a.Incarnation
for i := incBytes; i > 0; i-- {
value[pos+i] = byte(inc)
inc >>= 8
}
}
}

0 comments on commit 4b4d271

Please sign in to comment.