Skip to content

Commit

Permalink
Ran prettier:write
Browse files Browse the repository at this point in the history
  • Loading branch information
arweave-kyle committed Aug 5, 2020
1 parent 94e065a commit 950e801
Show file tree
Hide file tree
Showing 11 changed files with 435 additions and 326 deletions.
32 changes: 16 additions & 16 deletions src/common/chunks.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,32 @@
import Api from "./lib/api";
import { getError } from "./lib/error";
import * as ArweaveUtils from './lib/utils';
import * as ArweaveUtils from "./lib/utils";

export interface TransactionOffsetResponse {
size: string
offset: string
size: string;
offset: string;
}

export interface TransactionChunkResponse {
chunk: string
data_path: string
tx_path: string
chunk: string;
data_path: string;
tx_path: string;
}

export default class Chunks {
constructor(private api: Api) {}

constructor(private api: Api) {
}

async getTransactionOffset(id: string): Promise<TransactionOffsetResponse> {
const resp = await this.api.get(`tx/${id}/offset`)
const resp = await this.api.get(`tx/${id}/offset`);
if (resp.status === 200) {
return resp.data
return resp.data;
}
throw new Error(`Unable to get transaction offset: ${getError(resp)}`);
}

async getChunk(offset: string | number | BigInt): Promise<TransactionChunkResponse> {
async getChunk(
offset: string | number | BigInt
): Promise<TransactionChunkResponse> {
const resp = await this.api.get(`chunk/${offset}`);
if (resp.status === 200) {
return resp.data;
Expand All @@ -35,7 +35,7 @@ export default class Chunks {
}

async getChunkData(offset: string | number | BigInt): Promise<Uint8Array> {
const chunk = await this.getChunk(offset)
const chunk = await this.getChunk(offset);
const buf = ArweaveUtils.b64UrlToBuffer(chunk.chunk);
return buf;
}
Expand All @@ -50,10 +50,10 @@ export default class Chunks {
const size = parseInt(offsetResponse.size);
const endOffset = parseInt(offsetResponse.offset);
const startOffset = endOffset - size + 1;

const data = new Uint8Array(size);
let byte = 0;

while (startOffset + byte < endOffset) {
const chunkData = await this.getChunkData(startOffset + byte);
data.set(chunkData, byte);
Expand All @@ -62,4 +62,4 @@ export default class Chunks {

return data;
}
}
}
12 changes: 8 additions & 4 deletions src/common/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export default class Arweave {

public silo: Silo;

public chunks: Chunks
public chunks: Chunks;

public static init: (apiConfig: ApiConfig) => Arweave;

Expand Down Expand Up @@ -109,7 +109,9 @@ export default class Arweave {
}

if (attributes.data && !(attributes.data instanceof Uint8Array)) {
throw new Error("Expected data to be a string, Uint8Array or ArrayBuffer");
throw new Error(
"Expected data to be a string, Uint8Array or ArrayBuffer"
);
}

if (attributes.reward == undefined) {
Expand All @@ -120,8 +122,10 @@ export default class Arweave {
);
}

transaction.data_root = '';
transaction.data_size = attributes.data ? attributes.data.byteLength.toString() : '0'
transaction.data_root = "";
transaction.data_size = attributes.data
? attributes.data.byteLength.toString()
: "0";
transaction.data = attributes.data || new Uint8Array(0);

return new Transaction(transaction as TransactionInterface);
Expand Down
34 changes: 15 additions & 19 deletions src/common/lib/error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,37 +30,33 @@ export default class ArweaveError extends Error {
}
}


type AxiosResponseLite = { status: number, statusText?: string, data: { error: string } | any }

// Safely get error string
// from an axios response, falling back to
type AxiosResponseLite = {
status: number;
statusText?: string;
data: { error: string } | any;
};

// Safely get error string
// from an axios response, falling back to
// resp.data, statusText or 'unknown'.
// Note: a wrongly set content-type can
// cause what is a json response to be interepted
// as a string or Buffer, so we handle that too.

export function getError(resp: AxiosResponseLite) {
let data = resp.data;
let data = resp.data;

if (typeof resp.data === 'string') {
try {
data = JSON.parse(resp.data)
}
catch (e) {
}
if (typeof resp.data === "string") {
try {
data = JSON.parse(resp.data);
} catch (e) {}
}

if (resp.data instanceof ArrayBuffer || resp.data instanceof Uint8Array) {
try {
data = JSON.parse(data.toString());
} catch (e) {

}
} catch (e) {}
}

return data ?
(data.error || data)
:
(resp.statusText || 'unknown' )
return data ? data.error || data : resp.statusText || "unknown";
}
84 changes: 45 additions & 39 deletions src/common/lib/merkle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,14 @@ export async function chunkData(data: Uint8Array): Promise<Chunk[]> {
let cursor = 0;

while (rest.byteLength >= MAX_CHUNK_SIZE) {
let chunkSize = MAX_CHUNK_SIZE;

let chunkSize = MAX_CHUNK_SIZE;

// If the total bytes left will produce a chunk < MIN_CHUNK_SIZE,
// If the total bytes left will produce a chunk < MIN_CHUNK_SIZE,
// then adjust the amount we put in this 2nd last chunk.
let nextChunkSize = rest.byteLength - MAX_CHUNK_SIZE
if (nextChunkSize > 0 && nextChunkSize < MIN_CHUNK_SIZE) {
chunkSize = Math.ceil(rest.byteLength / 2)

let nextChunkSize = rest.byteLength - MAX_CHUNK_SIZE;
if (nextChunkSize > 0 && nextChunkSize < MIN_CHUNK_SIZE) {
chunkSize = Math.ceil(rest.byteLength / 2);
// console.log(`Last chunk will be: ${nextChunkSize} which is below ${MIN_CHUNK_SIZE}, adjusting current to ${chunkSize} with ${rest.byteLength} left.`)
}

Expand All @@ -66,15 +65,15 @@ export async function chunkData(data: Uint8Array): Promise<Chunk[]> {
chunks.push({
dataHash,
minByteRange: cursor - chunk.byteLength,
maxByteRange: cursor,
maxByteRange: cursor
});
rest = rest.slice(chunkSize);
}

chunks.push({
dataHash: await Arweave.crypto.hash(rest),
minByteRange: cursor,
maxByteRange: cursor + rest.byteLength,
maxByteRange: cursor + rest.byteLength
});

return chunks;
Expand All @@ -91,7 +90,7 @@ export async function generateLeaves(chunks: Chunk[]): Promise<LeafNode[]> {
),
dataHash: dataHash,
minByteRange,
maxByteRange,
maxByteRange
};
}
)
Expand All @@ -116,34 +115,33 @@ export async function generateTree(data: Uint8Array): Promise<MerkelNode> {
}

/**
* Generates the data_root, chunks & proofs
* needed for a transaction.
*
* Generates the data_root, chunks & proofs
* needed for a transaction.
*
* This also checks if the last chunk is a zero-length
* chunk and discards that chunk and proof if so.
* (we do not need to upload this zero length chunk)
*
* @param data
*
* @param data
*/
export async function generateTransactionChunks(data: Uint8Array) {

const chunks = await chunkData(data);
const leaves = await generateLeaves(chunks);
const root = await buildLayers(leaves);
const proofs = await generateProofs(root);

// Discard the last chunk & proof if it's zero length.
const lastChunk = chunks.slice(-1)[0];
if (lastChunk.maxByteRange - lastChunk.minByteRange === 0) {
chunks.splice(chunks.length-1, 1);
proofs.splice(proofs.length-1, 1);
chunks.splice(chunks.length - 1, 1);
proofs.splice(proofs.length - 1, 1);
}

return {
data_root: root.id,
chunks,
proofs
}
};
}

/**
Expand Down Expand Up @@ -183,7 +181,7 @@ export async function buildLayers(
export function generateProofs(root: MerkelNode) {
const proofs = resolveBranchProofs(root);
if (!Array.isArray(proofs)) {
return [ proofs ]
return [proofs];
}
return arrayFlatten<Proof>(proofs);
}
Expand All @@ -204,8 +202,8 @@ function resolveBranchProofs(
proof: concatBuffers([
proof,
node.dataHash,
intToBuffer(node.maxByteRange),
]),
intToBuffer(node.maxByteRange)
])
};
}

Expand All @@ -214,11 +212,11 @@ function resolveBranchProofs(
proof,
node.leftChild!.id!,
node.rightChild!.id!,
intToBuffer(node.byteRange),
intToBuffer(node.byteRange)
]);
return [
resolveBranchProofs(node.leftChild!, partialProof, depth + 1),
resolveBranchProofs(node.rightChild!, partialProof, depth + 1),
resolveBranchProofs(node.rightChild!, partialProof, depth + 1)
] as [Proof, Proof];
}

Expand All @@ -228,7 +226,7 @@ function resolveBranchProofs(
export function arrayFlatten<T = any>(input: T[]): T[] {
const flat: any[] = [];

input.forEach((item) => {
input.forEach(item => {
if (Array.isArray(item)) {
flat.push(...arrayFlatten(item));
} else {
Expand All @@ -251,12 +249,12 @@ async function hashBranch(
id: await hash([
await hash(left.id),
await hash(right.id),
await hash(intToBuffer(left.maxByteRange)),
await hash(intToBuffer(left.maxByteRange))
]),
byteRange: left.maxByteRange,
maxByteRange: right.maxByteRange,
leftChild: left,
rightChild: right,
rightChild: right
} as BranchNode;

return branch;
Expand All @@ -273,12 +271,12 @@ async function hash(data: Uint8Array | Uint8Array[]) {
export function intToBuffer(note: number): Uint8Array {
const buffer = new Uint8Array(NOTE_SIZE);

for (var i = buffer.length-1; i >= 0; i--) {
for (var i = buffer.length - 1; i >= 0; i--) {
var byte = note % 256;
buffer[i] = byte;
note = (note - byte) / 256 ;
note = (note - byte) / 256;
}

return buffer;
}

Expand All @@ -300,7 +298,10 @@ export async function validatePath(
leftBound: number,
rightBound: number,
path: Uint8Array
): Promise<false | { offset: number, leftBound: number, rightBound: number, chunkSize: number }> {
): Promise<
| false
| { offset: number; leftBound: number; rightBound: number; chunkSize: number }
> {
if (rightBound <= 0) {
return false;
}
Expand All @@ -322,13 +323,18 @@ export async function validatePath(

const pathDataHash = await hash([
await hash(pathData),
await hash(endOffsetBuffer),
await hash(endOffsetBuffer)
]);
let result = arrayCompare(id, pathDataHash);
let result = arrayCompare(id, pathDataHash);
if (result) {
return { offset: rightBound - 1, leftBound: leftBound, rightBound: rightBound, chunkSize: rightBound - leftBound }
return {
offset: rightBound - 1,
leftBound: leftBound,
rightBound: rightBound,
chunkSize: rightBound - leftBound
};
}
return false
return false;
}

const left = path.slice(0, HASH_SIZE);
Expand All @@ -346,7 +352,7 @@ export async function validatePath(
const pathHash = await hash([
await hash(left),
await hash(right),
await hash(offsetBuffer),
await hash(offsetBuffer)
]);

if (arrayCompare(id, pathHash)) {
Expand Down Expand Up @@ -397,7 +403,7 @@ export async function debug(proof: Uint8Array, output = ""): Promise<string> {
const pathHash = await hash([
await hash(left),
await hash(right),
await hash(offsetBuffer),
await hash(offsetBuffer)
]);

const updatedOutput = `${output}\n${inspect(Buffer.from(left))},${inspect(
Expand Down
Loading

0 comments on commit 950e801

Please sign in to comment.