Skip to content

Commit

Permalink
add new methods to generate an AddBlockRequest and send an AddBlockRe…
Browse files Browse the repository at this point in the history
…quest
  • Loading branch information
tobowers committed Apr 16, 2020
1 parent e1cbcf9 commit a04e27c
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 7 deletions.
4 changes: 4 additions & 0 deletions etc/tupelo-wasm-sdk.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
```ts

import { AddBlockRequest } from 'tupelo-messages/services/services_pb';
import CID from 'cids';
import EventEmitter from 'events';
import { NotaryGroup } from 'tupelo-messages/config/config_pb';
Expand Down Expand Up @@ -322,13 +323,16 @@ export namespace Tupelo {
export function getTip(did: string): Promise<Proof>;
// (undocumented)
export function keyFromPrivateBytes(bytes: Uint8Array): Promise<Uint8Array[]>;
export function newAddBlockRequest(tree: ChainTree, transactions: Transaction[]): Promise<AddBlockRequest>;
// (undocumented)
export function newEmptyTree(store: IBlockService, publicKey: Uint8Array): Promise<CID_2>;
// (undocumented)
export function passPhraseKey(phrase: Uint8Array, salt: Uint8Array): Promise<Uint8Array[]>;
// (undocumented)
export function playTransactions(tree: ChainTree, transactions: Transaction[]): Promise<Proof>;
// (undocumented)
export function sendAddBlockRequest(addBlockRequest: AddBlockRequest, timeout?: number): Promise<Proof>;
// (undocumented)
export function setLogLevel(name: string, level: string): Promise<void>;
// (undocumented)
export function startClient(pubsub: IPubSub, group: NotaryGroup, store: IBlockService): Promise<void>;
Expand Down
44 changes: 38 additions & 6 deletions src/tupelo.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { Community } from './community/community';
import Repo from './repo';
import debug from 'debug';
import CID from 'cids';
import { AddBlockRequest } from 'tupelo-messages/services/services_pb';

// import {LocalCommunity} from 'local-tupelo';

Expand Down Expand Up @@ -46,6 +47,37 @@ describe('Tupelo', () => {
expect(addr).to.have.lengthOf(42)
})

it('creates a new AddBlockRequest', async () => {
const c = await Community.getDefault()
const key = await EcdsaKey.generate()

let tree = await ChainTree.newEmptyTree(c.blockservice, key)
debugLog("created empty tree")
const trans = setDataTransaction("/hi", "hihi")

const abr = await Tupelo.newAddBlockRequest(tree, [trans])
expect(abr).instanceOf(AddBlockRequest)
return true
})

it('sends an ABR', async ()=> {
const c = await Community.getDefault()
const key = await EcdsaKey.generate()

let tree = await ChainTree.newEmptyTree(c.blockservice, key)
debugLog("created empty tree")
const trans = setDataTransaction("/hi", "hihi")

const abr = await Tupelo.newAddBlockRequest(tree, [trans])
expect(abr).instanceOf(AddBlockRequest)

const proof = await Tupelo.sendAddBlockRequest(abr)
tree.tip = new CID(Buffer.from(proof.getTip_asU8()))
const resolved = await tree.resolve("tree/data/hi")
expect(resolved.value).to.equal("hihi")
return true
})

// requires a running tupelo
it('plays transactions on a new tree', async () => {
const c = await Community.getDefault()
Expand Down Expand Up @@ -81,7 +113,7 @@ describe('Tupelo', () => {
return p
})

it('gets tip', async ()=> {
it('gets tip', async () => {
const c = await Community.getDefault()
const key = await EcdsaKey.generate()

Expand All @@ -98,7 +130,7 @@ describe('Tupelo', () => {
expect(playProof.getTip_asB64()).to.equal(tipProof.getTip_asB64())
})

it('gets latest', async ()=> {
it('gets latest', async () => {
const c = await Community.getDefault()
const key = await EcdsaKey.generate()

Expand Down Expand Up @@ -133,7 +165,7 @@ describe('Tupelo', () => {
throw new Error("unknown sender id")
}
const tokenName = "testtoken"
await c.playTransactions(senderTree, [establishTokenTransaction(tokenName, 10),mintTokenTransaction(tokenName, 5)])
await c.playTransactions(senderTree, [establishTokenTransaction(tokenName, 10), mintTokenTransaction(tokenName, 5)])

const sendId = "anewsendid"
let resp = await c.playTransactions(senderTree, [sendTokenTransaction(sendId, tokenName, 5, receiverId)])
Expand All @@ -151,17 +183,17 @@ describe('Tupelo', () => {
return p
})

it('verifies a returned proof', async ()=> {
it('verifies a returned proof', async () => {
const c = await Community.getDefault()

const p = new Promise(async (resolve, reject)=> {
const p = new Promise(async (resolve, reject) => {
const k = await EcdsaKey.generate()
const tree = await ChainTree.newEmptyTree(c.blockservice, k)
const resp = await c.playTransactions(tree, [setDataTransaction("hi", "hi")])
try {
let verified = await Tupelo.verifyProof(resp)
expect(verified).to.be.true
} catch(e) {
} catch (e) {
reject(e)
}
resolve()
Expand Down
63 changes: 62 additions & 1 deletion src/tupelo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import CID from 'cids';

const go = require('./js/go')
import { Transaction } from 'tupelo-messages'
import {AddBlockRequest} from 'tupelo-messages/services/services_pb'
import { TokenPayload } from 'tupelo-messages/transactions/transactions_pb'
import { IBlockService, IBlock } from './chaintree/dag/dag'
import { IBlockService } from './chaintree/dag/dag'
import ChainTree from './chaintree/chaintree';
import { Proof } from 'tupelo-messages/gossip/gossip_pb';
import { NotaryGroup } from 'tupelo-messages/config/config_pb';
Expand All @@ -27,6 +28,11 @@ interface IPlayTransactionOptions {
transactions: Uint8Array[],
}

interface ISendAddBlockRequestOptions {
addBlockRequest: Uint8Array,
timeout?: number,
}

interface IClientOptions {
pubsub: IPubSub,
notaryGroup: Uint8Array // protobuf encoded config.NotaryGroup
Expand Down Expand Up @@ -77,6 +83,12 @@ class UnderlyingWasm {
playTransactions(opts: IPlayTransactionOptions): Promise<Uint8Array> {
return new Promise<Uint8Array>((res, rej) => { }) // replaced by wasm
}
newAddBlockRequest(opts: IPlayTransactionOptions): Promise<Uint8Array> {
return new Promise<Uint8Array>((res, rej) => { }) // replaced by wasm
}
sendAddBlockRequest(opts: ISendAddBlockRequestOptions): Promise<Uint8Array> {
return new Promise<Uint8Array>((res, rej) => { }) // replaced by wasm
}
startClient(opts: IClientOptions): void {
// replaced by wasm
}
Expand Down Expand Up @@ -236,6 +248,55 @@ export namespace Tupelo {
})
}

/**
*
* @param addBlockRequest - the AddBlockRequest to send to the network
* @param timeout - the timeout to wait for the transaction to complete
*/
export async function sendAddBlockRequest(addBlockRequest:AddBlockRequest, timeout?:number):Promise<Proof> {
const tw = await TupeloWasm.get()
const abrBits = addBlockRequest.serializeBinary()
const resp = await tw.sendAddBlockRequest({
addBlockRequest: abrBits,
timeout: timeout,
})

const proof = Proof.deserializeBinary(resp)
return proof
}

/**
* newAddBlockRequest is mostly desigend in order to play transactions *locally* before sending these off to the network
* useful when you want your UI to update immediately
* @param tree - the tree to create the AddBlockRequest
* @param transactions - the list of transactions
*/
export async function newAddBlockRequest(tree:ChainTree, transactions: Transaction[]): Promise<AddBlockRequest> {
logger("newAddBlockRequest")
if (tree.key == undefined) {
throw new Error("playing transactions on a tree requires the tree to have a private key, use tree.key = <ecdsaKey>")
}
const tw = await TupeloWasm.get()
let transBits: Uint8Array[] = new Array<Uint8Array>()
for (var t of transactions) {
const serialized = t.serializeBinary()
transBits = transBits.concat(serialized)
}

const privateKey: Uint8Array = tree.key.privateKey ? tree.key.privateKey : new Uint8Array()
if (privateKey.length == 0) {
throw new Error("can only play transactions on a tree with a private key attached")
}

const resp = await tw.newAddBlockRequest({
privateKey: privateKey,
tip: tree.tip,
transactions: transBits,
})
const abr = AddBlockRequest.deserializeBinary(resp)
return abr
}

export async function playTransactions(tree: ChainTree, transactions: Transaction[]): Promise<Proof> {
logger("playTransactions")
if (tree.key == undefined) {
Expand Down

0 comments on commit a04e27c

Please sign in to comment.