Skip to content

Commit

Permalink
feat: (de)serialize ilp errors
Browse files Browse the repository at this point in the history
  • Loading branch information
justmoon committed Apr 28, 2017
1 parent 7832a76 commit 4cd5b2a
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 2 deletions.
90 changes: 88 additions & 2 deletions packages/ilp-packet/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { dateToGeneralizedTime, generalizedTimeToDate } from './src/utils/date'
import { stringToTwoNumbers, twoNumbersToString } from './src/utils/uint64'
import base64url from 'base64url-adhoc'
import Long = require('long')
import times = require('lodash/times')

enum Type {
TYPE_ILP_PAYMENT = 1,
Expand All @@ -11,7 +12,8 @@ enum Type {
TYPE_ILQP_BY_SOURCE_REQUEST = 4,
TYPE_ILQP_BY_SOURCE_RESPONSE = 5,
TYPE_ILQP_BY_DESTINATION_REQUEST = 6,
TYPE_ILQP_BY_DESTINATION_RESPONSE = 7
TYPE_ILQP_BY_DESTINATION_RESPONSE = 7,
TYPE_ILP_ERROR = 8
}

const serializeEnvelope = (type: number, contents: Buffer) => {
Expand Down Expand Up @@ -367,6 +369,88 @@ const deserializeIlqpByDestinationResponse = (binary: Buffer): IlqpByDestination
}
}

interface IlpError {
code: string,
name: string,
triggeredBy: string,
forwardedBy: string[],
triggeredAt: Date,
data: string
}

const ILP_ERROR_CODE_LENGTH = 3

const serializeIlpError = (json: IlpError) => {
const writer = new Writer()

// Convert code to buffer to ensure we are counting bytes, not UTF8 characters
const codeBuffer = Buffer.from(json.code, 'ascii')
if (codeBuffer.length !== ILP_ERROR_CODE_LENGTH) {
throw new Error('ILP error codes must be three bytes long, received: ' + json.code)
}

// code
writer.write(codeBuffer)

// name
writer.writeVarOctetString(Buffer.from(json.name, 'ascii'))

// triggeredBy
writer.writeVarOctetString(Buffer.from(json.triggeredBy, 'ascii'))

// forwardedBy
writer.writeVarUInt(json.forwardedBy.length)
json.forwardedBy.forEach(forwardedBy => {
writer.writeVarOctetString(Buffer.from(forwardedBy, 'ascii'))
})

// triggeredAt
writer.writeVarOctetString(Buffer.from(dateToGeneralizedTime(json.triggeredAt), 'ascii'))

// data
writer.writeVarOctetString(Buffer.from(json.data, 'ascii'))

// extensibility
writer.writeUInt8(0)

return serializeEnvelope(Type.TYPE_ILP_ERROR, writer.getBuffer())
}

const deserializeIlpError = (binary: Buffer): IlpError => {
const { type, contents } = deserializeEnvelope(binary)

if (type !== Type.TYPE_ILP_ERROR) {
throw new Error('Packet has incorrect type')
}

const reader = Reader.from(contents)

const code = reader.read(ILP_ERROR_CODE_LENGTH).toString('ascii')

const name = reader.readVarOctetString().toString('ascii')

const triggeredBy = reader.readVarOctetString().toString('ascii')

const forwardedBy = times(reader.readVarUInt()).map(() => {
return reader.readVarOctetString().toString('ascii')
})

const triggeredAt = generalizedTimeToDate(reader.readVarOctetString().toString('ascii'))

const data = reader.readVarOctetString().toString('ascii')

// Ignore remaining bytes for extensibility

return {
code,
name,
triggeredBy,
forwardedBy,
triggeredAt,
data
}
}

module.exports = {
Type,
serializeIlpPayment,
Expand All @@ -382,5 +466,7 @@ module.exports = {
serializeIlqpByDestinationRequest,
deserializeIlqpByDestinationRequest,
serializeIlqpByDestinationResponse,
deserializeIlqpByDestinationResponse
deserializeIlqpByDestinationResponse,
serializeIlpError,
deserializeIlpError
}
15 changes: 15 additions & 0 deletions packages/ilp-packet/test/data/ilp_error/valid/example01.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "example 1",
"binary": "086b4630310e496e76616c6964205061636b65740e6578616d706c652e75732e626f620102116578616d706c652e75732e636f6e6e6965116578616d706c652e75732e636f6e7261641332303137303332343032303031362e3136305a0e7b22666f6f223a2022626172227d00",
"json": {
"code": "F01",
"name": "Invalid Packet",
"triggeredBy": "example.us.bob",
"forwardedBy": [
"example.us.connie",
"example.us.conrad"
],
"triggeredAt": 1490320816160,
"data": "{\"foo\": \"bar\"}"
}
}
36 changes: 36 additions & 0 deletions packages/ilp-packet/test/parser.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -234,4 +234,40 @@ describe('Parser', function () {
}
})
})

describe('serializeIlpError', function () {
describe('correctly serializes valid ilqp by destination responses', function () {
const validTests = loadTests({ type: 'ilp_error' })

for (let test of validTests) {
it(test.name, function () {
const json = test.json

json.triggeredAt = new Date(json.triggeredAt)

const serialized = Parser.serializeIlpError(json)

assert.deepEqual(serialized.toString('hex'), test.binary)
})
}
})
})

describe('deserializeIlpError', function () {
describe('correctly parses valid ilqp by destination responses', function () {
const validTests = loadTests({ type: 'ilp_error' })

for (let test of validTests) {
it(test.name, function () {
const binary = new Buffer(test.binary, 'hex')

const parsed = Parser.deserializeIlpError(binary)

parsed.triggeredAt = parsed.triggeredAt.getTime()

assert.deepEqual(parsed, test.json)
})
}
})
})
})

0 comments on commit 4cd5b2a

Please sign in to comment.