mirror of
				https://github.com/hackku21/loc-chain-backend.git
				synced 2025-06-13 12:53:59 +00:00 
			
		
		
		
	Merge branch 'main' of github.com:hackku21/loc-chain-backend into main
This commit is contained in:
		
						commit
						e569841356
					
				| @ -17,6 +17,7 @@ export default { | ||||
|             refs: { | ||||
|                 peers: 'chain/server/peers', | ||||
|                 transaction: 'chain/pending/transactions', | ||||
|                 block: 'chain/local/block', | ||||
|             }, | ||||
|         }, | ||||
|     } | ||||
|  | ||||
							
								
								
									
										57
									
								
								src/app/rtdb/BlockResource.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								src/app/rtdb/BlockResource.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,57 @@ | ||||
| import {FirebaseResource, FirebaseResourceItem} from "../FirebaseResource" | ||||
| import {Injectable} from "@extollo/di" | ||||
| import {RTDBRef} from "../units/FirebaseUnit" | ||||
| import {AsyncCollection} from "@extollo/util" | ||||
| 
 | ||||
| export interface BlockEncounterTransaction { | ||||
|     combinedHash: string; | ||||
|     timestamp: number; | ||||
|     encodedGPSLocation: string; | ||||
| } | ||||
| 
 | ||||
| export interface BlockInfectionTransaction { | ||||
|     clientID: string; | ||||
|     timestamp: number; | ||||
| } | ||||
| 
 | ||||
| export type BlockTransaction = BlockInfectionTransaction | BlockEncounterTransaction | ||||
| 
 | ||||
| export function isBlockEncounterTransaction(what: any): what is BlockEncounterTransaction { | ||||
|     return ( | ||||
|         what | ||||
|         && typeof what.combinedHash === 'string' | ||||
|         && typeof what.timestamp === 'number' | ||||
|         && typeof what.encodedGPSLocation === 'string' | ||||
|     ) | ||||
| } | ||||
| 
 | ||||
| export function isBlockInfectionTransaction(what: any): what is BlockInfectionTransaction { | ||||
|     return ( | ||||
|         what | ||||
|         && typeof what.clientID === 'string' | ||||
|         && typeof what.timestamp === 'number' | ||||
|     ) | ||||
| } | ||||
| 
 | ||||
| export function isBlockTransaction(what: any): what is BlockTransaction { | ||||
|     return isBlockEncounterTransaction(what) || isBlockInfectionTransaction(what) | ||||
| } | ||||
| 
 | ||||
| export interface BlockResourceItem extends FirebaseResourceItem { | ||||
|     uuid: string; | ||||
|     combinedHash: string; | ||||
|     timestamp: number; | ||||
|     encodedGPSLocation: string; | ||||
|     transactions: BlockTransaction[]; | ||||
|     lastBlockHash: string; | ||||
|     lastBlockUUID: string; | ||||
| } | ||||
| 
 | ||||
| @Injectable() | ||||
| export class BlockResource extends FirebaseResource<BlockResourceItem> { | ||||
|     public static collect(): AsyncCollection<BlockResourceItem> { | ||||
|         return new AsyncCollection<BlockResourceItem>(new BlockResource()) | ||||
|     } | ||||
| 
 | ||||
|     protected refName: RTDBRef = 'block' | ||||
| } | ||||
							
								
								
									
										110
									
								
								src/app/units/Blockchain.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								src/app/units/Blockchain.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,110 @@ | ||||
| import {Singleton, Inject} from "@extollo/di" | ||||
| import {Unit, Logging} from "@extollo/lib" | ||||
| import {FirebaseUnit} from "./FirebaseUnit" | ||||
| import {BlockResource, BlockResourceItem, BlockTransaction} from "../rtdb/BlockResource" | ||||
| import {TransactionResourceItem} from "../rtdb/TransactionResource" | ||||
| import * as crypto from "crypto" | ||||
| 
 | ||||
