Composability of policies
Right now, the handling is just an array of policies, each of which might block more events that prior policies did not block.
The policies returning already something like a boolean I wonder if more in the sense of boolean logic could be done here.
Instead of implicit
acceptIfAllTrue(event, policy1, policy2, ...)
provide features to allow more boolean logic:
acceptIf(event, policy1 && policy2 || !policy3 ...).
This would also cover !3.
I'm trying to implement different policies for different pubkeys but due to the lack of composability, I can't re-use the existing policies or at least I don't know how. I'd like to do something like:
const webOfTrustPolicy = (msg, degree) {
const group = getFollows(degree)
return group.has(msg.event.pubkey))
}
for await (const msg of readStdin()) {
const pass = (webOfTrustPolicy(msg, 0) // me and my friends
|| ( webOfTrustPolicy(msg, 1) // our follows may do most sane stuff
&& hellthreadPolicy(msg, { limit: 100 })
&& antiDuplicationPolicy(msg, { ttl: 60000, minLength: 50 }]))
|| powPolicy(msg, { difficulty: 20000 })) // non-follows have to provide pow
&& pubkeyBanPolicy(msg, ['e810...', 'fafa...', '1e89...'])) // ban overrules all other rules
writeStdout({
id: msg.event.id,
action: pass ? 'accept' : 'reject'
});
}
I see that this policy project already lost the control for strfry's 'shadowReject' and this change here would essentially drop control for meaningful messages, too unless the user wants to spend both code and cpu time to fill in the blank "manually" but the gain would be great for my application at least.
The return msg could just collect all policy results:
const webOfTrustPolicy = (msg, degree) {
const group = getFollows(degree)
if (group.has(msg.event.pubkey)) {
msg.msgs.push('+WoT+')
return true
}
msg.msgs.push('-WoT-')
return false
}
for await (const msg of readStdin()) {
msg.msgs = []
...
writeStdout({
id: msg.event.id,
action: pass ? 'accept' : 'reject',
msg: msg.msgs.join()
});
}
This would not be in line with nip-20 though but we won't magically get from
- whitelistPolicy failed
- webOfTrustPolicy passed
- hellthreadPolicy passed
- antiDuplicationPolicy failed
- powPolicy failed
- pubkeyBanPolicy not tested
to
"blocked: follows of the whitelist may not post the same twice per minute unless they provide pow 2000"
As in the proposed composability, policies might get invoked multiple times, these should use/could use caching to avoid repeated computation or state issues with rate limiting for example:
const webOfTrustPolicy = (msg, degree) {
if (msg.webOfTrustPolicy === undefined) {
const group = getFollows(degree)
msg.webOfTrustPolicy = group.has(msg.event.pubkey))
}
return msg.webOfTrustPolicy
}