Add tests for decoding packed storage
This commit is contained in:
parent
b0fff9a1dd
commit
ebfb4965c7
@ -29,6 +29,8 @@ func Decode(row StorageDiffRow, metadata StorageValueMetadata) (interface{}, err
|
|||||||
return decodeUint256(row.StorageValue.Bytes()), nil
|
return decodeUint256(row.StorageValue.Bytes()), nil
|
||||||
case Uint48:
|
case Uint48:
|
||||||
return decodeUint48(row.StorageValue.Bytes()), nil
|
return decodeUint48(row.StorageValue.Bytes()), nil
|
||||||
|
case Uint128:
|
||||||
|
return decodeUint128(row.StorageValue.Bytes()), nil
|
||||||
case Address:
|
case Address:
|
||||||
return decodeAddress(row.StorageValue.Bytes()), nil
|
return decodeAddress(row.StorageValue.Bytes()), nil
|
||||||
case Bytes32:
|
case Bytes32:
|
||||||
@ -45,6 +47,11 @@ func decodeUint256(raw []byte) string {
|
|||||||
return n.String()
|
return n.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func decodeUint128(raw []byte) string {
|
||||||
|
n := big.NewInt(0).SetBytes(raw)
|
||||||
|
return n.String()
|
||||||
|
}
|
||||||
|
|
||||||
func decodeUint48(raw []byte) string {
|
func decodeUint48(raw []byte) string {
|
||||||
n := big.NewInt(0).SetBytes(raw)
|
n := big.NewInt(0).SetBytes(raw)
|
||||||
return n.String()
|
return n.String()
|
||||||
@ -54,14 +61,13 @@ func decodeAddress(raw []byte) string {
|
|||||||
return common.BytesToAddress(raw).Hex()
|
return common.BytesToAddress(raw).Hex()
|
||||||
}
|
}
|
||||||
|
|
||||||
//this may need to return a slice of strings, a string for each item
|
|
||||||
func decodePackedSlot(raw []byte, packedTypes map[int]ValueType) []string{
|
func decodePackedSlot(raw []byte, packedTypes map[int]ValueType) []string{
|
||||||
storageSlot := raw
|
storageSlot := raw
|
||||||
var results []string
|
var results []string
|
||||||
//the reason we're using a map and not a slice is that golang doesn't guarantee the order of a slice
|
//the reason we're using a map and not a slice is that golang doesn't guarantee the order of a slice
|
||||||
for _, valueType := range packedTypes {
|
for _, valueType := range packedTypes {
|
||||||
lengthOfStorageSlot := len(storageSlot)
|
lengthOfStorageSlot := len(storageSlot)
|
||||||
lengthOfItem := getLengthOfItem(valueType)
|
lengthOfItem := getNumberOfBytes(valueType)
|
||||||
itemStartingIndex := lengthOfStorageSlot - lengthOfItem
|
itemStartingIndex := lengthOfStorageSlot - lengthOfItem
|
||||||
value := storageSlot[itemStartingIndex:]
|
value := storageSlot[itemStartingIndex:]
|
||||||
decodedValue := decodeIndividualItems(value, valueType)
|
decodedValue := decodeIndividualItems(value, valueType)
|
||||||
@ -78,15 +84,20 @@ func decodeIndividualItems(itemBytes []byte, valueType ValueType) string {
|
|||||||
switch valueType {
|
switch valueType {
|
||||||
case Uint48:
|
case Uint48:
|
||||||
return decodeUint48(itemBytes)
|
return decodeUint48(itemBytes)
|
||||||
|
case Uint128:
|
||||||
|
return decodeUint128(itemBytes)
|
||||||
default:
|
default:
|
||||||
panic(fmt.Sprintf("can't decode unknown type: %d", valueType))
|
panic(fmt.Sprintf("can't decode unknown type: %d", valueType))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getLengthOfItem(valueType ValueType) int{
|
func getNumberOfBytes(valueType ValueType) int{
|
||||||
|
// 8 bits per byte
|
||||||
switch valueType {
|
switch valueType {
|
||||||
case Uint48:
|
case Uint48:
|
||||||
return 6
|
return 48 / 8
|
||||||
|
case Uint128:
|
||||||
|
return 128 / 8
|
||||||
default:
|
default:
|
||||||
panic(fmt.Sprintf("ValueType %d not recognized", valueType))
|
panic(fmt.Sprintf("ValueType %d not recognized", valueType))
|
||||||
}
|
}
|
||||||
|
@ -17,11 +17,10 @@
|
|||||||
package utils_test
|
package utils_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math/big"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
|
"math/big"
|
||||||
|
|
||||||
"github.com/vulcanize/vulcanizedb/libraries/shared/storage/utils"
|
"github.com/vulcanize/vulcanizedb/libraries/shared/storage/utils"
|
||||||
)
|
)
|
||||||
@ -38,6 +37,17 @@ var _ = Describe("Storage decoder", func() {
|
|||||||
Expect(result).To(Equal(big.NewInt(0).SetBytes(fakeInt.Bytes()).String()))
|
Expect(result).To(Equal(big.NewInt(0).SetBytes(fakeInt.Bytes()).String()))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("decodes uint128", func() {
|
||||||
|
fakeInt := common.HexToHash("0000000000000000000000000000000000000000000000000000000000011123")
|
||||||
|
row := utils.StorageDiffRow{StorageValue: fakeInt}
|
||||||
|
metadata := utils.StorageValueMetadata{Type: utils.Uint128}
|
||||||
|
|
||||||
|
result, err := utils.Decode(row, metadata)
|
||||||
|
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
Expect(result).To(Equal(big.NewInt(0).SetBytes(fakeInt.Bytes()).String()))
|
||||||
|
})
|
||||||
|
|
||||||
It("decodes uint48", func() {
|
It("decodes uint48", func() {
|
||||||
fakeInt := common.HexToHash("0000000000000000000000000000000000000000000000000000000000000123")
|
fakeInt := common.HexToHash("0000000000000000000000000000000000000000000000000000000000000123")
|
||||||
row := utils.StorageDiffRow{StorageValue: fakeInt}
|
row := utils.StorageDiffRow{StorageValue: fakeInt}
|
||||||
@ -49,8 +59,20 @@ var _ = Describe("Storage decoder", func() {
|
|||||||
Expect(result).To(Equal(big.NewInt(0).SetBytes(fakeInt.Bytes()).String()))
|
Expect(result).To(Equal(big.NewInt(0).SetBytes(fakeInt.Bytes()).String()))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("decodes address", func() {
|
||||||
|
fakeAddress := common.HexToAddress("0x12345")
|
||||||
|
row := utils.StorageDiffRow{StorageValue: fakeAddress.Hash()}
|
||||||
|
metadata := utils.StorageValueMetadata{Type: utils.Address}
|
||||||
|
|
||||||
|
result, err := utils.Decode(row, metadata)
|
||||||
|
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
Expect(result).To(Equal(fakeAddress.Hex()))
|
||||||
|
})
|
||||||
|
|
||||||
Describe("when there are multiple items packed in the storage slot", func() {
|
Describe("when there are multiple items packed in the storage slot", func() {
|
||||||
It("decodes the first uint48 item packed in", func() {
|
It("decodes uint48 items", func() {
|
||||||
|
//this is a real storage data example
|
||||||
packedStorage := common.HexToHash("000000000000000000000000000000000000000000000002a300000000002a30")
|
packedStorage := common.HexToHash("000000000000000000000000000000000000000000000002a300000000002a30")
|
||||||
row := utils.StorageDiffRow{StorageValue: packedStorage}
|
row := utils.StorageDiffRow{StorageValue: packedStorage}
|
||||||
packedTypes := map[int]utils.ValueType{}
|
packedTypes := map[int]utils.ValueType{}
|
||||||
@ -68,20 +90,63 @@ var _ = Describe("Storage decoder", func() {
|
|||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
expectedResult1 := big.NewInt(0).SetBytes(common.HexToHash("2a30").Bytes()).String()
|
expectedResult1 := big.NewInt(0).SetBytes(common.HexToHash("2a30").Bytes()).String()
|
||||||
expectedResult2 := big.NewInt(0).SetBytes(common.HexToHash("2a300").Bytes()).String()
|
expectedResult2 := big.NewInt(0).SetBytes(common.HexToHash("2a300").Bytes()).String()
|
||||||
Expect(decodedValues[0]).To(Equal(expectedResult1))
|
Expect(decodedValues).To(ConsistOf(expectedResult1, expectedResult2))
|
||||||
Expect(decodedValues[1]).To(Equal(expectedResult2))
|
|
||||||
})
|
})
|
||||||
|
|
||||||
})
|
It("decodes 5 uint48 items", func() {
|
||||||
|
//TODO: this packedStorageHex was generated by hand, it would be nice to test this against
|
||||||
|
//real storage data that has several items packed into it
|
||||||
|
packedStorageHex := "0000000A5D1AFFFFFFFFFFFE00000009F3C600000002A300000000002A30"
|
||||||
|
|
||||||
It("decodes address", func() {
|
packedStorage := common.HexToHash(packedStorageHex)
|
||||||
fakeAddress := common.HexToAddress("0x12345")
|
row := utils.StorageDiffRow{StorageValue: packedStorage}
|
||||||
row := utils.StorageDiffRow{StorageValue: fakeAddress.Hash()}
|
packedTypes := map[int]utils.ValueType{}
|
||||||
metadata := utils.StorageValueMetadata{Type: utils.Address}
|
packedTypes[0] = utils.Uint48
|
||||||
|
packedTypes[1] = utils.Uint48
|
||||||
|
packedTypes[2] = utils.Uint48
|
||||||
|
packedTypes[3] = utils.Uint48
|
||||||
|
packedTypes[4] = utils.Uint48
|
||||||
|
|
||||||
result, err := utils.Decode(row, metadata)
|
metadata := utils.StorageValueMetadata{
|
||||||
|
Type: utils.PackedSlot,
|
||||||
|
PackedTypes: packedTypes,
|
||||||
|
}
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
result, err := utils.Decode(row, metadata)
|
||||||
Expect(result).To(Equal(fakeAddress.Hex()))
|
decodedValues := result.([]string)
|
||||||
|
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
expectedResult1 := big.NewInt(0).SetBytes(common.HexToHash("A5D1A").Bytes()).String()
|
||||||
|
expectedResult2 := big.NewInt(0).SetBytes(common.HexToHash("FFFFFFFFFFFE").Bytes()).String()
|
||||||
|
expectedResult3 := big.NewInt(0).SetBytes(common.HexToHash("9F3C6").Bytes()).String()
|
||||||
|
expectedResult4 := big.NewInt(0).SetBytes(common.HexToHash("2a300").Bytes()).String()
|
||||||
|
expectedResult5 := big.NewInt(0).SetBytes(common.HexToHash("2a30").Bytes()).String()
|
||||||
|
Expect(decodedValues).To(ConsistOf(expectedResult1, expectedResult2, expectedResult3, expectedResult4, expectedResult5))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("decodes 2 uint128 items", func() {
|
||||||
|
//TODO: this packedStorageHex was generated by hand, it would be nice to test this against
|
||||||
|
//real storage data that has several items packed into it
|
||||||
|
packedStorageHex := "000000038D7EA4C67FF8E502B6730000" +
|
||||||
|
"0000000000000000AB54A98CEB1F0AD2"
|
||||||
|
packedStorage := common.HexToHash(packedStorageHex)
|
||||||
|
row := utils.StorageDiffRow{StorageValue: packedStorage}
|
||||||
|
packedTypes := map[int]utils.ValueType{}
|
||||||
|
packedTypes[0] = utils.Uint128
|
||||||
|
packedTypes[1] = utils.Uint128
|
||||||
|
|
||||||
|
metadata := utils.StorageValueMetadata{
|
||||||
|
Type: utils.PackedSlot,
|
||||||
|
PackedTypes: packedTypes,
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := utils.Decode(row, metadata)
|
||||||
|
decodedValues := result.([]string)
|
||||||
|
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
expectedResult1 := big.NewInt(0).SetBytes(common.HexToHash("000000038D7EA4C67FF8E502B6730000").Bytes()).String()
|
||||||
|
expectedResult2 := big.NewInt(0).SetBytes(common.HexToHash("AB54A98CEB1F0AD2").Bytes()).String()
|
||||||
|
Expect(decodedValues).To(ConsistOf(expectedResult1, expectedResult2))
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -21,6 +21,7 @@ type ValueType int
|
|||||||
const (
|
const (
|
||||||
Uint256 ValueType = iota
|
Uint256 ValueType = iota
|
||||||
Uint48
|
Uint48
|
||||||
|
Uint128
|
||||||
Bytes32
|
Bytes32
|
||||||
Address
|
Address
|
||||||
PackedSlot
|
PackedSlot
|
||||||
|
Loading…
Reference in New Issue
Block a user