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