Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
b2fe279
rpc: implement missing eth and debug apis
marcello33 Feb 11, 2026
13202ec
rpc: port erigon_blockNumber under bor namespace
marcello33 Feb 11, 2026
59838dc
rpc: port erigon_getHeaderByNumber under bor namespace
marcello33 Feb 11, 2026
24ba14e
rpc: port erigon_getHeaderByHash under bor namespace
marcello33 Feb 11, 2026
ecc4892
rpc: port erigon_getBlockReceiptsByBlockHash under bor namespace
marcello33 Feb 11, 2026
ca5d5c1
rpc: port erigon_forks under bor namespace
marcello33 Feb 11, 2026
1002711
rpc: port erigon_getLogsByHash under bor namespace / replace deprecat…
marcello33 Feb 11, 2026
6f9ea1e
rpc: port erigon_getBlockByTimestamp under bor namespace
marcello33 Feb 12, 2026
79a258d
rpc: port erigon_getBalanceChangesInBlock under bor namespace (may di…
marcello33 Feb 12, 2026
3fcca30
rpc: port erigon_getLogs and erigon_getLatestLogs under bor namespace
marcello33 Feb 12, 2026
3596882
rpc: refactor test files to distinguish between api and bor_api tests
marcello33 Feb 12, 2026
87cac90
rpc, internal/ethapi: address inconsistencies with newly added rpc me…
marcello33 Feb 18, 2026
df24f19
internal/ethapi: fix imports
marcello33 Feb 18, 2026
f88f2d5
internal/ethapi: fix bor api tests
marcello33 Feb 18, 2026
ed542a4
Merge branch 'develop' of https://github.com/0xPolygon/bor into mardi…
marcello33 Feb 18, 2026
4198ba9
internal/ethapi: move tests
marcello33 Feb 18, 2026
c137d24
revert gomock changes
marcello33 Feb 18, 2026
549aba4
Merge branch 'develop' into mardizzone/POS-3269
marcello33 Feb 24, 2026
f565aef
Merge branch 'develop' into mardizzone/POS-3269
marcello33 Feb 25, 2026
e40677a
internal, core: address review comments
marcello33 Feb 25, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion consensus/bor/genesis_contract_mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion consensus/bor/span_mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

50 changes: 50 additions & 0 deletions core/forkid/forkid.go
Original file line number Diff line number Diff line change
Expand Up @@ -311,3 +311,53 @@ func gatherForks(config *params.ChainConfig, genesis uint64) ([]uint64, []uint64

return forksByBlock, forksByTime
}

// GatherForks gathers all the known forks and creates a sorted list out of them.
// Returns heightForks (block number forks) and timeForks (timestamp forks, which are not supported in bor).
// Returns nil for empty fork lists.
// This extends the internal gatherForks with Bor-specific fork handling.
func GatherForks(config *params.ChainConfig, genesisTime uint64) (heightForks []uint64, timeForks []uint64) {
// Use the existing internal fork gathering logic
heightForks, timeForks = gatherForks(config, genesisTime)

// Add Bor-specific forks using reflection
if config.Bor != nil {
borKind := reflect.TypeOf(params.BorConfig{})
borConf := reflect.ValueOf(config.Bor).Elem()

for i := 0; i < borKind.NumField(); i++ {
field := borKind.Field(i)
// Only process fields ending in "Block"
if !strings.HasSuffix(field.Name, "Block") {
continue
}
// Only process *big.Int fields
if field.Type != reflect.TypeOf(new(big.Int)) {
continue
}
// Extract fork block number
if rule := borConf.Field(i).Interface().(*big.Int); rule != nil {
heightForks = append(heightForks, rule.Uint64())
}
}

// Re-sort and deduplicate after adding Bor forks
slices.Sort(heightForks)
heightForks = slices.Compact(heightForks)

// Re-apply filtering for block 0
if len(heightForks) > 0 && heightForks[0] == 0 {
heightForks = heightForks[1:]
}
}

// Ensure empty slices are nil
if len(heightForks) == 0 {
heightForks = nil
}
if len(timeForks) == 0 {
timeForks = nil
}

return heightForks, timeForks
}
41 changes: 41 additions & 0 deletions core/forkid/forkid_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"hash/crc32"
"math"
"math/big"
"reflect"
"testing"

"github.com/ethereum/go-ethereum/common"
Expand Down Expand Up @@ -442,3 +443,43 @@ func TestTimeBasedForkInGenesis(t *testing.T) {
}
}
}

func TestGatherForks_IncludesBorForks(t *testing.T) {
config := &params.ChainConfig{
HomesteadBlock: big.NewInt(5),
LondonBlock: big.NewInt(10),
Bor: &params.BorConfig{
JaipurBlock: big.NewInt(0), // should be filtered as genesis fork
DelhiBlock: big.NewInt(12), // should be included
IndoreBlock: big.NewInt(12), // duplicate should be deduplicated
RioBlock: big.NewInt(20),
MadhugiriBlock: big.NewInt(25),
},
}

heightForks, timeForks := GatherForks(config, 0)

wantHeights := []uint64{5, 10, 12, 20, 25}
if !reflect.DeepEqual(heightForks, wantHeights) {
t.Fatalf("height forks mismatch: have %v, want %v", heightForks, wantHeights)
}
if timeForks != nil {
t.Fatalf("expected nil time forks, got %v", timeForks)
}
}

