Skip to content

Commit

Permalink
xdpos API getV2Block (ethereum#227)
Browse files Browse the repository at this point in the history
  • Loading branch information
liam-lai authored Mar 4, 2023
1 parent 105f387 commit 9552500
Show file tree
Hide file tree
Showing 7 changed files with 115 additions and 14 deletions.
96 changes: 96 additions & 0 deletions consensus/XDPoS/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@
package XDPoS

import (
"encoding/base64"
"math/big"

"github.com/XinFinOrg/XDPoSChain/common"
"github.com/XinFinOrg/XDPoSChain/consensus"
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/utils"
"github.com/XinFinOrg/XDPoSChain/core/types"
"github.com/XinFinOrg/XDPoSChain/rlp"
"github.com/XinFinOrg/XDPoSChain/rpc"
)

Expand All @@ -31,6 +33,17 @@ type API struct {
chain consensus.ChainReader
XDPoS *XDPoS
}

type V2BlockInfo struct {
Hash common.Hash
Round types.Round
Number *big.Int
ParentHash common.Hash
Committed bool
EncodedRLP string
Error string
}

type NetworkInformation struct {
NetworkId *big.Int
XDCValidatorAddress common.Address
Expand Down Expand Up @@ -96,6 +109,89 @@ func (api *API) GetLatestCommittedBlockHeader() *types.BlockInfo {
return api.XDPoS.EngineV2.GetLatestCommittedBlockInfo()
}

func (api *API) GetV2BlockByHeader(header *types.Header, uncle bool) *V2BlockInfo {
committed := false
latestCommittedBlock := api.XDPoS.EngineV2.GetLatestCommittedBlockInfo()
if latestCommittedBlock == nil {
return &V2BlockInfo{
Hash: header.Hash(),
Error: "can not find latest committed block from consensus",
}
}
if header.Number.Uint64() <= latestCommittedBlock.Number.Uint64() {
committed = true && !uncle
}

round, err := api.XDPoS.EngineV2.GetRoundNumber(header)

if err != nil {
return &V2BlockInfo{
Hash: header.Hash(),
Error: err.Error(),
}
}

encodeBytes, err := rlp.EncodeToBytes(header)
if err != nil {
return &V2BlockInfo{
Hash: header.Hash(),
Error: err.Error(),
}
}

block := &V2BlockInfo{
Hash: header.Hash(),
ParentHash: header.ParentHash,
Number: header.Number,
Round: round,
Committed: committed,
EncodedRLP: base64.StdEncoding.EncodeToString(encodeBytes),
}
return block
}

func (api *API) GetV2BlockByNumber(number *rpc.BlockNumber) *V2BlockInfo {
var header *types.Header
if number == nil || *number == rpc.LatestBlockNumber {
header = api.chain.CurrentHeader()
} else if *number == rpc.CommittedBlockNumber {
hash := api.XDPoS.EngineV2.GetLatestCommittedBlockInfo().Hash
header = api.chain.GetHeaderByHash(hash)
} else {
header = api.chain.GetHeaderByNumber(uint64(number.Int64()))
}

if header == nil {
return &V2BlockInfo{
Number: big.NewInt(number.Int64()),
Error: "can not find block from this number",
}
}

uncle := false
return api.GetV2BlockByHeader(header, uncle)
}

// Confirm V2 Block Committed Status
func (api *API) GetV2BlockByHash(blockHash common.Hash) *V2BlockInfo {
header := api.chain.GetHeaderByHash(blockHash)
if header == nil {
return &V2BlockInfo{
Hash: blockHash,
Error: "can not find block from this hash",
}
}

// confirm this is on the main chain
chainHeader := api.chain.GetHeaderByNumber(header.Number.Uint64())
uncle := false
if header.Hash() != chainHeader.Hash() {
uncle = true
}

return api.GetV2BlockByHeader(header, uncle)
}

func (api *API) NetworkInformation() NetworkInformation {
info := NetworkInformation{}
info.NetworkId = api.chain.Config().ChainId
Expand Down
4 changes: 2 additions & 2 deletions eth/api_backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func (b *EthApiBackend) HeaderByNumber(ctx context.Context, blockNr rpc.BlockNum
// Otherwise resolve and return the block
if blockNr == rpc.LatestBlockNumber {
return b.eth.blockchain.CurrentBlock().Header(), nil
} else if blockNr == rpc.ConfirmedBlockNumber {
} else if blockNr == rpc.CommittedBlockNumber {
if b.eth.chainConfig.XDPoS == nil {
return nil, errors.New("PoW does not support confirmed block lookup")
}
Expand Down Expand Up @@ -110,7 +110,7 @@ func (b *EthApiBackend) BlockByNumber(ctx context.Context, blockNr rpc.BlockNumb
// Otherwise resolve and return the block
if blockNr == rpc.LatestBlockNumber {
return b.eth.blockchain.CurrentBlock(), nil
} else if blockNr == rpc.ConfirmedBlockNumber {
} else if blockNr == rpc.CommittedBlockNumber {
if b.eth.chainConfig.XDPoS == nil {
return nil, errors.New("PoW does not support confirmed block lookup")
}
Expand Down
4 changes: 2 additions & 2 deletions internal/jsre/deps/bindata.go

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion internal/jsre/deps/web3.js

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

8 changes: 6 additions & 2 deletions internal/web3ext/web3ext.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,12 @@ web3._extend({
params: 1
}),
new web3._extend.Method({
name: 'getLatestCommittedBlockInfo',
call: 'XDPoS_getLatestCommittedBlockHeader'
name: 'getV2Block',
call: function (args) {
return (web3._extend.utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? "XDPoS_getV2BlockByHash" : "XDPoS_getV2BlockByNumber";
},
params: 1,
inputFormatter: [web3._extend.formatters.inputBlockNumberFormatter]
}),
],
properties: [
Expand Down
8 changes: 4 additions & 4 deletions rpc/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,15 +120,15 @@ type BlockNumber int64
type EpochNumber int64

const (
ConfirmedBlockNumber = BlockNumber(-3)
CommittedBlockNumber = BlockNumber(-3)
PendingBlockNumber = BlockNumber(-2)
LatestBlockNumber = BlockNumber(-1)
EarliestBlockNumber = BlockNumber(0)
LatestEpochNumber = EpochNumber(-1)
)

// UnmarshalJSON parses the given JSON fragment into a BlockNumber. It supports:
// - "latest", "earliest", "pending" and "confirmed" as string arguments
// - "latest", "earliest", "pending" and "committed" as string arguments
// - the block number
// Returned errors:
// - an invalid block number error when the given argument isn't a known strings
Expand All @@ -145,8 +145,8 @@ func (bn *BlockNumber) UnmarshalJSON(data []byte) error {
case "pending":
*bn = PendingBlockNumber
return nil
case "confirmed":
*bn = ConfirmedBlockNumber
case "committed":
*bn = CommittedBlockNumber
return nil
}

Expand Down
7 changes: 4 additions & 3 deletions rpc/types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,10 @@ func TestBlockNumberJSONUnmarshal(t *testing.T) {
11: {`"pending"`, false, PendingBlockNumber},
12: {`"latest"`, false, LatestBlockNumber},
13: {`"earliest"`, false, EarliestBlockNumber},
14: {`someString`, true, BlockNumber(0)},
15: {`""`, true, BlockNumber(0)},
16: {``, true, BlockNumber(0)},
14: {`"committed"`, false, CommittedBlockNumber},
15: {`someString`, true, BlockNumber(0)},
16: {`""`, true, BlockNumber(0)},
17: {``, true, BlockNumber(0)},
}

for i, test := range tests {
Expand Down

0 comments on commit 9552500

Please sign in to comment.