mirror of
https://github.com/scsibug/nostr-rs-relay.git
synced 2024-11-14 15:09:07 -05:00
wip: schema addition and structure for delegation
This commit is contained in:
parent
274c61bb72
commit
43b738c434
72
src/delegation.rs
Normal file
72
src/delegation.rs
Normal file
|
@ -0,0 +1,72 @@
|
|||
//! Event parsing and validation
|
||||
//use crate::error::Error::*;
|
||||
//use crate::error::Result;
|
||||
//use crate::utils::unix_time;
|
||||
//use bitcoin_hashes::{sha256, Hash};
|
||||
//use lazy_static::lazy_static;
|
||||
//use secp256k1::{schnorr, Secp256k1, VerifyOnly, XOnlyPublicKey};
|
||||
use serde::{Deserialize, Serialize};
|
||||
//use serde_json::value::Value;
|
||||
//use serde_json::Number;
|
||||
//use std::collections::HashMap;
|
||||
//use std::collections::HashSet;
|
||||
//use std::str::FromStr;
|
||||
//use tracing::{debug, info};
|
||||
|
||||
// This handles everything related to delegation, in particular the
|
||||
// condition/rune parsing and logic.
|
||||
|
||||
// Conditions are poorly specified, so we will implement the minimum
|
||||
// necessary for now.
|
||||
|
||||
// fields MUST be either "kind" or "created_at".
|
||||
// operators supported are ">", "<", "=", "!".
|
||||
// no operations on 'content' are supported.
|
||||
|
||||
// this allows constraints for:
|
||||
// valid date ranges (valid from X->Y dates).
|
||||
// specific kinds (publish kind=1,5)
|
||||
// kind ranges (publish ephemeral events, kind>19999&kind<30001)
|
||||
|
||||
// for more complex scenarios (allow delegatee to publish ephemeral
|
||||
// AND replacement events), it may be necessary to generate and use
|
||||
// different condition strings, since we do not support grouping or
|
||||
// "OR" logic.
|
||||
|
||||
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)]
|
||||
pub enum Field {
|
||||
Kind,
|
||||
CreatedAt,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)]
|
||||
pub enum Operator {
|
||||
LessThan,
|
||||
GreaterThan,
|
||||
Equals,
|
||||
NotEquals,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)]
|
||||
pub enum Value {
|
||||
Number(u64),
|
||||
List(Vec<Value>),
|
||||
}
|
||||
|
||||
/// Parsed delegation statement
|
||||
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)]
|
||||
pub struct Delegation {
|
||||
pub(crate) pubkey: String,
|
||||
pub(crate) conditions: Vec<Condition>,
|
||||
pub(crate) signature: String,
|
||||
}
|
||||
|
||||
/// Parsed delegation condition
|
||||
/// see https://github.com/nostr-protocol/nips/pull/28#pullrequestreview-1084903800
|
||||
/// An example complex condition would be: kind=1,2,3&created_at<1665265999
|
||||
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)]
|
||||
pub struct Condition {
|
||||
pub(crate) field: Field,
|
||||
pub(crate) operator: Operator,
|
||||
pub(crate) value: Value,
|
||||
}
|
36
src/event.rs
36
src/event.rs
|
@ -110,6 +110,16 @@ impl Event {
|
|||
None
|
||||
}
|
||||
|
||||
// is this event delegated (properly)?
|
||||
// does the signature match, and are conditions valid?
|
||||
pub fn is_delegated(&self) -> bool {
|
||||
// is there a delegation tag?
|
||||
let _delegation_tag = self.tag_values_by_name("delegation");
|
||||
// delegation tags should have exactly 3 elements after the name (pubkey, condition, sig)
|
||||
// try to construct a delegation object (
|
||||
todo!();
|
||||
}
|
||||
|
||||
/// Build an event tag index
|
||||
fn build_index(&mut self) {
|
||||
// if there are no tags; just leave the index as None
|
||||
|
@ -388,6 +398,32 @@ mod tests {
|
|||
assert_eq!(v, vec!["foo", "bar", "baz"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn event_no_tag_select() {
|
||||
let e = Event {
|
||||
id: "999".to_owned(),
|
||||
pubkey: "012345".to_owned(),
|
||||
created_at: 501234,
|
||||
kind: 1,
|
||||
tags: vec![
|
||||
vec!["j".to_owned(), "abc".to_owned()],
|
||||
vec!["e".to_owned(), "foo".to_owned()],
|
||||
vec!["e".to_owned(), "baz".to_owned()],
|
||||
vec![
|
||||
"p".to_owned(),
|
||||
"aaaa".to_owned(),
|
||||
"ws://example.com".to_owned(),
|
||||
],
|
||||
],
|
||||
content: "this is a test".to_owned(),
|
||||
sig: "abcde".to_owned(),
|
||||
tagidx: None,
|
||||
};
|
||||
let v = e.tag_values_by_name("x");
|
||||
// asking for tags that don't exist just returns zero-length vector
|
||||
assert_eq!(v.len(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn event_canonical_with_tags() {
|
||||
let e = Event {
|
||||
|
|
|
@ -2,6 +2,7 @@ pub mod close;
|
|||
pub mod config;
|
||||
pub mod conn;
|
||||
pub mod db;
|
||||
pub mod delegation;
|
||||
pub mod error;
|
||||
pub mod event;
|
||||
pub mod hexrange;
|
||||
|
|
|
@ -20,7 +20,7 @@ pragma mmap_size = 536870912; -- 512MB of mmap
|
|||
"##;
|
||||
|
||||
/// Latest database version
|
||||
pub const DB_VERSION: usize = 6;
|
||||
pub const DB_VERSION: usize = 7;
|
||||
|
||||
/// Schema definition
|
||||
const INIT_SQL: &str = formatcp!(
|
||||
|
@ -40,6 +40,7 @@ event_hash BLOB NOT NULL, -- 4-byte hash
|
|||
first_seen INTEGER NOT NULL, -- when the event was first seen (not authored!) (seconds since 1970)
|
||||
created_at INTEGER NOT NULL, -- when the event was authored
|
||||
author BLOB NOT NULL, -- author pubkey
|
||||
delegator BLOB, -- delegator pubkey (NIP-26)
|
||||
kind INTEGER NOT NULL, -- event kind
|
||||
hidden INTEGER, -- relevant for queries
|
||||
content TEXT NOT NULL -- serialized json of event object
|
||||
|
@ -152,6 +153,9 @@ pub fn upgrade_db(conn: &mut PooledConnection) -> Result<()> {
|
|||
if curr_version == 5 {
|
||||
curr_version = mig_5_to_6(conn)?;
|
||||
}
|
||||
if curr_version == 6 {
|
||||
curr_version = mig_6_to_7(conn)?;
|
||||
}
|
||||
if curr_version == DB_VERSION {
|
||||
info!(
|
||||
"All migration scripts completed successfully. Welcome to v{}.",
|
||||
|
@ -348,3 +352,22 @@ fn mig_5_to_6(conn: &mut PooledConnection) -> Result<usize> {
|
|||
info!("vacuumed DB after tags rebuild in {:?}", start.elapsed());
|
||||
Ok(6)
|
||||
}
|
||||
|
||||
fn mig_6_to_7(conn: &mut PooledConnection) -> Result<usize> {
|
||||
info!("database schema needs update from 6->7");
|
||||
// only change is adding a hidden column to events.
|
||||
let upgrade_sql = r##"
|
||||
ALTER TABLE event ADD delegator BLOB;
|
||||
PRAGMA user_version = 7;
|
||||
"##;
|
||||
match conn.execute_batch(upgrade_sql) {
|
||||
Ok(()) => {
|
||||
info!("database schema upgraded v6 -> v7");
|
||||
}
|
||||
Err(err) => {
|
||||
error!("update failed: {}", err);
|
||||
panic!("database could not be upgraded");
|
||||
}
|
||||
}
|
||||
Ok(7)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user