|
|
@ -318,60 +318,49 @@ export class Blockchain extends Unit {
|
|
|
|
this.logging.debug('Called refresh().')
|
|
|
|
this.logging.debug('Called refresh().')
|
|
|
|
|
|
|
|
|
|
|
|
const peers = this.getPeers()
|
|
|
|
const peers = this.getPeers()
|
|
|
|
const time_x_block: {[key: string]: Block} = {}
|
|
|
|
let longestChain: Block[] = []
|
|
|
|
const time_x_blocks: {[key: string]: Block[]} = {}
|
|
|
|
const chains = await Promise.all(
|
|
|
|
const time_x_peer: {[key: string]: Peer | true} = {}
|
|
|
|
peers.map(peer => this.getPeerSubmit(peer))
|
|
|
|
|
|
|
|
)
|
|
|
|
await Promise.all(peers.map(async peer => {
|
|
|
|
|
|
|
|
const blocks: Block[] | undefined = await this.getPeerSubmit(peer)
|
|
|
|
for ( const chain of chains ) {
|
|
|
|
|
|
|
|
if (
|
|
|
|
if ( blocks && await this.validate(blocks) ) {
|
|
|
|
chain
|
|
|
|
const block = blocks.slice(-1)[0]
|
|
|
|
&& chain.length > longestChain.length
|
|
|
|
if ( !block ) return // TODO fixme
|
|
|
|
&& await this.validate(chain)
|
|
|
|
|
|
|
|
) {
|
|
|
|
const penalty = blocks.slice(0, 10)
|
|
|
|
longestChain = chain
|
|
|
|
.map(block => block.peer === peer.host)
|
|
|
|
|
|
|
|
.filter(Boolean).length * this.PENALTY_INTERVAL
|
|
|
|
|
|
|
|
* (Math.min(peers.length, this.MAX_PEERS_PENALTY))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
block.waitTime += penalty
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
time_x_block[block.waitTime] = block
|
|
|
|
|
|
|
|
time_x_blocks[block.waitTime] = blocks.reverse()
|
|
|
|
|
|
|
|
time_x_peer[block.waitTime] = peer
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
console.log('validation fail!')
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
console.log(time_x_blocks, time_x_peer, time_x_block)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const submitBlock = this.getSubmitBlock()
|
|
|
|
|
|
|
|
if ( submitBlock ) {
|
|
|
|
|
|
|
|
time_x_block[submitBlock.waitTime] = submitBlock
|
|
|
|
|
|
|
|
time_x_peer[submitBlock.waitTime] = true
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
console.log('submit block', submitBlock)
|
|
|
|
const submitted = this.getSubmitBlock()
|
|
|
|
|
|
|
|
if ( (this.approvedChain.length + (submitted ? 1 : 0)) > longestChain.length ) {
|
|
|
|
|
|
|
|
// Our chain is longer, so push the submit block onto it
|
|
|
|
|
|
|
|
if ( submitted ) {
|
|
|
|
|
|
|
|
this.approvedChain.push(submitted)
|
|
|
|
|
|
|
|
this.pendingTransactions = []
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
const temp: Block[] = this.approvedChain.reverse()
|
|
|
|
|
|
|
|
this.approvedChain = longestChain.map(x => {
|
|
|
|
|
|
|
|
if ( !x.transactions ) {
|
|
|
|
|
|
|
|
x.transactions = []
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const min = Math.min(...Object.keys(time_x_block).map(parseFloat))
|
|
|
|
return x
|
|
|
|
const peer = time_x_peer[min]
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
console.log('peer?', peer)
|
|
|
|
for ( const block of temp ) {
|
|
|
|
|
|
|
|
const found = this.approvedChain.some(otherBlock => {
|
|
|
|
|
|
|
|
return otherBlock.uuid === block.uuid
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
if ( peer === true ) {
|
|
|
|
if ( !found ) {
|
|
|
|
// Our version of the chain was accepted
|
|
|
|
this.pendingTransactions.concat(...(block.transactions || []))
|
|
|
|
this.approvedChain.push(submitBlock!)
|
|
|
|
} else {
|
|
|
|
this.pendingTransactions = []
|
|
|
|
break
|
|
|
|
} else if ( peer ) {
|
|
|
|
|
|
|
|
// A different server's chain was accepted
|
|
|
|
|
|
|
|
this.approvedChain = (time_x_blocks[min] || []).map(block => {
|
|
|
|
|
|
|
|
if (!block.transactions) {
|
|
|
|
|
|
|
|
block.transactions = []
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
return block
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
console.log('approved chain', this.approvedChain)
|
|
|
|
console.log('approved chain', this.approvedChain)
|
|
|
@ -443,7 +432,14 @@ export class Blockchain extends Unit {
|
|
|
|
* @param exposures
|
|
|
|
* @param exposures
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public submitExposures(...exposures: ExposureResourceItem[]) {
|
|
|
|
public submitExposures(...exposures: ExposureResourceItem[]) {
|
|
|
|
this.pendingTransactions.push(...exposures)
|
|
|
|
// @ts-ignore
|
|
|
|
|
|
|
|
this.pendingTransactions.push(...exposures.map(exposure => {
|
|
|
|
|
|
|
|
if ( !exposure.uuid ) {
|
|
|
|
|
|
|
|
exposure.uuid = uuid_v4()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return exposure
|
|
|
|
|
|
|
|
}))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -503,6 +499,7 @@ export class Blockchain extends Unit {
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
protected getEncounterTransaction(item: TransactionResourceItem): BlockEncounterTransaction {
|
|
|
|
protected getEncounterTransaction(item: TransactionResourceItem): BlockEncounterTransaction {
|
|
|
|
return {
|
|
|
|
return {
|
|
|
|
|
|
|
|
uuid: uuid_v4(),
|
|
|
|
combinedHash: item.combinedHash,
|
|
|
|
combinedHash: item.combinedHash,
|
|
|
|
timestamp: item.timestamp,
|
|
|
|
timestamp: item.timestamp,
|
|
|
|
encodedGPSLocation: item.encodedGPSLocation,
|
|
|
|
encodedGPSLocation: item.encodedGPSLocation,
|
|
|
|