diff --git a/Cargo.lock b/Cargo.lock index 031e1b139..9862a107e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1896,10 +1896,13 @@ dependencies = [ name = "trace_decoder" version = "0.3.1" dependencies = [ + "anyhow", "bitflags 2.5.0", + "bitvec", "bytes", "ciborium", "ciborium-io", + "either", "enum-as-inner", "enumn", "ethereum-types", diff --git a/trace_decoder/Cargo.toml b/trace_decoder/Cargo.toml index c8016d25b..40f5231bd 100644 --- a/trace_decoder/Cargo.toml +++ b/trace_decoder/Cargo.toml @@ -30,6 +30,9 @@ evm_arithmetization_type_1.workspace = true winnow = "0.6.11" bitflags = "2.5.0" nunny = { version = "0.2.1", features = ["serde"] } +either = "1.12.0" +anyhow = "1.0.86" +bitvec = "1.0.1" [dev-dependencies] hex = { workspace = true, features = ["serde"] } diff --git a/trace_decoder/src/lib.rs b/trace_decoder/src/lib.rs index 04bc6aeac..10eaf9de6 100644 --- a/trace_decoder/src/lib.rs +++ b/trace_decoder/src/lib.rs @@ -142,5 +142,7 @@ pub fn type_1( } mod type1 { + pub use witness::{Instruction, V1Header, Witness}; mod witness; + mod witness2forest; } diff --git a/trace_decoder/src/type1/snapshots/trace_decoder__type1__witness__witness_test_vectors-2.snap b/trace_decoder/src/type1/snapshots/trace_decoder__type1__witness__witness_test_vectors-2.snap index 164c1557c..e596ee145 100644 --- a/trace_decoder/src/type1/snapshots/trace_decoder__type1__witness__witness_test_vectors-2.snap +++ b/trace_decoder/src/type1/snapshots/trace_decoder__type1__witness__witness_test_vectors-2.snap @@ -1,458 +1,456 @@ --- source: trace_decoder/src/type1/witness.rs -expression: "witness::(&mut &*vector.bytes)" +expression: "witness::.parse(&*vector.bytes).unwrap()" --- -Ok( - Witness { - header: V1Header, - instructions: NonEmpty { - inner: [ - AccountLeaf { - key: NonEmpty { - inner: [ - 3, - 54, - 1, - 70, - 32, - 147, - 181, - 148, - 93, - 22, - 118, - 223, - 9, - 52, - 70, - 121, - 15, - 211, - 27, - 32, - 231, - 177, - 42, - 46, - 142, - 94, - 9, - 208, - 104, - 16, - 150, - 22, - 176, - ], - }, - nonce: None, - balance: Some( - 10000000000000000000000, - ), - has_code: false, - has_storage: false, - }, - AccountLeaf { - key: NonEmpty { - inner: [ - 3, - 70, - 130, - 136, - 5, - 99, - 16, - 200, - 42, - 164, - 192, - 26, - 126, - 18, - 161, - 15, - 129, - 17, - 160, - 86, - 14, - 114, - 183, - 0, - 85, - 84, - 121, - 3, - 27, - 134, - 195, - 87, - 208, - ], - }, - nonce: None, - balance: Some( +Witness { + header: V1Header, + instructions: NonEmpty { + inner: [ + AccountLeaf { + key: NonEmpty { + inner: [ + 3, + 54, 1, - ), - has_code: false, - has_storage: false, + 70, + 32, + 147, + 181, + 148, + 93, + 22, + 118, + 223, + 9, + 52, + 70, + 121, + 15, + 211, + 27, + 32, + 231, + 177, + 42, + 46, + 142, + 94, + 9, + 208, + 104, + 16, + 150, + 22, + 176, + ], }, - Hash { - raw_hash: [ + nonce: None, + balance: Some( + 10000000000000000000000, + ), + has_code: false, + has_storage: false, + }, + AccountLeaf { + key: NonEmpty { + inner: [ + 3, + 70, + 130, + 136, + 5, + 99, + 16, + 200, + 42, + 164, + 192, 26, - 105, 126, + 18, + 161, + 15, 129, - 71, - 88, - 40, - 25, + 17, + 160, + 86, + 14, 114, - 252, - 209, - 59, - 201, - 112, - 125, - 188, - 210, - 241, - 149, - 152, - 107, - 5, - 70, - 61, - 123, - 120, - 66, - 101, - 8, - 68, - 90, - 4, + 183, + 0, + 85, + 84, + 121, + 3, + 27, + 134, + 195, + 87, + 208, ], }, - AccountLeaf { - key: NonEmpty { - inner: [ - 3, - 183, - 14, - 128, - 83, - 138, - 205, - 171, - 214, - 19, - 115, - 83, - 176, - 249, - 216, - 209, - 73, - 244, - 219, - 169, - 30, - 139, - 226, - 231, - 148, - 110, - 64, - 155, - 253, - 190, - 104, - 91, - 144, - ], - }, - nonce: None, - balance: Some( - 1, - ), - has_code: false, - has_storage: false, - }, - AccountLeaf { - key: NonEmpty { - inner: [ - 3, - 137, - 128, - 45, - 110, - 209, - 162, - 139, - 4, - 158, - 157, - 79, - 229, - 51, - 76, - 89, - 2, - 253, - 155, - 192, - 12, - 66, - 130, - 28, - 130, - 248, - 46, - 226, - 218, - 16, - 190, - 144, - 128, - ], - }, - nonce: None, - balance: Some( - 1, - ), - has_code: false, - has_storage: false, - }, - AccountLeaf { - key: NonEmpty { - inner: [ - 2, - 86, - 39, - 74, - 39, - 221, - 117, - 36, - 149, - 84, - 23, - 193, - 30, - 205, - 145, - 114, - 81, - 204, - 124, - 76, - 131, - 16, - 244, - 199, - 228, - 189, - 60, - 48, - 77, - 61, - 154, - 121, - ], - }, - nonce: None, - balance: Some( - 10000000000000000000000, - ), - has_code: false, - has_storage: false, + nonce: None, + balance: Some( + 1, + ), + has_code: false, + has_storage: false, + }, + Hash { + raw_hash: [ + 26, + 105, + 126, + 129, + 71, + 88, + 40, + 25, + 114, + 252, + 209, + 59, + 201, + 112, + 125, + 188, + 210, + 241, + 149, + 152, + 107, + 5, + 70, + 61, + 123, + 120, + 66, + 101, + 8, + 68, + 90, + 4, + ], + }, + AccountLeaf { + key: NonEmpty { + inner: [ + 3, + 183, + 14, + 128, + 83, + 138, + 205, + 171, + 214, + 19, + 115, + 83, + 176, + 249, + 216, + 209, + 73, + 244, + 219, + 169, + 30, + 139, + 226, + 231, + 148, + 110, + 64, + 155, + 253, + 190, + 104, + 91, + 144, + ], }, - AccountLeaf { - key: NonEmpty { - inner: [ - 2, - 58, - 176, - 151, - 11, - 115, - 137, - 91, - 140, - 153, - 89, - 186, - 230, - 133, - 195, - 161, - 159, - 69, - 235, - 90, - 216, - 157, - 66, - 181, - 42, - 52, - 14, - 196, - 172, - 32, - 77, - 25, - ], - }, - nonce: None, - balance: Some( - 1, - ), - has_code: false, - has_storage: false, + nonce: None, + balance: Some( + 1, + ), + has_code: false, + has_storage: false, + }, + AccountLeaf { + key: NonEmpty { + inner: [ + 3, + 137, + 128, + 45, + 110, + 209, + 162, + 139, + 4, + 158, + 157, + 79, + 229, + 51, + 76, + 89, + 2, + 253, + 155, + 192, + 12, + 66, + 130, + 28, + 130, + 248, + 46, + 226, + 218, + 16, + 190, + 144, + 128, + ], }, - Branch { - mask: 4128, + nonce: None, + balance: Some( + 1, + ), + has_code: false, + has_storage: false, + }, + AccountLeaf { + key: NonEmpty { + inner: [ + 2, + 86, + 39, + 74, + 39, + 221, + 117, + 36, + 149, + 84, + 23, + 193, + 30, + 205, + 145, + 114, + 81, + 204, + 124, + 76, + 131, + 16, + 244, + 199, + 228, + 189, + 60, + 48, + 77, + 61, + 154, + 121, + ], }, - AccountLeaf { - key: NonEmpty { - inner: [ - 3, - 135, - 109, - 165, - 24, - 163, - 147, - 219, - 208, - 103, - 220, - 114, - 171, - 250, - 8, - 212, - 117, - 237, - 100, - 71, - 252, - 169, - 109, - 146, - 236, - 63, - 158, - 126, - 186, - 80, - 60, - 166, - 16, - ], - }, - nonce: None, - balance: Some( - 1, - ), - has_code: false, - has_storage: false, + nonce: None, + balance: Some( + 10000000000000000000000, + ), + has_code: false, + has_storage: false, + }, + AccountLeaf { + key: NonEmpty { + inner: [ + 2, + 58, + 176, + 151, + 11, + 115, + 137, + 91, + 140, + 153, + 89, + 186, + 230, + 133, + 195, + 161, + 159, + 69, + 235, + 90, + 216, + 157, + 66, + 181, + 42, + 52, + 14, + 196, + 172, + 32, + 77, + 25, + ], }, - AccountLeaf { - key: NonEmpty { - inner: [ - 3, - 82, - 104, - 138, - 143, - 146, - 108, - 129, - 108, - 161, - 224, - 121, - 6, - 124, - 171, - 169, - 68, - 241, - 88, - 231, - 100, - 129, - 123, - 131, - 252, - 67, - 89, - 67, - 112, - 202, - 156, - 246, - 32, - ], - }, - nonce: None, - balance: Some( - 1, - ), - has_code: false, - has_storage: false, + nonce: None, + balance: Some( + 1, + ), + has_code: false, + has_storage: false, + }, + Branch { + mask: 4128, + }, + AccountLeaf { + key: NonEmpty { + inner: [ + 3, + 135, + 109, + 165, + 24, + 163, + 147, + 219, + 208, + 103, + 220, + 114, + 171, + 250, + 8, + 212, + 117, + 237, + 100, + 71, + 252, + 169, + 109, + 146, + 236, + 63, + 158, + 126, + 186, + 80, + 60, + 166, + 16, + ], }, - AccountLeaf { - key: NonEmpty { - inner: [ - 3, - 105, - 11, - 35, - 155, - 163, - 170, - 249, - 147, - 228, - 67, - 174, - 20, - 174, - 255, - 196, - 76, - 248, - 217, - 147, - 26, - 121, - 186, - 237, - 159, - 161, - 65, - 208, - 228, - 80, - 110, - 19, - 16, - ], - }, - nonce: None, - balance: Some( - 1, - ), - has_code: false, - has_storage: false, + nonce: None, + balance: Some( + 1, + ), + has_code: false, + has_storage: false, + }, + AccountLeaf { + key: NonEmpty { + inner: [ + 3, + 82, + 104, + 138, + 143, + 146, + 108, + 129, + 108, + 161, + 224, + 121, + 6, + 124, + 171, + 169, + 68, + 241, + 88, + 231, + 100, + 129, + 123, + 131, + 252, + 67, + 89, + 67, + 112, + 202, + 156, + 246, + 32, + ], }, - Branch { - mask: 25971, + nonce: None, + balance: Some( + 1, + ), + has_code: false, + has_storage: false, + }, + AccountLeaf { + key: NonEmpty { + inner: [ + 3, + 105, + 11, + 35, + 155, + 163, + 170, + 249, + 147, + 228, + 67, + 174, + 20, + 174, + 255, + 196, + 76, + 248, + 217, + 147, + 26, + 121, + 186, + 237, + 159, + 161, + 65, + 208, + 228, + 80, + 110, + 19, + 16, + ], }, - ], - }, + nonce: None, + balance: Some( + 1, + ), + has_code: false, + has_storage: false, + }, + Branch { + mask: 25971, + }, + ], }, -) +} diff --git a/trace_decoder/src/type1/snapshots/trace_decoder__type1__witness__witness_test_vectors-3.snap b/trace_decoder/src/type1/snapshots/trace_decoder__type1__witness__witness_test_vectors-3.snap index c1c744acf..f6b88ae42 100644 --- a/trace_decoder/src/type1/snapshots/trace_decoder__type1__witness__witness_test_vectors-3.snap +++ b/trace_decoder/src/type1/snapshots/trace_decoder__type1__witness__witness_test_vectors-3.snap @@ -1,506 +1,504 @@ --- source: trace_decoder/src/type1/witness.rs -expression: "witness::(&mut &*vector.bytes)" +expression: "witness::.parse(&*vector.bytes).unwrap()" --- -Ok( - Witness { - header: V1Header, - instructions: NonEmpty { - inner: [ - AccountLeaf { - key: NonEmpty { - inner: [ - 3, - 54, - 1, - 70, - 32, - 147, - 181, - 148, - 93, - 22, - 118, - 223, - 9, - 52, - 70, - 121, - 15, - 211, - 27, - 32, - 231, - 177, - 42, - 46, - 142, - 94, - 9, - 208, - 104, - 16, - 150, - 22, - 176, - ], - }, - nonce: None, - balance: Some( - 10000000000000000000000, - ), - has_code: false, - has_storage: false, - }, - AccountLeaf { - key: NonEmpty { - inner: [ - 3, - 70, - 130, - 136, - 5, - 99, - 16, - 200, - 42, - 164, - 192, - 26, - 126, - 18, - 161, - 15, - 129, - 17, - 160, - 86, - 14, - 114, - 183, - 0, - 85, - 84, - 121, - 3, - 27, - 134, - 195, - 87, - 208, - ], - }, - nonce: None, - balance: Some( +Witness { + header: V1Header, + instructions: NonEmpty { + inner: [ + AccountLeaf { + key: NonEmpty { + inner: [ + 3, + 54, 1, - ), - has_code: false, - has_storage: false, + 70, + 32, + 147, + 181, + 148, + 93, + 22, + 118, + 223, + 9, + 52, + 70, + 121, + 15, + 211, + 27, + 32, + 231, + 177, + 42, + 46, + 142, + 94, + 9, + 208, + 104, + 16, + 150, + 22, + 176, + ], }, - Hash { - raw_hash: [ + nonce: None, + balance: Some( + 10000000000000000000000, + ), + has_code: false, + has_storage: false, + }, + AccountLeaf { + key: NonEmpty { + inner: [ + 3, + 70, + 130, + 136, + 5, + 99, + 16, + 200, + 42, + 164, + 192, 26, - 105, 126, + 18, + 161, + 15, 129, - 71, - 88, - 40, - 25, + 17, + 160, + 86, + 14, 114, - 252, - 209, - 59, - 201, - 112, - 125, - 188, - 210, - 241, - 149, - 152, - 107, - 5, - 70, - 61, - 123, - 120, - 66, - 101, - 8, - 68, - 90, - 4, + 183, + 0, + 85, + 84, + 121, + 3, + 27, + 134, + 195, + 87, + 208, ], }, - AccountLeaf { - key: NonEmpty { - inner: [ - 3, - 183, - 14, - 128, - 83, - 138, - 205, - 171, - 214, - 19, - 115, - 83, - 176, - 249, - 216, - 209, - 73, - 244, - 219, - 169, - 30, - 139, - 226, - 231, - 148, - 110, - 64, - 155, - 253, - 190, - 104, - 91, - 144, - ], - }, - nonce: None, - balance: Some( - 1, - ), - has_code: false, - has_storage: false, - }, - AccountLeaf { - key: NonEmpty { - inner: [ - 3, - 137, - 128, - 45, - 110, - 209, - 162, - 139, - 4, - 158, - 157, - 79, - 229, - 51, - 76, - 89, - 2, - 253, - 155, - 192, - 12, - 66, - 130, - 28, - 130, - 248, - 46, - 226, - 218, - 16, - 190, - 144, - 128, - ], - }, - nonce: None, - balance: Some( - 1, - ), - has_code: false, - has_storage: false, - }, - AccountLeaf { - key: NonEmpty { - inner: [ - 2, - 86, - 39, - 74, - 39, - 221, - 117, - 36, - 149, - 84, - 23, - 193, - 30, - 205, - 145, - 114, - 81, - 204, - 124, - 76, - 131, - 16, - 244, - 199, - 228, - 189, - 60, - 48, - 77, - 61, - 154, - 121, - ], - }, - nonce: Some( - 1, - ), - balance: Some( - 9998999981625000000000, - ), - has_code: false, - has_storage: false, - }, - AccountLeaf { - key: NonEmpty { - inner: [ - 2, - 58, - 176, - 151, - 11, - 115, - 137, - 91, - 140, - 153, - 89, - 186, - 230, - 133, - 195, - 161, - 159, - 69, - 235, - 90, - 216, - 157, - 66, - 181, - 42, - 52, - 14, - 196, - 172, - 32, - 77, - 25, - ], - }, - nonce: None, - balance: Some( - 1, - ), - has_code: false, - has_storage: false, + nonce: None, + balance: Some( + 1, + ), + has_code: false, + has_storage: false, + }, + Hash { + raw_hash: [ + 26, + 105, + 126, + 129, + 71, + 88, + 40, + 25, + 114, + 252, + 209, + 59, + 201, + 112, + 125, + 188, + 210, + 241, + 149, + 152, + 107, + 5, + 70, + 61, + 123, + 120, + 66, + 101, + 8, + 68, + 90, + 4, + ], + }, + AccountLeaf { + key: NonEmpty { + inner: [ + 3, + 183, + 14, + 128, + 83, + 138, + 205, + 171, + 214, + 19, + 115, + 83, + 176, + 249, + 216, + 209, + 73, + 244, + 219, + 169, + 30, + 139, + 226, + 231, + 148, + 110, + 64, + 155, + 253, + 190, + 104, + 91, + 144, + ], }, - Branch { - mask: 4128, + nonce: None, + balance: Some( + 1, + ), + has_code: false, + has_storage: false, + }, + AccountLeaf { + key: NonEmpty { + inner: [ + 3, + 137, + 128, + 45, + 110, + 209, + 162, + 139, + 4, + 158, + 157, + 79, + 229, + 51, + 76, + 89, + 2, + 253, + 155, + 192, + 12, + 66, + 130, + 28, + 130, + 248, + 46, + 226, + 218, + 16, + 190, + 144, + 128, + ], }, - AccountLeaf { - key: NonEmpty { - inner: [ - 2, - 30, - 236, - 43, - 132, - 240, - 186, - 52, - 79, - 212, - 180, - 210, - 240, - 34, - 70, - 159, - 235, - 231, - 167, - 114, - 196, - 120, - 154, - 207, - 193, - 25, - 235, - 85, - 138, - 177, - 218, - 61, - ], - }, - nonce: None, - balance: Some( - 1000000000000000000, - ), - has_code: false, - has_storage: false, + nonce: None, + balance: Some( + 1, + ), + has_code: false, + has_storage: false, + }, + AccountLeaf { + key: NonEmpty { + inner: [ + 2, + 86, + 39, + 74, + 39, + 221, + 117, + 36, + 149, + 84, + 23, + 193, + 30, + 205, + 145, + 114, + 81, + 204, + 124, + 76, + 131, + 16, + 244, + 199, + 228, + 189, + 60, + 48, + 77, + 61, + 154, + 121, + ], }, - AccountLeaf { - key: NonEmpty { - inner: [ - 2, - 118, - 218, - 81, - 138, - 57, - 61, - 189, - 6, - 125, - 199, - 42, - 191, - 160, - 141, - 71, - 94, - 214, - 68, - 127, - 202, - 150, - 217, - 46, - 195, - 249, - 231, - 235, - 165, - 3, - 202, - 97, - ], - }, - nonce: None, - balance: Some( - 1, - ), - has_code: false, - has_storage: false, + nonce: Some( + 1, + ), + balance: Some( + 9998999981625000000000, + ), + has_code: false, + has_storage: false, + }, + AccountLeaf { + key: NonEmpty { + inner: [ + 2, + 58, + 176, + 151, + 11, + 115, + 137, + 91, + 140, + 153, + 89, + 186, + 230, + 133, + 195, + 161, + 159, + 69, + 235, + 90, + 216, + 157, + 66, + 181, + 42, + 52, + 14, + 196, + 172, + 32, + 77, + 25, + ], }, - Branch { - mask: 288, + nonce: None, + balance: Some( + 1, + ), + has_code: false, + has_storage: false, + }, + Branch { + mask: 4128, + }, + AccountLeaf { + key: NonEmpty { + inner: [ + 2, + 30, + 236, + 43, + 132, + 240, + 186, + 52, + 79, + 212, + 180, + 210, + 240, + 34, + 70, + 159, + 235, + 231, + 167, + 114, + 196, + 120, + 154, + 207, + 193, + 25, + 235, + 85, + 138, + 177, + 218, + 61, + ], }, - AccountLeaf { - key: NonEmpty { - inner: [ - 3, - 82, - 104, - 138, - 143, - 146, - 108, - 129, - 108, - 161, - 224, - 121, - 6, - 124, - 171, - 169, - 68, - 241, - 88, - 231, - 100, - 129, - 123, - 131, - 252, - 67, - 89, - 67, - 112, - 202, - 156, - 246, - 32, - ], - }, - nonce: None, - balance: Some( - 1, - ), - has_code: false, - has_storage: false, + nonce: None, + balance: Some( + 1000000000000000000, + ), + has_code: false, + has_storage: false, + }, + AccountLeaf { + key: NonEmpty { + inner: [ + 2, + 118, + 218, + 81, + 138, + 57, + 61, + 189, + 6, + 125, + 199, + 42, + 191, + 160, + 141, + 71, + 94, + 214, + 68, + 127, + 202, + 150, + 217, + 46, + 195, + 249, + 231, + 235, + 165, + 3, + 202, + 97, + ], }, - AccountLeaf { - key: NonEmpty { - inner: [ - 3, - 105, - 11, - 35, - 155, - 163, - 170, - 249, - 147, - 228, - 67, - 174, - 20, - 174, - 255, - 196, - 76, - 248, - 217, - 147, - 26, - 121, - 186, - 237, - 159, - 161, - 65, - 208, - 228, - 80, - 110, - 19, - 16, - ], - }, - nonce: None, - balance: Some( - 1, - ), - has_code: false, - has_storage: false, + nonce: None, + balance: Some( + 1, + ), + has_code: false, + has_storage: false, + }, + Branch { + mask: 288, + }, + AccountLeaf { + key: NonEmpty { + inner: [ + 3, + 82, + 104, + 138, + 143, + 146, + 108, + 129, + 108, + 161, + 224, + 121, + 6, + 124, + 171, + 169, + 68, + 241, + 88, + 231, + 100, + 129, + 123, + 131, + 252, + 67, + 89, + 67, + 112, + 202, + 156, + 246, + 32, + ], }, - Branch { - mask: 25971, + nonce: None, + balance: Some( + 1, + ), + has_code: false, + has_storage: false, + }, + AccountLeaf { + key: NonEmpty { + inner: [ + 3, + 105, + 11, + 35, + 155, + 163, + 170, + 249, + 147, + 228, + 67, + 174, + 20, + 174, + 255, + 196, + 76, + 248, + 217, + 147, + 26, + 121, + 186, + 237, + 159, + 161, + 65, + 208, + 228, + 80, + 110, + 19, + 16, + ], }, - ], - }, + nonce: None, + balance: Some( + 1, + ), + has_code: false, + has_storage: false, + }, + Branch { + mask: 25971, + }, + ], }, -) +} diff --git a/trace_decoder/src/type1/snapshots/trace_decoder__type1__witness__witness_test_vectors-4.snap b/trace_decoder/src/type1/snapshots/trace_decoder__type1__witness__witness_test_vectors-4.snap index aa55faade..91e21c277 100644 --- a/trace_decoder/src/type1/snapshots/trace_decoder__type1__witness__witness_test_vectors-4.snap +++ b/trace_decoder/src/type1/snapshots/trace_decoder__type1__witness__witness_test_vectors-4.snap @@ -1,506 +1,504 @@ --- source: trace_decoder/src/type1/witness.rs -expression: "witness::(&mut &*vector.bytes)" +expression: "witness::.parse(&*vector.bytes).unwrap()" --- -Ok( - Witness { - header: V1Header, - instructions: NonEmpty { - inner: [ - AccountLeaf { - key: NonEmpty { - inner: [ - 3, - 54, - 1, - 70, - 32, - 147, - 181, - 148, - 93, - 22, - 118, - 223, - 9, - 52, - 70, - 121, - 15, - 211, - 27, - 32, - 231, - 177, - 42, - 46, - 142, - 94, - 9, - 208, - 104, - 16, - 150, - 22, - 176, - ], - }, - nonce: None, - balance: Some( - 10000000000000000000000, - ), - has_code: false, - has_storage: false, - }, - AccountLeaf { - key: NonEmpty { - inner: [ - 3, - 70, - 130, - 136, - 5, - 99, - 16, - 200, - 42, - 164, - 192, - 26, - 126, - 18, - 161, - 15, - 129, - 17, - 160, - 86, - 14, - 114, - 183, - 0, - 85, - 84, - 121, - 3, - 27, - 134, - 195, - 87, - 208, - ], - }, - nonce: None, - balance: Some( +Witness { + header: V1Header, + instructions: NonEmpty { + inner: [ + AccountLeaf { + key: NonEmpty { + inner: [ + 3, + 54, 1, - ), - has_code: false, - has_storage: false, + 70, + 32, + 147, + 181, + 148, + 93, + 22, + 118, + 223, + 9, + 52, + 70, + 121, + 15, + 211, + 27, + 32, + 231, + 177, + 42, + 46, + 142, + 94, + 9, + 208, + 104, + 16, + 150, + 22, + 176, + ], }, - Hash { - raw_hash: [ + nonce: None, + balance: Some( + 10000000000000000000000, + ), + has_code: false, + has_storage: false, + }, + AccountLeaf { + key: NonEmpty { + inner: [ + 3, + 70, + 130, + 136, + 5, + 99, + 16, + 200, + 42, + 164, + 192, 26, - 105, 126, + 18, + 161, + 15, 129, - 71, - 88, - 40, - 25, + 17, + 160, + 86, + 14, 114, - 252, - 209, - 59, - 201, - 112, - 125, - 188, - 210, - 241, - 149, - 152, - 107, - 5, - 70, - 61, - 123, - 120, - 66, - 101, - 8, - 68, - 90, - 4, + 183, + 0, + 85, + 84, + 121, + 3, + 27, + 134, + 195, + 87, + 208, ], }, - AccountLeaf { - key: NonEmpty { - inner: [ - 3, - 183, - 14, - 128, - 83, - 138, - 205, - 171, - 214, - 19, - 115, - 83, - 176, - 249, - 216, - 209, - 73, - 244, - 219, - 169, - 30, - 139, - 226, - 231, - 148, - 110, - 64, - 155, - 253, - 190, - 104, - 91, - 144, - ], - }, - nonce: None, - balance: Some( - 1, - ), - has_code: false, - has_storage: false, - }, - AccountLeaf { - key: NonEmpty { - inner: [ - 3, - 137, - 128, - 45, - 110, - 209, - 162, - 139, - 4, - 158, - 157, - 79, - 229, - 51, - 76, - 89, - 2, - 253, - 155, - 192, - 12, - 66, - 130, - 28, - 130, - 248, - 46, - 226, - 218, - 16, - 190, - 144, - 128, - ], - }, - nonce: None, - balance: Some( - 1, - ), - has_code: false, - has_storage: false, + nonce: None, + balance: Some( + 1, + ), + has_code: false, + has_storage: false, + }, + Hash { + raw_hash: [ + 26, + 105, + 126, + 129, + 71, + 88, + 40, + 25, + 114, + 252, + 209, + 59, + 201, + 112, + 125, + 188, + 210, + 241, + 149, + 152, + 107, + 5, + 70, + 61, + 123, + 120, + 66, + 101, + 8, + 68, + 90, + 4, + ], + }, + AccountLeaf { + key: NonEmpty { + inner: [ + 3, + 183, + 14, + 128, + 83, + 138, + 205, + 171, + 214, + 19, + 115, + 83, + 176, + 249, + 216, + 209, + 73, + 244, + 219, + 169, + 30, + 139, + 226, + 231, + 148, + 110, + 64, + 155, + 253, + 190, + 104, + 91, + 144, + ], }, - AccountLeaf { - key: NonEmpty { - inner: [ - 2, - 86, - 39, - 74, - 39, - 221, - 117, - 36, - 149, - 84, - 23, - 193, - 30, - 205, - 145, - 114, - 81, - 204, - 124, - 76, - 131, - 16, - 244, - 199, - 228, - 189, - 60, - 48, - 77, - 61, - 154, - 121, - ], - }, - nonce: Some( + nonce: None, + balance: Some( + 1, + ), + has_code: false, + has_storage: false, + }, + AccountLeaf { + key: NonEmpty { + inner: [ + 3, + 137, + 128, + 45, + 110, + 209, + 162, + 139, + 4, + 158, + 157, + 79, + 229, + 51, + 76, + 89, 2, - ), - balance: Some( - 9998899965538478213000, - ), - has_code: false, - has_storage: false, - }, - AccountLeaf { - key: NonEmpty { - inner: [ - 2, - 58, - 176, - 151, - 11, - 115, - 137, - 91, - 140, - 153, - 89, - 186, - 230, - 133, - 195, - 161, - 159, - 69, - 235, - 90, - 216, - 157, - 66, - 181, - 42, - 52, - 14, - 196, - 172, - 32, - 77, - 25, - ], - }, - nonce: None, - balance: Some( - 1, - ), - has_code: false, - has_storage: false, - }, - Branch { - mask: 4128, + 253, + 155, + 192, + 12, + 66, + 130, + 28, + 130, + 248, + 46, + 226, + 218, + 16, + 190, + 144, + 128, + ], }, - AccountLeaf { - key: NonEmpty { - inner: [ - 2, - 30, - 236, - 43, - 132, - 240, - 186, - 52, - 79, - 212, - 180, - 210, - 240, - 34, - 70, - 159, - 235, - 231, - 167, - 114, - 196, - 120, - 154, - 207, - 193, - 25, - 235, - 85, - 138, - 177, - 218, - 61, - ], - }, - nonce: None, - balance: Some( - 1100000000000000000, - ), - has_code: false, - has_storage: false, + nonce: None, + balance: Some( + 1, + ), + has_code: false, + has_storage: false, + }, + AccountLeaf { + key: NonEmpty { + inner: [ + 2, + 86, + 39, + 74, + 39, + 221, + 117, + 36, + 149, + 84, + 23, + 193, + 30, + 205, + 145, + 114, + 81, + 204, + 124, + 76, + 131, + 16, + 244, + 199, + 228, + 189, + 60, + 48, + 77, + 61, + 154, + 121, + ], }, - AccountLeaf { - key: NonEmpty { - inner: [ - 2, - 118, - 218, - 81, - 138, - 57, - 61, - 189, - 6, - 125, - 199, - 42, - 191, - 160, - 141, - 71, - 94, - 214, - 68, - 127, - 202, - 150, - 217, - 46, - 195, - 249, - 231, - 235, - 165, - 3, - 202, - 97, - ], - }, - nonce: None, - balance: Some( - 1, - ), - has_code: false, - has_storage: false, + nonce: Some( + 2, + ), + balance: Some( + 9998899965538478213000, + ), + has_code: false, + has_storage: false, + }, + AccountLeaf { + key: NonEmpty { + inner: [ + 2, + 58, + 176, + 151, + 11, + 115, + 137, + 91, + 140, + 153, + 89, + 186, + 230, + 133, + 195, + 161, + 159, + 69, + 235, + 90, + 216, + 157, + 66, + 181, + 42, + 52, + 14, + 196, + 172, + 32, + 77, + 25, + ], }, - Branch { - mask: 288, + nonce: None, + balance: Some( + 1, + ), + has_code: false, + has_storage: false, + }, + Branch { + mask: 4128, + }, + AccountLeaf { + key: NonEmpty { + inner: [ + 2, + 30, + 236, + 43, + 132, + 240, + 186, + 52, + 79, + 212, + 180, + 210, + 240, + 34, + 70, + 159, + 235, + 231, + 167, + 114, + 196, + 120, + 154, + 207, + 193, + 25, + 235, + 85, + 138, + 177, + 218, + 61, + ], }, - AccountLeaf { - key: NonEmpty { - inner: [ - 3, - 82, - 104, - 138, - 143, - 146, - 108, - 129, - 108, - 161, - 224, - 121, - 6, - 124, - 171, - 169, - 68, - 241, - 88, - 231, - 100, - 129, - 123, - 131, - 252, - 67, - 89, - 67, - 112, - 202, - 156, - 246, - 32, - ], - }, - nonce: None, - balance: Some( - 1, - ), - has_code: false, - has_storage: false, + nonce: None, + balance: Some( + 1100000000000000000, + ), + has_code: false, + has_storage: false, + }, + AccountLeaf { + key: NonEmpty { + inner: [ + 2, + 118, + 218, + 81, + 138, + 57, + 61, + 189, + 6, + 125, + 199, + 42, + 191, + 160, + 141, + 71, + 94, + 214, + 68, + 127, + 202, + 150, + 217, + 46, + 195, + 249, + 231, + 235, + 165, + 3, + 202, + 97, + ], }, - AccountLeaf { - key: NonEmpty { - inner: [ - 3, - 105, - 11, - 35, - 155, - 163, - 170, - 249, - 147, - 228, - 67, - 174, - 20, - 174, - 255, - 196, - 76, - 248, - 217, - 147, - 26, - 121, - 186, - 237, - 159, - 161, - 65, - 208, - 228, - 80, - 110, - 19, - 16, - ], - }, - nonce: None, - balance: Some( - 1, - ), - has_code: false, - has_storage: false, + nonce: None, + balance: Some( + 1, + ), + has_code: false, + has_storage: false, + }, + Branch { + mask: 288, + }, + AccountLeaf { + key: NonEmpty { + inner: [ + 3, + 82, + 104, + 138, + 143, + 146, + 108, + 129, + 108, + 161, + 224, + 121, + 6, + 124, + 171, + 169, + 68, + 241, + 88, + 231, + 100, + 129, + 123, + 131, + 252, + 67, + 89, + 67, + 112, + 202, + 156, + 246, + 32, + ], }, - Branch { - mask: 25971, + nonce: None, + balance: Some( + 1, + ), + has_code: false, + has_storage: false, + }, + AccountLeaf { + key: NonEmpty { + inner: [ + 3, + 105, + 11, + 35, + 155, + 163, + 170, + 249, + 147, + 228, + 67, + 174, + 20, + 174, + 255, + 196, + 76, + 248, + 217, + 147, + 26, + 121, + 186, + 237, + 159, + 161, + 65, + 208, + 228, + 80, + 110, + 19, + 16, + ], }, - ], - }, + nonce: None, + balance: Some( + 1, + ), + has_code: false, + has_storage: false, + }, + Branch { + mask: 25971, + }, + ], }, -) +} diff --git a/trace_decoder/src/type1/snapshots/trace_decoder__type1__witness__witness_test_vectors-5.snap b/trace_decoder/src/type1/snapshots/trace_decoder__type1__witness__witness_test_vectors-5.snap index b4b20a278..517a955b8 100644 --- a/trace_decoder/src/type1/snapshots/trace_decoder__type1__witness__witness_test_vectors-5.snap +++ b/trace_decoder/src/type1/snapshots/trace_decoder__type1__witness__witness_test_vectors-5.snap @@ -1,19 +1,140 @@ --- source: trace_decoder/src/type1/witness.rs -expression: "witness::(&mut &*vector.bytes)" +assertion_line: 250 +expression: "witness::.parse(&*vector.bytes).unwrap()" --- -Err( - Backtrack( - ContextError { - context: [], - cause: Some( - Io( - Error { - kind: UnexpectedEof, - message: "failed to fill whole buffer", - }, +Witness { + header: V1Header, + instructions: NonEmpty { + inner: [ + Hash { + raw_hash: [ + 166, + 136, + 91, + 55, + 49, + 112, + 45, + 166, + 46, + 142, + 74, + 143, + 88, + 74, + 196, + 106, + 127, + 104, + 34, + 244, + 226, + 186, + 80, + 251, + 169, + 2, + 246, + 123, + 21, + 136, + 210, + 59, + ], + }, + Leaf { + key: NonEmpty { + inner: [ + 2, + 128, + 21, + 101, + 126, + 41, + 141, + 53, + 41, + 14, + 105, + 98, + 139, + 224, + 61, + 145, + 247, + 77, + 97, + 60, + 175, + 58, + 253, + 190, + 9, + 19, + 140, + 250, + 65, + 94, + 254, + 47, + 80, + ], + }, + value: NonEmpty { + inner: [ + 222, + 173, + 190, + 239, + ], + }, + }, + AccountLeaf { + key: NonEmpty { + inner: [ + 2, + 24, + 178, + 137, + 147, + 106, + 8, + 116, + 204, + 206, + 230, + 87, + 18, + 200, + 140, + 218, + 160, + 163, + 5, + 176, + 4, + 211, + 253, + 162, + 148, + 43, + 43, + 45, + 197, + 79, + 20, + 246, + 17, + ], + }, + nonce: None, + balance: Some( + 1000000000, ), - ), - }, - ), -) + has_code: true, + has_storage: true, + }, + ], + }, +} diff --git a/trace_decoder/src/type1/snapshots/trace_decoder__type1__witness__witness_test_vectors-6.snap b/trace_decoder/src/type1/snapshots/trace_decoder__type1__witness__witness_test_vectors-6.snap deleted file mode 100644 index b0e507b9f..000000000 --- a/trace_decoder/src/type1/snapshots/trace_decoder__type1__witness__witness_test_vectors-6.snap +++ /dev/null @@ -1,12 +0,0 @@ ---- -source: trace_decoder/src/type1/witness.rs -expression: "witness::(&mut &*vector.bytes)" ---- -Err( - Backtrack( - ContextError { - context: [], - cause: None, - }, - ), -) diff --git a/trace_decoder/src/type1/snapshots/trace_decoder__type1__witness__witness_test_vectors-7.snap b/trace_decoder/src/type1/snapshots/trace_decoder__type1__witness__witness_test_vectors-7.snap deleted file mode 100644 index b0e507b9f..000000000 --- a/trace_decoder/src/type1/snapshots/trace_decoder__type1__witness__witness_test_vectors-7.snap +++ /dev/null @@ -1,12 +0,0 @@ ---- -source: trace_decoder/src/type1/witness.rs -expression: "witness::(&mut &*vector.bytes)" ---- -Err( - Backtrack( - ContextError { - context: [], - cause: None, - }, - ), -) diff --git a/trace_decoder/src/type1/snapshots/trace_decoder__type1__witness__witness_test_vectors.snap b/trace_decoder/src/type1/snapshots/trace_decoder__type1__witness__witness_test_vectors.snap index 8b40ac831..7d66f2f4a 100644 --- a/trace_decoder/src/type1/snapshots/trace_decoder__type1__witness__witness_test_vectors.snap +++ b/trace_decoder/src/type1/snapshots/trace_decoder__type1__witness__witness_test_vectors.snap @@ -1,103 +1,101 @@ --- source: trace_decoder/src/type1/witness.rs -expression: "witness::(&mut &*vector.bytes)" +expression: "witness::.parse(&*vector.bytes).unwrap()" --- -Ok( - Witness { - header: V1Header, - instructions: NonEmpty { - inner: [ - Leaf { - key: NonEmpty { - inner: [ - 16, - ], - }, - value: NonEmpty { - inner: [ - 49, - 50, - 51, - 52, - ], - }, +Witness { + header: V1Header, + instructions: NonEmpty { + inner: [ + Leaf { + key: NonEmpty { + inner: [ + 16, + ], }, - Leaf { - key: NonEmpty { - inner: [ - 16, - ], - }, - value: NonEmpty { - inner: [ - 49, - 50, - 51, - 52, - ], - }, + value: NonEmpty { + inner: [ + 49, + 50, + 51, + 52, + ], }, - Branch { - mask: 48, + }, + Leaf { + key: NonEmpty { + inner: [ + 16, + ], }, - Leaf { - key: NonEmpty { - inner: [ - 3, - 80, - ], - }, - value: NonEmpty { - inner: [ - 49, - 50, - 51, - 53, - ], - }, + value: NonEmpty { + inner: [ + 49, + 50, + 51, + 52, + ], }, - Branch { - mask: 24, + }, + Branch { + mask: 48, + }, + Leaf { + key: NonEmpty { + inner: [ + 3, + 80, + ], }, - Extension { - key: NonEmpty { - inner: [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 18, - ], - }, + value: NonEmpty { + inner: [ + 49, + 50, + 51, + 53, + ], }, - ], - }, + }, + Branch { + mask: 24, + }, + Extension { + key: NonEmpty { + inner: [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 18, + ], + }, + }, + ], }, -) +} diff --git a/trace_decoder/src/type1/witness.rs b/trace_decoder/src/type1/witness.rs index 28df2a6ce..3e1d012b5 100644 --- a/trace_decoder/src/type1/witness.rs +++ b/trace_decoder/src/type1/witness.rs @@ -166,7 +166,15 @@ fn account_leaf<'a, E: ParserError<'a>>(input: &mut &'a [u8]) -> PResult None, }, has_storage: flags.contains(AccountLeafFlags::HAS_STORAGE), - has_code: flags.contains(AccountLeafFlags::HAS_CODE), + has_code: { + let has_code = flags.contains(AccountLeafFlags::HAS_CODE); + if has_code { + // BUG: this field is undocumented, but the previous version of + // this code had it, and our tests fail without it + trace("code_length", cbor::).parse_next(input)?; + } + has_code + }, }) } @@ -239,6 +247,8 @@ fn witness_test_vectors() { } for vector in vectors() { - assert_debug_snapshot!(witness::(&mut &*vector.bytes)); + assert_debug_snapshot!(witness:: + .parse(&*vector.bytes) + .unwrap()); } } diff --git a/trace_decoder/src/type1/witness2forest.rs b/trace_decoder/src/type1/witness2forest.rs new file mode 100644 index 000000000..c9d9afb2b --- /dev/null +++ b/trace_decoder/src/type1/witness2forest.rs @@ -0,0 +1,193 @@ +use std::array; + +use anyhow::{bail, Context as _}; +use either::Either; +use ethereum_types::U256; +use nunny::NonEmpty; + +use super::Instruction; + +#[derive(Debug)] +pub struct Hash { + pub raw_hash: [u8; 32], +} + +#[derive(Debug)] +pub struct Value { + pub raw_value: NonEmpty>, +} + +#[derive(Debug)] +pub struct Account { + pub nonce: u64, + pub balance: U256, + pub storage: Option>, + pub code: Option>, +} + +#[derive(Debug)] +pub struct Code { + pub code: NonEmpty>, +} + +#[derive(Debug)] +pub struct Leaf { + pub key: NonEmpty>, + pub value: Either, +} + +#[derive(Debug)] +pub struct Extension { + pub key: NonEmpty>, + pub child: Box, +} + +#[derive(Debug)] +pub struct Branch { + pub children: [Option>; 16], +} + +#[derive(Debug)] +pub enum Node { + Hash(Hash), + Value(Value), + Account(Account), + Leaf(Leaf), + Extension(Extension), + Branch(Branch), + Code(Code), +} + +pub enum Witness { + Leaf(Leaf), + Extension(Extension), + Branch(Branch), +} + +pub fn forest( + instructions: impl IntoIterator, +) -> anyhow::Result>> { + let mut witnesses = vec![]; + let mut stack = vec![]; + for instruction in instructions { + match instruction { + Instruction::Hash { raw_hash } => stack.push(Node::Hash(Hash { raw_hash })), + Instruction::Code { raw_code } => stack.push(Node::Code(Code { code: raw_code })), + Instruction::Leaf { key, value } => stack.push(Node::Leaf(Leaf { + key, + value: Either::Left(Value { raw_value: value }), + })), + Instruction::Extension { key } => { + let child = Box::new(stack.pop().context("no Node for Extension")?); + stack.push(Node::Extension(Extension { key, child })) + } + Instruction::AccountLeaf { + key, // BUG?(0xaatif): why is this unused? + nonce, + balance, + has_code, + has_storage, + } => { + // BUG: the spec sometimes writes Node::Account with 5 fields.. + // TODO(0xaatif): should these fields even be optional? + let nonce = nonce.context("AccountLeaf has no nonce")?; + let balance = balance.context("AccountLeaf has no balance")?; + match (has_code, has_storage) { + (true, true) => match pop2(&mut stack) { + (Some(Node::Hash(hash)), Some(storage)) => { + stack.push(Node::Account(Account { + nonce, + balance, + storage: Some(Box::new(storage)), + code: Some(Either::Left(hash)), + })) + } + (Some(Node::Code(code)), Some(storage)) => { + stack.push(Node::Account(Account { + nonce, + balance, + storage: Some(Box::new(storage)), + code: Some(Either::Right(code)), + })) + } + other => bail!( + "expected (Code | Hash, Node) for AccountLeaf, got {:?}", + other + ), + }, + (false, true) => { + let storage = + Some(Box::new(stack.pop().context("no Node for AccountLeaf")?)); + stack.push(Node::Account(Account { + nonce, + balance, + storage, + code: None, + })) + } + (true, false) => match stack.pop() { + Some(Node::Hash(it)) => stack.push(Node::Account(Account { + nonce, + balance, + storage: None, + code: Some(Either::Left(it)), + })), + Some(Node::Code(it)) => stack.push(Node::Account(Account { + nonce, + balance, + storage: None, + code: Some(Either::Right(it)), + })), + other => bail!("expected Code | Hash for AccountLeaf, got {:?}", other), + }, + (false, false) => stack.push(Node::Account(Account { + nonce, + balance, + storage: None, + code: None, + })), + } + } + Instruction::Branch { mask } => { + use bitvec::{order::Lsb0, view::BitView as _}; + let mut children = array::from_fn(|_ix| None); + for (ix, it) in mask.view_bits::().iter().by_vals().enumerate() { + if it { + *children.get_mut(ix).context("oob mask bit for Branch")? = + Some(Box::new(stack.pop().context("no Node for Branch")?)); + } + } + stack.push(Node::Branch(Branch { children })) + } + Instruction::NewTrie => witnesses.push(finish_stack(&mut stack)?), + } + } + witnesses.push(finish_stack(&mut stack)?); + + NonEmpty::>::new(witnesses) + .ok() + .context("no instructions")?; + todo!() +} + +fn finish_stack(v: &mut Vec) -> anyhow::Result { + match (v.len(), v.pop()) { + (1, Some(node)) => match node { + Node::Leaf(it) => Ok(Witness::Leaf(it)), + Node::Extension(it) => Ok(Witness::Extension(it)), + Node::Branch(it) => Ok(Witness::Branch(it)), + other => bail!( + "expected stack to contain Leaf | Extension | Branch, got {:?}", + other + ), + }, + (n, _) => bail!("expected a stack with a single element, got {}", n), + } +} + +/// Makes it easier to write code that looks like the spec +fn pop2(v: &mut Vec) -> (Option, Option) { + let right = v.pop(); + let left = v.pop(); + (left, right) +}