Skip to content

Commit

Permalink
refactor(unpackTx)!: accept only tx_string, don't return binary
Browse files Browse the repository at this point in the history
BREAKING CHANGE: `unpackTx` not accepting transaction as buffer
Use `unpackTx(encode(tx, 'tx'))` instead.

BREAKING CHANGE: `unpackTx` deosn't return `binary`
Use `require('rlp').decode(unpackTx(tx).rlpEncoded)` instead.
  • Loading branch information
davidyuk committed Jun 12, 2022
1 parent 271cbe4 commit 658adee
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 36 deletions.
4 changes: 2 additions & 2 deletions src/channel/internal.ts
Expand Up @@ -119,7 +119,7 @@ const PONG_TIMEOUT_MS = 5000
// TODO: move to Channel instance to avoid is-null checks and for easier debugging
export const options = new WeakMap<Channel, ChannelOptions>()
export const status = new WeakMap<Channel, string>()
export const state = new WeakMap<Channel, Uint8Array>()
export const state = new WeakMap<Channel, EncodedData<'tx'>>()
const fsm = new WeakMap<Channel, ChannelFsm>()
const websockets = new WeakMap<Channel, W3CWebSocket>()
export const eventEmitters = new WeakMap<Channel, EventEmitter>()
Expand Down Expand Up @@ -158,7 +158,7 @@ export function changeStatus (channel: Channel, newStatus: string): void {
}
}

