diff --git a/Cargo.lock b/Cargo.lock index aa6df19d..f417bac7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -68,9 +68,9 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "alloy" -version = "0.7.3" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b0561294ccedc6181e5528b850b4579e3fbde696507baa00109bfd9054c5bb" +checksum = "59febb24956a41c29bb5f450978fbe825bd6456b3f80586c8bd558dc882e7b6a" dependencies = [ "alloy-consensus", "alloy-contract", @@ -107,9 +107,9 @@ dependencies = [ [[package]] name = "alloy-consensus" -version = "0.7.3" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a101d4d016f47f13890a74290fdd17b05dd175191d9337bc600791fb96e4dea8" +checksum = "e88e1edea70787c33e11197d3f32ae380f3db19e6e061e539a5bcf8184a6b326" dependencies = [ "alloy-eips", "alloy-primitives", @@ -125,9 +125,9 @@ dependencies = [ [[package]] name = "alloy-consensus-any" -version = "0.7.3" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa60357dda9a3d0f738f18844bd6d0f4a5924cc5cf00bfad2ff1369897966123" +checksum = "57b1bb53f40c0273cd1975573cd457b39213e68584e36d1401d25fd0398a1d65" dependencies = [ "alloy-consensus", "alloy-eips", @@ -139,9 +139,9 @@ dependencies = [ [[package]] name = "alloy-contract" -version = "0.7.3" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2869e4fb31331d3b8c58c7db567d1e4e4e94ef64640beda3b6dd9b7045690941" +checksum = "1b668c78c4b1f12f474ede5a85e8ce550d0aa1ef7d49fd1d22855a43b960e725" dependencies = [ "alloy-dyn-abi", "alloy-json-abi", @@ -160,9 +160,9 @@ dependencies = [ [[package]] name = "alloy-core" -version = "0.8.13" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8d22df68fa7d9744be0b1a9be3260e9aa089fbf41903ab182328333061ed186" +checksum = "c618bd382f0bc2ac26a7e4bfae01c9b015ca8f21b37ca40059ae35a7e62b3dc6" dependencies = [ "alloy-dyn-abi", "alloy-json-abi", @@ -173,9 +173,9 @@ dependencies = [ [[package]] name = "alloy-dyn-abi" -version = "0.8.13" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cf633ae9a1f0c82fdb9e559ed2be1c8e415c3e48fc47e1feaf32c6078ec0cdd" +checksum = "41056bde53ae10ffbbf11618efbe1e0290859e5eab0fe9ef82ebdb62f12a866f" dependencies = [ "alloy-json-abi", "alloy-primitives", @@ -215,9 +215,9 @@ dependencies = [ [[package]] name = "alloy-eips" -version = "0.7.3" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6755b093afef5925f25079dd5a7c8d096398b804ba60cb5275397b06b31689" +checksum = "5f9fadfe089e9ccc0650473f2d4ef0a28bc015bbca5631d9f0f09e49b557fdb3" dependencies = [ "alloy-eip2930", "alloy-eip7702", @@ -233,9 +233,9 @@ dependencies = [ [[package]] name = "alloy-genesis" -version = "0.7.3" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aeec8e6eab6e52b7c9f918748c9b811e87dbef7312a2e3a2ca1729a92966a6af" +checksum = "2b2a4cf7b70f3495788e74ce1c765260ffe38820a2a774ff4aacb62e31ea73f9" dependencies = [ "alloy-primitives", "alloy-serde", @@ -257,9 +257,9 @@ dependencies = [ [[package]] name = "alloy-json-rpc" -version = "0.7.3" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fa077efe0b834bcd89ff4ba547f48fb081e4fdc3673dd7da1b295a2cf2bb7b7" +checksum = "e29040b9d5fe2fb70415531882685b64f8efd08dfbd6cc907120650504821105" dependencies = [ "alloy-primitives", "alloy-sol-types", @@ -271,9 +271,9 @@ dependencies = [ [[package]] name = "alloy-network" -version = "0.7.3" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "209a1882a08e21aca4aac6e2a674dc6fcf614058ef8cb02947d63782b1899552" +checksum = "510cc00b318db0dfccfdd2d032411cfae64fc144aef9679409e014145d3dacc4" dependencies = [ "alloy-consensus", "alloy-consensus-any", @@ -296,9 +296,9 @@ dependencies = [ [[package]] name = "alloy-network-primitives" -version = "0.7.3" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c20219d1ad261da7a6331c16367214ee7ded41d001fabbbd656fbf71898b2773" +checksum = "9081c099e798b8a2bba2145eb82a9a146f01fc7a35e9ab6e7b43305051f97550" dependencies = [ "alloy-consensus", "alloy-eips", @@ -337,9 +337,9 @@ dependencies = [ [[package]] name = "alloy-provider" -version = "0.7.3" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9eefa6f4c798ad01f9b4202d02cea75f5ec11fa180502f4701e2b47965a8c0bb" +checksum = "dc2dfaddd9a30aa870a78a4e1316e3e115ec1e12e552cbc881310456b85c1f24" dependencies = [ "alloy-chains", "alloy-consensus", @@ -377,9 +377,9 @@ dependencies = [ [[package]] name = "alloy-pubsub" -version = "0.7.3" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aac9a7210e0812b1d814118f426f57eb7fc260a419224dd1c76d169879c06907" +checksum = "695809e743628d54510c294ad17a4645bd9f465aeb0d20ee9ce9877c9712dc9c" dependencies = [ "alloy-json-rpc", "alloy-primitives", @@ -418,9 +418,9 @@ dependencies = [ [[package]] name = "alloy-rpc-client" -version = "0.7.3" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed30bf1041e84cabc5900f52978ca345dd9969f2194a945e6fdec25b0620705c" +checksum = "531137b283547d5b9a5cafc96b006c64ef76810c681d606f28be9781955293b6" dependencies = [ "alloy-json-rpc", "alloy-primitives", @@ -444,9 +444,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types" -version = "0.7.3" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ab686b0fa475d2a4f5916c5f07797734a691ec58e44f0f55d4746ea39cbcefb" +checksum = "3410a472ce26c457e9780f708ee6bd540b30f88f1f31fdab7a11d00bd6aa1aee" dependencies = [ "alloy-primitives", "alloy-rpc-types-engine", @@ -457,9 +457,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-any" -version = "0.7.3" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "200661999b6e235d9840be5d60a6e8ae2f0af9eb2a256dd378786744660e36ec" +checksum = "ed98e1af55a7d856bfa385f30f63d8d56be2513593655c904a8f4a7ec963aa3e" dependencies = [ "alloy-consensus-any", "alloy-rpc-types-eth", @@ -468,9 +468,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-engine" -version = "0.7.3" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d297268357e3eae834ddd6888b15f764cbc0f4b3be9265f5f6ec239013f3d68" +checksum = "03bd16fa4959255ebf4a7702df08f325e5631df5cdca07c8a8e58bdc10fe02e3" dependencies = [ "alloy-consensus", "alloy-eips", @@ -484,9 +484,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-eth" -version = "0.7.3" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0600b8b5e2dc0cab12cbf91b5a885c35871789fb7b3a57b434bd4fced5b7a8b" +checksum = "8737d7a6e37ca7bba9c23e9495c6534caec6760eb24abc9d5ffbaaba147818e1" dependencies = [ "alloy-consensus", "alloy-consensus-any", @@ -504,9 +504,9 @@ dependencies = [ [[package]] name = "alloy-serde" -version = "0.7.3" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afa753a97002a33b2ccb707d9f15f31c81b8c1b786c95b73cc62bb1d1fd0c3f" +checksum = "5851bf8d5ad33014bd0c45153c603303e730acc8a209450a7ae6b4a12c2789e2" dependencies = [ "alloy-primitives", "serde", @@ -515,9 +515,9 @@ dependencies = [ [[package]] name = "alloy-signer" -version = "0.7.3" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2cbff01a673936c2efd7e00d4c0e9a4dbbd6d600e2ce298078d33efbb19cd7" +checksum = "7e10ca565da6500cca015ba35ee424d59798f2e1b85bc0dd8f81dafd401f029a" dependencies = [ "alloy-dyn-abi", "alloy-primitives", @@ -531,9 +531,9 @@ dependencies = [ [[package]] name = "alloy-signer-aws" -version = "0.7.3" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71ce77227fdb9059fd7a3b38a8679c0dae95d81886ee8c13ef8ad99d74866bbd" +checksum = "1e774d4203ad7dbeba06876c8528a169b7cb56770bd900bc061e6a2c2756a736" dependencies = [ "alloy-consensus", "alloy-network", @@ -549,9 +549,9 @@ dependencies = [ [[package]] name = "alloy-signer-gcp" -version = "0.7.3" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7622438a51e1fa6379cad6bff52e0cde88b0d4e5e3f2f15e5feebdee527ef5f2" +checksum = "9843facd50077d2010ac0ef9e9176f8a06f2e2c8e653d83d82859803c623c6fc" dependencies = [ "alloy-consensus", "alloy-network", @@ -567,9 +567,9 @@ dependencies = [ [[package]] name = "alloy-signer-ledger" -version = "0.7.3" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7b56789cbd13bace37acd7afd080aa7002ed65ab84f0220cd0c32e162b0afd6" +checksum = "08367716d2eee6f15f0f7ee2e855decbfedd12be12fe5f490a2d2717deda95bf" dependencies = [ "alloy-consensus", "alloy-dyn-abi", @@ -587,9 +587,9 @@ dependencies = [ [[package]] name = "alloy-signer-local" -version = "0.7.3" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd6d988cb6cd7d2f428a74476515b1a6e901e08c796767f9f93311ab74005c8b" +checksum = "47fababf5a745133490cde927d48e50267f97d3d1209b9fc9f1d1d666964d172" dependencies = [ "alloy-consensus", "alloy-network", @@ -678,9 +678,9 @@ dependencies = [ [[package]] name = "alloy-transport" -version = "0.7.3" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d69d36982b9e46075ae6b792b0f84208c6c2c15ad49f6c500304616ef67b70e0" +checksum = "538a04a37221469cac0ce231b737fd174de2fdfcdd843bdd068cb39ed3e066ad" dependencies = [ "alloy-json-rpc", "base64 0.22.1", @@ -698,9 +698,9 @@ dependencies = [ [[package]] name = "alloy-transport-http" -version = "0.7.3" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e02ffd5d93ffc51d72786e607c97de3b60736ca3e636ead0ec1f7dce68ea3fd" +checksum = "2ed40eb1e1265b2911512f6aa1dcece9702d078f5a646730c45e39e2be00ac1c" dependencies = [ "alloy-json-rpc", "alloy-transport", @@ -713,9 +713,9 @@ dependencies = [ [[package]] name = "alloy-transport-ipc" -version = "0.7.3" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b6f8b87cb84bae6d81ae6604b37741c8116f84f9784a0ecc6038c302e679d23" +checksum = "a7a172a59d24706b26a79a837f86d51745cb26ca6f8524712acd0208a14cff95" dependencies = [ "alloy-json-rpc", "alloy-pubsub", @@ -732,9 +732,9 @@ dependencies = [ [[package]] name = "alloy-transport-ws" -version = "0.7.3" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c085c4e1e7680b723ffc558f61a22c061ed3f70eb3436f93f3936779c59cec1" +checksum = "fba0e39d181d13c266dbb8ca54ed584a2c66d6e9279afca89c7a6b1825e98abb" dependencies = [ "alloy-pubsub", "alloy-transport", @@ -2650,6 +2650,12 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + [[package]] name = "flate2" version = "1.0.35" @@ -3722,7 +3728,8 @@ dependencies = [ "serde", "serde_json", "sqlx", - "tap_core", + "tap_core 2.0.0 (git+https://github.com/semiotic-ai/timeline-aggregation-protocol?rev=1dada3e)", + "tap_core 2.0.0 (git+https://github.com/semiotic-ai/timeline-aggregation-protocol?rev=3c56018)", "test-assets", "thegraph-core", "thegraph-graphql-http", @@ -3770,7 +3777,7 @@ dependencies = [ "serde_json", "sqlx", "tap_aggregator", - "tap_core", + "tap_core 2.0.0 (git+https://github.com/semiotic-ai/timeline-aggregation-protocol?rev=3c56018)", "tempfile", "test-assets", "test-log", @@ -4372,6 +4379,12 @@ dependencies = [ "version_check", ] +[[package]] +name = "multimap" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "defc4c55412d89136f966bbb339008b474350e5e6e78d2714439c386b3137a03" + [[package]] name = "native-tls" version = "0.2.12" @@ -4866,6 +4879,16 @@ dependencies = [ "ucd-trie", ] +[[package]] +name = "petgraph" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" +dependencies = [ + "fixedbitset", + "indexmap 2.7.0", +] + [[package]] name = "pharos" version = "0.5.3" @@ -4986,6 +5009,16 @@ dependencies = [ "yansi", ] +[[package]] +name = "prettyplease" +version = "0.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" +dependencies = [ + "proc-macro2", + "syn 2.0.90", +] + [[package]] name = "primitive-types" version = "0.12.2" @@ -5118,6 +5151,27 @@ dependencies = [ "prost-derive", ] +[[package]] +name = "prost-build" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c1318b19085f08681016926435853bbf7858f9c082d0999b80550ff5d9abe15" +dependencies = [ + "bytes", + "heck 0.4.1", + "itertools 0.10.5", + "log", + "multimap", + "once_cell", + "petgraph", + "prettyplease", + "prost", + "prost-types", + "regex", + "syn 2.0.90", + "tempfile", +] + [[package]] name = "prost-derive" version = "0.13.3" @@ -6790,23 +6844,27 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tap_aggregator" version = "0.3.2" -source = "git+https://github.com/semiotic-ai/timeline-aggregation-protocol?rev=1c6e29f#1c6e29f56fc1672087070c7e8e710bac0564e273" +source = "git+https://github.com/semiotic-ai/timeline-aggregation-protocol?rev=3c56018#3c56018a321736ff19103ea69015160c3647364b" dependencies = [ "alloy", "anyhow", "axum", "clap", "futures-util", + "hyper 1.5.1", "jsonrpsee", "lazy_static", "log", "prometheus", + "prost", "ruint", "serde", "serde_json", "strum", - "tap_core", + "tap_core 2.0.0 (git+https://github.com/semiotic-ai/timeline-aggregation-protocol?rev=3c56018)", "tokio", + "tonic", + "tonic-build", "tower 0.4.13", "tracing-subscriber", ] @@ -6814,7 +6872,22 @@ dependencies = [ [[package]] name = "tap_core" version = "2.0.0" -source = "git+https://github.com/semiotic-ai/timeline-aggregation-protocol?rev=1c6e29f#1c6e29f56fc1672087070c7e8e710bac0564e273" +source = "git+https://github.com/semiotic-ai/timeline-aggregation-protocol?rev=1dada3e#1dada3e32a62ce632c0425151960cbe8c914cb3b" +dependencies = [ + "alloy", + "anyhow", + "anymap3", + "async-trait", + "rand", + "serde", + "thiserror 1.0.69", + "tokio", +] + +[[package]] +name = "tap_core" +version = "2.0.0" +source = "git+https://github.com/semiotic-ai/timeline-aggregation-protocol?rev=3c56018#3c56018a321736ff19103ea69015160c3647364b" dependencies = [ "alloy", "anyhow", @@ -6846,7 +6919,8 @@ dependencies = [ "bip39", "indexer-allocation", "lazy_static", - "tap_core", + "tap_core 2.0.0 (git+https://github.com/semiotic-ai/timeline-aggregation-protocol?rev=1dada3e)", + "tap_core 2.0.0 (git+https://github.com/semiotic-ai/timeline-aggregation-protocol?rev=3c56018)", "thegraph-core", "tokio", "typed-builder", @@ -6875,8 +6949,7 @@ dependencies = [ [[package]] name = "thegraph-core" version = "0.9.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e669ad507b7afcf8b2d303e98de2d8bcd7af56042a8626cd708838349cc4d928" +source = "git+https://github.com/edgeandnode/toolshed?rev=d710e05#d710e05faafc8aa241363fdb0751111cba3b8927" dependencies = [ "alloy", "bs58", @@ -7202,6 +7275,21 @@ dependencies = [ "tower-layer", "tower-service", "tracing", + "zstd", +] + +[[package]] +name = "tonic-build" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9557ce109ea773b399c9b9e5dca39294110b74f1f342cb347a80d1fce8c26a11" +dependencies = [ + "prettyplease", + "proc-macro2", + "prost-build", + "prost-types", + "quote", + "syn 2.0.90", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index fd64e46c..ea807a2a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -52,14 +52,15 @@ uuid = { version = "1.11.0", features = ["v7"] } tracing = { version = "0.1.40", default-features = false } bigdecimal = "0.4.3" build-info = "0.0.39" -tap_core = { git = "https://github.com/semiotic-ai/timeline-aggregation-protocol", rev = "1c6e29f", default-features = false } -tap_aggregator = { git = "https://github.com/semiotic-ai/timeline-aggregation-protocol", rev = "1c6e29f", default-features = false } +tap_core = { git = "https://github.com/semiotic-ai/timeline-aggregation-protocol", rev = "3c56018", default-features = false } +tap_core_v2 = { git = "https://github.com/semiotic-ai/timeline-aggregation-protocol", rev = "1dada3e", package = "tap_core" } +tap_aggregator = { git = "https://github.com/semiotic-ai/timeline-aggregation-protocol", rev = "3c56018", default-features = false } tracing-subscriber = { version = "0.3", features = [ "json", "env-filter", "ansi", ], default-features = false } -thegraph-core = { version = "0.9.6", features = [ +thegraph-core = { git = "https://github.com/edgeandnode/toolshed", rev= "d710e05", features = [ "attestation", "alloy-eip712", "alloy-sol-types", diff --git a/crates/service/Cargo.toml b/crates/service/Cargo.toml index 167e19c2..7d413eaa 100644 --- a/crates/service/Cargo.toml +++ b/crates/service/Cargo.toml @@ -37,6 +37,7 @@ async-graphql-axum = "7.0.11" base64.workspace = true graphql = { git = "https://github.com/edgeandnode/toolshed", tag = "graphql-v0.3.0" } tap_core.workspace = true +tap_core_v2.workspace = true uuid.workspace = true typed-builder.workspace = true tower_governor = { version = "0.5.0", features = ["axum"] } diff --git a/crates/service/src/middleware/tap_receipt.rs b/crates/service/src/middleware/tap_receipt.rs index 3d068443..93c42d4a 100644 --- a/crates/service/src/middleware/tap_receipt.rs +++ b/crates/service/src/middleware/tap_receipt.rs @@ -14,10 +14,15 @@ use crate::service::TapReceipt; /// /// This is useful to not deserialize multiple times the same receipt pub async fn receipt_middleware(mut request: Request, next: Next) -> Response { - if let Ok(TypedHeader(TapReceipt(receipt))) = - request.extract_parts::>().await - { - request.extensions_mut().insert(receipt); + if let Ok(TypedHeader(receipt)) = request.extract_parts::>().await { + match receipt { + TapReceipt::V1(receipt) => { + request.extensions_mut().insert(receipt); + } + TapReceipt::V2(receipt) => { + request.extensions_mut().insert(receipt); + } + } } next.run(request).await } diff --git a/crates/service/src/service/tap_receipt_header.rs b/crates/service/src/service/tap_receipt_header.rs index 814b2c93..a1dc4536 100644 --- a/crates/service/src/service/tap_receipt_header.rs +++ b/crates/service/src/service/tap_receipt_header.rs @@ -4,10 +4,81 @@ use axum_extra::headers::{self, Header, HeaderName, HeaderValue}; use lazy_static::lazy_static; use prometheus::{register_counter, Counter}; -use tap_core::receipt::SignedReceipt; +use serde::de; +use serde_json::Value; +use tap_core::receipt::SignedReceipt as SignedReceiptV1; +use tap_core_v2::receipt::SignedReceipt as SignedReceiptV2; -#[derive(Debug, PartialEq)] -pub struct TapReceipt(pub SignedReceipt); +#[derive(Debug, PartialEq, Clone, serde::Serialize)] +#[serde(untagged)] +pub enum TapReceipt { + V1(SignedReceiptV1), + V2(SignedReceiptV2), +} + +impl<'de> serde::Deserialize<'de> for TapReceipt { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + let temp = Value::deserialize(deserializer)?; + + let is_v1 = temp + .as_object() + .ok_or(de::Error::custom("Didn't receive an object"))? + .get("message") + .ok_or(de::Error::custom("There's no message in the object"))? + .as_object() + .ok_or(de::Error::custom("Message is not an object"))? + .contains_key("allocation_id"); + + if is_v1 { + // Try V1 first + serde_json::from_value::(temp) + .map(TapReceipt::V1) + .map_err(de::Error::custom) + } else { + // Fall back to V2 + serde_json::from_value::(temp) + .map(TapReceipt::V2) + .map_err(de::Error::custom) + } + } +} + +impl From for TapReceipt { + fn from(value: SignedReceiptV1) -> Self { + Self::V1(value) + } +} + +impl From for TapReceipt { + fn from(value: SignedReceiptV2) -> Self { + Self::V2(value) + } +} + +impl TryFrom for SignedReceiptV1 { + type Error = anyhow::Error; + + fn try_from(value: TapReceipt) -> Result { + match value { + TapReceipt::V2(_) => Err(anyhow::anyhow!("TapReceipt is V2")), + TapReceipt::V1(receipt) => Ok(receipt), + } + } +} + +impl TryFrom for SignedReceiptV2 { + type Error = anyhow::Error; + + fn try_from(value: TapReceipt) -> Result { + match value { + TapReceipt::V1(_) => Err(anyhow::anyhow!("TapReceipt is V1")), + TapReceipt::V2(receipt) => Ok(receipt), + } + } +} lazy_static! { static ref TAP_RECEIPT: HeaderName = HeaderName::from_static("tap-receipt"); @@ -30,9 +101,9 @@ impl Header for TapReceipt { let raw_receipt = raw_receipt .to_str() .map_err(|_| headers::Error::invalid())?; - let parsed_receipt = + let parsed_receipt: TapReceipt = serde_json::from_str(raw_receipt).map_err(|_| headers::Error::invalid())?; - Ok(TapReceipt(parsed_receipt)) + Ok(parsed_receipt) }; execute().inspect_err(|_| TAP_RECEIPT_INVALID.inc()) } @@ -49,7 +120,10 @@ impl Header for TapReceipt { mod test { use axum::http::HeaderValue; use axum_extra::headers::Header; - use test_assets::{create_signed_receipt, SignedReceiptRequest}; + use test_assets::{ + create_signed_receipt, create_signed_receipt_v2, SignedReceiptRequest, + SignedReceiptV2Request, + }; use super::TapReceipt; @@ -57,12 +131,43 @@ mod test { async fn test_decode_valid_tap_receipt_header() { let original_receipt = create_signed_receipt(SignedReceiptRequest::builder().build()).await; let serialized_receipt = serde_json::to_string(&original_receipt).unwrap(); - let header_value = HeaderValue::from_str(&serialized_receipt).unwrap(); + + let original_receipt_v1: TapReceipt = original_receipt.clone().into(); + let serialized_receipt_v1 = serde_json::to_string(&original_receipt_v1).unwrap(); + + assert_eq!(serialized_receipt, serialized_receipt_v1); + + println!("Was able to serialize properly: {serialized_receipt_v1:?}"); + let deserialized: TapReceipt = serde_json::from_str(&serialized_receipt_v1).unwrap(); + println!("Was able to deserialize properly: {deserialized:?}"); + let header_value = HeaderValue::from_str(&serialized_receipt_v1).unwrap(); + let header_values = vec![&header_value]; + let decoded_receipt = TapReceipt::decode(&mut header_values.into_iter()) + .expect("tap receipt header value should be valid"); + + assert_eq!(decoded_receipt, original_receipt.into()); + } + + #[tokio::test] + async fn test_decode_valid_tap_v2_receipt_header() { + let original_receipt = + create_signed_receipt_v2(SignedReceiptV2Request::builder().build()).await; + let serialized_receipt = serde_json::to_string(&original_receipt).unwrap(); + + let original_receipt_v1: TapReceipt = original_receipt.clone().into(); + let serialized_receipt_v1 = serde_json::to_string(&original_receipt_v1).unwrap(); + + assert_eq!(serialized_receipt, serialized_receipt_v1); + + println!("Was able to serialize properly: {serialized_receipt_v1:?}"); + let deserialized: TapReceipt = serde_json::from_str(&serialized_receipt_v1).unwrap(); + println!("Was able to deserialize properly: {deserialized:?}"); + let header_value = HeaderValue::from_str(&serialized_receipt_v1).unwrap(); let header_values = vec![&header_value]; let decoded_receipt = TapReceipt::decode(&mut header_values.into_iter()) .expect("tap receipt header value should be valid"); - assert_eq!(decoded_receipt, TapReceipt(original_receipt)); + assert_eq!(decoded_receipt, original_receipt.into()); } #[test] diff --git a/crates/tap-agent/src/agent/sender_allocation.rs b/crates/tap-agent/src/agent/sender_allocation.rs index decb5c4c..cfac334e 100644 --- a/crates/tap-agent/src/agent/sender_allocation.rs +++ b/crates/tap-agent/src/agent/sender_allocation.rs @@ -1258,8 +1258,7 @@ pub mod tests { )); // Stop the TAP aggregator server. - handle.stop().unwrap(); - handle.stopped().await; + handle.abort(); } #[sqlx::test(migrations = "../../migrations")] diff --git a/crates/test-assets/Cargo.toml b/crates/test-assets/Cargo.toml index 568c14b9..c0ecc1c3 100644 --- a/crates/test-assets/Cargo.toml +++ b/crates/test-assets/Cargo.toml @@ -8,6 +8,7 @@ indexer-allocation = { path = "../allocation" } bip39 = "2.0.0" lazy_static.workspace = true tap_core.workspace = true +tap_core_v2.workspace = true thegraph-core.workspace = true typed-builder.workspace = true tokio.workspace = true diff --git a/crates/test-assets/src/lib.rs b/crates/test-assets/src/lib.rs index a475d3fa..9f3a5fb0 100644 --- a/crates/test-assets/src/lib.rs +++ b/crates/test-assets/src/lib.rs @@ -15,6 +15,12 @@ use tap_core::{ signed_message::EIP712SignedMessage, tap_eip712_domain, }; + +use tap_core_v2::{ + receipt::{Receipt as ReceiptV2, SignedReceipt as SignedReceiptV2}, + signed_message::EIP712SignedMessage as EIP712SignedMessageV2, + // tap_eip712_domain as tap_eip712_domain_v2, +}; use thegraph_core::{ alloy::{ primitives::{address, Address, U256}, @@ -353,6 +359,53 @@ pub async fn create_signed_receipt( .unwrap() } +#[derive(TypedBuilder)] +pub struct SignedReceiptV2Request { + #[builder(default = Address::ZERO)] + payer: Address, + #[builder(default = Address::ZERO)] + data_service: Address, + #[builder(default = Address::ZERO)] + service_provider: Address, + #[builder(default)] + nonce: u64, + #[builder(default_code = r#"SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap() + .as_nanos() as u64"#)] + timestamp_ns: u64, + #[builder(default = 1)] + value: u128, +} + +pub async fn create_signed_receipt_v2( + SignedReceiptV2Request { + payer, + data_service, + service_provider, + nonce, + timestamp_ns, + value, + }: SignedReceiptV2Request, +) -> SignedReceiptV2 { + let (wallet, _) = &*self::TAP_SIGNER; + + EIP712SignedMessageV2::new( + &self::TAP_EIP712_DOMAIN, + ReceiptV2 { + payer, + data_service, + service_provider, + nonce, + timestamp_ns, + value, + }, + wallet, + ) + .unwrap() +} + + pub async fn flush_messages(notify: &Notify) { loop { if tokio::time::timeout(Duration::from_millis(10), notify.notified())