alter the fetch logic a bit

This commit is contained in:
atvanguard 2020-05-19 21:16:37 +05:30
parent fa52ce61f7
commit 742c2104af
3 changed files with 53 additions and 20 deletions

View file

@ -1080,8 +1080,14 @@ func (c *Bor) CommitStates(
if err != nil { if err != nil {
return err return err
} }
from := lastSync.Add(time.Second * 1) // querying the interval [from, to) _lastStateID, err := c.genesisContractsClient.LastStateId(number - 1)
to := time.Unix(int64(chain.Chain.GetHeaderByNumber(number-c.config.Sprint).Time), 0) 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) { if !from.Before(to) {
return nil return nil
} }
@ -1119,14 +1125,11 @@ func (c *Bor) CommitStates(
chainID := c.chainConfig.ChainID.String() chainID := c.chainConfig.ChainID.String()
for _, eventRecord := range eventRecords { for _, eventRecord := range eventRecords {
// validateEventRecord checks whether an event lies in the specified time range if eventRecord.ID <= lastStateID {
// since the events are sorted by time and if it turns out that event i lies outside the time range, continue
// 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 { if err := validateEventRecord(eventRecord, number, from, to, lastStateID, chainID); err != nil {
log.Error( log.Error(err.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)))
break break
} }
@ -1144,13 +1147,14 @@ func (c *Bor) CommitStates(
return err return err
} }
} }
lastStateID++
return nil return nil
} }
func validateEventRecord(eventRecord *EventRecordWithTime, number uint64, from, to time.Time, chainID string) error { func validateEventRecord(eventRecord *EventRecordWithTime, number uint64, from, to time.Time, lastStateID uint64, chainID string) error {
// event should lie in the range [from, to) // event id should be sequential and event.Time should lie in the range [from, to)
if eventRecord.ChainID != chainID || eventRecord.Time.Before(from) || !eventRecord.Time.Before(to) { if lastStateID+1 != eventRecord.ID || eventRecord.ChainID != chainID || eventRecord.Time.Before(from) || !eventRecord.Time.Before(to) {
return &InvalidStateReceivedError{number, &from, &to, eventRecord} return &InvalidStateReceivedError{number, lastStateID, &from, &to, eventRecord}
} }
return nil return nil
} }

View file

@ -126,18 +126,20 @@ func (e *WrongDifficultyError) Error() string {
} }
type InvalidStateReceivedError struct { type InvalidStateReceivedError struct {
Number uint64 Number uint64
From *time.Time LastStateID uint64
To *time.Time From *time.Time
Event *EventRecordWithTime To *time.Time
Event *EventRecordWithTime
} }
func (e *InvalidStateReceivedError) Error() string { func (e *InvalidStateReceivedError) Error() string {
return fmt.Sprintf( 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.Number,
e.From.Format(time.RFC3339), e.From.Format(time.RFC3339),
e.To.Format(time.RFC3339), e.To.Format(time.RFC3339),
e.Event, e.LastStateID,
) )
} }

View file

@ -103,3 +103,30 @@ func (gc *GenesisContractsClient) LastStateSyncTime(snapshotNumber uint64) (*tim
_time := time.Unix((*ret).Int64(), 0) _time := time.Unix((*ret).Int64(), 0)
return &_time, nil 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
}