func TestGatherForks_EmptyResultsAreNil(t *testing.T) {
config := &params.ChainConfig{
Bor: &params.BorConfig{
JaipurBlock: big.NewInt(0), // filtered out
},
}

heightForks, timeForks := GatherForks(config, 0)
if heightForks != nil {
t.Fatalf("expected nil height forks, got %v", heightForks)
}
if timeForks != nil {
t.Fatalf("expected nil time forks, got %v", timeForks)
}
}
66 changes: 61 additions & 5 deletions eth/api_backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/consensus/misc/eip4844"
"github.com/ethereum/go-ethereum/core"
Expand All @@ -39,6 +40,7 @@ import (
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/eth/gasprice"
"github.com/ethereum/go-ethereum/eth/protocols/eth"
"github.com/ethereum/go-ethereum/eth/relay"
"github.com/ethereum/go-ethereum/eth/tracers"
"github.com/ethereum/go-ethereum/ethdb"
Expand Down Expand Up @@ -68,6 +70,14 @@ func (b *EthAPIBackend) CurrentBlock() *types.Header {
return b.eth.blockchain.CurrentBlock()
}

func (b *EthAPIBackend) CurrentSafeBlock() *types.Header {
return b.eth.blockchain.CurrentSafeBlock()
}

func (b *EthAPIBackend) GetFinalizedBlockNumber(_ context.Context) (uint64, error) {
return getFinalizedBlockNumber(b.eth)
}

func (b *EthAPIBackend) SetHead(number uint64) {
b.eth.handler.downloader.Cancel()
b.eth.blockchain.SetHead(number)
Expand Down Expand Up @@ -351,17 +361,17 @@ func (b *EthAPIBackend) GetTdByNumber(ctx context.Context, blockNr rpc.BlockNumb
return nil
}

func (b *EthAPIBackend) GetEVM(ctx context.Context, state *state.StateDB, header *types.Header, vmConfig *vm.Config, blockCtx *vm.BlockContext) *vm.EVM {
func (b *EthAPIBackend) GetEVM(_ context.Context, state *state.StateDB, header *types.Header, vmConfig *vm.Config, blockCtx *vm.BlockContext) *vm.EVM {
if vmConfig == nil {
vmConfig = b.eth.blockchain.GetVMConfig()
}
var context vm.BlockContext
var ctx vm.BlockContext
if blockCtx != nil {
context = *blockCtx
ctx = *blockCtx
} else {
context = core.NewEVMBlockContext(header, b.eth.BlockChain(), nil)
ctx = core.NewEVMBlockContext(header, b.eth.BlockChain(), nil)
}
return vm.NewEVM(context, state, b.ChainConfig(), *vmConfig)
return vm.NewEVM(ctx, state, b.ChainConfig(), *vmConfig)
}

func (b *EthAPIBackend) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription {
Expand Down Expand Up @@ -728,6 +738,52 @@ func (b *EthAPIBackend) RPCTxSyncMaxTimeout() time.Duration {
return b.eth.config.TxSyncMaxTimeout
}

// Etherbase returns the address that mining rewards will be sent to.
func (b *EthAPIBackend) Etherbase() (common.Address, error) {
return b.eth.Etherbase()
}

// Hashrate returns the POW hashrate.
func (b *EthAPIBackend) Hashrate() (uint64, error) {
return b.eth.Miner().Hashrate(), nil
}

// Mining returns an indication if this node is currently mining.
func (b *EthAPIBackend) Mining() (bool, error) {
return b.eth.IsMining(), nil
}

// ProtocolVersion returns the current Ethereum protocol version.
func (b *EthAPIBackend) ProtocolVersion() uint {
return eth.ProtocolVersions[0]
}

// GetWork returns a work package for external miners.
func (b *EthAPIBackend) GetWork() ([4]string, error) {
if _, ok := b.eth.engine.(consensus.PoW); !ok {
return [4]string{}, errors.New("not supported, consensus engine is not ethash")
}
return [4]string{}, errors.New("mining work API not implemented by backend")
}

// SubmitWork can be used by external miner to submit their POW solution.
func (b *EthAPIBackend) SubmitWork(_ types.BlockNonce, _, _ common.Hash) (bool, error) {
// Check if the consensus engine is PoW (not our case...)
if _, ok := b.eth.engine.(consensus.PoW); !ok {
return false, errors.New("not supported, consensus engine is not ethash")
}
return false, errors.New("mining work API not implemented by backend")
}

// SubmitHashrate can be used for remote miners to submit their hash rate.
func (b *EthAPIBackend) SubmitHashrate(_ hexutil.Uint64, _ common.Hash) (bool, error) {
// Check if the consensus engine is PoW (not our case...)
if _, ok := b.eth.engine.(consensus.PoW); !ok {
return false, errors.New("not supported, consensus engine is not ethash")
}
return false, errors.New("mining work API not implemented by backend")
}

// Preconf / Private tx related API for relay
func (b *EthAPIBackend) PreconfEnabled() bool {
return b.relay.PreconfEnabled()
Expand Down
Loading
Loading