@@ -28,6 +28,7 @@ import (
2828 "math"
2929 "math/big"
3030 "sort"
31+ "strings"
3132 "sync"
3233 "sync/atomic"
3334 "time"
@@ -243,6 +244,11 @@ func New(config *params.DBFTConfig, _ ethdb.Database) (*DBFT, error) {
243244 copy (conf .StandByValidators , config .StandByValidators )
244245 slices .SortFunc (conf .StandByValidators , common .Address .Cmp )
245246
247+ govABI , err := abi .JSON (strings .NewReader (systemcontracts .GovernanceABI ))
248+ if err != nil {
249+ return nil , fmt .Errorf ("failed to parse Governance contract ABI" )
250+ }
251+
246252 c := & DBFT {
247253 config : & conf ,
248254 blockQueue : newBlockQueue (),
@@ -253,6 +259,8 @@ func New(config *params.DBFTConfig, _ ethdb.Database) (*DBFT, error) {
253259
254260 quit : make (chan struct {}),
255261 finished : make (chan struct {}),
262+
263+ governanceABI : govABI ,
256264 }
257265
258266 logger , _ := zap .NewDevelopment ()
@@ -1375,6 +1383,7 @@ func payloadFromMessage(ep *dbftproto.Message) *Payload {
13751383
13761384func (c * DBFT ) validatePayload (p * Payload ) bool {
13771385 h := c .chain .CurrentBlock ()
1386+ // TODO: need validators cache at least for payloads verification, otherwise we'll end up in endless state-dependent computations.
13781387 validators , err := c .getNextBlockValidators (h .Hash (), h .Number .Uint64 (), false )
13791388 if err != nil {
13801389 return false
@@ -1593,7 +1602,8 @@ func (c *DBFT) APIs(chain consensus.ChainHeaderReader) []rpc.API {
15931602// to be sorted by bytes order (even if returned from governance contract).
15941603func (c * DBFT ) getNextBlockValidators (blockHash common.Hash , blockNum uint64 , compute bool ) ([]common.Address , error ) {
15951604 // Currently we don't have governance contract, thus, always return standby set.
1596- if true {
1605+ // TODO: to be removed.
1606+ if blockNum == 0 {
15971607 return c .config .StandByValidators , nil
15981608 }
15991609
@@ -1603,13 +1613,20 @@ func (c *DBFT) getNextBlockValidators(blockHash common.Hash, blockNum uint64, co
16031613
16041614 // Once we have governance contract, we don't need StandByValidators in the dBFT's
16051615 // config, governance contract will handle it internally.
1606- blockNr := rpc .BlockNumberOrHashWithHash ( blockHash , false )
1616+ blockNr := rpc .BlockNumberOrHashWithNumber ( rpc . BlockNumber ( blockNum ) )
16071617
16081618 // Different values depending on dBFT epoch.
1609- method := "getNextBlockValidators" // current epoch validators
1610- if compute {
1611- method = "computeNextBlockValidators" // current epoch validators for the middle of dBFT epoch and next epoch validators for the last block in epoch
1612- }
1619+ method := "getCurrentConsensus" // current epoch validators
1620+ /*if compute {
1621+ // TODO: given time-dependent `EPOCH_DURATION`, calculation of next consensus becomes complicated. We need
1622+ // `getNextConsensus` API to be presented in Governance contract since `getConsensus` is not enough.
1623+ // `getConsensus` calculates consensus based on the current state, even if epoch is not finished yet. What we need
1624+ // is `getNextConsensus` that returns current epoch validators for the middle of dBFT epoch and next epoch validators
1625+ // for the last block in the epoch. We can organize this at the code-level, but it complicates getNextBlockValidators call, so
1626+ // why not to move it to the contract level where it costs nothing.
1627+ // @roman-khimov, agree?
1628+ method = "getNextConsensus" // current epoch validators for the middle of dBFT epoch and next epoch validators for the last block in epoch
1629+ }*/
16131630
16141631 ctx , cancel := context .WithCancel (context .Background ())
16151632 // Cancel when we are finished consuming integers
@@ -1621,7 +1638,7 @@ func (c *DBFT) getNextBlockValidators(blockHash common.Hash, blockNum uint64, co
16211638 }
16221639 // do smart contract call
16231640 msgData := (hexutil .Bytes )(data )
1624- toAddress := common .HexToAddress (systemcontracts .GovernanceContract )
1641+ toAddress := common .HexToAddress (systemcontracts .GovernanceHash )
16251642 gas := (hexutil .Uint64 )(uint64 (math .MaxUint64 / 2 ))
16261643 result , err := c .ethAPI .Call (ctx , ethapi.TransactionArgs {
16271644 Gas : & gas ,
@@ -1634,6 +1651,10 @@ func (c *DBFT) getNextBlockValidators(blockHash common.Hash, blockNum uint64, co
16341651
16351652 var valSet []common.Address
16361653 err = c .governanceABI .UnpackIntoInterface (& valSet , method , result )
1654+
1655+ // TODO: roman-khimov, we've agreed that validators are sorted using lexicographic order, but in contract they are
1656+ // sorted by votes. Need to come to some single solution.
1657+ slices .SortFunc (valSet , common .Address .Cmp )
16371658 return valSet , err
16381659}
16391660
0 commit comments