From 742c2104afaba0712bff0790bae539dacb6fb55a Mon Sep 17 00:00:00 2001
From: atvanguard <93arpit@gmail.com>
Date: Tue, 19 May 2020 21:16:37 +0530
Subject: [PATCH] alter the fetch logic a bit

---
 consensus/bor/bor.go                      | 32 +++++++++++++----------
 consensus/bor/errors.go                   | 14 +++++-----
 consensus/bor/genesis_contracts_client.go | 27 +++++++++++++++++++
 3 files changed, 53 insertions(+), 20 deletions(-)

diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go
index e34a604c6..f2ba5cdb0 100644
--- a/consensus/bor/bor.go
+++ b/consensus/bor/bor.go
@@ -1080,8 +1080,14 @@ func (c *Bor) CommitStates(
 	if err != nil {
 		return err
 	}
-	from := lastSync.Add(time.Second * 1) // querying the interval [from, to)
-	to := time.Unix(int64(chain.Chain.GetHeaderByNumber(number-c.config.Sprint).Time), 0)
+	_lastStateID, err := c.genesisContractsClient.LastStateId(number - 1)
+	if err != nil {
+		return err
+	}
+
+	from := *lastSync
+	to := time.Unix(int64(chain.Chain.GetHeaderByNumber(number-1).Time), 0)
+	lastStateID := _lastStateID.Uint64()
 	if !from.Before(to) {
 		return nil
 	}
@@ -1119,14 +1125,11 @@ func (c *Bor) CommitStates(
 
 	chainID := c.chainConfig.ChainID.String()
 	for _, eventRecord := range eventRecords {
-		// validateEventRecord checks whether an event lies in the specified time range
-		// since the events are sorted by time and if it turns out that event i lies outside the time range,
-		// it would mean all subsequent events lie outside of the time range. Hence we don't probe any further and break the loop
-		if err := validateEventRecord(eventRecord, number, from, to, chainID); err != nil {
-			log.Error(
-				fmt.Sprintf(
-					"Received event %s does not lie in the time range, from %s, to %s",
-					eventRecord, from.Format(time.RFC3339), to.Format(time.RFC3339)))
+		if eventRecord.ID <= lastStateID {
+			continue
+		}
+		if err := validateEventRecord(eventRecord, number, from, to, lastStateID, chainID); err != nil {
+			log.Error(err.Error())
 			break
 		}
 
@@ -1144,13 +1147,14 @@ func (c *Bor) CommitStates(
 			return err
 		}
 	}
+	lastStateID++
 	return nil
 }
 
-func validateEventRecord(eventRecord *EventRecordWithTime, number uint64, from, to time.Time, chainID string) error {
-	// event should lie in the range [from, to)
-	if eventRecord.ChainID != chainID || eventRecord.Time.Before(from) || !eventRecord.Time.Before(to) {
-		return &InvalidStateReceivedError{number, &from, &to, eventRecord}
+func validateEventRecord(eventRecord *EventRecordWithTime, number uint64, from, to time.Time, lastStateID uint64, chainID string) error {
+	// event id should be sequential and event.Time should lie in the range [from, to)
+	if lastStateID+1 != eventRecord.ID || eventRecord.ChainID != chainID || eventRecord.Time.Before(from) || !eventRecord.Time.Before(to) {
+		return &InvalidStateReceivedError{number, lastStateID, &from, &to, eventRecord}
 	}
 	return nil
 }
diff --git a/consensus/bor/errors.go b/consensus/bor/errors.go
index fce71cd6f..778a2672b 100644
--- a/consensus/bor/errors.go
+++ b/consensus/bor/errors.go
@@ -126,18 +126,20 @@ func (e *WrongDifficultyError) Error() string {
 }
 
 type InvalidStateReceivedError struct {
-	Number uint64
-	From   *time.Time
-	To     *time.Time
-	Event  *EventRecordWithTime
+	Number      uint64
+	LastStateID uint64
+	From        *time.Time
+	To          *time.Time
+	Event       *EventRecordWithTime
 }
 
 func (e *InvalidStateReceivedError) Error() string {
 	return fmt.Sprintf(
-		"Received event with invalid timestamp at block %d. Requested events from %s to %s. Received %s\n",
+		"Received invalid event %s at block %d. Requested events from %s to %s. lastStateID was %d.\n",
+		e.Event,
 		e.Number,
 		e.From.Format(time.RFC3339),
 		e.To.Format(time.RFC3339),
-		e.Event,
+		e.LastStateID,
 	)
 }
diff --git a/consensus/bor/genesis_contracts_client.go b/consensus/bor/genesis_contracts_client.go
index bd679e2f7..48c4bb5e6 100644
--- a/consensus/bor/genesis_contracts_client.go
+++ b/consensus/bor/genesis_contracts_client.go
@@ -103,3 +103,30 @@ func (gc *GenesisContractsClient) LastStateSyncTime(snapshotNumber uint64) (*tim
 	_time := time.Unix((*ret).Int64(), 0)
 	return &_time, nil
 }
+
+func (gc *GenesisContractsClient) LastStateId(snapshotNumber uint64) (*big.Int, error) {
+	method := "lastStateId"
+	data, err := gc.stateReceiverABI.Pack(method)
+	if err != nil {
+		log.Error("Unable to pack tx for getLastSyncTime", "error", err)
+		return nil, err
+	}
+
+	msgData := (hexutil.Bytes)(data)
+	toAddress := common.HexToAddress(gc.StateReceiverContract)
+	gas := (hexutil.Uint64)(uint64(math.MaxUint64 / 2))
+	result, err := gc.ethAPI.Call(context.Background(), ethapi.CallArgs{
+		Gas:  &gas,
+		To:   &toAddress,
+		Data: &msgData,
+	}, rpc.BlockNumber(snapshotNumber))
+	if err != nil {
+		return nil, err
+	}
+
+	var ret = new(*big.Int)
+	if err := gc.stateReceiverABI.Unpack(ret, method, result); err != nil {
+		return nil, err
+	}
+	return *ret, nil
+}
-- 
GitLab