diff --git a/go.mod b/go.mod index 1fdb460..3d03923 100644 --- a/go.mod +++ b/go.mod @@ -14,21 +14,27 @@ require ( github.com/gobwas/ws v1.4.0 github.com/graph-gophers/dataloader/v7 v7.1.0 github.com/greatroar/blobloom v0.8.0 + github.com/jmoiron/sqlx v1.3.5 github.com/mailru/easyjson v0.7.7 + github.com/mattn/go-sqlite3 v1.14.18 + github.com/ncruces/go-sqlite3 v0.18.3 github.com/puzpuzpuz/xsync/v3 v3.4.0 github.com/stretchr/testify v1.9.0 github.com/tidwall/gjson v1.17.3 + github.com/tursodatabase/go-libsql v0.0.0-20240916111504-922dfa87e1e6 github.com/tyler-smith/go-bip32 v1.0.0 github.com/tyler-smith/go-bip39 v1.1.0 - golang.org/x/crypto v0.14.0 + golang.org/x/crypto v0.27.0 golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 - golang.org/x/net v0.17.0 - golang.org/x/text v0.15.0 + golang.org/x/net v0.21.0 + golang.org/x/text v0.18.0 + modernc.org/sqlite v1.33.1 ) require ( github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e // indirect github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec // indirect + github.com/antlr4-go/antlr/v4 v4.13.0 // indirect github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect @@ -36,13 +42,27 @@ require ( github.com/dustin/go-humanize v1.0.1 // indirect github.com/gobwas/pool v0.2.1 // indirect github.com/golang/glog v1.1.2 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/kr/pretty v0.3.1 // indirect + github.com/libsql/sqlite-antlr4-parser v0.0.0-20240327125255-dbf53b6cbf06 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/ncruces/go-strftime v0.1.9 // indirect + github.com/ncruces/julianday v1.0.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect + github.com/tetratelabs/wazero v1.8.0 // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.1 // indirect golang.org/x/sys v0.25.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect + modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 // indirect + modernc.org/libc v1.55.3 // indirect + modernc.org/mathutil v1.6.0 // indirect + modernc.org/memory v1.8.0 // indirect + modernc.org/strutil v1.2.0 // indirect + modernc.org/token v1.1.0 // indirect ) diff --git a/go.sum b/go.sum index 213b5e6..972fbdd 100644 --- a/go.sum +++ b/go.sum @@ -5,6 +5,8 @@ github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec/go.mod h1 github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI= +github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g= github.com/bluekeyes/go-gitdiff v0.7.1 h1:graP4ElLRshr8ecu0UtqfNTCHrtSyZd3DABQm/DWesQ= github.com/bluekeyes/go-gitdiff v0.7.1/go.mod h1:QpfYYO1E0fTVHVZAZKiRjtSGY9823iCdvGXBcEzHGbM= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= @@ -59,6 +61,9 @@ github.com/fiatjaf/generic-ristretto v0.0.1 h1:LUJSU87X/QWFsBXTwnH3moFe4N8AjUxT+ github.com/fiatjaf/generic-ristretto v0.0.1/go.mod h1:cvV6ANHDA/GrfzVrig7N7i6l8CWnkVZvtQ2/wk9DPVE= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI= +github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU= github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM= github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og= @@ -78,13 +83,23 @@ github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd h1:gbpYu9NMq8jhDVbvlGkMFWCjLFlqqEZjEmObmhUy6Vo= +github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/graph-gophers/dataloader/v7 v7.1.0 h1:Wn8HGF/q7MNXcvfaBnLEPEFJttVHR8zuEqP1obys/oc= github.com/graph-gophers/dataloader/v7 v7.1.0/go.mod h1:1bKE0Dm6OUcTB/OAuYVOZctgIz7Q3d0XrYtlIzTgg6Q= github.com/greatroar/blobloom v0.8.0 h1:I9RlEkfqK9/6f1v9mFmDYegDQ/x0mISCpiNpAm23Pt4= github.com/greatroar/blobloom v0.8.0/go.mod h1:mjMJ1hh1wjGVfr93QIHJ6FfDNVrA0IELv8OvMHJxHKs= +github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= +github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g= +github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= @@ -93,8 +108,24 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= +github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/libsql/sqlite-antlr4-parser v0.0.0-20240327125255-dbf53b6cbf06 h1:JLvn7D+wXjH9g4Jsjo+VqmzTUpl/LX7vfr6VOfSWTdM= +github.com/libsql/sqlite-antlr4-parser v0.0.0-20240327125255-dbf53b6cbf06/go.mod h1:FUkZ5OHjlGPjnM2UyGJz9TypXQFgYqw6AFNO1UiROTM= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= +github.com/mattn/go-sqlite3 v1.14.18 h1:JL0eqdCOq6DJVNPSvArO/bIV9/P7fbGrV00LZHc+5aI= +github.com/mattn/go-sqlite3 v1.14.18/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= +github.com/ncruces/go-sqlite3 v0.18.3 h1:tyMa75uh7LcINcfo0WrzOvcTkfz8Hqu0TEPX+KVyes4= +github.com/ncruces/go-sqlite3 v0.18.3/go.mod h1:HAwOtA+cyEX3iN6YmkpQwfT4vMMgCB7rQRFUdOgEFik= +github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= +github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= +github.com/ncruces/julianday v1.0.0 h1:fH0OKwa7NWvniGQtxdJRxAgkBMolni2BjDHaWTxqt7M= +github.com/ncruces/julianday v1.0.0/go.mod h1:Dusn2KvZrrovOMJuOt0TNXL6tB7U2E8kvza5fFc9G7g= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -111,6 +142,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/puzpuzpuz/xsync/v3 v3.4.0 h1:DuVBAdXuGFHv8adVXjWWZ63pJq+NRXOWVXlKDBZ+mJ4= github.com/puzpuzpuz/xsync/v3 v3.4.0/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= @@ -125,6 +158,8 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= +github.com/tetratelabs/wazero v1.8.0 h1:iEKu0d4c2Pd+QSRieYbnQC9yiFlMS9D+Jr0LsRmcF4g= +github.com/tetratelabs/wazero v1.8.0/go.mod h1:yAI0XTsMBhREkM/YDAK/zNou3GoiAce1P6+rp/wQhjs= github.com/tidwall/gjson v1.17.3 h1:bwWLZU7icoKRG+C+0PNwIKC6FCJO/Q3p2pZvuP0jN94= github.com/tidwall/gjson v1.17.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= @@ -132,6 +167,8 @@ github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JT github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tursodatabase/go-libsql v0.0.0-20240916111504-922dfa87e1e6 h1:bFxO2fsY5mHZRrVvhmrAo/O8Agi9HDAIMmmOClZMrkQ= +github.com/tursodatabase/go-libsql v0.0.0-20240916111504-922dfa87e1e6/go.mod h1:TjsB2miB8RW2Sse8sdxzVTdeGlx74GloD5zJYUC38d8= github.com/tyler-smith/go-bip32 v1.0.0 h1:sDR9juArbUgX+bO/iblgZnMPeWY1KZMUC2AFUJdv5KE= github.com/tyler-smith/go-bip32 v1.0.0/go.mod h1:onot+eHknzV4BVPwrzqY5OoVpyCvnwD7lMawL5aQupE= github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= @@ -140,18 +177,22 @@ golang.org/x/crypto v0.0.0-20170613210332-850760c427c5/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= -golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= +golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk= golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY= +golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= +golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -167,9 +208,11 @@ golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= -golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= +golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.25.0 h1:oFU9pkj/iJgs+0DT+VMHrx+oBKs/LJMV+Uvg78sl+fE= +golang.org/x/tools v0.25.0/go.mod h1:/vtpO8WL1N9cQC3FN5zPqb//fRXskFHbLKk4OW1Q7rg= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= @@ -189,5 +232,33 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= +gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= launchpad.net/gocheck v0.0.0-20140225173054-000000000087 h1:Izowp2XBH6Ya6rv+hqbceQyw/gSGoXfH/UPoTGduL54= launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM= +modernc.org/cc/v4 v4.21.4 h1:3Be/Rdo1fpr8GrQ7IVw9OHtplU4gWbb+wNgeoBMmGLQ= +modernc.org/cc/v4 v4.21.4/go.mod h1:HM7VJTZbUCR3rV8EYBi9wxnJ0ZBRiGE5OeGXNA0IsLQ= +modernc.org/ccgo/v4 v4.19.2 h1:lwQZgvboKD0jBwdaeVCTouxhxAyN6iawF3STraAal8Y= +modernc.org/ccgo/v4 v4.19.2/go.mod h1:ysS3mxiMV38XGRTTcgo0DQTeTmAO4oCmJl1nX9VFI3s= +modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE= +modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ= +modernc.org/gc/v2 v2.4.1 h1:9cNzOqPyMJBvrUipmynX0ZohMhcxPtMccYgGOJdOiBw= +modernc.org/gc/v2 v2.4.1/go.mod h1:wzN5dK1AzVGoH6XOzc3YZ+ey/jPgYHLuVckd62P0GYU= +modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 h1:5D53IMaUuA5InSeMu9eJtlQXS2NxAhyWQvkKEgXZhHI= +modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4= +modernc.org/libc v1.55.3 h1:AzcW1mhlPNrRtjS5sS+eW2ISCgSOLLNyFzRh/V3Qj/U= +modernc.org/libc v1.55.3/go.mod h1:qFXepLhz+JjFThQ4kzwzOjA/y/artDeg+pcYnY+Q83w= +modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= +modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= +modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= +modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= +modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= +modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= +modernc.org/sortutil v1.2.0 h1:jQiD3PfS2REGJNzNCMMaLSp/wdMNieTbKX920Cqdgqc= +modernc.org/sortutil v1.2.0/go.mod h1:TKU2s7kJMf1AE84OoiGppNHJwvB753OYfNl2WRb++Ss= +modernc.org/sqlite v1.33.1 h1:trb6Z3YYoeM9eDL1O8do81kP+0ejv+YzgyFo+Gwy0nM= +modernc.org/sqlite v1.33.1/go.mod h1:pXV2xHxhzXZsgT/RtTFAPY6JJDEvOTcTdwADQCCWD4k= +modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= +modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= +modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= +modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= diff --git a/sdk/hints/interface.go b/sdk/hints/interface.go index 8000911..048897c 100644 --- a/sdk/hints/interface.go +++ b/sdk/hints/interface.go @@ -5,4 +5,5 @@ import "github.com/nbd-wtf/go-nostr" type HintsDB interface { TopN(pubkey string, n int) []string Save(pubkey string, relay string, key HintKey, score nostr.Timestamp) + PrintScores() } diff --git a/sdk/hints/memory/memory_hints.go b/sdk/hints/memory/db.go similarity index 85% rename from sdk/hints/memory/memory_hints.go rename to sdk/hints/memory/db.go index ed0d773..5ef22eb 100644 --- a/sdk/hints/memory/memory_hints.go +++ b/sdk/hints/memory/db.go @@ -27,13 +27,6 @@ func NewHintDB() *HintDB { } func (db *HintDB) Save(pubkey string, relay string, key hints.HintKey, ts nostr.Timestamp) { - now := nostr.Now() - // this is used for calculating what counts as a usable hint - threshold := (now - 60*60*24*180) - if threshold < 0 { - threshold = 0 - } - relayIndex := slices.Index(db.RelayBySerial, relay) if relayIndex == -1 { relayIndex = len(db.RelayBySerial) @@ -104,6 +97,9 @@ func (db *HintDB) PrintScores() { fmt.Println("== relay scores for", pubkey) for i, re := range rfpk.Entries { fmt.Printf(" %3d :: %30s (%3d) ::> %12d\n", i, db.RelayBySerial[re.Relay], re.Relay, re.Sum()) + // for i, ts := range re.Timestamps { + // fmt.Printf(" %-10d %s\n", ts, hints.HintKey(i).String()) + // } } } } @@ -114,7 +110,7 @@ type RelaysForPubKey struct { type RelayEntry struct { Relay int - Timestamps [8]nostr.Timestamp + Timestamps [7]nostr.Timestamp } func (re RelayEntry) Sum() int64 { @@ -125,18 +121,9 @@ func (re RelayEntry) Sum() int64 { continue } - hk := hints.HintKey(i) - divisor := int64(now - ts) - if divisor == 0 { - divisor = 1 - } else { - divisor = int64(math.Pow(float64(divisor), 1.3)) - } - - multiplier := hk.BasePoints() - value := multiplier * 10000000000 / divisor + value := float64(hints.HintKey(i).BasePoints()) * 10000000000 / math.Pow(float64(max(now-ts, 1)), 1.3) // fmt.Println(" ", i, "value:", value) - sum += value + sum += int64(value) } return sum } diff --git a/sdk/hints/sqlite/db.go b/sdk/hints/sqlite/db.go new file mode 100644 index 0000000..8774607 --- /dev/null +++ b/sdk/hints/sqlite/db.go @@ -0,0 +1,147 @@ +package sqlite + +import ( + "database/sql" + "fmt" + "strconv" + "strings" + + "github.com/jmoiron/sqlx" + "github.com/nbd-wtf/go-nostr" + "github.com/nbd-wtf/go-nostr/sdk/hints" +) + +type SQLiteHints struct { + *sqlx.DB + + saves [7]*sqlx.Stmt + topN *sqlx.Stmt +} + +func NewSQLiteHints(db *sqlx.DB) (SQLiteHints, error) { + sh := SQLiteHints{DB: db} + + // create table and indexes + cols := strings.Builder{} + cols.Grow(len(hints.KeyBasePoints) * 20) + for i := range hints.KeyBasePoints { + name := hints.HintKey(i).String() + cols.WriteString(name) + cols.WriteString(" integer") + if i == len(hints.KeyBasePoints)-1 { + cols.WriteString(")") + } else { + cols.WriteString(",") + } + } + + _, err := sh.Exec(`CREATE TABLE pubkey_relays (pubkey text, relay text, ` + cols.String()) + if err != nil { + return SQLiteHints{}, err + } + + _, err = sh.Exec(`CREATE UNIQUE INDEX IF NOT EXISTS pkr ON pubkey_relays (pubkey, relay)`) + if err != nil { + return SQLiteHints{}, err + } + + _, err = sh.Exec(`CREATE INDEX IF NOT EXISTS bypk ON pubkey_relays (pubkey)`) + if err != nil { + return SQLiteHints{}, err + } + + // prepare statements + for i := range hints.KeyBasePoints { + col := hints.HintKey(i).String() + + stmt, err := sh.Preparex( + `INSERT INTO pubkey_relays (pubkey, relay, ` + col + `) VALUES (?, ?, ?) + ON CONFLICT (pubkey, relay) DO UPDATE SET ` + col + ` = max(?, coalesce(` + col + `, 0))`, + ) + if err != nil { + return sh, fmt.Errorf("failed to prepare statement for %s: %w", col, err) + } + sh.saves[i] = stmt + } + + { + stmt, err := sh.Preparex( + `SELECT relay FROM pubkey_relays WHERE pubkey = ? ORDER BY (` + scorePartialQuery() + `) DESC LIMIT ?`, + ) + if err != nil { + return sh, fmt.Errorf("failed to prepare statement for querying: %w", err) + } + sh.topN = stmt + } + + return sh, nil +} + +func (sh SQLiteHints) TopN(pubkey string, n int) []string { + res := make([]string, 0, n) + err := sh.topN.Select(&res, pubkey, n) + if err != nil && err != sql.ErrNoRows { + nostr.InfoLogger.Printf("[sdk/hints/sqlite] unexpected error on query for %s: %s\n", + pubkey, err) + } + return res +} + +func (sh SQLiteHints) Save(pubkey string, relay string, key hints.HintKey, score nostr.Timestamp) { + _, err := sh.saves[key].Exec(pubkey, relay, score, score) + if err != nil { + nostr.InfoLogger.Printf("[sdk/hints/sqlite] unexpected error on insert for %s, %s, %d: %s\n", + pubkey, relay, score, err) + } +} + +func (sh SQLiteHints) PrintScores() { + fmt.Println("= print scores") + + allpubkeys := make([]string, 0, 50) + if err := sh.Select(&allpubkeys, `SELECT DISTINCT pubkey FROM pubkey_relays`); err != nil { + panic(err) + } + + allrelays := make([]struct { + PubKey string `db:"pubkey"` + Relay string `db:"relay"` + Score float64 `db:"score"` + }, 0, 20) + for _, pubkey := range allpubkeys { + fmt.Println("== relay scores for", pubkey) + if err := sh.Select(&allrelays, + `SELECT pubkey, relay, coalesce(`+scorePartialQuery()+`, 0) AS score + FROM pubkey_relays WHERE pubkey = ? ORDER BY score DESC`, pubkey); err != nil { + panic(err) + } + + for i, re := range allrelays { + fmt.Printf(" %3d :: %30s ::> %12d\n", i, re.Relay, int(re.Score)) + } + } +} + +func scorePartialQuery() string { + calc := strings.Builder{} + calc.Grow(len(hints.KeyBasePoints) * (10 + 25 + 51 + 25 + 24 + 4 + 12 + 3)) + + for i, points := range hints.KeyBasePoints { + col := hints.HintKey(i).String() + multiplier := strconv.FormatInt(points, 10) + + calc.WriteString(`(CASE WHEN `) + calc.WriteString(col) + calc.WriteString(` IS NOT NULL THEN 10000000000 * `) + calc.WriteString(multiplier) + calc.WriteString(` / power(max(1, (unixepoch() + 86400) - `) + calc.WriteString(col) + calc.WriteString(`), 1.3) ELSE 0 END)`) + + if i != len(hints.KeyBasePoints)-1 { + calc.WriteString(` + `) + } + } + + return calc.String() +} diff --git a/sdk/hints/test/libsql_test.go b/sdk/hints/test/libsql_test.go new file mode 100644 index 0000000..0b6c8a2 --- /dev/null +++ b/sdk/hints/test/libsql_test.go @@ -0,0 +1,28 @@ +//go:build !sqlite_math_functions + +package test + +import ( + "os" + "testing" + + "github.com/jmoiron/sqlx" + "github.com/nbd-wtf/go-nostr/sdk/hints/sqlite" + "github.com/stretchr/testify/require" + _ "github.com/tursodatabase/go-libsql" +) + +func TestSQLiteHintsLibsql(t *testing.T) { + path := "/tmp/tmpsdkhintssqlite" + os.RemoveAll(path) + + db, err := sqlx.Connect("libsql", "file://"+path) + + require.NoError(t, err, "failed to create sqlitehints db") + db.SetMaxOpenConns(1) + + sh, err := sqlite.NewSQLiteHints(db) + require.NoError(t, err, "failed to setup sqlitehints db") + + runTestWith(t, sh) +} diff --git a/sdk/hints/test/mattnsqlite_test.go b/sdk/hints/test/mattnsqlite_test.go new file mode 100644 index 0000000..bf48436 --- /dev/null +++ b/sdk/hints/test/mattnsqlite_test.go @@ -0,0 +1,28 @@ +//go:build sqlite_math_functions + +package test + +import ( + "os" + "testing" + + "github.com/jmoiron/sqlx" + _ "github.com/mattn/go-sqlite3" + "github.com/nbd-wtf/go-nostr/sdk/hints/sqlite" + "github.com/stretchr/testify/require" +) + +func TestSQLiteHintsMattn(t *testing.T) { + path := "/tmp/tmpsdkhintssqlite" + os.RemoveAll(path) + + db, err := sqlx.Connect("sqlite3", path) + + require.NoError(t, err, "failed to create sqlitehints db") + db.SetMaxOpenConns(1) + + sh, err := sqlite.NewSQLiteHints(db) + require.NoError(t, err, "failed to setup sqlitehints db") + + runTestWith(t, sh) +} diff --git a/sdk/hints/test/memory_test.go b/sdk/hints/test/memory_test.go new file mode 100644 index 0000000..425762f --- /dev/null +++ b/sdk/hints/test/memory_test.go @@ -0,0 +1,11 @@ +package test + +import ( + "testing" + + "github.com/nbd-wtf/go-nostr/sdk/hints/memory" +) + +func TestMemoryHints(t *testing.T) { + runTestWith(t, memory.NewHintDB()) +} diff --git a/sdk/hints/test/moderncsqlite_test.go b/sdk/hints/test/moderncsqlite_test.go new file mode 100644 index 0000000..cdb0109 --- /dev/null +++ b/sdk/hints/test/moderncsqlite_test.go @@ -0,0 +1,26 @@ +package test + +import ( + "os" + "testing" + + "github.com/jmoiron/sqlx" + "github.com/nbd-wtf/go-nostr/sdk/hints/sqlite" + "github.com/stretchr/testify/require" + _ "modernc.org/sqlite" +) + +func TestSQLiteHintsModernC(t *testing.T) { + path := "/tmp/tmpsdkhintssqlite" + os.RemoveAll(path) + + db, err := sqlx.Connect("sqlite", path) + + require.NoError(t, err, "failed to create sqlitehints db") + db.SetMaxOpenConns(1) + + sh, err := sqlite.NewSQLiteHints(db) + require.NoError(t, err, "failed to setup sqlitehints db") + + runTestWith(t, sh) +} diff --git a/sdk/hints/memory/memory_test.go b/sdk/hints/test/suite.go similarity index 97% rename from sdk/hints/memory/memory_test.go rename to sdk/hints/test/suite.go index e85bef4..3070eef 100644 --- a/sdk/hints/memory/memory_test.go +++ b/sdk/hints/test/suite.go @@ -1,4 +1,4 @@ -package memory +package test import ( "testing" @@ -9,16 +9,14 @@ import ( "github.com/stretchr/testify/require" ) -func TestRelayPicking(t *testing.T) { - hdb := NewHintDB() - +func runTestWith(t *testing.T, hdb hints.HintsDB) { const key1 = "0000000000000000000000000000000000000000000000000000000000000001" const key2 = "0000000000000000000000000000000000000000000000000000000000000002" const key3 = "0000000000000000000000000000000000000000000000000000000000000003" const key4 = "0000000000000000000000000000000000000000000000000000000000000004" const relayA = "wss://aaa.com" - const relayB = "wss://bbb.online" - const relayC = "wss://ccc.technology" + const relayB = "wss://bbb.net" + const relayC = "wss://ccc.org" hour := nostr.Timestamp((time.Hour).Seconds()) day := hour * 24 diff --git a/sdk/hints/test/wasmsqlite_test.go b/sdk/hints/test/wasmsqlite_test.go new file mode 100644 index 0000000..4c67a60 --- /dev/null +++ b/sdk/hints/test/wasmsqlite_test.go @@ -0,0 +1,29 @@ +//go:build !sqlite_math_functions + +package test + +import ( + "os" + "testing" + + "github.com/jmoiron/sqlx" + "github.com/nbd-wtf/go-nostr/sdk/hints/sqlite" + _ "github.com/ncruces/go-sqlite3/driver" + _ "github.com/ncruces/go-sqlite3/embed" + "github.com/stretchr/testify/require" +) + +func TestSQLiteHintsNcruces(t *testing.T) { + path := "/tmp/tmpsdkhintssqlite" + os.RemoveAll(path) + + db, err := sqlx.Connect("sqlite3", path) + + require.NoError(t, err, "failed to create sqlitehints db") + db.SetMaxOpenConns(1) + + sh, err := sqlite.NewSQLiteHints(db) + require.NoError(t, err, "failed to setup sqlitehints db") + + runTestWith(t, sh) +}