-
Notifications
You must be signed in to change notification settings - Fork 718
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Synchronizer support Feijoa Part 1 (#3560)
* update go library to v1.13.14 * Etherman: Add a consensus client for the retrieve the Blobs (./beacon_client) * Etherman: Add etherman new structure for Feija events (to be able to adapt zkevm-l1-sync library) * Etherman: Add support for EIP-4844 (using beacon client) * Etherman: process sequenceBlob for CallData, synchronizer support the event (missing Blob support) * Etherman: if Consensus clients fails disable Feijoa support (this have to be converted in a error) * State: Add BlobSequences (It's probably not the final version) * Synchronizer: Add initial support to synchronizer to SequenceBlobs (write sequence) (missing process BlobInner) --------- Co-authored-by: tclemos <thiago@polygon.technology>
- Loading branch information
1 parent
d565619
commit bdf9f34
Showing
48 changed files
with
84,791 additions
and
105 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
//go:generate oapi-codegen -package=examplepkg -generate=types,client,spec -o=examplepkg/example-client.go beacon-node-oapi.json | ||
package beaconclient | ||
|
||
import ( | ||
"context" | ||
"encoding/json" | ||
"fmt" | ||
"io" | ||
"net/http" | ||
) | ||
|
||
// BeaconAPIClient client of Beacon API | ||
// https://ethereum.github.io/beacon-APIs/ | ||
type BeaconAPIClient struct { | ||
urlBase string | ||
} | ||
|
||
// NewBeaconAPIClient creates an instance of client | ||
func NewBeaconAPIClient(url string) *BeaconAPIClient { | ||
return &BeaconAPIClient{ | ||
urlBase: url, | ||
} | ||
} | ||
|
||
// BeaconAPIResponse represents the response of the beacon API | ||
type BeaconAPIResponse struct { | ||
Result json.RawMessage | ||
} | ||
|
||
// JSONRPCBeaconCall executes restapi call to beacon-api node | ||
func JSONRPCBeaconCall(ctx context.Context, urlBase, methodPath string) (BeaconAPIResponse, error) { | ||
//url := path.Join(urlBase, methodPath) | ||
url := fmt.Sprintf("%s%s", urlBase, methodPath) | ||
httpReq, err := http.NewRequestWithContext(ctx, http.MethodGet, url, http.NoBody) | ||
if err != nil { | ||
return BeaconAPIResponse{}, err | ||
} | ||
httpReq.Header.Add("Content-type", "application/json") | ||
|
||
httpRes, err := http.DefaultClient.Do(httpReq) | ||
if err != nil { | ||
return BeaconAPIResponse{}, err | ||
} | ||
|
||
resBody, err := io.ReadAll(httpRes.Body) | ||
if err != nil { | ||
return BeaconAPIResponse{}, err | ||
} | ||
defer httpRes.Body.Close() | ||
|
||
if httpRes.StatusCode != http.StatusOK { | ||
return BeaconAPIResponse{}, fmt.Errorf("BeaconClient fails url:%s status_code:%v response:%v", url, httpRes.StatusCode, string(resBody)) | ||
} | ||
|
||
return BeaconAPIResponse{ | ||
Result: resBody, | ||
}, nil | ||
} | ||
|
||
func unserializeGenericResponse[T any](response BeaconAPIResponse) (T, error) { | ||
var result T | ||
err := json.Unmarshal(response.Result, &result) | ||
if err != nil { | ||
var zero T | ||
return zero, err | ||
} | ||
return result, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
package beaconclient | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"strconv" | ||
|
||
"github.com/0xPolygonHermez/zkevm-node/hex" | ||
) | ||
|
||
const beaconBlobSidecarsPath = "/eth/v1/beacon/blob_sidecars/" | ||
|
||
// BeaconBlobSidecarsResponse represents the response of the beacon blob sidecars endpoint | ||
type BeaconBlobSidecarsResponse struct { | ||
Sidecars map[uint64]BeaconBlobSidecarResponse | ||
} | ||
|
||
// BeaconBlobSidecarResponse represents the response of the config spec endpoint | ||
type BeaconBlobSidecarResponse struct { | ||
Index uint64 | ||
KzgCommitment string | ||
Blob []byte | ||
} | ||
|
||
type beaconBlobSidecarsResponseInternal struct { | ||
Data []struct { | ||
Index string `json:"index"` | ||
Blob string `json:"blob"` | ||
KzgCommitment string `json:"kzg_commitment"` | ||
KzgProof string `json:"kzg_proof"` | ||
SignedBlockHeader struct { | ||
Message struct { | ||
Slot string `json:"slot"` | ||
ProposerIndex string `json:"proposer_index"` | ||
ParentRoot string `json:"parent_root"` | ||
StateRoot string `json:"state_root"` | ||
BodyRoot string `json:"body_root"` | ||
} `json:"message"` | ||
Signature string `json:"signature"` | ||
} `json:"signed_block_header"` | ||
KzgCommitmentInclusionProof []string `json:"kzg_commitment_inclusion_proof"` | ||
} `json:"data"` | ||
} | ||
|
||
func has0xPrefix(str string) bool { | ||
return len(str) >= 2 && str[0] == '0' && (str[1] == 'x' || str[1] == 'X') | ||
} | ||
|
||
func convertBeaconBlobSidecarsResponseInternal(data beaconBlobSidecarsResponseInternal) (*BeaconBlobSidecarsResponse, error) { | ||
response := BeaconBlobSidecarsResponse{ | ||
Sidecars: make(map[uint64]BeaconBlobSidecarResponse), | ||
} | ||
for _, sidecar := range data.Data { | ||
index, err := strconv.ParseUint(sidecar.Index, 0, hex.BitSize64) | ||
if err != nil { | ||
return nil, fmt.Errorf("error parsing Index: %v", err) | ||
} | ||
//common.Hex2Bytes(sidecar.Blob) | ||
if has0xPrefix(sidecar.Blob) { | ||
sidecar.Blob = sidecar.Blob[2:] | ||
} | ||
blob, err := hex.DecodeHex(sidecar.Blob) | ||
if err != nil { | ||
return nil, fmt.Errorf("error decoding Blob: %v", err) | ||
} | ||
response.Sidecars[index] = BeaconBlobSidecarResponse{ | ||
Index: index, | ||
KzgCommitment: sidecar.KzgCommitment, | ||
Blob: blob, | ||
} | ||
} | ||
return &response, nil | ||
} | ||
|
||
// BeaconBlobSidecars fetches the blob sidecars for a given blockID | ||
func (c *BeaconAPIClient) BeaconBlobSidecars(ctx context.Context, blockID uint64) (*BeaconBlobSidecarsResponse, error) { | ||
response, err := JSONRPCBeaconCall(ctx, c.urlBase, beaconBlobSidecarsPath+fmt.Sprintf("%d", blockID)) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
internalStruct, err := unserializeGenericResponse[beaconBlobSidecarsResponseInternal](response) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
responseData, err := convertBeaconBlobSidecarsResponseInternal(internalStruct) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return responseData, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
package beaconclient | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"strconv" | ||
|
||
"github.com/0xPolygonHermez/zkevm-node/hex" | ||
"github.com/ethereum/go-ethereum/common" | ||
) | ||
|
||
// /eth/v1/beacon/genesis | ||
const beaconGenesisPath = "/eth/v1/beacon/genesis" | ||
|
||
// BeaconGenesisResponse represents the response of the beacon genesis endpoint | ||
type BeaconGenesisResponse struct { | ||
GenesisTime uint64 | ||
GenesisValidatorsRoot common.Address | ||
GenesisForkVersion string | ||
} | ||
|
||
type beaconGenesisResponseInternal struct { | ||
Data struct { | ||
GenesisTime string `json:"genesis_time"` | ||
GenesisValidatorsRoot string `json:"genesis_validators_root"` | ||
GenesisForkVersion string `json:"genesis_fork_version"` | ||
} `json:"data"` | ||
} | ||
|
||
func convertBeaconGenesisResponseInternal(data beaconGenesisResponseInternal) (BeaconGenesisResponse, error) { | ||
genesisTime, err := strconv.ParseUint(data.Data.GenesisTime, 0, hex.BitSize64) | ||
if err != nil { | ||
return BeaconGenesisResponse{}, fmt.Errorf("error parsing genesisTime: %v", err) | ||
} | ||
res := BeaconGenesisResponse{ | ||
GenesisTime: genesisTime, | ||
GenesisValidatorsRoot: common.HexToAddress(data.Data.GenesisValidatorsRoot), | ||
GenesisForkVersion: data.Data.GenesisForkVersion, | ||
} | ||
return res, nil | ||
} | ||
|
||
// BeaconGenesis request the current beacon chain genesis | ||
func (c *BeaconAPIClient) BeaconGenesis(ctx context.Context) (*BeaconGenesisResponse, error) { | ||
response, err := JSONRPCBeaconCall(ctx, c.urlBase, beaconGenesisPath) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
internalStruct, err := unserializeGenericResponse[beaconGenesisResponseInternal](response) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
responseData, err := convertBeaconGenesisResponseInternal(internalStruct) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return &responseData, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
package beaconclient | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"strconv" | ||
|
||
"github.com/0xPolygonHermez/zkevm-node/hex" | ||
) | ||
|
||
// ConfigSpec returns the current beacon chain configuration | ||
// Curl example: | ||
// curl -X 'GET' \ | ||
// 'http://localhost/eth/v1/config/spec' \ | ||
// -H 'accept: application/json' | ||
const configSpecPath = "/eth/v1/config/spec" | ||
|
||
// ConfigSpecNodeResponse represents the response of the config spec endpoint | ||
type ConfigSpecNodeResponse struct { | ||
SecondsPerSlot uint64 | ||
SecondsPerEth1Block uint64 | ||
} | ||
|
||
type configSpecNodeResponseInternal struct { | ||
Data struct { | ||
SecondsPerSlot string `json:"SECONDS_PER_SLOT"` | ||
SecondsPerEth1Block string `json:"SECONDS_PER_ETH1_BLOCK"` | ||
} | ||
} | ||
|
||
func convertConfigSpecResponseInternal(data configSpecNodeResponseInternal) (ConfigSpecNodeResponse, error) { | ||
tmpSecondsPerSlot, err := strconv.ParseUint(data.Data.SecondsPerSlot, 0, hex.BitSize64) | ||
if err != nil { | ||
return ConfigSpecNodeResponse{}, fmt.Errorf("error parsing SecondsPerSlot: %v", err) | ||
} | ||
tmpSecondsPerEth1Block, err := strconv.ParseUint(data.Data.SecondsPerEth1Block, 0, hex.BitSize64) | ||
if err != nil { | ||
return ConfigSpecNodeResponse{}, fmt.Errorf("error parsing SecondsPerSlot: %v", err) | ||
} | ||
res := ConfigSpecNodeResponse{ | ||
SecondsPerSlot: tmpSecondsPerSlot, | ||
SecondsPerEth1Block: tmpSecondsPerEth1Block, | ||
} | ||
return res, nil | ||
} | ||
|
||
// ConfigSpec returns the current beacon chain configuration | ||
func (c *BeaconAPIClient) ConfigSpec(ctx context.Context) (*ConfigSpecNodeResponse, error) { | ||
response, err := JSONRPCBeaconCall(ctx, c.urlBase, configSpecPath) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
internalStruct, err := unserializeGenericResponse[configSpecNodeResponseInternal](response) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
responseData, err := convertConfigSpecResponseInternal(internalStruct) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return &responseData, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
-- +migrate Up | ||
|
||
|
||
-- Add first blob_sequence? | ||
CREATE TABLE state.blob_sequence | ||
( | ||
index BIGINT PRIMARY KEY, | ||
coinbase VARCHAR, | ||
final_acc_input_hash VARCHAR, | ||
first_blob_sequenced BIGINT, | ||
last_blob_sequenced BIGINT, | ||
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), | ||
block_num BIGINT NOT NULL REFERENCES state.block (block_num) ON DELETE CASCADE | ||
); | ||
|
||
|
||
|
||
-- +migrate Down |
Oops, something went wrong.