Skip to content

Commit

Permalink
updateing databse models and indexes
Browse files Browse the repository at this point in the history
updating log filter logic
  • Loading branch information
StoyanD committed Jul 23, 2024
1 parent 036c680 commit fda33c2
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 46 deletions.
69 changes: 55 additions & 14 deletions src/source-intent/schemas/source-intent-data.schema.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,60 @@
import { Schema, SchemaFactory } from '@nestjs/mongoose'
import { SourceIntentWS } from '../dtos/SourceIntentWS'
import { Network } from 'alchemy-sdk'
import { IntentStruct } from '../../typing/contracts/IntentSource'
import { AddressLike, BigNumberish, BytesLike } from 'ethers'

@Schema()
export class SourceIntentDataModel implements SourceIntentWS {
blockNumber: number
blockHash: string
transactionIndex: number
removed: boolean
address: string
network: Network
data: string
topics: string[]
transactionHash: string
logIndex: number
export class SourceIntentDataModel implements IntentStruct {
hash: BytesLike
creator: AddressLike
destinationChain: BigNumberish
targets: AddressLike[]
data: BytesLike[]
rewardTokens: AddressLike[]
rewardAmounts: BigNumberish[]
expiryTime: BigNumberish
hasBeenWithdrawn: boolean
nonce: BytesLike

constructor(
hash: BytesLike,
creator: AddressLike,
destinationChain: BigNumberish,
targets: AddressLike[],
data: BytesLike[],
rewardTokens: AddressLike[],
rewardAmounts: BigNumberish[],
expiryTime: BigNumberish,
nonce: BytesLike,
) {
this.hash = hash
this.creator = creator
this.destinationChain = destinationChain
this.targets = targets
this.data = data
this.rewardTokens = rewardTokens
this.rewardAmounts = rewardAmounts
this.expiryTime = expiryTime
this.hasBeenWithdrawn = false
this.nonce = nonce
}

static fromEvent(event: Array<any>): SourceIntentDataModel {
return new SourceIntentDataModel(
event[0],
event[1],
event[2],
event[3],
event[4],
event[5],
event[6],
event[7],
event[8],
)
}
}
export const SourceIntentDataSchema = SchemaFactory.createForClass(SourceIntentDataModel)
SourceIntentDataSchema.index({ transactionHash: 1 }, { unique: true })
SourceIntentDataSchema.index({ hash: 1 }, { unique: true })
SourceIntentDataSchema.index(
{ hasBeenWithdrawn: 1, destinationChain: 'ascending', expiryTime: 'ascending' },
{ unique: false },
)
19 changes: 19 additions & 0 deletions src/source-intent/schemas/source-intent-event.schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Schema, SchemaFactory } from '@nestjs/mongoose'
import { SourceIntentWS } from '../dtos/SourceIntentWS'
import { Network } from 'alchemy-sdk'

@Schema()
export class SourceIntentEventModel implements SourceIntentWS {
blockNumber: number
blockHash: string
transactionIndex: number
removed: boolean
address: string
network: Network
data: string
topics: string[]
transactionHash: string
logIndex: number
}
export const SourceIntentEventSchema = SchemaFactory.createForClass(SourceIntentEventModel)
SourceIntentEventSchema.index({ transactionHash: 1 }, { unique: true })
6 changes: 5 additions & 1 deletion src/source-intent/schemas/source-intent.schema.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'
import { ContractTransactionReceipt } from 'ethers'
import { SourceIntentEventModel } from './source-intent-event.schema'
import { SourceIntentDataModel } from './source-intent-data.schema'

export type SourceIntentStatus = 'PENDING' | 'SOLVED' | 'EXPIRED'

