diff --git a/Cargo.lock b/Cargo.lock index 61576dcd..eb36e0a3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,21 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + [[package]] name = "android-tzdata" version = "0.1.1" @@ -17,12 +32,71 @@ dependencies = [ "libc", ] +[[package]] +name = "anyhow" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519" + +[[package]] +name = "arrayref" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" + +[[package]] +name = "async-trait" +version = "0.1.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "autocfg" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" +[[package]] +name = "backtrace" +version = "0.3.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "bitflags" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + [[package]] name = "block-buffer" version = "0.10.4" @@ -38,6 +112,18 @@ version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" + [[package]] name = "cc" version = "1.0.94" @@ -79,6 +165,37 @@ dependencies = [ "libc", ] +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + [[package]] name = "crypto-common" version = "0.1.6" @@ -89,16 +206,57 @@ dependencies = [ "typenum", ] +[[package]] +name = "crypto-mac" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + [[package]] name = "digest" version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer", + "block-buffer 0.10.4", "crypto-common", ] +[[package]] +name = "either" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2" + +[[package]] +name = "errno" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "fastrand" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984" + [[package]] name = "generic-array" version = "0.14.7" @@ -120,12 +278,45 @@ dependencies = [ "wasi", ] +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + [[package]] name = "hex-literal" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" +[[package]] +name = "hmac" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840" +dependencies = [ + "crypto-mac", + "digest 0.9.0", +] + +[[package]] +name = "hmac-drbg" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17ea0a1394df5b6574da6e0c1ade9e78868c9fb0a4e5ef4428e32da4676b85b1" +dependencies = [ + "digest 0.9.0", + "generic-array", + "hmac", +] + [[package]] name = "iana-time-zone" version = "0.1.60" @@ -170,22 +361,123 @@ version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +[[package]] +name = "libsecp256k1" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95b09eff1b35ed3b33b877ced3a691fc7a481919c7e29c53c906226fcf55e2a1" +dependencies = [ + "arrayref", + "base64", + "digest 0.9.0", + "hmac-drbg", + "libsecp256k1-core", + "libsecp256k1-gen-ecmult", + "libsecp256k1-gen-genmult", + "rand", + "serde", + "sha2 0.9.9", + "typenum", +] + +[[package]] +name = "libsecp256k1-core" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5be9b9bb642d8522a44d533eab56c16c738301965504753b03ad1de3425d5451" +dependencies = [ + "crunchy", + "digest 0.9.0", + "subtle", +] + +[[package]] +name = "libsecp256k1-gen-ecmult" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3038c808c55c87e8a172643a7d87187fc6c4174468159cb3090659d55bcb4809" +dependencies = [ + "libsecp256k1-core", +] + +[[package]] +name = "libsecp256k1-gen-genmult" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3db8d6ba2cec9eacc40e6e8ccc98931840301f1006e95647ceb2dd5c3aa06f7c" +dependencies = [ + "libsecp256k1-core", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" + [[package]] name = "log" version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +[[package]] +name = "memchr" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" + +[[package]] +name = "memmap2" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" +dependencies = [ + "libc", +] + +[[package]] +name = "merkletree" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a0ed8c0ce1e281870da29266398541a0dbab168f5fb5fd36d7ef2bbdbf808a3" +dependencies = [ + "anyhow", + "arrayref", + "log", + "memmap2", + "positioned-io", + "rayon", + "serde", + "tempfile", + "typenum", +] + [[package]] name = "mining-challenge" version = "0.1.0" dependencies = [ "chrono", + "hex", "hex-literal", - "ring", + "libsecp256k1", + "merkletree", + "ripemd", + "secp256k1", "serde", "serde_json", - "sha2", + "sha2 0.10.8", + "sha256", + "signature", +] + +[[package]] +name = "miniz_oxide" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +dependencies = [ + "adler", ] [[package]] @@ -197,12 +489,50 @@ dependencies = [ "autocfg", ] +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + +[[package]] +name = "pin-project-lite" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + +[[package]] +name = "positioned-io" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccabfeeb89c73adf4081f0dca7f8e28dbda90981a222ceea37f619e93ea6afe9" +dependencies = [ + "byteorder", + "libc", + "winapi", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + [[package]] name = "proc-macro2" version = "1.0.79" @@ -222,17 +552,80 @@ dependencies = [ ] [[package]] -name = "ring" -version = "0.17.8" +name = "rand" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "cc", - "cfg-if", "getrandom", +] + +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "ripemd" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustix" +version = "0.38.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +dependencies = [ + "bitflags", + "errno", "libc", - "spin", - "untrusted", + "linux-raw-sys", "windows-sys", ] @@ -242,6 +635,24 @@ version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" +[[package]] +name = "secp256k1" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e0cc0f1cf93f4969faf3ea1c7d8a9faed25918d96affa959720823dfe86d4f3" +dependencies = [ + "secp256k1-sys", +] + +[[package]] +name = "secp256k1-sys" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1433bd67156263443f14d603720b082dd3121779323fce20cba2aa07b874bc1b" +dependencies = [ + "cc", +] + [[package]] name = "serde" version = "1.0.197" @@ -273,6 +684,19 @@ dependencies = [ "serde", ] +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + [[package]] name = "sha2" version = "0.10.8" @@ -281,14 +705,33 @@ checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", - "digest", + "digest 0.10.7", ] [[package]] -name = "spin" -version = "0.9.8" +name = "sha256" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +checksum = "18278f6a914fa3070aa316493f7d2ddfb9ac86ebc06fa3b83bffda487e9065b0" +dependencies = [ + "async-trait", + "bytes", + "hex", + "sha2 0.10.8", + "tokio", +] + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" + +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "syn" @@ -301,6 +744,29 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "tempfile" +version = "3.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +dependencies = [ + "cfg-if", + "fastrand", + "rustix", + "windows-sys", +] + +[[package]] +name = "tokio" +version = "1.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" +dependencies = [ + "backtrace", + "bytes", + "pin-project-lite", +] + [[package]] name = "typenum" version = "1.17.0" @@ -313,12 +779,6 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" -[[package]] -name = "untrusted" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" - [[package]] name = "version_check" version = "0.9.4" @@ -385,6 +845,28 @@ version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + [[package]] name = "windows-core" version = "0.52.0" diff --git a/Cargo.toml b/Cargo.toml index 445172fb..8d00cf07 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,12 @@ edition = "2021" serde = { version = "1.0", features = ["derive"]} chrono = "0.4.37" hex-literal = "0.4.1" -ring = "0.17.8" serde_json = "1.0.115" sha2 = "0.10.8" +ripemd = "0.1.3" +merkletree = "0.23.0" +sha256 = "1.5.0" +hex = "0.4.3" +secp256k1 = "0.29.0" +signature = "2.2.0" +libsecp256k1 = "0.7.1" diff --git a/output.txt b/output.txt new file mode 100644 index 00000000..64ca2145 --- /dev/null +++ b/output.txt @@ -0,0 +1 @@ +f10eb050b1bf49d12cf34459ec07a7e0e4d0bbfe0fbb35a16385c1f26c889dd6 diff --git a/src/block/block.rs b/src/block/block.rs index b5668b34..cfd71cc1 100644 --- a/src/block/block.rs +++ b/src/block/block.rs @@ -1,12 +1,12 @@ #![allow(dead_code, unused)] use super::block_header::BlockHeader; -use crate::transactions::{self, tx::Tx}; +use crate::{mempool::mempool::Mempool, transactions::{self, tx::Tx}}; use core::fmt; const BLOCK_MAX_SIZE: u32 = 8000000; -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct Block{ pub block_header: BlockHeader, pub transactions: Vec, @@ -23,6 +23,20 @@ impl Block { } } + pub fn insert_transactions_from_mempool(&mut self, mempool: &mut Mempool) { + loop { + if mempool.txs.len() > 0{ + if mempool.txs.last().unwrap().get_tx_size_in_bits() < self.get_block_size_left(){ + self.push_transaction(mempool.txs.pop().unwrap()); + println!("Txs Left on Mempool: {}", mempool.txs.len()); + } + else { + break; + } + } + } + } + pub fn calculate_total_block_fee(&self) -> u64 { let mut total_fee: u64 = 0; diff --git a/src/main.rs b/src/main.rs index d720d8a8..e852b279 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,30 +7,61 @@ use block::block_header::BlockHeader; use block::block::Block; use chrono::Utc; use utils::{read_mempool, read_tx_from_file}; -use ring::digest::{Context, Digest, SHA256}; -use std::fmt::Write; +use std::fs::File; +use std::io::prelude::*; use mempool::mempool::Mempool; use std::fs; +use crate::utils::validate_transaction_inputs; + fn main() { // let file_size = fs::metadata("/home/gabriel/projects/bitcoin-mining-challenge/mempool/ff73248e38bfcdac87261f5a51f3143478937fda6b0d1def46e794b8f250e6dd.json").expect("Falha ao ler o arquivo"); // println!("Size: {} ", file_size.len()); let mut mempool: Mempool = read_mempool("/home/gabriel/projects/bitcoin-mining-challenge/mempool/"); mempool.sort_mempool_by_tx(); - let first_block_header: BlockHeader = BlockHeader::new(String::from("00000000000000000000000000000000"), String::from("00000000000000000000000000000000"), Utc::now(), 128); - let mut block = Block::new(first_block_header, vec![]); + let genesis_block_header: BlockHeader = BlockHeader::new(String::from("00000000000000000000000000000000"), String::from("00000000000000000000000000000000"), Utc::now(), 128); + let mut genesis_block = Block::new(genesis_block_header.clone(), vec![]); + + println!("{}", genesis_block.get_block_size()); + + let mut block_chain: Vec = vec![]; - for tx in mempool.txs{ - if tx.get_tx_size_in_bits() < block.get_block_size_left(){ - block.push_transaction(tx); - } - else { - continue; - } - } - - println!("{}", block); + println!("Mempool Size Before: {}", mempool.txs.len()); + + genesis_block.insert_transactions_from_mempool(&mut mempool); + block_chain.push(genesis_block.clone()); + println!("Mempool Size After: {}", mempool.txs.len()); + let tx = read_tx_from_file("/home/gabriel/projects/bitcoin-mining-challenge/mempool/0a8b21af1cfcc26774df1f513a72cd362a14f5a598ec39d915323078efb5a240.json"); + // let tx = read_tx_from_file("/home/gabriel/projects/bitcoin-mining-challenge/mempool/0ac528562a1626863c0cb912eb725530c54e786e6485380c16633e4b9bce1720.json"); + + validate_transaction_inputs(&tx); + + let mut file: File = File::create("output.txt").expect("Error while creating file"); + + file.write_all(genesis_block.block_header.get_block_header_sha256sum().as_bytes()); + file.write_all(b"\n"); + + // while mempool.txs.len() > 6000 { + // let mut new_block_header: BlockHeader = BlockHeader::new(block_chain.last().unwrap().block_header.get_block_header_sha256sum(), String::from("00000000000000000000000000000000"), Utc::now(), 0); + // let mut new_block: Block = Block::new(new_block_header, vec![]); + // // if mempool.txs.last().unwrap().get_tx_size_in_bits() < new_block.get_block_size_left(){ + // // new_block.push_transaction(mempool.txs.pop().unwrap()); + // // println!("Txs Left on Mempool: {}", mempool.txs.len()); + // // } + // // else { + // // break; + // // } + // println!("Inserting Txs on Block {}", new_block.block_header.block_id); + // new_block.insert_transactions_from_mempool(&mut mempool); + // block_chain.push(new_block); + // } + + // println!("{}", block_chain.len()); + + // for block in block_chain{ + // println!("{}", block); + // } // println!("================================="); // println!("{}", first_block_header); diff --git a/src/mempool/mempool.rs b/src/mempool/mempool.rs index 493dcf0e..0d477f41 100644 --- a/src/mempool/mempool.rs +++ b/src/mempool/mempool.rs @@ -40,7 +40,6 @@ impl Mempool{ pub fn sort_mempool_by_tx(&mut self) { self.txs.sort_by(|a, b| a.get_tx_fee_per_bit().partial_cmp(&b.get_tx_fee_per_bit()).unwrap()); - self.txs.reverse(); } } \ No newline at end of file diff --git a/src/script/mod.rs b/src/script/mod.rs new file mode 100644 index 00000000..d8885587 --- /dev/null +++ b/src/script/mod.rs @@ -0,0 +1,3 @@ +pub fn OP_DUP() { + +} \ No newline at end of file diff --git a/src/transactions/tx.rs b/src/transactions/tx.rs index 296bd036..62e5c38a 100644 --- a/src/transactions/tx.rs +++ b/src/transactions/tx.rs @@ -78,7 +78,7 @@ impl Tx{ let result = hasher.finalize(); - let hash_string = result.iter().map(|byte| format!("{:02x}", byte)).collect::(); + let hash_string: String = result.iter().map(|byte| format!("{:02x}", byte)).collect::(); return hash_string; } diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 0dfdb6e0..da63d7cf 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -1,14 +1,167 @@ // use std::env; #![allow(dead_code, unused)] -// use core::panicking::panic; +pub mod tree; -use crate::transactions::tx::{Tx, TxInput, TxOutput}; +use crate::transactions::tx::{self, Tx, TxInput, TxOutput}; use crate::mempool::mempool::Mempool; use serde_json; +use sha2::digest::core_api::TruncSide; +use sha2::{Sha256, Sha256VarCore}; +use sha256::{digest, try_digest}; use std::path::Path; use std::io::{self, Read}; use std::fs::{self, File}; +use std::str::FromStr; +use std::thread::sleep; +use std::time; +use ripemd::{Ripemd160, Digest}; +use hex; +use secp256k1::{Secp256k1, Message, SecretKey, PublicKey, ecdsa}; +// use libsecp256k1::{Message, PublicKey, Signature, PublicKeyFormat}; + + +pub fn get_merkle_root(tx_vec: &Vec) -> String { + let merkle_root: String = String::new(); + + for tx in tx_vec{ + + } + + String::new() +} + +pub fn validate_transaction_inputs(tx: &Tx) -> Vec { + let mut script: Vec = vec![]; + for vin in &tx.tx_input { + let mut scriptsig: Vec = vec![]; + scriptsig.extend(vin.scriptsig_asm.clone().split_whitespace().map(String::from)); + + let signature: String = scriptsig[1].clone(); + let pubkey: String = scriptsig[3].clone(); + + script.push(signature); + script.push(pubkey); + script.extend(vin.prevout.scriptpubkey_asm.clone().split_whitespace().map(String::from)); + } + + let mut stack: Vec = vec![]; + + println!("Starting the Script Stack"); + + for instruction in &script{ + match instruction.as_str() { + "OP_DUP" => { + println!("OP_DUP de {}", stack.last().unwrap()); + stack.push(stack.last().unwrap().clone()); + println!("{:?}\n", stack); + } + "OP_HASH160" => { + let value: String = stack.pop().unwrap(); + + let mut value_hash = hash_160(&value); + + println!("OP_HASH160 de {} virando {}", value, value_hash); + + stack.push(value_hash); + println!("{:?}\n", stack); + } + "OP_EQUALVERIFY" => { + let last_stack_value = stack.pop().unwrap(); + let pubkey = stack.pop().unwrap(); + if last_stack_value != pubkey { + stack.push("OP_0".to_string()); + } + } + "OP_CHECKSIG" => { + println!("{:?}", stack); + + let secp = Secp256k1::new(); + + let pubkey_pop = stack.pop().unwrap(); + + // let pubkey_test = PublicKey::parse_slice(&hex::decode(&pubkey_pop).expect("Error while decoding pubkey to hex"), Some(PublicKeyFormat::Compressed)).expect("Error while parsing pubkey"); + + let pubkey_hex = hex::decode(pubkey_pop).expect("Error while decoding pubkey to hex"); + + let pubkey = PublicKey::from_slice(&pubkey_hex).expect("public keys must be 33 or 65 bytes, serialized according to SEC 2"); + + println!("{:?}", stack); + + let signature = stack.pop().unwrap(); + + // println!("Signature {}", signature); + // println!("Signature len {}", &hex::decode(&signature).expect("Error while decoding signature to hex").len()); + + let mut signature_hex = hex::decode(&signature).expect("Error while decoding signature to hex"); + + signature_hex.remove(signature_hex.len() - 1); + + // let sig_test = Signature::parse_der(&signature_hex).expect("Error while parsing signature"); + + // println!("sig_test {:?}", sig_test); + + let signature = ecdsa::Signature::from_der(&signature_hex).expect("compact signatures are 64 bytes; DER signatures are 68-72 bytes"); + + println!("signature {}", signature); + + let message_pop = tx.tx_input[0].txid.clone(); + + // println!("message_pop len {}", message_pop.len()); + + let mut message_hex = hex::decode(&message_pop).expect("Error while decoding message to hex"); + // println!("message hex {:?}", message_hex); + // message_hex.reverse(); + // println!("message hex {:?}", message_hex); + + // println!("Address {}", hash_160(&pubkey_pop)); + + // let message_test = Message::parse_slice(&message_hex).expect("Error while parsing message"); + + let message = Message::from_digest_slice(&message_hex).expect("messages must be 32 bytes and are expected to be hashes"); + + + // println!("tx op_checksig {}", libsecp256k1::verify(&message_test, &sig_test, &pubkey_test)); + println!("{}", secp.verify_ecdsa(&message, &signature, &pubkey).unwrap_err()); + // assert!(); + } + instruction if instruction.starts_with("OP_PUSHBYTES_") => { + println!("Pushing bytes"); + } + _ => { + println!("Inserindo item na lista"); + stack.push(instruction.clone()); + println!("{:?}\n", stack); + } + } + // sleep(time::Duration::from_secs(1)); + } + + script +} + +pub fn hash_160(value: &String) -> String { + + let hex_value = hex::decode(value).expect("Error while parsing hex from string"); + + let mut hasher256 = Sha256::new(); + + hasher256.update(hex_value); + + let result_256 = hasher256.finalize(); + + let mut hasher_ripemd = Ripemd160::new(); + + hasher_ripemd.update(result_256); + + let result_ripemd = hasher_ripemd.finalize(); + + let hash160_string: String = result_ripemd.clone().iter().map(|byte| format!("{:02x}", byte)).collect::(); + + println!("\nHash RIPEMD160 de {} => {}\n", value, hash160_string); + + hash160_string +} pub fn read_mempool(path: &str) -> Mempool { diff --git a/src/utils/sha256.rs b/src/utils/sha256.rs new file mode 100644 index 00000000..12d87d6a --- /dev/null +++ b/src/utils/sha256.rs @@ -0,0 +1,14 @@ +use sha2::{Digest, Sha256, Sha256VarCore}; + +pub fn hash_sha256(value: String) -> String { + + let bytes = value.as_bytes(); + + let mut hasher = Sha256::new(); + + hasher.update(bytes); + + let result = hasher.finalize(); + + println!("{:?}", result); +} \ No newline at end of file diff --git a/src/utils/tree.rs b/src/utils/tree.rs new file mode 100644 index 00000000..0a59d2c9 --- /dev/null +++ b/src/utils/tree.rs @@ -0,0 +1,47 @@ +// use std::collections::VecDeque; + +// #[derive(Debug, Clone)] +// pub struct TreeNode { +// pub value: T, +// pub left: Option>>, +// pub right: Option>>, +// } + +// impl TreeNode{ +// pub fn new(value: T) -> Option>>{ +// Some(Box::new(TreeNode { +// value, +// left: None, +// right: None, +// })) +// } +// } + +// pub fn build_binary_tree_from_array(array: Vec>) -> Option>> where T: Clone, { +// let mut root: Option>> = None; +// let mut queue: VecDeque<(Option>>, usize)> = VecDeque::new(); + +// if let Some(root_val) = array.get(0).cloned().flatten() { +// root = Some(Box::new(TreeNode::new(root_val.clone()))); + +// queue.push_back((root.as_mut().map(|r| r.as_mut()), 0)); + +// while let Some((mut node, index)) = queue.pop_front() { +// let left_index = 2 * index + 1; +// let right_index = 2 * index + 2; + +// if let Some(left_val) = array.get(left_index).cloned().flatten() { +// let left_child: Option>> = Some(Box::new(TreeNode::new(left_val.clone()))); +// node.as_mut().unwrap().left = left_child.clone(); +// queue.push_back((left_child, left_index)); +// } + +// if let Some(right_val) = array.get(right_index).cloned().flatten() { +// let right_child: Option>> = Some(Box::new(TreeNode::new(right_val.clone()))); +// node.as_mut().unwrap().right = right_child.clone(); +// queue.push_back((right_child, right_index)); +// } +// } + +// } +// } \ No newline at end of file