Potential fix for sync failure at block 2792476 ()

* Fixes

* Fix

* Fix to stream
This commit is contained in:
ledgerwatch 2020-05-07 06:58:37 +01:00 committed by GitHub
parent 8cde4d5c4c
commit c391731dc4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 53 additions and 35 deletions

View File

@ -260,13 +260,13 @@ func (hb *HashBuilder) accountLeafHash(length int, keyHex []byte, storageSize ui
hb.acc.Incarnation = incarnation
popped := 0
if fieldSet&uint32(4) != 0 {
if fieldSet&AccountFieldStorageOnly != 0 {
copy(hb.acc.Root[:], hb.hashStack[len(hb.hashStack)-popped*hashStackStride-common.HashLength:len(hb.hashStack)-popped*hashStackStride])
popped++
} else {
copy(hb.acc.Root[:], EmptyRoot[:])
}
if fieldSet&uint32(8) != 0 {
if fieldSet&AccountFieldCodeOnly != 0 {
copy(hb.acc.CodeHash[:], hb.hashStack[len(hb.hashStack)-popped*hashStackStride-common.HashLength:len(hb.hashStack)-popped*hashStackStride])
popped++
} else {

View File

@ -144,13 +144,10 @@ func (tr *Resolver) Print() {
const (
AccountFieldNonceOnly uint32 = 0x01
AccountFieldBalanceOnly uint32 = 0x02
AccountFieldRootOnly uint32 = 0x04
AccountFieldCodeHashOnly uint32 = 0x08
AccountFieldStorageOnly uint32 = 0x04
AccountFieldCodeOnly uint32 = 0x08
AccountFieldSSizeOnly uint32 = 0x10
AccountFieldSetNotAccount uint32 = 0x00
AccountFieldSetNotContract uint32 = 0x03 // Bit 0 is set for nonce, bit 1 is set for balance
AccountFieldSetContract uint32 = 0x0f // Bits 0-3 are set for nonce, balance, storageRoot and codeHash
AccountFieldSetContractWithSize uint32 = 0x1f // Bits 0-4 are set for nonce, balance, storageRoot, codeHash and storageSize
)
// ResolveWithDb resolves and hooks subtries using a state database.

View File

@ -221,34 +221,35 @@ func (tr *ResolverStateful) finaliseRoot() error {
tr.currStorage.Reset()
tr.succStorage.Reset()
}
if tr.a.IsEmptyCodeHash() && tr.a.IsEmptyRoot() {
tr.accData.FieldSet = AccountFieldSetNotContract
} else {
tr.accData.FieldSet = AccountFieldSetContract
tr.accData.FieldSet = 0
if !tr.a.IsEmptyCodeHash() {
tr.accData.FieldSet |= AccountFieldCodeOnly
}
if storageNode != nil || !tr.a.IsEmptyRoot() {
tr.accData.FieldSet |= AccountFieldStorageOnly
}
tr.accData.Balance.Set(&tr.a.Balance)
if tr.a.Balance.Sign() != 0 {
tr.accData.FieldSet |= AccountFieldBalanceOnly
}
tr.accData.Nonce = tr.a.Nonce
if tr.a.Nonce != 0 {
tr.accData.FieldSet |= AccountFieldNonceOnly
}
tr.accData.Incarnation = tr.a.Incarnation
data = &tr.accData
if !tr.a.IsEmptyCodeHash() || !tr.a.IsEmptyRoot() {
if !tr.a.IsEmptyCodeHash() {
// the first item ends up deepest on the stack, the second item - on the top
err = tr.hb.hash(tr.a.CodeHash[:])
if err != nil {
return err
}
//if tr.hb.trace {
// fmt.Printf("HASH\n")
//}
}
if storageNode != nil || !tr.a.IsEmptyRoot() {
tr.hb.hashStack = append(tr.hb.hashStack, 0x80+common.HashLength)
tr.hb.hashStack = append(tr.hb.hashStack, tr.a.Root[:]...)
tr.hb.nodeStack = append(tr.hb.nodeStack, storageNode)
// err = tr.hb.hash(tr.a.Root[:])
// if err != nil {
// return err
// }
}
}
tr.groups, err = GenStructStep(tr.currentRsChopped.HashOnly, tr.curr.Bytes(), tr.succ.Bytes(), tr.hb, data, tr.groups, false)
@ -602,24 +603,32 @@ func (tr *ResolverStateful) WalkerAccount(isIH bool, keyIdx int, k, v []byte) er
}
}
}
if tr.a.IsEmptyCodeHash() && tr.a.IsEmptyRoot() {
tr.accData.FieldSet = AccountFieldSetNotContract
} else {
tr.accData.FieldSet = AccountFieldSetContract
tr.accData.FieldSet = 0
if !tr.a.IsEmptyCodeHash() {
tr.accData.FieldSet |= AccountFieldCodeOnly
}
if storageNode != nil || !tr.a.IsEmptyRoot() {
tr.accData.FieldSet |= AccountFieldStorageOnly
}
tr.accData.Balance.Set(&tr.a.Balance)
if tr.a.Balance.Sign() != 0 {
tr.accData.FieldSet |= AccountFieldBalanceOnly
}
tr.accData.Nonce = tr.a.Nonce
if tr.a.Nonce != 0 {
tr.accData.FieldSet |= AccountFieldNonceOnly
}
tr.accData.Incarnation = tr.a.Incarnation
data = &tr.accData
if !tr.a.IsEmptyCodeHash() || !tr.a.IsEmptyRoot() {
if !tr.a.IsEmptyCodeHash() {
// the first item ends up deepest on the stack, the second item - on the top
err = tr.hb.hash(tr.a.CodeHash[:])
if err != nil {
return err
}
}
if storageNode != nil || !tr.a.IsEmptyRoot() {
tr.hb.hashStack = append(tr.hb.hashStack, 0x80+common.HashLength)
tr.hb.hashStack = append(tr.hb.hashStack, tr.a.Root[:]...)
tr.hb.nodeStack = append(tr.hb.nodeStack, storageNode)

View File

@ -583,6 +583,7 @@ func StreamHash(it *StreamMergeIterator, storagePrefixLen int, hb *HashBuilder,
var groups, sGroups []uint16 // Separate groups slices for storage items and for accounts
var aRoot common.Hash
var aEmptyRoot = true
var isAccount bool
var fieldSet uint32
var itemType, sItemType StreamItem
var hashData GenStructStepHashData
@ -597,7 +598,7 @@ func StreamHash(it *StreamMergeIterator, storagePrefixLen int, hb *HashBuilder,
if hashRef != nil {
copy(hashData.Hash[:], hashRef)
return &hashData
} else if fieldSet == AccountFieldSetNotAccount {
} else if !isAccount {
leafData.Value = rlphacks.RlpSerializableBytes(value.Bytes())
return &leafData
} else {
@ -615,25 +616,27 @@ func StreamHash(it *StreamMergeIterator, storagePrefixLen int, hb *HashBuilder,
currStorage.Write(succStorage.Bytes())
succStorage.Reset()
if currStorage.Len() > 0 {
isAccount = false
var err error
sGroups, err = GenStructStep(hashOnly, currStorage.Bytes(), succStorage.Bytes(), hb, makeData(AccountFieldSetNotAccount, hashRefStorage), sGroups, trace)
if err != nil {
return common.Hash{}, err
}
currStorage.Reset()
fieldSet += AccountFieldRootOnly
fieldSet += AccountFieldStorageOnly
}
} else if itemType == AccountStreamItem && !aEmptyRoot {
if err := hb.hash(aRoot[:]); err != nil {
return common.Hash{}, err
}
fieldSet += AccountFieldRootOnly
fieldSet += AccountFieldStorageOnly
}
curr.Reset()
curr.Write(succ.Bytes())
succ.Reset()
succ.Write(hex)
if curr.Len() > 0 {
isAccount = true
var err error
groups, err = GenStructStep(hashOnly, curr.Bytes(), succ.Bytes(), hb, makeData(fieldSet, hashRef), groups, trace)
if err != nil {
@ -649,9 +652,15 @@ func StreamHash(it *StreamMergeIterator, storagePrefixLen int, hb *HashBuilder,
accData.Incarnation = a.Incarnation
aEmptyRoot = a.IsEmptyRoot()
copy(aRoot[:], a.Root[:])
fieldSet = AccountFieldSetNotContract // base level - nonce and balance
fieldSet = 0
if a.Balance.Sign() != 0 {
fieldSet |= AccountFieldBalanceOnly
}
if a.Nonce != 0 {
fieldSet |= AccountFieldNonceOnly
}
if !a.IsEmptyCodeHash() {
fieldSet += AccountFieldCodeHashOnly
fieldSet |= AccountFieldCodeOnly
if err := hb.hash(a.CodeHash[:]); err != nil {
return common.Hash{}, err
}
@ -667,6 +676,7 @@ func StreamHash(it *StreamMergeIterator, storagePrefixLen int, hb *HashBuilder,
succStorage.Reset()
succStorage.Write(hex[2*storagePrefixLen+1:])
if currStorage.Len() > 0 {
isAccount = false
var err error
sGroups, err = GenStructStep(hashOnly, currStorage.Bytes(), succStorage.Bytes(), hb, makeData(AccountFieldSetNotAccount, hashRefStorage), sGroups, trace)
if err != nil {
@ -691,24 +701,26 @@ func StreamHash(it *StreamMergeIterator, storagePrefixLen int, hb *HashBuilder,
currStorage.Write(succStorage.Bytes())
succStorage.Reset()
if currStorage.Len() > 0 {
isAccount = false
var err error
_, err = GenStructStep(hashOnly, currStorage.Bytes(), succStorage.Bytes(), hb, makeData(AccountFieldSetNotAccount, hashRefStorage), sGroups, trace)
if err != nil {
return common.Hash{}, err
}
currStorage.Reset()
fieldSet += AccountFieldRootOnly
fieldSet |= AccountFieldStorageOnly
}
} else if itemType == AccountStreamItem && !aEmptyRoot {
if err := hb.hash(aRoot[:]); err != nil {
return common.Hash{}, err
}
fieldSet += AccountFieldRootOnly
fieldSet |= AccountFieldStorageOnly
}
curr.Reset()
curr.Write(succ.Bytes())
succ.Reset()
if curr.Len() > 0 {
isAccount = true
var err error
_, err = GenStructStep(hashOnly, curr.Bytes(), succ.Bytes(), hb, makeData(fieldSet, hashRef), groups, trace)
if err != nil {