-
Notifications
You must be signed in to change notification settings - Fork 45
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* support eth67 * secured go.mod * fix compile error * upgrade wealdtech/go-eth2-types/v2 from v2.5.2 to v2.8.1, to avoid bnb forked fastssz * downgrade github.com/wealdtech/go-eth2-types to v2.6.0, to kept github.com/ferranbt/fastssz version as v0.1.2 * rever back github.com/herumi/bls-eth-go-binary original version * integrate bsc cancun support * import bsc PR #2428 * import bsc PR #2525 * import bsc PR #2350 * import bsc PR #2311 * import bsc PR #2337 * organize ParentBeaconRoot handling * unsupport eth67 * fix linter error * fix `unexpected withdrawal hash value in oasys` * set blob index during commit it * add fake beacon api * fix blob freeze bugs * Updated with `gencodec -dir eth/ethconfig/ -type Config -formats toml -out eth/ethconfig/gen_config.go` (#94) * Import eth/handler.go from [email protected] (#93) * Update core/blockchain.go Co-authored-by: ironbeer <[email protected]> * Update core/chain_makers.go Co-authored-by: ironbeer <[email protected]> * respond review by ironbeer part1 * Restore changes from 4e4fa3e (#95) * Update params/config.go Co-authored-by: ironbeer <[email protected]> * fastfinality: incorporate bsc changes ##2589 * fastfinality: incorporate bsc PR #2568 * fix consensus making failure caused by integration of bsc pr #2589 * Import miner/worker.go from [email protected] (2) (#99) * Import miner/worker.go from [email protected] (3) (#100) * Dedup of BaseFee field after cancun (#102) * Import blob fee API from [email protected] (#103) * Fixed fakebeacon (#104) * Change index field to string type * Modified block estimation for Oasys * respond feedback from ironbeer --------- Co-authored-by: ironbeer <[email protected]>
- Loading branch information
Showing
36 changed files
with
806 additions
and
255 deletions.
There are no files selected for viewing
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,106 @@ | ||
package fakebeacon | ||
|
||
import ( | ||
"context" | ||
"sort" | ||
"strconv" | ||
|
||
"github.com/ethereum/go-ethereum/common" | ||
"github.com/ethereum/go-ethereum/crypto/kzg4844" | ||
"github.com/ethereum/go-ethereum/internal/ethapi" | ||
"github.com/ethereum/go-ethereum/log" | ||
"github.com/ethereum/go-ethereum/rpc" | ||
) | ||
|
||
// spec: https://ethereum.github.io/beacon-APIs/#/Beacon/getBlobSidecars | ||
type BlobSidecar struct { | ||
Blob kzg4844.Blob `json:"blob"` | ||
Index Uint64String `json:"index"` | ||
KZGCommitment kzg4844.Commitment `json:"kzg_commitment"` | ||
KZGProof kzg4844.Proof `json:"kzg_proof"` | ||
} | ||
|
||
type APIGetBlobSidecarsResponse struct { | ||
Data []*BlobSidecar `json:"data"` | ||
} | ||
|
||
type ReducedGenesisData struct { | ||
GenesisTime string `json:"genesis_time"` | ||
} | ||
|
||
type APIGenesisResponse struct { | ||
Data ReducedGenesisData `json:"data"` | ||
} | ||
|
||
type ReducedConfigData struct { | ||
SecondsPerSlot string `json:"SECONDS_PER_SLOT"` | ||
} | ||
|
||
type IndexedBlobHash struct { | ||
Index int // absolute index in the block, a.k.a. position in sidecar blobs array | ||
Hash common.Hash // hash of the blob, used for consistency checks | ||
} | ||
|
||
// Uint64String is a decimal string representation of an uint64, for usage in the Beacon API JSON encoding | ||
type Uint64String uint64 | ||
|
||
func (v Uint64String) MarshalText() (out []byte, err error) { | ||
out = strconv.AppendUint(out, uint64(v), 10) | ||
return | ||
} | ||
|
||
func (v *Uint64String) UnmarshalText(b []byte) error { | ||
n, err := strconv.ParseUint(string(b), 0, 64) | ||
if err != nil { | ||
return err | ||
} | ||
*v = Uint64String(n) | ||
return nil | ||
} | ||
|
||
func configSpec() ReducedConfigData { | ||
return ReducedConfigData{SecondsPerSlot: "1"} | ||
} | ||
|
||
func beaconGenesis() APIGenesisResponse { | ||
return APIGenesisResponse{Data: ReducedGenesisData{GenesisTime: "0"}} | ||
} | ||
|
||
func beaconBlobSidecars(ctx context.Context, backend ethapi.Backend, slot uint64, indices []int) (APIGetBlobSidecarsResponse, error) { | ||
var blockNrOrHash rpc.BlockNumberOrHash | ||
header, err := fetchBlockNumberByTime(ctx, int64(slot), backend) | ||
if err != nil { | ||
log.Error("Error fetching block number", "slot", slot, "indices", indices) | ||
return APIGetBlobSidecarsResponse{}, err | ||
} | ||
sideCars, err := backend.GetBlobSidecars(ctx, header.Hash()) | ||
if err != nil { | ||
log.Error("Error fetching Sidecars", "blockNrOrHash", blockNrOrHash, "err", err) | ||
return APIGetBlobSidecarsResponse{}, err | ||
} | ||
sort.Ints(indices) | ||
fullBlob := len(indices) == 0 | ||
res := APIGetBlobSidecarsResponse{} | ||
idx := 0 | ||
curIdx := 0 | ||
for _, sideCar := range sideCars { | ||
for i := 0; i < len(sideCar.Blobs); i++ { | ||
//hash := kZGToVersionedHash(sideCar.Commitments[i]) | ||
if !fullBlob && curIdx >= len(indices) { | ||
break | ||
} | ||
if fullBlob || idx == indices[curIdx] { | ||
res.Data = append(res.Data, &BlobSidecar{ | ||
Index: Uint64String(idx), | ||
Blob: sideCar.Blobs[i], | ||
KZGCommitment: sideCar.Commitments[i], | ||
KZGProof: sideCar.Proofs[i], | ||
}) | ||
curIdx++ | ||
} | ||
idx++ | ||
} | ||
} | ||
|
||
return res, 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,88 @@ | ||
package fakebeacon | ||
|
||
import ( | ||
"fmt" | ||
"net/http" | ||
"net/url" | ||
"strconv" | ||
"strings" | ||
|
||
"github.com/prysmaticlabs/prysm/v5/api/server/structs" | ||
field_params "github.com/prysmaticlabs/prysm/v5/config/fieldparams" | ||
"github.com/prysmaticlabs/prysm/v5/network/httputil" | ||
) | ||
|
||
var ( | ||
versionMethod = "/eth/v1/node/version" | ||
specMethod = "/eth/v1/config/spec" | ||
genesisMethod = "/eth/v1/beacon/genesis" | ||
sidecarsMethodPrefix = "/eth/v1/beacon/blob_sidecars/{slot}" | ||
) | ||
|
||
func VersionMethod(w http.ResponseWriter, r *http.Request) { | ||
resp := &structs.GetVersionResponse{ | ||
Data: &structs.Version{ | ||
Version: "", | ||
}, | ||
} | ||
httputil.WriteJson(w, resp) | ||
} | ||
|
||
func SpecMethod(w http.ResponseWriter, r *http.Request) { | ||
httputil.WriteJson(w, &structs.GetSpecResponse{Data: configSpec()}) | ||
} | ||
|
||
func GenesisMethod(w http.ResponseWriter, r *http.Request) { | ||
httputil.WriteJson(w, beaconGenesis()) | ||
} | ||
|
||
func (s *Service) SidecarsMethod(w http.ResponseWriter, r *http.Request) { | ||
indices, err := parseIndices(r.URL) | ||
if err != nil { | ||
httputil.HandleError(w, err.Error(), http.StatusBadRequest) | ||
return | ||
} | ||
segments := strings.Split(r.URL.Path, "/") | ||
slot, err := strconv.ParseUint(segments[len(segments)-1], 10, 64) | ||
if err != nil { | ||
httputil.HandleError(w, "not a valid slot(timestamp)", http.StatusBadRequest) | ||
return | ||
} | ||
|
||
resp, err := beaconBlobSidecars(r.Context(), s.backend, slot, indices) | ||
if err != nil { | ||
httputil.HandleError(w, err.Error(), http.StatusBadRequest) | ||
return | ||
} | ||
httputil.WriteJson(w, resp) | ||
} | ||
|
||
// parseIndices filters out invalid and duplicate blob indices | ||
func parseIndices(url *url.URL) ([]int, error) { | ||
rawIndices := url.Query()["indices"] | ||
indices := make([]int, 0, field_params.MaxBlobsPerBlock) | ||
invalidIndices := make([]string, 0) | ||
loop: | ||
for _, raw := range rawIndices { | ||
ix, err := strconv.Atoi(raw) | ||
if err != nil { | ||
invalidIndices = append(invalidIndices, raw) | ||
continue | ||
} | ||
if ix >= field_params.MaxBlobsPerBlock { | ||
invalidIndices = append(invalidIndices, raw) | ||
continue | ||
} | ||
for i := range indices { | ||
if ix == indices[i] { | ||
continue loop | ||
} | ||
} | ||
indices = append(indices, ix) | ||
} | ||
|
||
if len(invalidIndices) > 0 { | ||
return nil, fmt.Errorf("requested blob indices %v are invalid", invalidIndices) | ||
} | ||
return indices, 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,97 @@ | ||
package fakebeacon | ||
|
||
import ( | ||
"net/http" | ||
"strconv" | ||
|
||
"github.com/ethereum/go-ethereum/internal/ethapi" | ||
"github.com/gorilla/mux" | ||
"github.com/prysmaticlabs/prysm/v5/api/server" | ||
) | ||
|
||
const ( | ||
DefaultAddr = "localhost" | ||
DefaultPort = 8686 | ||
) | ||
|
||
type Config struct { | ||
Enable bool | ||
Addr string | ||
Port int | ||
} | ||
|
||
func defaultConfig() *Config { | ||
return &Config{ | ||
Enable: false, | ||
Addr: DefaultAddr, | ||
Port: DefaultPort, | ||
} | ||
} | ||
|
||
type Service struct { | ||
cfg *Config | ||
router *mux.Router | ||
backend ethapi.Backend | ||
} | ||
|
||
func NewService(cfg *Config, backend ethapi.Backend) *Service { | ||
cfgs := defaultConfig() | ||
if cfg.Addr != "" { | ||
cfgs.Addr = cfg.Addr | ||
} | ||
if cfg.Port > 0 { | ||
cfgs.Port = cfg.Port | ||
} | ||
|
||
s := &Service{ | ||
cfg: cfgs, | ||
backend: backend, | ||
} | ||
router := s.newRouter() | ||
s.router = router | ||
return s | ||
} | ||
|
||
func (s *Service) Run() { | ||
_ = http.ListenAndServe(s.cfg.Addr+":"+strconv.Itoa(s.cfg.Port), s.router) | ||
} | ||
|
||
func (s *Service) newRouter() *mux.Router { | ||
r := mux.NewRouter() | ||
r.Use(server.NormalizeQueryValuesHandler) | ||
for _, e := range s.endpoints() { | ||
r.HandleFunc(e.path, e.handler).Methods(e.methods...) | ||
} | ||
return r | ||
} | ||
|
||
type endpoint struct { | ||
path string | ||
handler http.HandlerFunc | ||
methods []string | ||
} | ||
|
||
func (s *Service) endpoints() []endpoint { | ||
return []endpoint{ | ||
{ | ||
path: versionMethod, | ||
handler: VersionMethod, | ||
methods: []string{http.MethodGet}, | ||
}, | ||
{ | ||
path: specMethod, | ||
handler: SpecMethod, | ||
methods: []string{http.MethodGet}, | ||
}, | ||
{ | ||
path: genesisMethod, | ||
handler: GenesisMethod, | ||
methods: []string{http.MethodGet}, | ||
}, | ||
{ | ||
path: sidecarsMethodPrefix, | ||
handler: s.SidecarsMethod, | ||
methods: []string{http.MethodGet}, | ||
}, | ||
} | ||
} |
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,81 @@ | ||
package fakebeacon | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"fmt" | ||
"math/rand" | ||
"time" | ||
|
||
"github.com/ethereum/go-ethereum/core/types" | ||
"github.com/ethereum/go-ethereum/internal/ethapi" | ||
"github.com/ethereum/go-ethereum/params" | ||
"github.com/ethereum/go-ethereum/rpc" | ||
) | ||
|
||
func fetchBlockNumberByTime(ctx context.Context, ts int64, backend ethapi.Backend) (*types.Header, error) { | ||
// calc the block number of the ts. | ||
currentHeader := backend.CurrentHeader() | ||
blockTime := int64(currentHeader.Time) | ||
if ts > blockTime { | ||
return nil, errors.New("time too large") | ||
} | ||
blockPeriod := getBlockPeriod(backend.ChainConfig()) | ||
adjustedBlockPeriod := getBlockPeriod(backend.ChainConfig())*2 - 1 | ||
blockNum := currentHeader.Number.Uint64() | ||
estimateEndNumber := int64(blockNum) - (blockTime-ts)/adjustedBlockPeriod | ||
// find the end number | ||
for { | ||
header, err := backend.HeaderByNumber(ctx, rpc.BlockNumber(estimateEndNumber)) | ||
if err != nil { | ||
time.Sleep(time.Duration(rand.Int()%180) * time.Millisecond) | ||
continue | ||
} | ||
if header == nil { | ||
estimateEndNumber -= 1 | ||
time.Sleep(time.Duration(rand.Int()%180) * time.Millisecond) | ||
continue | ||
} | ||
headerTime := int64(header.Time) | ||
if headerTime == ts { | ||
return header, nil | ||
} | ||
|
||
// let the estimateEndNumber a little bigger than real value | ||
if headerTime > ts+(blockPeriod*4) { | ||
estimateEndNumber -= (headerTime - ts) / adjustedBlockPeriod | ||
} else if headerTime < ts { | ||
estimateEndNumber += (ts-headerTime)/adjustedBlockPeriod + 1 | ||
} else { | ||
// search one by one | ||
for headerTime >= ts { | ||
header, err = backend.HeaderByNumber(ctx, rpc.BlockNumber(estimateEndNumber-1)) | ||
if err != nil { | ||
time.Sleep(time.Duration(rand.Int()%180) * time.Millisecond) | ||
continue | ||
} | ||
headerTime = int64(header.Time) | ||
if headerTime == ts { | ||
return header, nil | ||
} | ||
estimateEndNumber -= 1 | ||
if headerTime < ts { //found the real endNumber | ||
return nil, fmt.Errorf("block not found by time %d", ts) | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
func getBlockPeriod(cfg *params.ChainConfig) int64 { | ||
switch { | ||
case cfg.ChainID.Cmp(params.OasysMainnetChainConfig.ChainID) == 0: | ||
return params.SHORT_BLOCK_TIME_SECONDS | ||
case cfg.ChainID.Cmp(params.OasysTestnetChainConfig.ChainID) == 0: | ||
return params.SHORT_BLOCK_TIME_SECONDS | ||
case cfg.Oasys != nil: | ||
return int64(cfg.Oasys.Period) // for local chain | ||
default: | ||
return 1 | ||
} | ||
} |
Oops, something went wrong.