@Schema()
export class SourceIntentModel {
@Prop()
intentData: SourceIntentDataModel
event: SourceIntentEventModel

@Prop()
intent: SourceIntentDataModel

@Prop()
receipt: ContractTransactionReceipt
Expand Down
25 changes: 14 additions & 11 deletions src/source-intent/source-intent.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { InjectModel } from '@nestjs/mongoose'
import { SourceIntentModel } from './schemas/source-intent.schema'
import { Model } from 'mongoose'
import { EcoLogMessage } from '../common/logging/eco-log-message'
import { decodeCreateIntentLog } from '../ws/ws.helpers'

/**
* Service class for solving an intent on chain
Expand All @@ -22,9 +23,10 @@ export class SourceIntentService implements OnModuleInit {

onModuleInit() {}

async createIntent(data: SourceIntentWS) {
this.logger.log(`Creating intent: ${data}`)
const lock = await this.redlockService.acquireLock([data.transactionHash], 5000)
async createIntent(intentWs: SourceIntentWS) {
const intent = decodeCreateIntentLog(intentWs.data, intentWs.topics)
this.logger.log(`Creating intent: `)
const lock = await this.redlockService.acquireLock([intent.hash as string], 5000)
//this instance didn`t get the lock, so just break out here
if (!lock) {
return
Expand All @@ -33,16 +35,16 @@ export class SourceIntentService implements OnModuleInit {
try {
//check db if the intent is already filled
const model = await this.intentModel.findOne({
'intentData.transactionHash': data.transactionHash,
'intent.hash': intent.hash,
})
if (model) {
// Record already exists, do nothing and return
this.logger.debug(
EcoLogMessage.fromDefault({
message: `Record for intent already exists ${data.transactionHash}`,
message: `Record for intent already exists ${intent.hash}`,
properties: {
eventHash: data.transactionHash,
event: data,
intentHash: intent.hash,
intent: intent,
},
}),
)
Expand All @@ -51,16 +53,17 @@ export class SourceIntentService implements OnModuleInit {

//update db
const record = await this.intentModel.create<SourceIntentModel>({
intentData: data,
event: intentWs,
intent: intent,
receipt: null,
status: 'PENDING',
})
this.logger.debug(
EcoLogMessage.fromDefault({
message: `Recorded intent ${record.intentData.transactionHash}`,
message: `Recorded intent ${record.intent.hash}`,
properties: {
eventHash: data.transactionHash,
event: record.intentData,
intentHash: intent.hash,
intent: record.intent,
},
}),
)
Expand Down
53 changes: 33 additions & 20 deletions src/ws/ws.helpers.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,43 @@
import { Utils } from 'alchemy-sdk'
import { EventFilter } from 'ethers'
import { IntentSource__factory } from '../typing/contracts'
import { SourceIntentDataModel } from '../source-intent/schemas/source-intent-data.schema'

/**
*
* Creates the filter for the events that we want to listen to for the IntentSource contract
*
* event IntentCreated(
bytes32 indexed _hash,
address _creator,
uint256 indexed _destinationChain,
address[] _targets,
bytes[] _data,
address[] _rewardTokens,
uint256[] _rewardAmounts,
uint256 indexed _expiryTime,
bytes32 nonce
);
* @param sourceIntentContractAddress
* @returns
* bytes32 indexed _hash,
* address _creator,
* uint256 indexed _destinationChain,
* address[] _targets,
* bytes[] _data,
* address[] _rewardTokens,
* uint256[] _rewardAmounts,
* uint256 indexed _expiryTime,
* bytes32 nonce
* );
*
* @param sourceIntentContractAddress address of the contract
* @returns
*/
export function getCreateIntentLogFilter(sourceIntentContractAddress: string): EventFilter {
const intentCreated = IntentSource__factory.createInterface().getEvent('IntentCreated').topicHash
return {
address: sourceIntentContractAddress,
topics: [
Utils.id(
'IntentCreated(bytes32,address,uint256,address[],bytes[],address[],uint256[],uint256,bytes32)',
),
],
topics: [intentCreated],
}
}

/**
* Decodes the IntentCreated event log
*
* @param data the encoded data from the event log
* @param topics the log topics
* @returns
*/
export function decodeCreateIntentLog(data: string, topics: string[]): SourceIntentDataModel {
const ii = IntentSource__factory.createInterface()
const frag = ii.getEvent('IntentCreated')
const decode = ii.decodeEventLog(frag, data, topics)
return SourceIntentDataModel.fromEvent(decode)
}

0 comments on commit fda33c2

Please sign in to comment.