diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index bb6790ed..b23d41ed 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -79,3 +79,19 @@ jobs: run: RUST_BACKTRACE=1 ${{ matrix.tests }} --ignored - name: Stop bitcoin node run: ./scripts/stop_node.sh + sample_test: + name: sample-test + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - uses: actions/checkout@v2 + - name: Set permission + run: docker-compose run oracle-db bash -c "chown postgres:postgres /certs/db.key && chgrp postgres /certs/db.key && chmod 600 /certs/db.key" + - name: Start environment + run: docker-compose --profile oracle up -d + - name: Wait for container to run + run: ./scripts/wait_for_container.sh oracle-server + - name: Wait for electrs to be ready + run: ./scripts/wait_for_electrs.sh + - name: Run test + run: cargo test -- --ignored sample diff --git a/docker-compose.yml b/docker-compose.yml index df1bcf87..81873994 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -23,6 +23,48 @@ services: - bitcoind-data:/home/bitcoin/.bitcoin ports: - 3004:3004 + oracle-server: + image: ghcr.io/p2pderivatives/oracle:v0.2.3 + container_name: oracle-server + profiles: [oracle] + command: | + -config /config + -appname p2pdoracle + -e integration + -migrate + environment: + - P2PDORACLE_DATABASE_HOST=oracle-db + - P2PDORACLE_ORACLE_KEYFILE=/key/key.pem + - P2PDORACLE_ORACLE_KEYPASS_FILE=/key/pass.txt + restart: always + depends_on: + - oracle-db + ports: + - 8080:8080 + volumes: + - ./testconfig/oracle:/config + - ./testconfig/oracle/certs/oracle:/key + + oracle-db: + image: "postgres:12.2" + profiles: [oracle] + command: | + -c log_statement=all + -c ssl=on + -c ssl_cert_file=/certs/db.crt + -c ssl_key_file=/certs/db.key + restart: always + ports: + - 5432:5432 + environment: + - POSTGRES_USER=postgres + - POSTGRES_PASSWORD=1234 + - POSTGRES_DB=db + volumes: + - oracle-db-data:/var/lib/postgresql/data/ # persist data even if container shuts down + - ./testconfig/oracle/certs/db:/certs + volumes: bitcoind-data: + oracle-db-data: diff --git a/sample/Cargo.toml b/sample/Cargo.toml index aebda58d..83f11fcb 100644 --- a/sample/Cargo.toml +++ b/sample/Cargo.toml @@ -20,3 +20,9 @@ serde_json = "1.0" serde_yaml = "0.9.14" time = "0.3.16" tokio = {version = "1.5", features = ["io-util", "macros", "rt", "rt-multi-thread", "sync", "net", "time"]} + +[dev-dependencies] +assert_cmd = "2.0.12" +bitcoin-test-utils = { path = "../bitcoin-test-utils" } +predicates = "3.0.3" +rexpect = "0.5.0" diff --git a/sample/Readme.md b/sample/Readme.md index dbb16dc0..489d0157 100644 --- a/sample/Readme.md +++ b/sample/Readme.md @@ -8,10 +8,10 @@ Example configurations and contract input are available in the [examples](./exam ## Quick run -To give a quick try to this sample, run the following set of commands (assuming that the working directory is the one in which this readme is located and that docker or podman is available on your machine): +To give a quick try to this sample, run the following set of commands (assuming that the working directory is the one in which this readme is located and that docker and docker-compose is available on your machine): ```bash -../scripts/start_node.sh +docker-compose --profile oracle up -d ../scripts/create_wallets.sh cargo run ./examples/configurations/alice.yml ``` @@ -21,6 +21,8 @@ In a different terminal: cargo run ./examples/configurations/bob.yml ``` +Update the [example contract](./examples/contracts/numerical_contract_input.json#L82) replacing the number after `btcusd` with a unix timestamp some time in the future (this will correspond to the contract maturity date). + ### On chain DLC From the second instance (Bob), type: @@ -114,4 +116,4 @@ In the other terminal, use the `listrenewchanneloffers` to display the received To accept the offer, use the `acceptrenewchanneloffer` passing the channel id as a parameter. Three messages need to be exchanged between the peers to properly settle the channel, press `Enter` once in the terminal where the settle offer was made, once where the settle offer was received and once more where the settle offer was made for the settlement to be finalized. -To reject the offer, use the `rejectrenewchanneloffer` command, passing the channel id as a parameter. \ No newline at end of file +To reject the offer, use the `rejectrenewchanneloffer` command, passing the channel id as a parameter. diff --git a/sample/examples/configurations/alice.yml b/sample/examples/configurations/alice.yml index c5a457bd..71524ea6 100644 --- a/sample/examples/configurations/alice.yml +++ b/sample/examples/configurations/alice.yml @@ -9,4 +9,4 @@ networkConfiguration: peerListeningPort: 9000 network: regtest oracleConfig: - host: 'https://oracle.p2pderivatives.io/' + host: 'http://localhost:8080/' diff --git a/sample/examples/configurations/bob.yml b/sample/examples/configurations/bob.yml index 145f70db..40ddd2fb 100644 --- a/sample/examples/configurations/bob.yml +++ b/sample/examples/configurations/bob.yml @@ -9,4 +9,4 @@ networkConfiguration: peerListeningPort: 9001 network: regtest oracleConfig: - host: 'https://oracle.p2pderivatives.io/' + host: 'http://localhost:8080/' diff --git a/sample/examples/contracts/numerical_contract_input.json b/sample/examples/contracts/numerical_contract_input.json index a4b356a2..02d65e40 100644 --- a/sample/examples/contracts/numerical_contract_input.json +++ b/sample/examples/contracts/numerical_contract_input.json @@ -1,7 +1,6 @@ { "offerCollateral": 100000000, "acceptCollateral": 100000000, - "maturityTime": 1653378780, "feeRate": 2, "contractInfos": [ { @@ -76,9 +75,9 @@ }, "oracles": { "publicKeys": [ - "ce4b7ad2b45de01f0897aa716f67b4c2f596e54506431e693f898712fe7e9bf3" + "0d829c1cc556aa59060df5a9543c5357199ace5db9bcd5a8ddd6ee2fc7b6d174" ], - "eventId": "btcusd1653378780", + "eventId": "btcusd1707120297", "threshold": 1 } } diff --git a/sample/src/main.rs b/sample/src/main.rs index 7d712c8f..5bea995f 100644 --- a/sample/src/main.rs +++ b/sample/src/main.rs @@ -5,14 +5,14 @@ mod hex_utils; use disk::FilesystemLogger; use bitcoin::secp256k1::rand::{thread_rng, RngCore}; -use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey}; +use bitcoin::secp256k1::SecretKey; use bitcoin_rpc_provider::BitcoinCoreProvider; use dlc_manager::{CachedContractSignerProvider, Oracle, SimpleSigner, SystemTimeProvider}; use dlc_messages::message_handler::MessageHandler as DlcMessageHandler; use lightning::ln::peer_handler::{ ErroringMessageHandler, IgnoringMessageHandler, MessageHandler, PeerManager as LdkPeerManager, }; -use lightning::sign::KeysManager; +use lightning::sign::{KeysManager, NodeSigner}; use lightning_net_tokio::SocketDescriptor; use p2pd_oracle_client::P2PDOracleClient; use std::collections::hash_map::HashMap; @@ -118,10 +118,6 @@ async fn main() { // Setup a handler for the DLC messages that will be sent/received through LDK. let dlc_message_handler = Arc::new(DlcMessageHandler::new()); - println!( - "Node public key: {}", - PublicKey::from_secret_key(&Secp256k1::new(), &sk) - ); let time = SystemTime::now() .duration_since(SystemTime::UNIX_EPOCH) @@ -133,6 +129,11 @@ async fn main() { time.as_nanos() as u32, )); + println!( + "Node public key: {}", + km.get_node_id(lightning::sign::Recipient::Node).unwrap() + ); + // The peer manager helps us establish connections and communicate with our peers. let peer_manager: Arc = Arc::new(PeerManager::new( MessageHandler { diff --git a/testconfig/oracle/certs/db/db.crt b/testconfig/oracle/certs/db/db.crt new file mode 100644 index 00000000..181f0600 --- /dev/null +++ b/testconfig/oracle/certs/db/db.crt @@ -0,0 +1,67 @@ +Certificate: + Data: + Version: 1 (0x0) + Serial Number: + b4:4b:9e:02:a0:9c:f2:eb + Signature Algorithm: sha256WithRSAEncryption + Issuer: CN=localhost + Validity + Not Before: Feb 3 06:22:22 2023 GMT + Not After : Mar 5 06:22:22 2023 GMT + Subject: CN=localhost + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public-Key: (2048 bit) + Modulus: + 00:b8:b3:0c:44:18:91:f1:a1:7f:bf:3a:c9:f2:69: + 3d:4e:0d:eb:69:5c:a9:b4:20:4a:0a:24:0b:fe:aa: + 46:c6:5f:4b:69:d1:fb:93:76:36:bf:6d:d9:bd:e7: + 4c:cb:31:0d:f5:3d:04:12:7c:6a:e0:6b:59:cd:51: + 3a:50:75:54:4c:19:16:07:47:68:00:15:27:b1:22: + 8b:56:71:5f:b6:c0:e7:55:0b:0b:a2:68:a5:5d:b3: + 6f:91:a0:bb:e2:a4:e5:96:66:51:1d:ea:53:6b:01: + 5d:84:a8:16:b2:3d:a4:69:df:51:0e:61:18:e4:b5: + 07:41:27:53:a8:c7:6f:08:45:ae:f6:0e:f0:20:f8: + 16:2c:be:b1:2f:dc:94:b1:da:76:02:ff:7d:4f:cb: + c6:c4:81:52:dc:2c:77:02:18:98:ef:9a:e5:72:c4: + de:74:27:27:8a:f3:e1:52:79:91:10:df:76:6a:aa: + 0b:f4:9a:c9:c3:66:70:06:10:3d:9e:db:07:2b:f6: + 32:df:f7:ec:86:16:b5:03:85:41:d2:e8:2a:94:fd: + 46:4a:c8:8c:21:1b:40:cb:47:52:cf:54:cf:2c:02: + cc:a0:17:f8:94:33:5f:e8:eb:5a:a7:37:c7:29:b6: + 25:ec:4d:51:e5:26:aa:0b:40:b9:a0:ac:12:c7:de: + 1a:c5 + Exponent: 65537 (0x10001) + Signature Algorithm: sha256WithRSAEncryption + 8d:8f:96:9d:43:03:64:54:df:1b:cd:cd:3d:8a:cd:a0:bc:ce: + ee:72:57:81:77:8b:ff:5e:a6:db:38:a5:b3:a2:e8:dd:60:e9: + 09:33:40:50:6b:09:54:78:34:ce:d9:63:06:8c:5b:d8:2d:34: + 77:d3:c0:b0:44:83:45:75:9b:37:c9:93:5b:61:0e:c3:c8:e6: + 94:ca:c7:81:58:fa:fe:db:a1:94:61:b5:cd:86:6e:81:72:36: + b1:43:54:c9:73:05:48:b3:91:e0:88:ee:1c:cb:3b:5f:68:de: + 25:06:79:d6:3a:75:8d:4d:c4:e7:7b:f8:71:f0:b4:02:d9:e5: + 3f:e3:7d:fe:f7:4f:b0:3a:2f:03:14:92:db:b1:19:ed:5e:ca: + 79:fe:68:e8:07:60:28:00:0f:83:f4:f6:21:91:88:e0:2c:46: + 96:7a:ef:88:9d:05:67:b1:ce:a1:df:9d:f8:09:df:c7:71:71: + 4b:d7:aa:f0:69:a9:de:13:3b:f8:f0:c8:f4:c3:33:c7:3e:60: + e3:6f:86:ee:49:5f:bb:80:81:bb:73:a5:50:da:56:b2:47:c6: + d2:f8:80:12:09:96:0a:ee:7a:65:ae:b9:9d:83:55:da:a6:f4: + 7d:4f:27:f2:eb:9b:1a:10:38:1c:6c:40:be:e9:64:55:d9:9e: + ec:36:0d:33 +-----BEGIN CERTIFICATE----- +MIICpDCCAYwCCQC0S54CoJzy6zANBgkqhkiG9w0BAQsFADAUMRIwEAYDVQQDDAls +b2NhbGhvc3QwHhcNMjMwMjAzMDYyMjIyWhcNMjMwMzA1MDYyMjIyWjAUMRIwEAYD +VQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC4 +swxEGJHxoX+/OsnyaT1ODetpXKm0IEoKJAv+qkbGX0tp0fuTdja/bdm950zLMQ31 +PQQSfGrga1nNUTpQdVRMGRYHR2gAFSexIotWcV+2wOdVCwuiaKVds2+RoLvipOWW +ZlEd6lNrAV2EqBayPaRp31EOYRjktQdBJ1Oox28IRa72DvAg+BYsvrEv3JSx2nYC +/31Py8bEgVLcLHcCGJjvmuVyxN50JyeK8+FSeZEQ33Zqqgv0msnDZnAGED2e2wcr +9jLf9+yGFrUDhUHS6CqU/UZKyIwhG0DLR1LPVM8sAsygF/iUM1/o61qnN8cptiXs +TVHlJqoLQLmgrBLH3hrFAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAI2Plp1DA2RU +3xvNzT2KzaC8zu5yV4F3i/9epts4pbOi6N1g6QkzQFBrCVR4NM7ZYwaMW9gtNHfT +wLBEg0V1mzfJk1thDsPI5pTKx4FY+v7boZRhtc2GboFyNrFDVMlzBUizkeCI7hzL +O19o3iUGedY6dY1NxOd7+HHwtALZ5T/jff73T7A6LwMUktuxGe1eynn+aOgHYCgA +D4P09iGRiOAsRpZ674idBWexzqHfnfgJ38dxcUvXqvBpqd4TO/jwyPTDM8c+YONv +hu5JX7uAgbtzpVDaVrJHxtL4gBIJlgruemWuuZ2DVdqm9H1PJ/LrmxoQOBxsQL7p +ZFXZnuw2DTM= +-----END CERTIFICATE----- diff --git a/testconfig/oracle/certs/db/db.key b/testconfig/oracle/certs/db/db.key new file mode 100644 index 00000000..4fb470c3 --- /dev/null +++ b/testconfig/oracle/certs/db/db.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAuLMMRBiR8aF/vzrJ8mk9Tg3raVyptCBKCiQL/qpGxl9LadH7 +k3Y2v23ZvedMyzEN9T0EEnxq4GtZzVE6UHVUTBkWB0doABUnsSKLVnFftsDnVQsL +omilXbNvkaC74qTllmZRHepTawFdhKgWsj2kad9RDmEY5LUHQSdTqMdvCEWu9g7w +IPgWLL6xL9yUsdp2Av99T8vGxIFS3Cx3AhiY75rlcsTedCcnivPhUnmREN92aqoL +9JrJw2ZwBhA9ntsHK/Yy3/fshha1A4VB0ugqlP1GSsiMIRtAy0dSz1TPLALMoBf4 +lDNf6OtapzfHKbYl7E1R5SaqC0C5oKwSx94axQIDAQABAoIBACJ9XNcCd45ViBNf +mQJpYIdI1iLwqMf4F5tZK9w8U8cLWHvEOGRK+OI6UyTBInf3CxI2eKIzFYoewcAz +YN5RapJjRNfLH8KUMLtFJhvYQ/VOhGQ/EcccH3Ul4rmg+DTUcgLpzE/3x+f9c0co +VESoeiFDEFHNE+bxXw9tlpO32iYC++DWB4xGHicZ1U7EonbD1GGTcZFVACMtnrml +WotqKe1jcxMU7ozPxvfddKyaJggYqyFLNS6q7rCMTYyWSqg6BXJBxqj6IzeS4ItZ +YhavmDV9Exb4PdL8dotywDYsbVWN7Z8SH3JKJhaS2brs5xmjytpvmoRM4x/KzgDI +tWHUB4ECgYEA5DIcbqqJuZUs0eDBnuL1TQcKoyLEt1thZyYjmA0zCvV3BVEtmKVs +lOk7Q4FhxcyKOKnfGuzW7XEclHRx4KvK4z/Esro6FdExdNWzSKWgjLxf7IwV9Gee +/idC4keUdGG9fiVyW8WST6DjfB8Dr2EKeixyzNh7O8kFtSlyv3bLsrUCgYEAzzQy +l4EbQ8HeAcUg4BDIOhDrn8wUYBw7yUC46qempUolNGEu0EsE9qEgZw0R4bpshMr+ +bstvEhe86DoOq0yUb3lov3kFqykTGfonNPXaPHgR8BsWZh9EwKfBbIlT7Hdy98Wq +dG0IOboEQ9LpNE4nSeNdEqCow+J3pLWr6cr0gdECgYAkxAoerm1YMDezbPHlJo39 +JhhJpm1pWVi9JMDxW5cQufG+MpEVGfn/mABLZQoas1TFwmDG1sfeI65GIOjEGQms +SXbokOaQ406Dk3a6Sq0uX59Y3k0fPp64Nh0plfzOL303WNMvBAsJt1NPiTOvywPE +IWsxo+NfA4le4dmyDXLOTQKBgQDIGLdWufZTe8/iU7VIzMwfzyFMgy+WFQ3jb15k +NZzn+G9vYv5rZlcXuUhqXCPNolOT9di5tDnB9iyW8yIhaOXbtRpj9gJ0ZUkuB/Z+ +3YFwbd+cyPvbiQzDI/3Vy9TBAiWDg1716ilMXggqW26b9XFZmHjUOVRhPr2d0VeA +gl+XUQKBgQDHq2n4NrF1uV4+ab/7PApLoPG/h2U3ocusqYvfUJZboNM8G1bGvBf6 +ArRIl0JqnQ7BSMEuJh9I8yG15BWfkuHdN841G222cEYBuxP6x8E4sFwutNoSB0vc +rykrADchduIUKgXFap+1MaInsuKUUIptFz06y37wjt8kUWHVL4ShRg== +-----END RSA PRIVATE KEY----- diff --git a/testconfig/oracle/certs/oracle/key.pem b/testconfig/oracle/certs/oracle/key.pem new file mode 100644 index 00000000..9f14015c --- /dev/null +++ b/testconfig/oracle/certs/oracle/key.pem @@ -0,0 +1,8 @@ +-----BEGIN EC PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-256-CBC,4FB3A4FF77E83E33ADAE25754D937359 + +JPp+2MkwFeHGH1rAntW3nQaFmur5vjpRdpQNKzHqMyOTzYunnCAAVeP1QqQJmcjz +V/fkakJwOC0hCPxavgCYNFPwlhIpXEwopYaqAZ1ULZyzTrgbdLSv6ozYI8YrTLt8 +QSN2N1bzyW1y3NOPpT7/yP3wfhVkpPY+sJTwdJ6P6SE= +-----END EC PRIVATE KEY----- diff --git a/testconfig/oracle/certs/oracle/pass.txt b/testconfig/oracle/certs/oracle/pass.txt new file mode 100644 index 00000000..72b98c82 --- /dev/null +++ b/testconfig/oracle/certs/oracle/pass.txt @@ -0,0 +1 @@ +Qj6Yb+GMC/MTRBO02Qal+sTDQRlvu2EfseHiDy9dANo= diff --git a/testconfig/oracle/integration.yaml b/testconfig/oracle/integration.yaml new file mode 100644 index 00000000..02236964 --- /dev/null +++ b/testconfig/oracle/integration.yaml @@ -0,0 +1,44 @@ +server: + address: "0.0.0.0:8080" +oracle: + keyFile: ../../certs/oracle/key.pem + keyPass: + file: ../../certs/oracle/pass.txt +log: + dir: _log + output_stdout: true + basename: unittest.log.%Y-%m-%d + rotation_interval: PT24H + rotation_counts: 7 + format: json + level: info +database: + log: false + host: localhost + port: 5432 + dbuser: postgres + dbpassword: 1234 + dbname: db +api: + assets: + btcusd: + startDate: 2020-01-01T00:00:00Z + frequency: PT1H + range: P10DT + unit: usd/btc + precision: 0 + signconfig: + base: 2 + nbDigits: 20 + btcjpy: + startDate: 2020-01-01T00:00:00Z + frequency: PT1H + range: P2MT + unit: jpy/btc + precision: 0 + signconfig: + base: 2 + nbDigits: 20 +datafeed: + dummy: + returnValue: 9000