1 2
import { create as createLogger } from '../common/log'
2 2
const log = createLogger('echo')
3
import reduct = require('reduct')
4 2
import { serializeIlpPrepare, IlpPrepare, Errors } from 'ilp-packet'
5 2
import { Reader, Writer } from 'oer-utils'
6 2
import Config from '../services/config'
7 2
import RouteBuilder from '../services/route-builder'
8 2
const { InvalidPacketError } = Errors
9

10 2
const MINIMUM_ECHO_PACKET_DATA_LENGTH = 16 + 1
11 2
const ECHO_DATA_PREFIX = Buffer.from('ECHOECHOECHOECHO', 'ascii')
12

13 2
export default class EchoController {
14
  private config: Config
15
  private routeBuilder: RouteBuilder
16

17
  constructor (deps: reduct.Injector) {
18 2
    this.config = deps(Config)
19 2
    this.routeBuilder = deps(RouteBuilder)
20
  }
21

22
  async handle (
23
    data: Buffer,
24
    sourceAccount: string,
25
    { parsedPacket, outbound }: {
26
      parsedPacket: IlpPrepare,
27
      outbound: (data: Buffer, accountId: string) => Promise<Buffer>
28
    }
29
  ) {
30 2
    if (parsedPacket.data.length < MINIMUM_ECHO_PACKET_DATA_LENGTH) {
31 0
      throw new InvalidPacketError('packet data too short for echo request. length=' + parsedPacket.data.length)
32
    }
33

34 2
    if (!parsedPacket.data.slice(0, 16).equals(ECHO_DATA_PREFIX)) {
35 0
      throw new InvalidPacketError('packet data does not start with ECHO prefix.')
36
    }
37

38 0
    const reader = new Reader(parsedPacket.data)
39

40 0
    reader.skip(ECHO_DATA_PREFIX.length)
41

42 0
    const type = reader.readUInt8Number()
43

44 2
    if (type === 0) {
45 0
      const sourceAddress = reader.readVarOctetString().toString('ascii')
46

47 0
      log.trace('responding to ping. sourceAccount=%s sourceAddress=%s cond=%s', sourceAccount, sourceAddress, parsedPacket.executionCondition.slice(0, 9).toString('base64'))
48

49 0
      const nextHop = this.routeBuilder.getNextHop(sourceAccount, sourceAddress)
50

51 0
      const writer = new Writer()
52

53 0
      writer.write(ECHO_DATA_PREFIX)
54

55 0
      writer.writeUInt8(0x01) // type = response
56

57 0
      return outbound(serializeIlpPrepare({
58
        amount: parsedPacket.amount,
59
        destination: sourceAddress,
60
        executionCondition: parsedPacket.executionCondition,
61
        expiresAt: new Date(Number(parsedPacket.expiresAt) - this.config.minMessageWindow),
62
        data: writer.getBuffer()
63
      }), nextHop)
64
    } else {
65 0
      log.error('received unexpected ping response. sourceAccount=%s', sourceAccount)
66 0
      throw new InvalidPacketError('unexpected ping response.')
67
    }
68
  }
69
}

Read our documentation on viewing source code .

Loading