2017-10-31 18:05:15 +01:00
const logger = require ( 'winston' ) ;
2017-11-01 00:23:11 +01:00
const NO _CHANNEL = 'NO_CHANNEL' ;
2017-10-31 18:05:15 +01:00
function sortResult ( result , longId ) {
let claimIndex ;
let shortId = longId . substring ( 0 , 1 ) ; // default sort id is the first letter
let shortIdLength = 0 ;
// find the index of this certificate
claimIndex = result . findIndex ( element => {
return element . claimId === longId ;
} ) ;
if ( claimIndex < 0 ) { throw new Error ( 'channelId not found in possible sorted list' ) }
// get an array of all certificates with lower height
let possibleMatches = result . slice ( 0 , claimIndex ) ;
// remove certificates with the same prefixes until none are left.
while ( possibleMatches . length > 0 ) {
shortIdLength += 1 ;
shortId = longId . substring ( 0 , shortIdLength ) ;
possibleMatches = possibleMatches . filter ( element => {
return ( element . claimId . substring ( 0 , shortIdLength ) === shortId ) ;
} ) ;
}
// return the short Id
logger . debug ( 'short channel id ===' , shortId ) ;
return shortId ;
}
2017-11-01 00:23:11 +01:00
module . exports = ( sequelize , { STRING , BOOLEAN , INTEGER , TEXT , ARRAY , DECIMAL , DOUBLE , Op } ) => {
2017-08-21 22:27:13 +02:00
const Certificate = sequelize . define (
'Certificate' ,
{
address : {
type : STRING ,
default : null ,
} ,
amount : {
type : STRING ,
default : null ,
} ,
claimId : {
type : STRING ,
default : null ,
} ,
claimSequence : {
type : INTEGER ,
default : null ,
} ,
decodedClaim : {
type : BOOLEAN ,
default : null ,
} ,
depth : {
type : INTEGER ,
default : null ,
} ,
effectiveAmount : {
type : STRING ,
default : null ,
} ,
hasSignature : {
type : BOOLEAN ,
default : null ,
} ,
height : {
type : STRING ,
default : null ,
} ,
hex : {
type : TEXT ( 'long' ) ,
default : null ,
} ,
name : {
type : STRING ,
default : null ,
} ,
nout : {
type : INTEGER ,
default : null ,
} ,
txid : {
type : STRING ,
default : null ,
} ,
validAtHeight : {
type : STRING ,
default : null ,
} ,
outpoint : {
type : STRING ,
default : null ,
} ,
valueVersion : {
type : STRING ,
default : null ,
} ,
claimType : {
type : STRING ,
default : null ,
} ,
certificateVersion : {
type : STRING ,
default : null ,
} ,
keyType : {
type : STRING ,
default : null ,
} ,
publicKey : {
type : TEXT ( 'long' ) ,
default : null ,
} ,
} ,
{
freezeTableName : true ,
}
) ;
2017-09-15 23:41:47 +02:00
Certificate . associate = db => {
2017-09-26 06:03:43 +02:00
Certificate . belongsTo ( db . Channel , {
2017-09-15 23:41:47 +02:00
onDelete : 'cascade' ,
foreignKey : {
allowNull : true ,
} ,
} ) ;
} ;
2017-10-31 18:05:15 +01:00
Certificate . getShortChannelIdFromLongChannelId = function ( longChannelId , channelName ) {
logger . debug ( ` finding short channel id for ${ channelName } : ${ longChannelId } ` ) ;
return new Promise ( ( resolve , reject ) => {
this
. findAll ( {
where : { name : channelName } ,
order : [ [ 'height' , 'ASC' ] ] ,
} )
. then ( result => {
switch ( result . length ) {
case 0 :
throw new Error ( 'That is an invalid channel name' ) ;
default :
return resolve ( sortResult ( result , longChannelId ) ) ;
}
} )
. catch ( error => {
reject ( error ) ;
} ) ;
} ) ;
} ;
2017-11-01 00:23:11 +01:00
// sequelize.query(`SELECT claimId, height FROM Certificate WHERE name = '${channelName}' AND claimId LIKE '${channelId}%' ORDER BY height ASC LIMIT 1;`, { type: db.sequelize.QueryTypes.SELECT })
Certificate . getLongChannelIdFromShortChannelId = function ( channelName , channelId ) {
return new Promise ( ( resolve , reject ) => {
this
. findAll ( {
where : {
name : channelName ,
claimId : {
[ Op . like ] : ` ${ channelId } % ` ,
} ,
order : [ [ 'height' , 'ASC' ] ] ,
} ,
} )
. then ( result => {
switch ( result . length ) {
case 0 :
return resolve ( NO _CHANNEL ) ;
default : // note results must be sorted
return resolve ( result [ 0 ] . claimId ) ;
}
} )
. catch ( error => {
reject ( error ) ;
} ) ;
} ) ;
} ;
// sequelize.query(`SELECT claimId, amount, height FROM Certificate WHERE name = '${channelName}' ORDER BY effectiveAmount DESC, height ASC LIMIT 1;`, { type: db.sequelize.QueryTypes.SELECT })
Certificate . getLongChannelIdFromChannelName = function ( channelName ) {
logger . debug ( ` getLongChannelIdFromChannelName( ${ channelName } ) ` ) ;
return new Promise ( ( resolve , reject ) => {
this
. findAll ( {
where : { name : channelName } ,
order : [ [ 'effectiveAmount' , 'DESC' ] , [ 'height' , 'ASC' ] ] ,
} )
. then ( result => {
switch ( result . length ) {
case 0 :
return resolve ( NO _CHANNEL ) ;
default :
return resolve ( result [ 0 ] . claimId ) ;
}
} )
. catch ( error => {
reject ( error ) ;
} ) ;
} ) ;
} ;
Certificate . getLongChannelId = function ( channelName , channelId ) {
logger . debug ( ` getLongChannelId( ${ channelName } , ${ channelId } ) ` ) ;
if ( channelId && ( channelId . length === 40 ) ) { // if a full channel id is provided
return new Promise ( ( resolve , reject ) => resolve ( channelId ) ) ;
} else if ( channelId && channelId . length < 40 ) { // if a short channel id is provided
return this . getLongChannelIdFromShortChannelId ( channelName , channelId ) ;
} else {
return this . getLongChannelIdFromChannelName ( channelName ) ; // if no channel id provided
}
} ;
2017-08-21 22:27:13 +02:00
return Certificate ;
} ;