| export class Block implements BlockResourceItem { | ||||
|     seqID: number; | ||||
|     uuid: string; | ||||
|     combinedHash: string; | ||||
|     timestamp: number; | ||||
|     encodedGPSLocation: string; | ||||
|     transactions: BlockTransaction[]; | ||||
|     lastBlockHash: string; | ||||
|     lastBlockUUID: string; | ||||
| 
 | ||||
|     constructor(rec: BlockResourceItem) { | ||||
|         this.seqID = rec.seqID | ||||
|         this.uuid = rec.uuid | ||||
|         this.combinedHash = rec.combinedHash | ||||
|         this.timestamp = rec.timestamp | ||||
|         this.encodedGPSLocation = rec.encodedGPSLocation | ||||
|         this.transactions = rec.transactions | ||||
|         this.lastBlockHash = rec.lastBlockHash | ||||
|         this.lastBlockUUID = rec.lastBlockUUID | ||||
|     } | ||||
| 
 | ||||
|     hash() { | ||||
|         return crypto.createHash('sha256') | ||||
|             .update(this.toString(), 'utf-8') | ||||
|             .digest('hex') | ||||
|     } | ||||
| 
 | ||||
|     toString() { | ||||
|         return [ | ||||
|             this.uuid, | ||||
|             this.combinedHash, | ||||
|             this.timestamp.toString(), | ||||
|             this.encodedGPSLocation, | ||||
|             JSON.stringify(this.transactions), | ||||
|             this.lastBlockHash, | ||||
|             this.lastBlockUUID, | ||||
|         ].join('%') | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| export interface Peer { | ||||
|     host: string, | ||||
|     name?: string, | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Blockchain Unit | ||||
|  * --------------------------------------- | ||||
|  * Main service for interacting with the contact blockchain. | ||||
|  */ | ||||
| @Singleton() | ||||
| export class Blockchain extends Unit { | ||||
|     @Inject() | ||||
|     protected readonly logging!: Logging | ||||
| 
 | ||||
|     @Inject() | ||||
|     protected readonly firebase!: FirebaseUnit | ||||
| 
 | ||||
|     public async hasPeer(host: string): Promise<boolean> { | ||||
|         const peers = await this.getPeers() | ||||
|         return peers.some(peer => peer.host.toLowerCase() === host.toLowerCase()) | ||||
|     } | ||||
| 
 | ||||
|     public async getPeers(): Promise<Peer[]> { | ||||
|         const data = await this.firebase.ref('peers').once('value') | ||||
|         return (data.val() as Peer[]) || [] | ||||
|     } | ||||
| 
 | ||||
|     public async registerPeer(peer: Peer) { | ||||
|         if ( !(await this.hasPeer(peer.host)) ) { | ||||
|             await this.firebase.ref('peers').push().set(peer) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public async validate(chain: Block[]) { | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     public async refresh() { | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     public async submitBlock(afterBlock: Block, proofToken: string) { | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     public async submitTransactions(group: [TransactionResourceItem, TransactionResourceItem]) { | ||||
|         // Not sure yet
 | ||||
|     } | ||||
| 
 | ||||
|     public async getLastBlock(): Promise<Block | undefined> { | ||||
|         const rec: BlockResourceItem | undefined = await BlockResource.collect().last() | ||||
|         return rec ? new Block(rec) : undefined | ||||
|     } | ||||
| 
 | ||||
|     public async up() { | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     public async down() { | ||||
| 
 | ||||
|     } | ||||
| } | ||||
| @ -2,7 +2,7 @@ import {Singleton, Inject} from "@extollo/di" | ||||
| import {Unit, Logging, Config} from "@extollo/lib" | ||||
| import * as firebase from "firebase-admin" | ||||
| 
 | ||||
| export type RTDBRef = 'peers' | 'transaction' | ||||
| export type RTDBRef = 'peers' | 'transaction' | 'block' | ||||
| 
 | ||||
| /** | ||||
|  * FirebaseUnit Unit | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user