每个地址需要有丰富的交互记录,每一条交互记为一个任务。
每个地址的任务执行应当呈现出随机性——时间随机、具体内容随机,同样,任务之间的间隔也需要随机。
任务之间可能存在依赖关系,例如需要先去LDO抵押ETH,才能去AAVE借出stETH,再进一步租借USDC,这种依赖关系呈现为:
[
{
"id": 1,
"description": "stake ETH on Lido"
},
{
"id": 2,
"description": "Lend stETH on Aave",
"dependsOn": 1
},
{
"id": 3,
"description": "Borrow USDC on Aave",
"dependsOn": 2
}
]
同时,某些任务可能需要随机、重复完成,用来在链上呈现出一种无意义的行为,这种任务表示为:
{
"id": 4,
"description": "mint a NFT on polygon",
"repeatable": true
}
在系统设计时,调度系统和执行引擎应当分离。
调度系统只负责任务和地址的选取,即从任务列表中随机取任务,再从账户列表中随机选一个账户,交给执行引擎执行,引擎执行结束后将结果存储于数据库中,用于下次调度时查询。
该逻辑以伪码表示为:
const account = get_random_account()
const task = get_random_task()
// 如果该账户已经完成过该任务,则直接跳过
if (account.hasFinished(task)) {
return
}
// 如果任务有依赖关系,先检查依赖任务的完成情况
if (task.hasDependency()) {
const dependency = task.getDependency()
// 如果依赖任务尚未完成,则该任务无法完成,暂且跳过
if (!account.hasFinished(dependency)) {
return
} else {
executor.execute(account, task)
}
} else {
executor.execute(account, task)
}