mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2024-12-22 11:41:19 +00:00
Decoding incarnation and Tests (#2727)
This commit is contained in:
parent
5da7fb64bf
commit
3f1d51121c
@ -504,6 +504,7 @@ func (a *Account) DecodeForStorage(enc []byte) error {
|
||||
}
|
||||
|
||||
if fieldSet&8 > 0 {
|
||||
|
||||
decodeLength := int(enc[pos])
|
||||
|
||||
if decodeLength != 32 {
|
||||
@ -526,6 +527,54 @@ func (a *Account) DecodeForStorage(enc []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func DecodeIncarnationFromStorage(enc []byte) (uint64, error) {
|
||||
|
||||
if len(enc) == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
var fieldSet = enc[0]
|
||||
var pos = 1
|
||||
|
||||
//looks for the position incarnation is at
|
||||
if fieldSet&1 > 0 {
|
||||
decodeLength := int(enc[pos])
|
||||
if len(enc) < pos+decodeLength+1 {
|
||||
return 0, fmt.Errorf(
|
||||
"malformed CBOR for Account.Nonce: %s, Length %d",
|
||||
enc[pos+1:], decodeLength)
|
||||
}
|
||||
pos += decodeLength + 1
|
||||
}
|
||||
|
||||
if fieldSet&2 > 0 {
|
||||
decodeLength := int(enc[pos])
|
||||
if len(enc) < pos+decodeLength+1 {
|
||||
return 0, fmt.Errorf(
|
||||
"malformed CBOR for Account.Nonce: %s, Length %d",
|
||||
enc[pos+1:], decodeLength)
|
||||
}
|
||||
pos += decodeLength + 1
|
||||
}
|
||||
|
||||
if fieldSet&4 > 0 {
|
||||
decodeLength := int(enc[pos])
|
||||
|
||||
//checks if the ending position is correct if not returns 0
|
||||
if len(enc) < pos+decodeLength+1 {
|
||||
return 0, fmt.Errorf(
|
||||
"malformed CBOR for Account.Incarnation: %s, Length %d",
|
||||
enc[pos+1:], decodeLength)
|
||||
}
|
||||
|
||||
incarnation := bytesToUint64(enc[pos+1 : pos+decodeLength+1])
|
||||
return incarnation, nil
|
||||
}
|
||||
|
||||
return 0, nil
|
||||
|
||||
}
|
||||
|
||||
func (a *Account) SelfCopy() *Account {
|
||||
newAcc := NewAccount()
|
||||
newAcc.Copy(a)
|
||||
|
@ -289,6 +289,7 @@ func BenchmarkDecodingAccount(b *testing.B) {
|
||||
b.StartTimer()
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
b.StopTimer()
|
||||
@ -297,6 +298,78 @@ func BenchmarkDecodingAccount(b *testing.B) {
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkDecodingIncarnation(b *testing.B) {
|
||||
accountCases := []struct {
|
||||
name string
|
||||
acc *Account
|
||||
}{
|
||||
{
|
||||
name: "EmptyAccount",
|
||||
acc: &Account{
|
||||
Nonce: 0,
|
||||
Balance: *new(uint256.Int),
|
||||
Root: emptyRoot, // extAccount doesn't have Root value
|
||||
CodeHash: emptyCodeHash, // extAccount doesn't have CodeHash value
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
name: "AccountEncodeWithCode",
|
||||
acc: &Account{
|
||||
Nonce: 2,
|
||||
Balance: *new(uint256.Int).SetUint64(1000),
|
||||
Root: common.HexToHash("0000000000000000000000000000000000000000000000000000000000000021"),
|
||||
CodeHash: common.BytesToHash(crypto.Keccak256([]byte{1, 2, 3})),
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
name: "AccountEncodeWithCodeWithStorageSizeHack",
|
||||
acc: &Account{
|
||||
Nonce: 2,
|
||||
Balance: *new(uint256.Int).SetUint64(1000),
|
||||
Root: common.HexToHash("0000000000000000000000000000000000000000000000000000000000000021"),
|
||||
CodeHash: common.BytesToHash(crypto.Keccak256([]byte{1, 2, 3})),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
var decodedIncarnations []uint64
|
||||
b.ResetTimer()
|
||||
for _, test := range accountCases {
|
||||
test := test
|
||||
encodedAccount := make([]byte, test.acc.EncodingLengthForStorage())
|
||||
b.Run(fmt.Sprint(test.name), func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
b.StopTimer()
|
||||
|
||||
test.acc.Nonce = uint64(i)
|
||||
test.acc.Balance.SetUint64(uint64(i))
|
||||
test.acc.EncodeForStorage(encodedAccount)
|
||||
|
||||
b.StartTimer()
|
||||
|
||||
if _, err := DecodeIncarnationFromStorage(encodedAccount); err != nil {
|
||||
b.Fatal("can't decode the incarnation", err, encodedAccount)
|
||||
}
|
||||
|
||||
decodedIncarnation, _ := DecodeIncarnationFromStorage(encodedAccount)
|
||||
|
||||
b.StopTimer()
|
||||
decodedIncarnations = append(decodedIncarnations, decodedIncarnation)
|
||||
|
||||
b.StartTimer()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
b.StopTimer()
|
||||
for _, incarnation := range decodedIncarnations {
|
||||
fmt.Fprint(ioutil.Discard, incarnation)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func BenchmarkRLPEncodingAccount(b *testing.B) {
|
||||
accountCases := []struct {
|
||||
name string
|
||||
|
@ -189,3 +189,96 @@ func isAccountsEqual(t *testing.T, src, dst Account) {
|
||||
t.Fatal("cant decode the account Version", src.Incarnation, dst.Incarnation)
|
||||
}
|
||||
}
|
||||
|
||||
func testIncarnationForEmptyAccount(t *testing.T) {
|
||||
a := Account{
|
||||
Initialised: true,
|
||||
Nonce: 100,
|
||||
Balance: *new(uint256.Int),
|
||||
Root: emptyRoot,
|
||||
CodeHash: emptyCodeHash,
|
||||
Incarnation: 4,
|
||||
}
|
||||
|
||||
encodedAccount := make([]byte, a.EncodingLengthForStorage())
|
||||
a.EncodeForStorage(encodedAccount)
|
||||
var decodedIncarnation uint64
|
||||
if _, err := DecodeIncarnationFromStorage(encodedAccount); err != nil {
|
||||
t.Fatal("Can't decode the incarnation", err, encodedAccount)
|
||||
}
|
||||
|
||||
decodedIncarnation, _ = DecodeIncarnationFromStorage(encodedAccount)
|
||||
|
||||
isIncarnationEqual(t, a.Incarnation, decodedIncarnation)
|
||||
}
|
||||
|
||||
func testEmptyIncarnationForEmptyAccount2(t *testing.T) {
|
||||
a := Account{}
|
||||
|
||||
encodedAccount := make([]byte, a.EncodingLengthForStorage())
|
||||
a.EncodeForStorage(encodedAccount)
|
||||
|
||||
var decodedIncarnation uint64
|
||||
if _, err := DecodeIncarnationFromStorage(encodedAccount); err != nil {
|
||||
t.Fatal("Can't decode the incarnation", err, encodedAccount)
|
||||
}
|
||||
|
||||
decodedIncarnation, _ = DecodeIncarnationFromStorage(encodedAccount)
|
||||
|
||||
isIncarnationEqual(t, a.Incarnation, decodedIncarnation)
|
||||
|
||||
}
|
||||
|
||||
func testIncarnationWithNonEmptyAccount(t *testing.T) {
|
||||
a := Account{
|
||||
Initialised: true,
|
||||
Nonce: 2,
|
||||
Balance: *new(uint256.Int).SetUint64(1000),
|
||||
Root: common.HexToHash("0000000000000000000000000000000000000000000000000000000000000021"),
|
||||
CodeHash: common.BytesToHash(crypto.Keccak256([]byte{1, 2, 3})),
|
||||
Incarnation: 4,
|
||||
}
|
||||
|
||||
encodedAccount := make([]byte, a.EncodingLengthForStorage())
|
||||
a.EncodeForStorage(encodedAccount)
|
||||
|
||||
var decodedIncarnation uint64
|
||||
if _, err := DecodeIncarnationFromStorage(encodedAccount); err != nil {
|
||||
t.Fatal("Can't decode the incarnation", err, encodedAccount)
|
||||
}
|
||||
|
||||
decodedIncarnation, _ = DecodeIncarnationFromStorage(encodedAccount)
|
||||
|
||||
isIncarnationEqual(t, a.Incarnation, decodedIncarnation)
|
||||
|
||||
}
|
||||
|
||||
func testIncarnationWithNoIncarnation(t *testing.T) {
|
||||
a := Account{
|
||||
Initialised: true,
|
||||
Nonce: 2,
|
||||
Balance: *new(uint256.Int).SetUint64(1000),
|
||||
Root: common.HexToHash("0000000000000000000000000000000000000000000000000000000000000021"),
|
||||
CodeHash: common.BytesToHash(crypto.Keccak256([]byte{1, 2, 3})),
|
||||
Incarnation: 0,
|
||||
}
|
||||
|
||||
encodedAccount := make([]byte, a.EncodingLengthForStorage())
|
||||
a.EncodeForStorage(encodedAccount)
|
||||
|
||||
var decodedIncarnation uint64
|
||||
if _, err := DecodeIncarnationFromStorage(encodedAccount); err != nil {
|
||||
t.Fatal("Can't decode the incarnation", err, encodedAccount)
|
||||
}
|
||||
|
||||
decodedIncarnation, _ = DecodeIncarnationFromStorage(encodedAccount)
|
||||
|
||||
isIncarnationEqual(t, a.Incarnation, decodedIncarnation)
|
||||
|
||||
}
|
||||
|
||||
func isIncarnationEqual(t *testing.T, initialIncarnation uint64, decodedIncarnation uint64) {
|
||||
if initialIncarnation != decodedIncarnation {
|
||||
t.Fatal("Can't decode the incarnation", initialIncarnation, decodedIncarnation)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user