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 {
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
}

View file

@ -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,
)
}

View file

@ -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
}