export function changeState (channel: Channel, newState: Uint8Array): void {
export function changeState (channel: Channel, newState: EncodedData<'tx'>): void {
state.set(channel, newState)
emit(channel, 'stateChanged', newState)
}
Expand Down
28 changes: 11 additions & 17 deletions src/tx/builder/index.ts
Expand Up @@ -83,15 +83,15 @@ function deserializeField (
case FIELD_TYPES.pointers:
return readPointers(value)
case FIELD_TYPES.rlpBinary:
return unpackTx(value, { fromRlpBinary: true })
return unpackTx(encode(value, 'tx'))
case FIELD_TYPES.rlpBinaries:
return value.map((v: Buffer) => unpackTx(v, { fromRlpBinary: true }))
return value.map((v: Buffer) => unpackTx(encode(v, 'tx')))
case FIELD_TYPES.rawBinary:
return value
case FIELD_TYPES.hex:
return value.toString('hex')
case FIELD_TYPES.offChainUpdates:
return value.map((v: Buffer) => unpackTx(v, { fromRlpBinary: true }))
return value.map((v: Buffer) => unpackTx(encode(v, 'tx')))
case FIELD_TYPES.callStack:
// TODO: fix this
return [readInt(value)]
Expand Down Expand Up @@ -496,28 +496,23 @@ export interface TxUnpacked<Tx extends TxSchema> {
txType: TX_TYPE
tx: RawTxObject<Tx>
rlpEncoded: Uint8Array
binary: Uint8Array | NestedUint8Array
}
/**
* Unpack transaction hash
* @function
* @alias module:@aeternity/aepp-sdk/es/tx/builder
* @param encodedTx String or RLP encoded transaction array
* (if fromRlpBinary flag is true)
* @param fromRlpBinary Unpack from RLP encoded transaction (default: false)
* @param encodedTx Transaction to unpack
* @param options
* @param options.txType Expected transaction type
* @returns object
* @returns object.tx Object with transaction param's
* @returns object.rlpEncoded rlp encoded transaction
* @returns object.binary binary transaction
* @returns object.txType Transaction type
*/
export function unpackTx<TxType extends TX_TYPE> (
encodedTx: EncodedData<'tx'> | Uint8Array,
{ txType, fromRlpBinary = false }:
{ txType?: TxType, fromRlpBinary?: boolean } = {
fromRlpBinary: false
}
encodedTx: EncodedData<'tx' | 'pi'>,
{ txType }: { txType?: TxType } = {}
): TxUnpacked<TxTypeSchemas[TxType]> {
const rlpEncoded = fromRlpBinary ? encodedTx as Uint8Array : decode(encodedTx as EncodedData<'tx'>)
const rlpEncoded = decode(encodedTx)
const binary = rlpDecode(rlpEncoded)
const objId = +readInt(binary[0] as Buffer)
if (!isKeyOfObject(objId, TX_SCHEMA)) throw new DecodeError(`Unknown transaction tag: ${objId}`)
Expand All @@ -528,8 +523,7 @@ export function unpackTx<TxType extends TX_TYPE> (
return {
txType: objId,
tx: unpackRawTx<TxTypeSchemas[TxType]>(binary, schema),
rlpEncoded,
binary
rlpEncoded
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/tx/validator.ts
Expand Up @@ -210,14 +210,14 @@ const getSenderAddress = (
* @example const errors = await verifyTransaction(transaction, node)
*/
export default async function verifyTransaction (
transaction: Buffer | EncodedData<'tx'>,
transaction: EncodedData<'tx' | 'pi'>,
node: Node,
parentTxTypes: TX_TYPE[] = []
): Promise<ValidatorResult[]> {
const { tx, txType } = unpackTx(transaction)
const address = getSenderAddress(tx) ??
(txType === TX_TYPE.signed
? getSenderAddress((tx as TxTypeSchemas[typeof txType]).encodedTx.tx)
? getSenderAddress((tx as TxTypeSchemas[TX_TYPE.signed]).encodedTx.tx)
: undefined)
const [account, { height }, { consensusProtocolVersion, nodeNetworkId }] = await Promise.all([
address == null
Expand Down
23 changes: 10 additions & 13 deletions test/integration/channel.ts
Expand Up @@ -23,7 +23,6 @@ import { getSdk, BaseAe, networkId } from '.'
import { generateKeyPair } from '../../src/utils/crypto'
import { pause } from '../../src/utils/other'
import { unpackTx, buildTx, buildTxHash } from '../../src/tx/builder'
import { decode } from '../../src/tx/builder/helpers'
import { TX_TYPE } from '../../src/tx/builder/schema'
import Channel from '../../src/channel'
import { ChannelOptions, send } from '../../src/channel/internal'
Expand Down Expand Up @@ -207,7 +206,7 @@ describe('Channel', function () {
}])
})
)
const { txType } = unpackTx(sign.firstCall.args[0] as Uint8Array)
const { txType } = unpackTx(sign.firstCall.args[0] as EncodedData<'tx'>)
txType.should.equal(TX_TYPE.channelOffChain)

expect(sign.firstCall.args[1]).to.eql({
Expand Down Expand Up @@ -263,7 +262,7 @@ describe('Channel', function () {
}])
})
)
const { txType } = unpackTx(sign.firstCall.args[0] as Uint8Array)
const { txType } = unpackTx(sign.firstCall.args[0] as EncodedData<'tx'>)
txType.should.equal(TX_TYPE.channelOffChain)
expect(sign.firstCall.args[1]).to.eql({
updates: [
Expand Down Expand Up @@ -343,7 +342,7 @@ describe('Channel', function () {
}])
})
)
const { txType } = unpackTx(sign.firstCall.args[0] as Uint8Array)
const { txType } = unpackTx(sign.firstCall.args[0] as EncodedData<'tx'>)
txType.should.equal(TX_TYPE.channelOffChain)
expect(sign.firstCall.args[1]).to.eql({
updates: [
Expand Down Expand Up @@ -386,10 +385,8 @@ describe('Channel', function () {
const responderPoi: EncodedData<'pi'> = await responderCh.poi(params)
initiatorPoi.should.be.a('string')
responderPoi.should.be.a('string')
const unpackedInitiatorPoi = unpackTx(
decode(initiatorPoi), { txType: TX_TYPE.proofOfInclusion, fromRlpBinary: true })
const unpackedResponderPoi = unpackTx(
decode(responderPoi), { txType: TX_TYPE.proofOfInclusion, fromRlpBinary: true })
const unpackedInitiatorPoi = unpackTx(initiatorPoi, { txType: TX_TYPE.proofOfInclusion })
const unpackedResponderPoi = unpackTx(responderPoi, { txType: TX_TYPE.proofOfInclusion })
buildTx(unpackedInitiatorPoi.tx, unpackedInitiatorPoi.txType, { prefix: 'pi' }).tx.should.equal(initiatorPoi)
buildTx(unpackedResponderPoi.tx, unpackedResponderPoi.txType, { prefix: 'pi' }).tx.should.equal(responderPoi)
})
Expand Down Expand Up @@ -467,7 +464,7 @@ describe('Channel', function () {
}]
})
)
const { txType, tx } = unpackTx(sign.firstCall.args[0] as Uint8Array)
const { txType, tx } = unpackTx(sign.firstCall.args[0] as EncodedData<'tx'>)
txType.should.equal(TX_TYPE.channelWithdraw)
tx.should.eql({
...tx,
Expand Down Expand Up @@ -520,7 +517,7 @@ describe('Channel', function () {
}]
})
)
const { txType, tx } = unpackTx(sign.firstCall.args[0] as Uint8Array)
const { txType, tx } = unpackTx(sign.firstCall.args[0] as EncodedData<'tx'>)
txType.should.equal(TX_TYPE.channelWithdraw)
tx.should.eql({
...tx,
Expand Down Expand Up @@ -596,7 +593,7 @@ describe('Channel', function () {
}])
})
)
const { txType, tx } = unpackTx(sign.firstCall.args[0] as Uint8Array)
const { txType, tx } = unpackTx(sign.firstCall.args[0] as EncodedData<'tx'>)
txType.should.equal(TX_TYPE.channelDeposit)
tx.should.eql({
...tx,
Expand Down Expand Up @@ -637,7 +634,7 @@ describe('Channel', function () {
}]
})
)
const { txType, tx } = unpackTx(sign.firstCall.args[0] as Uint8Array)
const { txType, tx } = unpackTx(sign.firstCall.args[0] as EncodedData<'tx'>)
txType.should.equal(TX_TYPE.channelDeposit)
tx.should.eql({
...tx,
Expand Down Expand Up @@ -682,7 +679,7 @@ describe('Channel', function () {
)
sinon.assert.calledOnce(sign)
sinon.assert.calledWithExactly(sign, sinon.match.string)
const { txType, tx } = unpackTx(sign.firstCall.args[0] as Uint8Array)
const { txType, tx } = unpackTx(sign.firstCall.args[0] as EncodedData<'tx'>)
txType.should.equal(TX_TYPE.channelCloseMutual)
tx.should.eql({
...tx,
Expand Down
4 changes: 2 additions & 2 deletions test/unit/tx.ts
Expand Up @@ -109,8 +109,8 @@ describe('Tx', function () {
})

it('Deserialize tx: invalid tx VSN', () => {
const tx = rlpEncode([10, 99])
expect(() => unpackTx(tx, { fromRlpBinary: true }))
const tx = encode(rlpEncode([10, 99]), 'tx')
expect(() => unpackTx(tx))
.to.throw(SchemaNotFoundError, `Transaction deserialization not implemented for tag ${10} version ${99}`)
})

Expand Down

0 comments on commit 658adee

Please sign in to comment.