import { Bool , ByteArray , BytesReader } from 'as-scale-codec' ; import { Call , InherentData , Log , ResponseCodes } from 'subsembly-core' ; import { StorageEntry } from '../../frame' ; import { Pallets , TimestampCalls } from '../../generated/dispatcher' ; import { Inherent , Moment , TimestampConfig } from '../../runtime/runtime' ; description export namespace TimestampStorageEntries { /**
     * Current set Timestamp value
     */ export function Now ( ) { return new StorageEntry < Moment > ( "Timestamp" , "Now" ) ; } ; /**
     * Checks if Timestamp was updated for current slot
     */ export function DidUpdate ( ) { return new StorageEntry < Bool > ( "Timestamp" , "DidUpdate" ) ; } ; } ; description export class Timestamp { public static readonly INHERENT_IDENTIFIER : string = "timstap0" ; description static _toggleUpdate ( ) { const value = TimestampStorageEntries . DidUpdate ( ) . get ( ) ; TimestampStorageEntries . DidUpdate ( ) . set ( new Bool ( ! ( value . unwrap ( ) ) ) ) ; } description param now static set ( now ) { const didUpdate = TimestampStorageEntries . DidUpdate ( ) . get ( ) ; if ( didUpdate . unwrap ( ) ) { Log . error ( 'Validation error: Timestamp must be updated only once in the block' ) ; return this . _tooFrequentResponseCode ( ) ; } let minValue = TimestampStorageEntries . Now ( ) . get ( ) . unwrap ( ) + TimestampConfig . minimumPeriod ( ) . unwrap ( ) ; if ( now . unwrap ( ) < minValue ) { Log . error ( 'Validation error: Timestamp must increment by at least <MinimumPeriod> between sequential blocks' ) ; return this . _timeframeTooLowResponceCode ( ) ; } TimestampStorageEntries . DidUpdate ( ) . set ( new Bool ( true ) ) ; TimestampStorageEntries . Now ( ) . set ( now ) ; Timestamp . _toggleUpdate ( ) ; return ResponseCodes . SUCCESS ; } description param data static _createInherent ( data ) { const timestampData = BytesReader . decodeInto < Moment > ( this . _extractInherentData ( data ) . unwrap ( ) ) ; let nextTime = timestampData ; const now = TimestampStorageEntries . Now ( ) . get ( ) ; if ( now . unwrap ( ) ) { let nextTimeValue = timestampData . unwrap ( ) > now . unwrap ( ) + TimestampConfig . minimumPeriod ( ) . unwrap ( ) ? timestampData . unwrap ( ) : now . unwrap ( ) + TimestampConfig . minimumPeriod ( ) . unwrap ( ) ; nextTime = instantiate < Moment > ( nextTimeValue ) ; } const call = new Call ( [ < u8 > Pallets . Timestamp , < u8 > TimestampCalls . set ] , nextTime . toU8a ( ) ) ; return instantiate < Inherent > ( call ) ; } description param t param data static _checkInherent ( t , data ) { const MAX_TIMESTAMP_DRIFT_MILLS = instantiate < Moment > ( 30 * 1000 ) ; const timestampData = BytesReader . decodeInto < Moment > ( this . _extractInherentData ( data ) . unwrap ( ) ) ; const minimum = instantiate < Moment > ( TimestampStorageEntries . Now ( ) . get ( ) . unwrap ( ) + TimestampConfig . minimumPeriod ( ) . unwrap ( ) ) ; if ( t . unwrap ( ) > timestampData . unwrap ( ) + MAX_TIMESTAMP_DRIFT_MILLS . unwrap ( ) ) { return false ; } else if ( t . unwrap ( ) < minimum . unwrap ( ) ) { return false ; } else { return true ; } } description static _tooFrequentResponseCode ( ) { return ResponseCodes . dispatchError ( < u8 > Pallets . Timestamp , 1 ) ; } description static _timeframeTooLowResponceCode ( ) { return ResponseCodes . dispatchError ( < u8 > Pallets . Timestamp , 2 ) ; } description param inhData static _extractInherentData ( inhData ) { return inhData . getData ( ) . get ( Timestamp . INHERENT_IDENTIFIER ) ; } }