mirror of
https://github.com/hackku21/loc-chain-backend.git
synced 2024-10-27 20:34:03 +00:00
Basic infrastructure for remote peering
This commit is contained in:
parent
46131e2219
commit
313fdb65e9
@ -81,7 +81,7 @@ export class FirebaseResource<T extends FirebaseResourceItem> extends Iterable<T
|
|||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
delete item.firebaseID
|
delete item.firebaseID
|
||||||
collection.push(item)
|
collection.push(this.filter(item))
|
||||||
|
|
||||||
return collection
|
return collection
|
||||||
})
|
})
|
||||||
@ -123,4 +123,22 @@ export class FirebaseResource<T extends FirebaseResourceItem> extends Iterable<T
|
|||||||
inst.refName = this.refName
|
inst.refName = this.refName
|
||||||
return inst
|
return inst
|
||||||
}
|
}
|
||||||
|
|
||||||
|
filter(obj: {[key: string]: any}) {
|
||||||
|
for (let key in obj) {
|
||||||
|
if (obj[key] === undefined) {
|
||||||
|
delete obj[key]
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj[key] && typeof obj[key] === "object") {
|
||||||
|
this.filter(obj[key])
|
||||||
|
if (!Object.keys(obj[key]).length) {
|
||||||
|
delete obj[key]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return obj
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,10 @@ export default {
|
|||||||
|
|
||||||
base_url: env('BASE_URL', 'http://localhost:8000/'),
|
base_url: env('BASE_URL', 'http://localhost:8000/'),
|
||||||
|
|
||||||
|
peers: [
|
||||||
|
// 'http://127.0.0.1:8100/',
|
||||||
|
],
|
||||||
|
|
||||||
session: {
|
session: {
|
||||||
/* The implementation of @extollo/lib.Session that serves as the session backend. */
|
/* The implementation of @extollo/lib.Session that serves as the session backend. */
|
||||||
driver: MemorySession,
|
driver: MemorySession,
|
||||||
|
@ -22,11 +22,11 @@ export class ServerGPGTokenVerify extends Middleware {
|
|||||||
}
|
}
|
||||||
// if single string
|
// if single string
|
||||||
if (typeof(value) === 'string') {
|
if (typeof(value) === 'string') {
|
||||||
this.verifyToken(value)
|
this.verifyToken(Buffer.from(value, 'base64').toString('utf-8'))
|
||||||
return
|
return
|
||||||
} else { // else an array of strings
|
} else { // else an array of strings
|
||||||
for (const item of value) {
|
for (const item of value) {
|
||||||
if (await this.verifyToken(item)) {
|
if (await this.verifyToken(Buffer.from(item, 'base64').toString('utf-8'))) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -144,6 +144,15 @@ export class Blockchain extends Unit {
|
|||||||
|
|
||||||
protected isSubmitting: boolean = false
|
protected isSubmitting: boolean = false
|
||||||
|
|
||||||
|
async up() {
|
||||||
|
const peers = this.config.get('server.peers')
|
||||||
|
for ( const peer of peers ) {
|
||||||
|
await this.registerPeer({
|
||||||
|
host: peer,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the given host is registered as a peer.
|
* Returns true if the given host is registered as a peer.
|
||||||
* @param host
|
* @param host
|
||||||
@ -166,7 +175,7 @@ export class Blockchain extends Unit {
|
|||||||
*/
|
*/
|
||||||
public async getPeerSubmit(peer: Peer): Promise<Block[] | undefined> {
|
public async getPeerSubmit(peer: Peer): Promise<Block[] | undefined> {
|
||||||
try {
|
try {
|
||||||
const result = await axios.get(peer.host)
|
const result = await axios.get(`${peer.host}api/v1/chain/submit`)
|
||||||
const blocks: unknown = result.data?.data?.records
|
const blocks: unknown = result.data?.data?.records
|
||||||
if ( Array.isArray(blocks) && blocks.every(isBlockResourceItem) ) {
|
if ( Array.isArray(blocks) && blocks.every(isBlockResourceItem) ) {
|
||||||
return blocks.map(x => new Block(x))
|
return blocks.map(x => new Block(x))
|
||||||
@ -182,6 +191,7 @@ export class Blockchain extends Unit {
|
|||||||
*/
|
*/
|
||||||
public async registerPeer(peer: Peer) {
|
public async registerPeer(peer: Peer) {
|
||||||
if (!(await this.hasPeer(peer.host))) {
|
if (!(await this.hasPeer(peer.host))) {
|
||||||
|
this.logging.info(`Registering peer: ${peer.host}`)
|
||||||
await (<PeerResource> this.make(PeerResource)).push({
|
await (<PeerResource> this.make(PeerResource)).push({
|
||||||
firebaseID: '',
|
firebaseID: '',
|
||||||
seqID: -1,
|
seqID: -1,
|
||||||
@ -189,7 +199,28 @@ export class Blockchain extends Unit {
|
|||||||
host: peer.host,
|
host: peer.host,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const header = this.config.get('app.api_server_header')
|
||||||
|
|
||||||
|
try {
|
||||||
|
console.log('return peering', [`${peer.host}api/v1/peer`, {
|
||||||
|
host: this.getBaseURL(),
|
||||||
|
}, {
|
||||||
|
headers: {
|
||||||
|
[header]: await this.getPeerToken(),
|
||||||
|
}
|
||||||
|
}])
|
||||||
|
await axios.post(`${peer.host}api/v1/peer`, {
|
||||||
|
host: this.getBaseURL(),
|
||||||
|
}, {
|
||||||
|
headers: {
|
||||||
|
[header]: await this.getPeerToken(),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
this.refresh()
|
this.refresh()
|
||||||
|
} catch (e) {
|
||||||
|
this.logging.error(e)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -289,7 +320,7 @@ export class Blockchain extends Unit {
|
|||||||
await (<BlockResource>this.app().make(BlockResource)).push(block)
|
await (<BlockResource>this.app().make(BlockResource)).push(block)
|
||||||
} else {
|
} else {
|
||||||
await this.firebase.ref('block').transaction((_) => {
|
await this.firebase.ref('block').transaction((_) => {
|
||||||
return time_x_blocks[min].map(x => x.toItem())
|
return (time_x_blocks[min] || []).map(x => x.toItem())
|
||||||
})
|
})
|
||||||
|
|
||||||
this.pendingSubmit = undefined
|
this.pendingSubmit = undefined
|
||||||
@ -307,6 +338,7 @@ export class Blockchain extends Unit {
|
|||||||
blocks.push(submit.toItem())
|
blocks.push(submit.toItem())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.refresh()
|
||||||
return blocks
|
return blocks
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -404,6 +436,18 @@ export class Blockchain extends Unit {
|
|||||||
return new Block(block)*/
|
return new Block(block)*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async getPeerToken() {
|
||||||
|
const message = openpgp.Message.fromText("0000")
|
||||||
|
const privateKey = this.config.get("app.gpg.key.private")
|
||||||
|
|
||||||
|
return Buffer.from((await openpgp.sign({
|
||||||
|
message,
|
||||||
|
privateKeys: await openpgp.readKey({
|
||||||
|
armoredKey: privateKey
|
||||||
|
}),
|
||||||
|
})), 'utf-8').toString('base64')
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiate the genesis block of the entire chain.
|
* Instantiate the genesis block of the entire chain.
|
||||||
*/
|
*/
|
||||||
@ -513,7 +557,7 @@ export class Blockchain extends Unit {
|
|||||||
*/
|
*/
|
||||||
protected getBaseURL(): string {
|
protected getBaseURL(): string {
|
||||||
const base = this.config.get('server.base_url')
|
const base = this.config.get('server.base_url')
|
||||||
return `${base}${base.endsWith('/') ? '' : '/'}api/v1/chain/submit`
|
return `${base}${base.endsWith('/') ? '' : '/'}`
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sleep for (roughly) the given number of milliseconds. */
|
/** Sleep for (roughly) the given number of milliseconds. */
|
||||||
|
Loading…
Reference in New Issue
Block a user