76: Add indexing of ExecutionPayloads (and other Merge-related updates). #73

Merged
telackey merged 30 commits from telackey/the_merge into main 2022-09-29 01:39:56 +00:00
4 changed files with 475 additions and 93 deletions
Showing only changes of commit 2a426c260c - Show all commits

View File

@ -20,6 +20,7 @@ import (
"encoding/hex" "encoding/hex"
"encoding/json" "encoding/json"
"fmt" "fmt"
consensus "github.com/umbracle/go-eth-consensus"
"net/http" "net/http"
"os" "os"
"path/filepath" "path/filepath"
@ -29,11 +30,6 @@ import (
"github.com/jarcoal/httpmock" "github.com/jarcoal/httpmock"
. "github.com/onsi/ginkgo/v2" . "github.com/onsi/ginkgo/v2"
"github.com/prysmaticlabs/prysm/beacon-chain/state"
si "github.com/prysmaticlabs/prysm/consensus-types/interfaces"
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
dt "github.com/prysmaticlabs/prysm/encoding/ssz/detect"
st "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
"github.com/r3labs/sse" "github.com/r3labs/sse"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
@ -49,10 +45,10 @@ var (
port int = 8080 port int = 8080
protocol string = "http" protocol string = "http"
dbHost string = "localhost" dbHost string = "localhost"
dbPort int = 8076 dbPort int = 15432
dbName string = "vulcanize_testing" dbName string = "postgres"
dbUser string = "vdbm" dbUser string = "postgres"
dbPassword string = "password" dbPassword string = "secret12"
dbDriver string = "pgx" dbDriver string = "pgx"
bcUniqueIdentifier int = 100 bcUniqueIdentifier int = 100
dummyParentRoot string = "46f98c08b54a71dfda4d56e29ec3952b8300cd8d6b67a9b6c562ae96a7a25a42" dummyParentRoot string = "46f98c08b54a71dfda4d56e29ec3952b8300cd8d6b67a9b6c562ae96a7a25a42"
@ -332,12 +328,12 @@ var _ = Describe("Capturehead", Label("head"), func() {
}) })
}) })
Context("Phase 0: We have a correctly formated SSZ SignedBeaconBlock and BeaconState", func() { Context("Phase 0: We have a correctly formated SSZ SignedBeaconBlock and BeaconState", func() {
It("Should be able to get each objects root hash.", func() { It("Should be able to get each objects root hash (100).", func() {
testSszRoot(BeaconNodeTester.TestEvents["100"]) testSszRoot(BeaconNodeTester.TestEvents["100"])
}) })
}) })
Context("Altair: We have a correctly formated SSZ SignedBeaconBlock and BeaconState", func() { Context("Altair: We have a correctly formated SSZ SignedBeaconBlock and BeaconState", func() {
It("Should be able to get each objects root hash.", func() { It("Should be able to get each objects root hash (2375703).", func() {
testSszRoot(BeaconNodeTester.TestEvents["2375703"]) testSszRoot(BeaconNodeTester.TestEvents["2375703"])
}) })
}) })
@ -566,22 +562,22 @@ func queryDbSlotAndBlock(db sql.Database, querySlot string, queryBlockRoot strin
func queryDbSignedBeaconBlock(db sql.Database, querySlot string, queryBlockRoot string) (int, string, string, string, string) { func queryDbSignedBeaconBlock(db sql.Database, querySlot string, queryBlockRoot string) (int, string, string, string, string) {
sqlStatement := `SELECT slot, block_root, parent_block_root, eth1_block_hash, mh_key FROM eth_beacon.signed_block WHERE slot=$1 AND block_root=$2;` sqlStatement := `SELECT slot, block_root, parent_block_root, eth1_block_hash, mh_key FROM eth_beacon.signed_block WHERE slot=$1 AND block_root=$2;`
var slot int var slot int
var blockRoot, parent_block_root, eth1_block_hash, mh_key string var blockRoot, parentBlockRoot, eth1BlockHash, mhKey string
row := db.QueryRow(context.Background(), sqlStatement, querySlot, queryBlockRoot) row := db.QueryRow(context.Background(), sqlStatement, querySlot, queryBlockRoot)
err := row.Scan(&slot, &blockRoot, &parent_block_root, &eth1_block_hash, &mh_key) err := row.Scan(&slot, &blockRoot, &parentBlockRoot, &eth1BlockHash, &mhKey)
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
return slot, blockRoot, parent_block_root, eth1_block_hash, mh_key return slot, blockRoot, parentBlockRoot, eth1BlockHash, mhKey
} }
// A helper function to query the eth_beacon.signed_block table based on the slot and block_root. // A helper function to query the eth_beacon.signed_block table based on the slot and block_root.
func queryDbBeaconState(db sql.Database, querySlot string, queryStateRoot string) (int, string, string) { func queryDbBeaconState(db sql.Database, querySlot string, queryStateRoot string) (int, string, string) {
sqlStatement := `SELECT slot, state_root, mh_key FROM eth_beacon.state WHERE slot=$1 AND state_root=$2;` sqlStatement := `SELECT slot, state_root, mh_key FROM eth_beacon.state WHERE slot=$1 AND state_root=$2;`
var slot int var slot int
var stateRoot, mh_key string var stateRoot, mhKey string
row := db.QueryRow(context.Background(), sqlStatement, querySlot, queryStateRoot) row := db.QueryRow(context.Background(), sqlStatement, querySlot, queryStateRoot)
err := row.Scan(&slot, &stateRoot, &mh_key) err := row.Scan(&slot, &stateRoot, &mhKey)
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
return slot, stateRoot, mh_key return slot, stateRoot, mhKey
} }
// Count the entries in the knownGaps table. // Count the entries in the knownGaps table.
@ -620,55 +616,27 @@ func writeSlot(db sql.Database, slot string) {
// Read a file with the SignedBeaconBlock in SSZ and return the SSZ object. This is used for testing only. // Read a file with the SignedBeaconBlock in SSZ and return the SSZ object. This is used for testing only.
// We can't use the readSignedBeaconBlockInterface to update struct fields so this is the workaround. // We can't use the readSignedBeaconBlockInterface to update struct fields so this is the workaround.
func readSignedBeaconBlock(slotFile string) (*st.SignedBeaconBlock, error) { func readSignedBeaconBlock(slotFile string) (*beaconclient.SignedBeaconBlock, error) {
dat, err := os.ReadFile(slotFile) dat, err := os.ReadFile(slotFile)
if err != nil { if err != nil {
return nil, fmt.Errorf("Can't find the slot file, %s", slotFile) return nil, fmt.Errorf("Can't find the slot file, %s", slotFile)
} }
block := &st.SignedBeaconBlock{} var block beaconclient.SignedBeaconBlock
err = block.UnmarshalSSZ(dat) err = block.UnmarshalSSZ(dat)
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
return block, nil return &block, nil
}
// Read a file with the SignedBeaconBlock in SSZ and return the SSZ object. This is used for testing only.
// We can't use the readSignedBeaconBlockInterface to update struct fields so this is the workaround.
func readSignedBeaconBlockAltair(slotFile string) (*st.SignedBeaconBlockAltair, error) {
dat, err := os.ReadFile(slotFile)
if err != nil {
return nil, fmt.Errorf("Can't find the slot file, %s", slotFile)
}
block := &st.SignedBeaconBlockAltair{}
err = block.UnmarshalSSZ(dat)
Expect(err).ToNot(HaveOccurred())
return block, nil
}
// Read a file with the SignedBeaconBlock in SSZ and return the SSZ objects interface. This is production like.
// It will provide the correct struct for the given fork.
func readSignedBeaconBlockInterface(slotFile string, vm *dt.VersionedUnmarshaler) (si.SignedBeaconBlock, error) {
dat, err := os.ReadFile(slotFile)
if err != nil {
return nil, fmt.Errorf("Can't find the slot file, %s", slotFile)
}
block, err := vm.UnmarshalBeaconBlock(dat)
Expect(err).ToNot(HaveOccurred())
return block, nil
} }
// Read a file with the BeaconState in SSZ and return the SSZ object // Read a file with the BeaconState in SSZ and return the SSZ object
func readBeaconState(slotFile string) (state.BeaconState, *dt.VersionedUnmarshaler, error) { func readBeaconState(slotFile string) (*beaconclient.BeaconState, error) {
dat, err := os.ReadFile(slotFile) dat, err := os.ReadFile(slotFile)
if err != nil { if err != nil {
return nil, nil, fmt.Errorf("Can't find the slot file, %s", slotFile) return nil, fmt.Errorf("Can't find the slot file, %s", slotFile)
} }
versionedUnmarshaler, err := dt.FromState(dat) var beaconState beaconclient.BeaconState
err = beaconState.UnmarshalSSZ(dat)
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
state, err := versionedUnmarshaler.UnmarshalBeaconState(dat) return &beaconState, nil
Expect(err).ToNot(HaveOccurred())
return state, versionedUnmarshaler, nil
} }
// An object that is used to aggregate test functions. Test functions are needed because we need to // An object that is used to aggregate test functions. Test functions are needed because we need to
@ -768,52 +736,62 @@ func (tbc TestBeaconNode) provideSsz(slotIdentifier string, sszIdentifier string
if err != nil { if err != nil {
return nil, err return nil, err
} }
Expect(block.IsPhase0()).To(BeTrue())
var phase0 = block.GetPhase0()
slot, err := strconv.ParseUint(Message.HeadMessage.Slot, 10, 64) slot, err := strconv.ParseUint(Message.HeadMessage.Slot, 10, 64)
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
block.Block.Slot = types.Slot(slot) phase0.Block.Slot = slot
block.Block.StateRoot, err = hex.DecodeString(Message.HeadMessage.State) phase0.Block.StateRoot, err = decodeRoot(Message.HeadMessage.State)
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
if Message.MimicConfig.ParentRoot == "" { if Message.MimicConfig.ParentRoot == "" {
block.Block.ParentRoot, err = hex.DecodeString(dummyParentRoot) phase0.Block.ParentRoot, err = decodeRoot(dummyParentRoot)
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
} else { } else {
block.Block.ParentRoot, err = hex.DecodeString(Message.MimicConfig.ParentRoot) phase0.Block.ParentRoot, err = decodeRoot(Message.MimicConfig.ParentRoot)
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
} }
return block.MarshalSSZ() return block.MarshalSSZ()
case "altair": case "altair":
block, err := readSignedBeaconBlockAltair(slotFile) block, err := readSignedBeaconBlock(slotFile)
if err != nil { if err != nil {
return nil, err return nil, err
} }
Expect(block.IsAltair()).To(BeTrue())
var altair = block.GetAltair()
slot, err := strconv.ParseUint(Message.HeadMessage.Slot, 10, 64) slot, err := strconv.ParseUint(Message.HeadMessage.Slot, 10, 64)
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
block.Block.Slot = types.Slot(slot) altair.Block.Slot = slot
block.Block.StateRoot, err = hex.DecodeString(Message.HeadMessage.State) altair.Block.StateRoot, err = decodeRoot(Message.HeadMessage.State)
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
if Message.MimicConfig.ParentRoot == "" { if Message.MimicConfig.ParentRoot == "" {
block.Block.ParentRoot, err = hex.DecodeString(dummyParentRoot) altair.Block.ParentRoot, err = decodeRoot(dummyParentRoot)
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
} else { } else {
block.Block.ParentRoot, err = hex.DecodeString(Message.MimicConfig.ParentRoot) altair.Block.ParentRoot, err = decodeRoot(Message.MimicConfig.ParentRoot)
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
} }
return block.MarshalSSZ() return block.MarshalSSZ()
} }
} }
if sszIdentifier == "state" { if sszIdentifier == "state" {
state, _, err := readBeaconState(slotFile) state, err := readBeaconState(slotFile)
if err != nil { if err != nil {
return nil, err return nil, err
} }
slot, err := strconv.ParseUint(Message.HeadMessage.Slot, 10, 64) slot, err := strconv.ParseUint(Message.HeadMessage.Slot, 10, 64)
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
err = state.SetSlot(types.Slot(slot)) if state.IsBellatrix() {
Expect(err).ToNot(HaveOccurred()) state.GetBellatrix().Slot = slot
} else if state.IsAltair() {
state.GetAltair().Slot = slot
} else {
state.GetPhase0().Slot = slot
}
return state.MarshalSSZ() return state.MarshalSSZ()
} }
} }
@ -979,15 +957,25 @@ func (tbc TestBeaconNode) testKnownGapsMessages(bc *beaconclient.BeaconClient, t
// This function will make sure we are properly able to get the SszRoot of the SignedBeaconBlock and the BeaconState. // This function will make sure we are properly able to get the SszRoot of the SignedBeaconBlock and the BeaconState.
func testSszRoot(msg Message) { func testSszRoot(msg Message) {
state, vm, err := readBeaconState(msg.BeaconState) state, err := readBeaconState(msg.BeaconState)
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
stateRoot, err := state.HashTreeRoot(context.Background()) stateRoot, err := state.HashTreeRoot()
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
Expect(msg.HeadMessage.State).To(Equal("0x" + hex.EncodeToString(stateRoot[:]))) Expect(msg.HeadMessage.State).To(Equal("0x" + hex.EncodeToString(stateRoot[:])))
block, err := readSignedBeaconBlockInterface(msg.SignedBeaconBlock, vm) block, err := readSignedBeaconBlock(msg.SignedBeaconBlock)
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
blockRoot, err := block.Block().HashTreeRoot() blockRoot, err := block.Block().HashTreeRoot()
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
Expect(msg.HeadMessage.Block).To(Equal("0x" + hex.EncodeToString(blockRoot[:]))) Expect(msg.HeadMessage.Block).To(Equal("0x" + hex.EncodeToString(blockRoot[:])))
} }
func decodeRoot(raw string) (consensus.Root, error) {
value, err := hex.DecodeString(raw)
if err != nil {
return consensus.Root{}, err
}
var root consensus.Root
copy(root[:], value[:32])
return root, nil
}

View File

@ -0,0 +1,366 @@
package beaconclient
import (
"errors"
log "github.com/sirupsen/logrus"
consensus "github.com/umbracle/go-eth-consensus"
)
type SignedBeaconBlock struct {
signedBeaconBlockBellatrix *consensus.SignedBeaconBlockBellatrix
signedBeaconBlockAltair *consensus.SignedBeaconBlockAltair
signedBeaconBlockPhase0 *consensus.SignedBeaconBlockPhase0
}
type BeaconBlock struct {
beaconBlockBellatrix *consensus.BeaconBlockBellatrix
beaconBlockAltair *consensus.BeaconBlockAltair
beaconBlockPhase0 *consensus.BeaconBlockPhase0
}
type BeaconBlockBody struct {
beaconBlockBodyBellatrix *consensus.BeaconBlockBodyBellatrix
beaconBlockBodyAltair *consensus.BeaconBlockBodyAltair
beaconBlockBodyPhase0 *consensus.BeaconBlockBodyPhase0
}
type BeaconState struct {
beaconStateBellatrix *consensus.BeaconStateBellatrix
beaconStateAltair *consensus.BeaconStateAltair
beaconStatePhase0 *consensus.BeaconStatePhase0
}
func (s *SignedBeaconBlock) UnmarshalSSZ(ssz []byte) error {
var bellatrix consensus.SignedBeaconBlockBellatrix
err := bellatrix.UnmarshalSSZ(ssz)
if nil == err {
s.signedBeaconBlockBellatrix = &bellatrix
s.signedBeaconBlockAltair = nil
s.signedBeaconBlockPhase0 = nil
log.Info("Unmarshalled Bellatrix SignedBeaconBlock")
return nil
}
var altair consensus.SignedBeaconBlockAltair
err = altair.UnmarshalSSZ(ssz)
if nil == err {
s.signedBeaconBlockBellatrix = nil
s.signedBeaconBlockAltair = &altair
s.signedBeaconBlockPhase0 = nil
log.Info("Unmarshalled Altair SignedBeaconBlock")
return nil
}
var phase0 consensus.SignedBeaconBlockPhase0
err = phase0.UnmarshalSSZ(ssz)
if nil == err {
s.signedBeaconBlockBellatrix = nil
s.signedBeaconBlockAltair = nil
s.signedBeaconBlockPhase0 = &phase0
log.Info("Unmarshalled Phase0 SignedBeaconBlock")
return nil
}
s.signedBeaconBlockBellatrix = nil
s.signedBeaconBlockAltair = nil
s.signedBeaconBlockPhase0 = nil
log.Warning("Unable to unmarshal SignedBeaconBlock")
return err
}
func (s *SignedBeaconBlock) MarshalSSZ() ([]byte, error) {
if s.IsBellatrix() {
return s.signedBeaconBlockBellatrix.MarshalSSZ()
}
if s.IsAltair() {
return s.signedBeaconBlockAltair.MarshalSSZ()
}
if s.IsPhase0() {
return s.signedBeaconBlockPhase0.MarshalSSZ()
}
return []byte{}, errors.New("SignedBeaconBlock not set")
}
func (s *SignedBeaconBlock) IsBellatrix() bool {
return s.signedBeaconBlockBellatrix != nil
}
func (s *SignedBeaconBlock) IsAltair() bool {
return s.signedBeaconBlockAltair != nil
}
func (s *SignedBeaconBlock) IsPhase0() bool {
return s.signedBeaconBlockPhase0 != nil
}
func (s *SignedBeaconBlock) GetBellatrix() *consensus.SignedBeaconBlockBellatrix {
return s.signedBeaconBlockBellatrix
}
func (s *SignedBeaconBlock) GetAltair() *consensus.SignedBeaconBlockAltair {
return s.signedBeaconBlockAltair
}
func (s *SignedBeaconBlock) GetPhase0() *consensus.SignedBeaconBlockPhase0 {
return s.signedBeaconBlockPhase0
}
func (s *SignedBeaconBlock) Signature() *consensus.Signature {
if s.IsBellatrix() {
return &s.signedBeaconBlockBellatrix.Signature
}
if s.IsAltair() {
return &s.signedBeaconBlockAltair.Signature
}
if s.IsPhase0() {
return &s.signedBeaconBlockPhase0.Signature
}
return nil
}
func (s *SignedBeaconBlock) Block() *BeaconBlock {
if s.IsBellatrix() {
return &BeaconBlock{beaconBlockBellatrix: s.signedBeaconBlockBellatrix.Block}
}
if s.IsAltair() {
return &BeaconBlock{beaconBlockAltair: s.signedBeaconBlockAltair.Block}
}
if s.IsPhase0() {
return &BeaconBlock{beaconBlockPhase0: s.signedBeaconBlockPhase0.Block}
}
return nil
}
func (b *BeaconBlock) IsBellatrix() bool {
return b.beaconBlockBellatrix != nil
}
func (b *BeaconBlock) IsAltair() bool {
return b.beaconBlockAltair != nil
}
func (b *BeaconBlock) IsPhase0() bool {
return b.beaconBlockPhase0 != nil
}
func (s *BeaconBlock) GetBellatrix() *consensus.BeaconBlockBellatrix {
return s.beaconBlockBellatrix
}
func (s *BeaconBlock) GetAltair() *consensus.BeaconBlockAltair {
return s.beaconBlockAltair
}
func (s *BeaconBlock) GetPhase0() *consensus.BeaconBlockPhase0 {
return s.beaconBlockPhase0
}
func (b *BeaconBlock) ParentRoot() *consensus.Root {
if b.IsBellatrix() {
return &b.beaconBlockBellatrix.ParentRoot
}
if b.IsAltair() {
return &b.beaconBlockAltair.ParentRoot
}
if b.IsPhase0() {
return &b.beaconBlockPhase0.ParentRoot
}
return nil
}
func (b *BeaconBlock) StateRoot() *consensus.Root {
if b.IsBellatrix() {
return &b.beaconBlockBellatrix.StateRoot
}
if b.IsAltair() {
return &b.beaconBlockAltair.StateRoot
}
if b.IsPhase0() {
return &b.beaconBlockPhase0.StateRoot
}
return nil
}
func (b *BeaconBlock) Body() *BeaconBlockBody {
if b.IsBellatrix() {
return &BeaconBlockBody{beaconBlockBodyBellatrix: b.beaconBlockBellatrix.Body}
}
if b.IsAltair() {
return &BeaconBlockBody{beaconBlockBodyAltair: b.beaconBlockAltair.Body}
}
if b.IsPhase0() {
return &BeaconBlockBody{beaconBlockBodyPhase0: b.beaconBlockPhase0.Body}
}
return nil
}
func (b *BeaconBlockBody) IsBellatrix() bool {
return b.beaconBlockBodyBellatrix != nil
}
func (b *BeaconBlockBody) IsAltair() bool {
return b.beaconBlockBodyAltair != nil
}
func (b *BeaconBlockBody) IsPhase0() bool {
return b.beaconBlockBodyPhase0 != nil
}
func (b *BeaconBlockBody) Eth1Data() *consensus.Eth1Data {
if b.IsBellatrix() {
return b.beaconBlockBodyBellatrix.Eth1Data
}
if b.IsAltair() {
return b.beaconBlockBodyAltair.Eth1Data
}
if b.IsPhase0() {
return b.beaconBlockBodyPhase0.Eth1Data
}
return nil
}
func (b *BeaconBlock) HashTreeRoot() ([32]byte, error) {
if b.IsBellatrix() {
return b.beaconBlockBellatrix.HashTreeRoot()
}
if b.IsAltair() {
return b.beaconBlockAltair.HashTreeRoot()
}
if b.IsPhase0() {
return b.beaconBlockPhase0.HashTreeRoot()
}
return [32]byte{}, errors.New("BeaconBlock not set")
}
func (s *BeaconState) UnmarshalSSZ(ssz []byte) error {
var bellatrix consensus.BeaconStateBellatrix
err := bellatrix.UnmarshalSSZ(ssz)
if nil == err {
s.beaconStateBellatrix = &bellatrix
s.beaconStateAltair = nil
s.beaconStatePhase0 = nil
log.Info("Unmarshalled Bellatrix BeaconState")
return nil
}
var altair consensus.BeaconStateAltair
err = altair.UnmarshalSSZ(ssz)
if nil == err {
s.beaconStateBellatrix = nil
s.beaconStateAltair = &altair
s.beaconStatePhase0 = nil
log.Info("Unmarshalled Altair BeaconState")
return nil
}
var phase0 consensus.BeaconStatePhase0
err = phase0.UnmarshalSSZ(ssz)
if nil == err {
s.beaconStateBellatrix = nil
s.beaconStateAltair = nil
s.beaconStatePhase0 = &phase0
log.Info("Unmarshalled Phase0 BeaconState")
return nil
}
s.beaconStateBellatrix = nil
s.beaconStateAltair = nil
s.beaconStatePhase0 = nil
log.Warning("Unable to unmarshal BeaconState")
return err
}
func (s *BeaconState) MarshalSSZ() ([]byte, error) {
if s.IsBellatrix() {
return s.beaconStateBellatrix.MarshalSSZ()
}
if s.IsAltair() {
return s.beaconStateAltair.MarshalSSZ()
}
if s.IsPhase0() {
return s.beaconStatePhase0.MarshalSSZ()
}
return []byte{}, errors.New("BeaconState not set")
}
func (s *BeaconState) IsBellatrix() bool {
return s.beaconStateBellatrix != nil
}
func (s *BeaconState) IsAltair() bool {
return s.beaconStateAltair != nil
}
func (s *BeaconState) IsPhase0() bool {
return s.beaconStatePhase0 != nil
}
func (s *BeaconState) Slot() uint64 {
if s.IsBellatrix() {
return s.beaconStateBellatrix.Slot
}
if s.IsAltair() {
return s.beaconStateAltair.Slot
}
if s.IsPhase0() {
return s.beaconStatePhase0.Slot
}
// TODO(telackey): Something better than 0?
return 0
}
func (b *BeaconState) HashTreeRoot() ([32]byte, error) {
if b.IsBellatrix() {
return b.beaconStateBellatrix.HashTreeRoot()
}
if b.IsAltair() {
return b.beaconStateAltair.HashTreeRoot()
}
if b.IsPhase0() {
return b.beaconStatePhase0.HashTreeRoot()
}
return [32]byte{}, errors.New("BeaconState not set")
}
func (s *BeaconState) GetBellatrix() *consensus.BeaconStateBellatrix {
return s.beaconStateBellatrix
}
func (s *BeaconState) GetAltair() *consensus.BeaconStateAltair {
return s.beaconStateAltair
}
func (s *BeaconState) GetPhase0() *consensus.BeaconStatePhase0 {
return s.beaconStatePhase0
}

View File

@ -24,8 +24,6 @@ import (
"encoding/hex" "encoding/hex"
"fmt" "fmt"
consensus "github.com/umbracle/go-eth-consensus" consensus "github.com/umbracle/go-eth-consensus"
"github.com/umbracle/go-eth-consensus/http"
"strconv" "strconv"
"strings" "strings"
"time" "time"
@ -54,10 +52,10 @@ type ProcessSlot struct {
// BeaconBlock // BeaconBlock
SszSignedBeaconBlock []byte // The entire SSZ encoded SignedBeaconBlock SszSignedBeaconBlock []byte // The entire SSZ encoded SignedBeaconBlock
FullSignedBeaconBlock consensus.SignedBeaconBlockBellatrix // The unmarshaled BeaconState object, the unmarshalling could have errors. FullSignedBeaconBlock SignedBeaconBlock // The unmarshaled BeaconState object, the unmarshalling could have errors.
// BeaconState // BeaconState
FullBeaconState consensus.BeaconStateBellatrix // The unmarshaled BeaconState object, the unmarshalling could have errors. FullBeaconState BeaconState // The unmarshaled BeaconState object, the unmarshalling could have errors.
SszBeaconState []byte // The entire SSZ encoded BeaconState SszBeaconState []byte // The entire SSZ encoded BeaconState
// DB Write objects // DB Write objects
@ -247,19 +245,24 @@ func (ps *ProcessSlot) getSignedBeaconBlock(serverAddress string) error {
} else { } else {
blockIdentifier = strconv.Itoa(ps.Slot) blockIdentifier = strconv.Itoa(ps.Slot)
} }
client := http.New(serverAddress)
var signedBeaconBlock consensus.SignedBeaconBlockBellatrix blockEndpoint := serverAddress + BcBlockQueryEndpoint + blockIdentifier
err := client.Get(BcBlockQueryEndpoint+blockIdentifier, &signedBeaconBlock) sszSignedBeaconBlock, rc, err := querySsz(blockEndpoint, strconv.Itoa(ps.Slot))
if err != nil {
if err != nil || rc != 200 {
loghelper.LogSlotError(strconv.Itoa(ps.Slot), err).Error("Unable to properly query the slot.") loghelper.LogSlotError(strconv.Itoa(ps.Slot), err).Error("Unable to properly query the slot.")
return err ps.FullSignedBeaconBlock = SignedBeaconBlock{}
ps.SszSignedBeaconBlock = []byte{}
ps.ParentBlockRoot = ""
ps.Status = "skipped"
return nil
} }
sszSignedBeaconBlock, err := signedBeaconBlock.MarshalSSZ() var signedBeaconBlock SignedBeaconBlock
err = signedBeaconBlock.UnmarshalSSZ(sszSignedBeaconBlock)
if err != nil { if err != nil {
loghelper.LogSlotError(strconv.Itoa(ps.Slot), err).Error("Unable to marshal SignedBeaconBlock to SSZ.") loghelper.LogSlotError(strconv.Itoa(ps.Slot), err).Error("Unable to unmarshal SignedBeaconBlock for slot.")
ps.FullSignedBeaconBlock = consensus.SignedBeaconBlockBellatrix{} ps.FullSignedBeaconBlock = SignedBeaconBlock{}
ps.SszSignedBeaconBlock = []byte{} ps.SszSignedBeaconBlock = []byte{}
ps.ParentBlockRoot = "" ps.ParentBlockRoot = ""
ps.Status = "skipped" ps.Status = "skipped"
@ -269,7 +272,7 @@ func (ps *ProcessSlot) getSignedBeaconBlock(serverAddress string) error {
ps.FullSignedBeaconBlock = signedBeaconBlock ps.FullSignedBeaconBlock = signedBeaconBlock
ps.SszSignedBeaconBlock = sszSignedBeaconBlock ps.SszSignedBeaconBlock = sszSignedBeaconBlock
ps.ParentBlockRoot = rootToHex(&ps.FullSignedBeaconBlock.Block.ParentRoot) ps.ParentBlockRoot = rootToHex(ps.FullSignedBeaconBlock.Block().ParentRoot())
return nil return nil
} }
@ -281,18 +284,18 @@ func (ps *ProcessSlot) getBeaconState(serverEndpoint string) error {
} else { } else {
stateIdentifier = strconv.Itoa(ps.Slot) stateIdentifier = strconv.Itoa(ps.Slot)
} }
client := http.New(serverEndpoint)
var beaconState consensus.BeaconStateBellatrix stateEndpoint := serverEndpoint + BcStateQueryEndpoint + stateIdentifier
err := client.Get(BcStateQueryEndpoint+stateIdentifier, &beaconState) sszBeaconState, _, err := querySsz(stateEndpoint, strconv.Itoa(ps.Slot))
if err != nil { if err != nil {
loghelper.LogSlotError(strconv.Itoa(ps.Slot), err).Error("Unable to properly query the BeaconState.") loghelper.LogSlotError(strconv.Itoa(ps.Slot), err).Error("Unable to properly query the BeaconState.")
return err return err
} }
sszBeaconState, err := beaconState.MarshalSSZ() var beaconState BeaconState
err = beaconState.UnmarshalSSZ(sszBeaconState)
if err != nil { if err != nil {
loghelper.LogSlotError(strconv.Itoa(ps.Slot), err).Error("Unable to marshal BeaconState.") loghelper.LogSlotError(strconv.Itoa(ps.Slot), err).Error("Unable to unmarshal the BeaconState.")
return err return err
} }
@ -303,8 +306,8 @@ func (ps *ProcessSlot) getBeaconState(serverEndpoint string) error {
// Check to make sure that the previous block we processed is the parent of the current block. // Check to make sure that the previous block we processed is the parent of the current block.
func (ps *ProcessSlot) checkPreviousSlot(tx sql.Tx, ctx context.Context, previousSlot int, previousBlockRoot string, knownGapsTableIncrement int) { func (ps *ProcessSlot) checkPreviousSlot(tx sql.Tx, ctx context.Context, previousSlot int, previousBlockRoot string, knownGapsTableIncrement int) {
parentRoot := rootToHex(&ps.FullSignedBeaconBlock.Block.ParentRoot) parentRoot := rootToHex(ps.FullSignedBeaconBlock.Block().ParentRoot())
slot := int(ps.FullBeaconState.Slot) slot := int(ps.FullBeaconState.Slot())
if previousSlot == slot { if previousSlot == slot {
log.WithFields(log.Fields{ log.WithFields(log.Fields{
"slot": slot, "slot": slot,
@ -366,21 +369,21 @@ func (ps *ProcessSlot) provideFinalHash() (string, string, string, error) {
if ps.StateRoot != "" { if ps.StateRoot != "" {
stateRoot = ps.StateRoot stateRoot = ps.StateRoot
} else { } else {
stateRoot = rootToHex(&ps.FullSignedBeaconBlock.Block.StateRoot) stateRoot = rootToHex(ps.FullSignedBeaconBlock.Block().StateRoot())
log.Debug("StateRoot: ", stateRoot) log.Debug("StateRoot: ", stateRoot)
} }
if ps.BlockRoot != "" { if ps.BlockRoot != "" {
blockRoot = ps.BlockRoot blockRoot = ps.BlockRoot
} else { } else {
rawBlockRoot, err := ps.FullSignedBeaconBlock.Block.HashTreeRoot() rawBlockRoot, err := ps.FullSignedBeaconBlock.Block().HashTreeRoot()
if err != nil { if err != nil {
return "", "", "", err return "", "", "", err
} }
blockRoot = byteArrayToHex(&rawBlockRoot) blockRoot = byteArrayToHex(&rawBlockRoot)
log.WithFields(log.Fields{"blockRoot": blockRoot}).Debug("Block Root from ssz") log.WithFields(log.Fields{"blockRoot": blockRoot}).Debug("Block Root from ssz")
} }
eth1BlockHash = byteArrayToHex(&ps.FullSignedBeaconBlock.Block.Body.Eth1Data.BlockHash) eth1BlockHash = byteArrayToHex(&ps.FullSignedBeaconBlock.Block().Body().Eth1Data().BlockHash)
} }
return blockRoot, stateRoot, eth1BlockHash, nil return blockRoot, stateRoot, eth1BlockHash, nil
} }

View File

@ -37,6 +37,31 @@ type BlockRootMessage struct {
Root string `json:"root"` Root string `json:"root"`
} }
// A helper function to query endpoints that utilize slots.
func querySsz(endpoint string, slot string) ([]byte, int, error) {
log.WithFields(log.Fields{"endpoint": endpoint}).Debug("Querying endpoint")
client := &http.Client{}
req, err := http.NewRequest("GET", endpoint, nil)
if err != nil {
loghelper.LogSlotError(slot, err).Error("Unable to create a request!")
return nil, 0, fmt.Errorf("Unable to create a request!: %s", err.Error())
}
req.Header.Set("Accept", "application/octet-stream")
response, err := client.Do(req)
if err != nil {
loghelper.LogSlotError(slot, err).Error("Unable to query Beacon Node!")
return nil, 0, fmt.Errorf("Unable to query Beacon Node: %s", err.Error())
}
defer response.Body.Close()
rc := response.StatusCode
body, err := ioutil.ReadAll(response.Body)
if err != nil {
loghelper.LogSlotError(slot, err).Error("Unable to turn response into a []bytes array!")
return nil, rc, fmt.Errorf("Unable to turn response into a []bytes array!: %s", err.Error())
}
return body, rc, nil
}
// A function to query the blockroot for a given slot. // A function to query the blockroot for a given slot.
func queryBlockRoot(endpoint string, slot string) (string, error) { func queryBlockRoot(endpoint string, slot string) (string, error) {
log.WithFields(log.Fields{"endpoint": endpoint}).Debug("Querying endpoint") log.WithFields(log.Fields{"endpoint": endpoint}).Debug("Querying endpoint")