mirror of
https://gitlab.com/pulsechaincom/prysm-pulse.git
synced 2024-12-22 03:30:35 +00:00
sharding: Local networked P2P! (#222)
Former-commit-id: d22d05529bb0050b8a03053a28d876e3e458bbff [formerly 284a04699110aa285a42f5b0ad244ca9bd77d2df] Former-commit-id: 83cd9c8a48fb5ce9c57ff8ef6c2b1741a4d05130
This commit is contained in:
parent
77267169ea
commit
9ac88d11da
@ -107,7 +107,7 @@ $ bazel build //sharding/...
|
||||
Make sure a geth node is running as a separate process. Then, to deposit ETH and join as a notary in the Sharding Manager Contract, run the following command:
|
||||
|
||||
```
|
||||
$ bazel run //sharding --actor "notary" --deposit --datadir /path/to/your/datadir --password /path/to/your/password.txt --networkid 12345
|
||||
$ ./bazel-bin/path/to/your/sharding/binary --actor "notary" --deposit --datadir /path/to/your/datadir --password /path/to/your/password.txt --networkid 12345
|
||||
```
|
||||
|
||||
This will extract 1000ETH from your account balance and insert you into the SMC's notaries. Then, the program will listen for incoming block headers and notify you when you have been selected as to vote on proposals for a certain shard in a given period. Once you are selected, your sharding node will download collation information to check for data availability on vote on proposals that have been submitted via the `addHeader` function on the SMC.
|
||||
@ -117,14 +117,14 @@ Concurrently, you will need to run another service that is tasked with processin
|
||||
## Running a Collation Proposal Node
|
||||
|
||||
```
|
||||
$ bazel run //sharding --actor "proposer" --datadir /path/to/your/datadir --password /path/to/your/password.txt --shardid 0 --networkid 12345
|
||||
$ ./bazel-bin/path/to/your/sharding/binary --actor "proposer" --datadir /path/to/your/datadir --password /path/to/your/password.txt --shardid 0 --networkid 12345
|
||||
```
|
||||
|
||||
This node is tasked with processing pending transactions into blobs within collations by serializing data into collation bodies. It is responsible for submitting proposals on shard 0 (collation headers) to the SMC via the `addHeader` function.
|
||||
|
||||
## Running an Observer Node
|
||||
|
||||
$ bazel run //sharding --datadir /path/to/your/datadir --password /path/to/your/password.txt --shardid 0 --networkid 12345
|
||||
$ ./bazel-bin/path/to/your/sharding/binary --datadir /path/to/your/datadir --password /path/to/your/password.txt --shardid 0 --networkid 12345
|
||||
|
||||
Omitting the `--actor` flag will launch a simple observer service attached to the sharding client that is able to listen to changes happening throughout the sharded Ethereum network on shard 0.
|
||||
|
||||
|
422
WORKSPACE
422
WORKSPACE
@ -48,6 +48,336 @@ go_repository(
|
||||
commit = "ca190fb6ffbc076ff49197b7168a760f30182d2e",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_libp2p_go_floodsub",
|
||||
commit = "1b4fbb865d4944a602b27e24e8123a57095e9987",
|
||||
importpath = "github.com/libp2p/go-floodsub",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_libp2p_go_libp2p",
|
||||
commit = "934606d0f292f265eab890101233d18ffeabfda0",
|
||||
importpath = "github.com/libp2p/go-libp2p",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_libp2p_go_libp2p_peer",
|
||||
commit = "a26c4b782bfe3b2570c539f69dc7777a45117a90",
|
||||
importpath = "github.com/libp2p/go-libp2p-peer",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_libp2p_go_libp2p_crypto",
|
||||
commit = "18915b5467c77ad8c07a35328c2cab468667a4e8",
|
||||
importpath = "github.com/libp2p/go-libp2p-crypto",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_multiformats_go_multiaddr",
|
||||
commit = "96804982667ed1672985566d0d0c2a7ed6f10e1f",
|
||||
importpath = "github.com/multiformats/go-multiaddr",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_ipfs_go_log",
|
||||
commit = "5dc2060baaf8db344f31dafd852340b93811d03f",
|
||||
importpath = "github.com/ipfs/go-log",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_multiformats_go_multihash",
|
||||
commit = "8be2a682ab9f254311de1375145a2f78a809b07d",
|
||||
importpath = "github.com/multiformats/go-multihash",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_libp2p_go_libp2p_swarm",
|
||||
commit = "81c57653cf47f106c6779a17a1e24ce192a0a42d",
|
||||
importpath = "github.com/libp2p/go-libp2p-swarm",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_libp2p_go_libp2p_host",
|
||||
commit = "c2196843b63fc9da2999045ca7fbae64e53b6461",
|
||||
importpath = "github.com/libp2p/go-libp2p-host",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_libp2p_go_libp2p_peerstore",
|
||||
commit = "49898a5f59ac4bea31b49d0c62ba214a6da16dbd",
|
||||
importpath = "github.com/libp2p/go-libp2p-peerstore",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_libp2p_go_libp2p_circuit",
|
||||
commit = "ee6dd9116af74cc17c03a199c258817543b0704b",
|
||||
importpath = "github.com/libp2p/go-libp2p-circuit",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_coreos_go_semver",
|
||||
commit = "e214231b295a8ea9479f11b70b35d5acf3556d9b",
|
||||
importpath = "github.com/coreos/go-semver",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_libp2p_go_libp2p_interface_connmgr",
|
||||
commit = "ba1fa6b3d7aed40798c930634ba109bcd7b879d9",
|
||||
importpath = "github.com/libp2p/go-libp2p-interface-connmgr",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_libp2p_go_conn_security_multistream",
|
||||
commit = "df26ef91ad66a626a4b7147fd95d18962395a20e",
|
||||
importpath = "github.com/libp2p/go-conn-security-multistream",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_libp2p_go_libp2p_metrics",
|
||||
commit = "c51c712333790bf9318c6d02b2e0129c239b5d65",
|
||||
importpath = "github.com/libp2p/go-libp2p-metrics",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_libp2p_go_libp2p_net",
|
||||
commit = "d387f776809c666d02d69953e860be9f5bad5640",
|
||||
importpath = "github.com/libp2p/go-libp2p-net",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_whyrusleeping_mafmt",
|
||||
commit = "1dc32401ee9fdd3f6cdb3405ec984d5dae877b2a",
|
||||
importpath = "github.com/whyrusleeping/mafmt",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_multiformats_go_multiaddr_net",
|
||||
commit = "cba4f9fea8613343eb7ecc4ddadd8e7298a00c39",
|
||||
importpath = "github.com/multiformats/go-multiaddr-net",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_agl_ed25519",
|
||||
commit = "5312a61534124124185d41f09206b9fef1d88403",
|
||||
importpath = "github.com/agl/ed25519",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_minio_blake2b_simd",
|
||||
commit = "3f5f724cb5b182a5c278d6d3d55b40e7f8c2efb4",
|
||||
importpath = "github.com/minio/blake2b-simd",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_gxed_hashland",
|
||||
commit = "d9f6b97f8db22dd1e090fd0bbbe98f09cc7dd0a8",
|
||||
importpath = "github.com/gxed/hashland",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_mattn_go_colorable",
|
||||
commit = "efa589957cd060542a26d2dd7832fd6a6c6c3ade",
|
||||
importpath = "github.com/mattn/go-colorable",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_whyrusleeping_mdns",
|
||||
commit = "348bb87e5cd39b33dba9a33cb20802111e5ee029",
|
||||
importpath = "github.com/whyrusleeping/mdns",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_btcsuite_btcd",
|
||||
commit = "fdfc19097e7ac6b57035062056f5b7b4638b8898",
|
||||
importpath = "github.com/btcsuite/btcd",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_minio_sha256_simd",
|
||||
commit = "ad98a36ba0da87206e3378c556abbfeaeaa98668",
|
||||
importpath = "github.com/minio/sha256-simd",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_mr_tron_base58",
|
||||
commit = "4df4dc6e86a912614d09719d10cad427b087cbfb",
|
||||
importpath = "github.com/mr-tron/base58",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_whyrusleeping_go_smux_yamux",
|
||||
commit = "eac25f3e2d47aae211e457e7664b52634c95eea8",
|
||||
importpath = "github.com/whyrusleeping/go-smux-yamux",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_libp2p_go_libp2p_secio",
|
||||
commit = "6cb371175c430ef0d98ed06c0b1de4df275a2b2d",
|
||||
importpath = "github.com/libp2p/go-libp2p-secio",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_libp2p_go_tcp_transport",
|
||||
commit = "d8cd27e09a919868bf2a9bbe144453b974a35b3f",
|
||||
importpath = "github.com/libp2p/go-tcp-transport",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_libp2p_go_libp2p_protocol",
|
||||
commit = "b29f3d97e3a2fb8b29c5d04290e6cb5c5018004b",
|
||||
importpath = "github.com/libp2p/go-libp2p-protocol",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_jbenet_goprocess",
|
||||
commit = "b497e2f366b8624394fb2e89c10ab607bebdde0b",
|
||||
importpath = "github.com/jbenet/goprocess",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_multiformats_go_multistream",
|
||||
commit = "aea59cd120a7f60ed64cc98ffc1af2e6a84c470f",
|
||||
importpath = "github.com/multiformats/go-multistream",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_libp2p_go_libp2p_loggables",
|
||||
commit = "825bdca6800792bf8013c54670072023f58f2770",
|
||||
importpath = "github.com/libp2p/go-libp2p-loggables",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_libp2p_go_libp2p_nat",
|
||||
commit = "b2342fe96714ea4535cd80706967f7deab0706e9",
|
||||
importpath = "github.com/libp2p/go-libp2p-nat",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_multiformats_go_multiaddr_dns",
|
||||
commit = "78f39e8892d4f8c5c9f18679cc06d0b40ecab8cf",
|
||||
importpath = "github.com/multiformats/go-multiaddr-dns",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_fd_go_nat",
|
||||
commit = "bad65a492f32121a87197f4a085905c35e2a367e",
|
||||
importpath = "github.com/fd/go-nat",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_whyrusleeping_go_logging",
|
||||
commit = "0457bb6b88fc1973573aaf6b5145d8d3ae972390",
|
||||
importpath = "github.com/whyrusleeping/go-logging",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_mattn_go_isatty",
|
||||
commit = "6ca4dbf54d38eea1a992b3c722a76a5d1c4cb25c",
|
||||
importpath = "github.com/mattn/go-isatty",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_libp2p_go_stream_muxer",
|
||||
commit = "9c6bd93eecbbab56630bb2688bb435d9fd1dfeb1",
|
||||
importpath = "github.com/libp2p/go-stream-muxer",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_libp2p_go_libp2p_transport_upgrader",
|
||||
commit = "baf347fe2d1b8d138a9eccaebfacbb8d45f565ff",
|
||||
importpath = "github.com/libp2p/go-libp2p-transport-upgrader",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_libp2p_go_testutil",
|
||||
commit = "f967bbd5fcb7fb6337504e5d78c53c865e80733c",
|
||||
importpath = "github.com/libp2p/go-testutil",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_whyrusleeping_go_smux_multistream",
|
||||
commit = "c707bf3c25fa380b20b54907790efde288775938",
|
||||
importpath = "github.com/whyrusleeping/go-smux-multistream",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_libp2p_go_maddr_filter",
|
||||
commit = "57fd7e2ed649ba28b4f2c7bcab3a606e7cc4b12c",
|
||||
importpath = "github.com/libp2p/go-maddr-filter",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_libp2p_go_libp2p_transport",
|
||||
commit = "52a99afeb515360b51a5e357fedc925b2dcb1deb",
|
||||
importpath = "github.com/libp2p/go-libp2p-transport",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_libp2p_go_addr_util",
|
||||
commit = "56c6a7f748424cab4ff68da653ff01363e3cd745",
|
||||
importpath = "github.com/libp2p/go-addr-util",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_libp2p_go_libp2p_interface_pnet",
|
||||
commit = "86e6fc84b906599eac696308369896ece0ced63b",
|
||||
importpath = "github.com/libp2p/go-libp2p-interface-pnet",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_libp2p_go_conn_security",
|
||||
commit = "1f43a64c9d5d3796daca8d9e9dd2f2001272a706",
|
||||
importpath = "github.com/libp2p/go-conn-security",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_whyrusleeping_timecache",
|
||||
commit = "cfcb2f1abfee846c430233aef0b630a946e0a5a6",
|
||||
importpath = "github.com/whyrusleeping/timecache",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_miekg_dns",
|
||||
commit = "3e6e47bc11bc7f93f9e2f1c7bd6481ba4802808b",
|
||||
importpath = "github.com/miekg/dns",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_opentracing_opentracing_go",
|
||||
commit = "bd9c3193394760d98b2fa6ebb2291f0cd1d06a7d",
|
||||
importpath = "github.com/opentracing/opentracing-go",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_libp2p_go_reuseport",
|
||||
commit = "c2c3368efe65c8b85ddff6b278df5bef3ce235e2",
|
||||
importpath = "github.com/libp2p/go-reuseport",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_huin_goupnp",
|
||||
commit = "1395d1447324cbea88d249fbfcfd70ea878fdfca",
|
||||
importpath = "github.com/huin/goupnp",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_spaolacci_murmur3",
|
||||
commit = "f09979ecbc725b9e6d41a297405f65e7e8804acc",
|
||||
importpath = "github.com/spaolacci/murmur3",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_jbenet_go_temp_err_catcher",
|
||||
commit = "aac704a3f4f27190b4ccc05f303a4931fd1241ff",
|
||||
importpath = "github.com/jbenet/go-temp-err-catcher",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_satori_go_uuid",
|
||||
commit = "36e9d2ebbde5e3f13ab2e25625fd453271d6522e",
|
||||
importpath = "github.com/satori/go.uuid",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_sirupsen_logrus",
|
||||
importpath = "github.com/sirupsen/logrus",
|
||||
@ -56,16 +386,106 @@ go_repository(
|
||||
|
||||
go_repository(
|
||||
name = "org_golang_x_sys",
|
||||
commit = "1b2967e3c290b7c545b3db0deeda16e9be4f98a2",
|
||||
commit = "3c6ecd8f22c6f40fbeec94c000a069d7d87c7624",
|
||||
importpath = "golang.org/x/sys",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_whyrusleeping_yamux",
|
||||
commit = "35d045d4429ecf19430a2b94efc590bc40f2f7af",
|
||||
importpath = "github.com/whyrusleeping/yamux",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_libp2p_go_flow_metrics",
|
||||
commit = "3b3bcfcf78f2dc0e85be13ef3c3adc64cc5a9347",
|
||||
importpath = "github.com/libp2p/go-flow-metrics",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_libp2p_go_msgio",
|
||||
commit = "d82125c9907e1365775356505f14277d47dfd4d6",
|
||||
importpath = "github.com/libp2p/go-msgio",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_jackpal_gateway",
|
||||
commit = "cbcf4e3f3baee7952fc386c8b2534af4d267c875",
|
||||
importpath = "github.com/jackpal/gateway",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_whyrusleeping_multiaddr_filter",
|
||||
commit = "e903e4adabd70b78bc9293b6ee4f359afb3f9f59",
|
||||
importpath = "github.com/whyrusleeping/multiaddr-filter",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_libp2p_go_ws_transport",
|
||||
commit = "0c9c253a870ece2182843290e616b8c103abb9c6",
|
||||
importpath = "github.com/libp2p/go-ws-transport",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "org_golang_x_crypto",
|
||||
commit = "a49355c7e3f8fe157a85be2f77e6e269a0f89602",
|
||||
importpath = "golang.org/x/crypto",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_jackpal_go_nat_pmp",
|
||||
commit = "28a68d0c24adce1da43f8df6a57340909ecd7fdd",
|
||||
importpath = "github.com/jackpal/go-nat-pmp",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_libp2p_go_reuseport_transport",
|
||||
commit = "3165117d78404111af975e3e9af2b54dd46f0819",
|
||||
importpath = "github.com/libp2p/go-reuseport-transport",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_libp2p_go_sockaddr",
|
||||
commit = "3c898fbfff40e5933d76362819727708dae6da97",
|
||||
importpath = "github.com/libp2p/go-sockaddr",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_whyrusleeping_go_notifier",
|
||||
commit = "097c5d47330ff6a823f67e3515faa13566a62c6f",
|
||||
importpath = "github.com/whyrusleeping/go-notifier",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_gorilla_websocket",
|
||||
commit = "5ed622c449da6d44c3c8329331ff47a9e5844f71",
|
||||
importpath = "github.com/gorilla/websocket",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_whyrusleeping_go_smux_multiplex",
|
||||
commit = "121cd99ce58b0b5a36d9630e3f673bce4733ac6f",
|
||||
importpath = "github.com/whyrusleeping/go-smux-multiplex",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_gxed_eventfd",
|
||||
commit = "80a92cca79a8041496ccc9dd773fcb52a57ec6f9",
|
||||
importpath = "github.com/gxed/eventfd",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_whyrusleeping_go_multiplex",
|
||||
commit = "015295179194cbcc2eb7e13504222749af868544",
|
||||
importpath = "github.com/whyrusleeping/go-multiplex",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_gxed_goendian",
|
||||
commit = "0f5c6873267e5abf306ffcdfcfa4bf77517ef4a7",
|
||||
importpath = "github.com/gxed/GoEndian",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "com_github_syndtr_goleveldb",
|
||||
commit = "c4c61651e9e37fa117f53c5a906d3b63090d8445",
|
||||
|
24
contracts/deployVRC/BUILD.bazel
Normal file
24
contracts/deployVRC/BUILD.bazel
Normal file
@ -0,0 +1,24 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["deployVRC.go"],
|
||||
importpath = "github.com/prysmaticlabs/geth-sharding/contracts/deployVRC",
|
||||
visibility = ["//visibility:private"],
|
||||
deps = [
|
||||
"//contracts:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//accounts/abi/bind:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//accounts/keystore:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//crypto:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//ethclient:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//rpc:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
"@com_github_urfave_cli//:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_binary(
|
||||
name = "deployVRC",
|
||||
embed = [":go_default_library"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
45
contracts/deployVRC/README.md
Normal file
45
contracts/deployVRC/README.md
Normal file
@ -0,0 +1,45 @@
|
||||
## Utility to Deploy Validator Registraction Contract
|
||||
|
||||
This is a utility to help users deploy validator registration contract for running their own beacon chain node in a local containerized set up. To run the utility, it assumes there is a running geth node as a separate process attached to proof-of-work main chain. The utility will deploy the validator registration contract and print out the contract address. Users will pass the contract address to the beacon chain node to monitor when they have been conducted to become an active validator.
|
||||
|
||||
### Usage
|
||||
|
||||
*Name:*
|
||||
**deployVRC** - this is a util to deploy validator registration contract
|
||||
|
||||
*Usage:*
|
||||
deployVRC [global options] command [command options] [arguments...]
|
||||
|
||||
*Flags:*
|
||||
**--keystoreUTCPath** Keystore UTC file to unlock account (default: "./datadir/keystore/UTC...")
|
||||
**--ipcPath** Filename for IPC socket/pipe within the datadir (default: "./geth.ipc")
|
||||
**--httpPath** HTTP-RPC server listening interface (default: "http://localhost:8545/")
|
||||
**--passwordFile** Password file for unlock account (default: "./password.txt")
|
||||
**--privKey** Private key to unlock account
|
||||
**--help, -h** show help
|
||||
**--version, -v** print the version
|
||||
|
||||
### Example
|
||||
To use private key with default RPC:
|
||||
```
|
||||
bazel run //deployVRC --privKey yourPrivateKey
|
||||
```
|
||||
|
||||
To use UTC JSON with IPC:
|
||||
```
|
||||
bazel run //deployVRC --ipcPath /path/to/your/geth.ipc --UTCPath /path/to/your/keystore/UTCJSON --passwordFile /path/to/your/password.txt
|
||||
```
|
||||
To use UTC JSON with RPC:
|
||||
```
|
||||
bazel run //deployVRC --httpPath http://localhost:8545/ --UTCPath /path/to/your/keystore/UTCJSON --passwordFile /path/to/your/password.txt
|
||||
```
|
||||
or
|
||||
```
|
||||
bazel run //deployVRC --UTCPath /path/to/your/keystore/UTCJSON --passwordFile /path/to/your/password.txt
|
||||
|
||||
```
|
||||
|
||||
### Output
|
||||
```
|
||||
INFO[0001] New contract deployed at 0x5275C2220C574330E230bFB7e4a0b96f60a18f02
|
||||
```
|
131
contracts/deployVRC/deployVRC.go
Normal file
131
contracts/deployVRC/deployVRC.go
Normal file
@ -0,0 +1,131 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"io/ioutil"
|
||||
"math/big"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||
"github.com/ethereum/go-ethereum/accounts/keystore"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/ethclient"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
"github.com/prysmaticlabs/geth-sharding/contracts"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var keystoreUTCPath string
|
||||
var ipcPath string
|
||||
var passwordFile string
|
||||
var httpPath string
|
||||
var privKeyString string
|
||||
|
||||
app := cli.NewApp()
|
||||
app.Name = "deployVRC"
|
||||
app.Usage = "this is a util to deploy validator registration contract"
|
||||
app.Flags = []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "keystoreUTCPath",
|
||||
Usage: "Location of keystore",
|
||||
Destination: &keystoreUTCPath,
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "ipcPath",
|
||||
Usage: "Filename for IPC socket/pipe within the datadir",
|
||||
Destination: &ipcPath,
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "httpPath",
|
||||
Value: "http://localhost:8545/",
|
||||
Usage: "HTTP-RPC server listening interface",
|
||||
Destination: &httpPath,
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "passwordFile",
|
||||
Value: "./password.txt",
|
||||
Usage: "Password file for unlock account",
|
||||
Destination: &passwordFile,
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "privKey",
|
||||
Usage: "Private key to unlock account",
|
||||
Destination: &privKeyString,
|
||||
},
|
||||
}
|
||||
|
||||
app.Action = func(c *cli.Context) {
|
||||
// Set up RPC client
|
||||
var rpcClient *rpc.Client
|
||||
var err error
|
||||
var txOps *bind.TransactOpts
|
||||
|
||||
// Uses HTTP-RPC if IPC is not set
|
||||
if ipcPath == "" {
|
||||
rpcClient, err = rpc.Dial(httpPath)
|
||||
} else {
|
||||
rpcClient, err = rpc.Dial(ipcPath)
|
||||
}
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
client := ethclient.NewClient(rpcClient)
|
||||
|
||||
// User inputs private key, sign tx with private key
|
||||
if privKeyString != "" {
|
||||
privKey, err := crypto.HexToECDSA(privKeyString)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
txOps = bind.NewKeyedTransactor(privKey)
|
||||
txOps.Value = big.NewInt(0)
|
||||
|
||||
// User inputs keystore json file, sign tx with keystore json
|
||||
} else {
|
||||
file, err := os.Open(passwordFile)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
scanner := bufio.NewScanner(file)
|
||||
scanner.Split(bufio.ScanWords)
|
||||
scanner.Scan()
|
||||
password := scanner.Text()
|
||||
|
||||
keyJSON, _ := ioutil.ReadFile(keystoreUTCPath)
|
||||
privKey, err := keystore.DecryptKey(keyJSON, password)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
txOps = bind.NewKeyedTransactor(privKey.PrivateKey)
|
||||
txOps.Value = big.NewInt(0)
|
||||
}
|
||||
|
||||
// Deploy validator registration contract
|
||||
addr, tx, _, err := contracts.DeployValidatorRegistration(txOps, client)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Wait for contract to mine
|
||||
for pending := true; pending; _, pending, err = client.TransactionByHash(context.Background(), tx.Hash()) {
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
time.Sleep(1 * time.Second)
|
||||
}
|
||||
|
||||
log.Infof("New contract deployed at %s", addr.Hex())
|
||||
}
|
||||
|
||||
err := app.Run(os.Args)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
@ -19,7 +19,7 @@ import (
|
||||
const ValidatorRegistrationABI = "[{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"usedPubkey\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"VALIDATOR_DEPOSIT\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_pubkey\",\"type\":\"bytes32\"},{\"name\":\"_withdrawalShardID\",\"type\":\"uint256\"},{\"name\":\"_withdrawalAddressbytes32\",\"type\":\"address\"},{\"name\":\"_randaoCommitment\",\"type\":\"bytes32\"}],\"name\":\"deposit\",\"outputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"pubKey\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"withdrawalShardID\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"withdrawalAddressbytes32\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"randaoCommitment\",\"type\":\"bytes32\"}],\"name\":\"ValidatorRegistered\",\"type\":\"event\"}]"
|
||||
|
||||
// ValidatorRegistrationBin is the compiled bytecode used for deploying new contracts.
|
||||
const ValidatorRegistrationBin = `0x608060405234801561001057600080fd5b506101d3806100206000396000f3006080604052600436106100565763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166301110845811461005b578063441d92cc14610087578063881d2135146100ae575b600080fd5b34801561006757600080fd5b506100736004356100da565b604080519115158252519081900360200190f35b34801561009357600080fd5b5061009c6100ef565b60408051918252519081900360200190f35b6100d860043560243573ffffffffffffffffffffffffffffffffffffffff604435166064356100fc565b005b60006020819052908152604090205460ff1681565b6801bc16d674ec80000081565b346801bc16d674ec8000001461011157600080fd5b60008481526020819052604090205460ff161561012d57600080fd5b60008481526020818152604091829020805460ff19166001179055815186815290810185905273ffffffffffffffffffffffffffffffffffffffff8416818301526060810183905290517f7b0678aab009b61a805f5004869728b53a444f9a3e6bb9e22b8537c89af512749181900360800190a1505050505600a165627a7a72305820ba933a3e2d7a01de483490b3379e3c0ff9eb8040d0bb6eccf192fca140f752d70029`
|
||||
const ValidatorRegistrationBin = `0x608060405234801561001057600080fd5b506101d3806100206000396000f3006080604052600436106100565763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166301110845811461005b578063441d92cc14610087578063881d2135146100ae575b600080fd5b34801561006757600080fd5b506100736004356100da565b604080519115158252519081900360200190f35b34801561009357600080fd5b5061009c6100ef565b60408051918252519081900360200190f35b6100d860043560243573ffffffffffffffffffffffffffffffffffffffff604435166064356100fc565b005b60006020819052908152604090205460ff1681565b6801bc16d674ec80000081565b346801bc16d674ec8000001461011157600080fd5b60008481526020819052604090205460ff161561012d57600080fd5b60008481526020818152604091829020805460ff19166001179055815186815290810185905273ffffffffffffffffffffffffffffffffffffffff8416818301526060810183905290517f7b0678aab009b61a805f5004869728b53a444f9a3e6bb9e22b8537c89af512749181900360800190a1505050505600a165627a7a7230582030b51cf5829c9fac611cd2060acc062996b9cc9cf3d57d32b2b54c509a32b85d0029`
|
||||
|
||||
// DeployValidatorRegistration deploys a new Ethereum contract, binding an instance of ValidatorRegistration to it.
|
||||
func DeployValidatorRegistration(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *ValidatorRegistration, error) {
|
||||
|
28
proto/sharding/v1/BUILD.bazel
Normal file
28
proto/sharding/v1/BUILD.bazel
Normal file
@ -0,0 +1,28 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
|
||||
|
||||
proto_library(
|
||||
name = "messages_proto",
|
||||
srcs = ["messages.proto"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
go_proto_library(
|
||||
name = "messages_go_proto",
|
||||
importpath = "github.com/prysmaticlabs/geth-sharding/proto/sharding/v1",
|
||||
proto = ":ethereum_messages_v1_proto",
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
embed = [":messages_go_proto"],
|
||||
importpath = "github.com/prysmaticlabs/geth-sharding/proto/sharding/v1",
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
proto_library(
|
||||
name = "ethereum_messages_v1_proto",
|
||||
srcs = ["messages.proto"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
346
proto/sharding/v1/messages.pb.go
Normal file
346
proto/sharding/v1/messages.pb.go
Normal file
@ -0,0 +1,346 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// source: messages.proto
|
||||
|
||||
package ethereum_messages_v1
|
||||
|
||||
import proto "github.com/golang/protobuf/proto"
|
||||
import fmt "fmt"
|
||||
import math "math"
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
|
||||
|
||||
type Topic int32
|
||||
|
||||
const (
|
||||
Topic_UNKNOWN Topic = 0
|
||||
Topic_COLLATION_BODY_REQUEST Topic = 1
|
||||
Topic_COLLATION_BODY_RESPONSE Topic = 2
|
||||
Topic_TRANSACTIONS Topic = 3
|
||||
)
|
||||
|
||||
var Topic_name = map[int32]string{
|
||||
0: "UNKNOWN",
|
||||
1: "COLLATION_BODY_REQUEST",
|
||||
2: "COLLATION_BODY_RESPONSE",
|
||||
3: "TRANSACTIONS",
|
||||
}
|
||||
var Topic_value = map[string]int32{
|
||||
"UNKNOWN": 0,
|
||||
"COLLATION_BODY_REQUEST": 1,
|
||||
"COLLATION_BODY_RESPONSE": 2,
|
||||
"TRANSACTIONS": 3,
|
||||
}
|
||||
|
||||
func (x Topic) String() string {
|
||||
return proto.EnumName(Topic_name, int32(x))
|
||||
}
|
||||
func (Topic) EnumDescriptor() ([]byte, []int) {
|
||||
return fileDescriptor_messages_b2b448a5e8345e4f, []int{0}
|
||||
}
|
||||
|
||||
type CollationBodyRequest struct {
|
||||
ShardId uint64 `protobuf:"varint,1,opt,name=shard_id,json=shardId,proto3" json:"shard_id,omitempty"`
|
||||
Period uint64 `protobuf:"varint,2,opt,name=period,proto3" json:"period,omitempty"`
|
||||
ChunkRoot []byte `protobuf:"bytes,3,opt,name=chunk_root,json=chunkRoot,proto3" json:"chunk_root,omitempty"`
|
||||
ProposerAddress []byte `protobuf:"bytes,4,opt,name=proposer_address,json=proposerAddress,proto3" json:"proposer_address,omitempty"`
|
||||
Signature []byte `protobuf:"bytes,5,opt,name=signature,proto3" json:"signature,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *CollationBodyRequest) Reset() { *m = CollationBodyRequest{} }
|
||||
func (m *CollationBodyRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*CollationBodyRequest) ProtoMessage() {}
|
||||
func (*CollationBodyRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_messages_b2b448a5e8345e4f, []int{0}
|
||||
}
|
||||
func (m *CollationBodyRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_CollationBodyRequest.Unmarshal(m, b)
|
||||
}
|
||||
func (m *CollationBodyRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_CollationBodyRequest.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (dst *CollationBodyRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_CollationBodyRequest.Merge(dst, src)
|
||||
}
|
||||
func (m *CollationBodyRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_CollationBodyRequest.Size(m)
|
||||
}
|
||||
func (m *CollationBodyRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_CollationBodyRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_CollationBodyRequest proto.InternalMessageInfo
|
||||
|
||||
func (m *CollationBodyRequest) GetShardId() uint64 {
|
||||
if m != nil {
|
||||
return m.ShardId
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *CollationBodyRequest) GetPeriod() uint64 {
|
||||
if m != nil {
|
||||
return m.Period
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *CollationBodyRequest) GetChunkRoot() []byte {
|
||||
if m != nil {
|
||||
return m.ChunkRoot
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *CollationBodyRequest) GetProposerAddress() []byte {
|
||||
if m != nil {
|
||||
return m.ProposerAddress
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *CollationBodyRequest) GetSignature() []byte {
|
||||
if m != nil {
|
||||
return m.Signature
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type CollationBodyResponse struct {
|
||||
HeaderHash []byte `protobuf:"bytes,1,opt,name=header_hash,json=headerHash,proto3" json:"header_hash,omitempty"`
|
||||
Body []byte `protobuf:"bytes,2,opt,name=body,proto3" json:"body,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *CollationBodyResponse) Reset() { *m = CollationBodyResponse{} }
|
||||
func (m *CollationBodyResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*CollationBodyResponse) ProtoMessage() {}
|
||||
func (*CollationBodyResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_messages_b2b448a5e8345e4f, []int{1}
|
||||
}
|
||||
func (m *CollationBodyResponse) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_CollationBodyResponse.Unmarshal(m, b)
|
||||
}
|
||||
func (m *CollationBodyResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_CollationBodyResponse.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (dst *CollationBodyResponse) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_CollationBodyResponse.Merge(dst, src)
|
||||
}
|
||||
func (m *CollationBodyResponse) XXX_Size() int {
|
||||
return xxx_messageInfo_CollationBodyResponse.Size(m)
|
||||
}
|
||||
func (m *CollationBodyResponse) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_CollationBodyResponse.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_CollationBodyResponse proto.InternalMessageInfo
|
||||
|
||||
func (m *CollationBodyResponse) GetHeaderHash() []byte {
|
||||
if m != nil {
|
||||
return m.HeaderHash
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *CollationBodyResponse) GetBody() []byte {
|
||||
if m != nil {
|
||||
return m.Body
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Transaction struct {
|
||||
Nonce uint64 `protobuf:"varint,1,opt,name=nonce,proto3" json:"nonce,omitempty"`
|
||||
GasPrice uint64 `protobuf:"varint,2,opt,name=gas_price,json=gasPrice,proto3" json:"gas_price,omitempty"`
|
||||
GasLimit uint64 `protobuf:"varint,3,opt,name=gas_limit,json=gasLimit,proto3" json:"gas_limit,omitempty"`
|
||||
Recipient []byte `protobuf:"bytes,4,opt,name=recipient,proto3" json:"recipient,omitempty"`
|
||||
Value uint64 `protobuf:"varint,5,opt,name=value,proto3" json:"value,omitempty"`
|
||||
Input []byte `protobuf:"bytes,6,opt,name=input,proto3" json:"input,omitempty"`
|
||||
Signature *Signture `protobuf:"bytes,7,opt,name=signature,proto3" json:"signature,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Transaction) Reset() { *m = Transaction{} }
|
||||
func (m *Transaction) String() string { return proto.CompactTextString(m) }
|
||||
func (*Transaction) ProtoMessage() {}
|
||||
func (*Transaction) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_messages_b2b448a5e8345e4f, []int{2}
|
||||
}
|
||||
func (m *Transaction) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_Transaction.Unmarshal(m, b)
|
||||
}
|
||||
func (m *Transaction) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_Transaction.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (dst *Transaction) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_Transaction.Merge(dst, src)
|
||||
}
|
||||
func (m *Transaction) XXX_Size() int {
|
||||
return xxx_messageInfo_Transaction.Size(m)
|
||||
}
|
||||
func (m *Transaction) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_Transaction.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_Transaction proto.InternalMessageInfo
|
||||
|
||||
func (m *Transaction) GetNonce() uint64 {
|
||||
if m != nil {
|
||||
return m.Nonce
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *Transaction) GetGasPrice() uint64 {
|
||||
if m != nil {
|
||||
return m.GasPrice
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *Transaction) GetGasLimit() uint64 {
|
||||
if m != nil {
|
||||
return m.GasLimit
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *Transaction) GetRecipient() []byte {
|
||||
if m != nil {
|
||||
return m.Recipient
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Transaction) GetValue() uint64 {
|
||||
if m != nil {
|
||||
return m.Value
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *Transaction) GetInput() []byte {
|
||||
if m != nil {
|
||||
return m.Input
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Transaction) GetSignature() *Signture {
|
||||
if m != nil {
|
||||
return m.Signature
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Signture struct {
|
||||
V uint64 `protobuf:"varint,1,opt,name=v,proto3" json:"v,omitempty"`
|
||||
R uint64 `protobuf:"varint,2,opt,name=r,proto3" json:"r,omitempty"`
|
||||
S uint64 `protobuf:"varint,3,opt,name=s,proto3" json:"s,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Signture) Reset() { *m = Signture{} }
|
||||
func (m *Signture) String() string { return proto.CompactTextString(m) }
|
||||
func (*Signture) ProtoMessage() {}
|
||||
func (*Signture) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_messages_b2b448a5e8345e4f, []int{3}
|
||||
}
|
||||
func (m *Signture) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_Signture.Unmarshal(m, b)
|
||||
}
|
||||
func (m *Signture) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_Signture.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (dst *Signture) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_Signture.Merge(dst, src)
|
||||
}
|
||||
func (m *Signture) XXX_Size() int {
|
||||
return xxx_messageInfo_Signture.Size(m)
|
||||
}
|
||||
func (m *Signture) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_Signture.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_Signture proto.InternalMessageInfo
|
||||
|
||||
func (m *Signture) GetV() uint64 {
|
||||
if m != nil {
|
||||
return m.V
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *Signture) GetR() uint64 {
|
||||
if m != nil {
|
||||
return m.R
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *Signture) GetS() uint64 {
|
||||
if m != nil {
|
||||
return m.S
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*CollationBodyRequest)(nil), "ethereum.messages.v1.CollationBodyRequest")
|
||||
proto.RegisterType((*CollationBodyResponse)(nil), "ethereum.messages.v1.CollationBodyResponse")
|
||||
proto.RegisterType((*Transaction)(nil), "ethereum.messages.v1.Transaction")
|
||||
proto.RegisterType((*Signture)(nil), "ethereum.messages.v1.Signture")
|
||||
proto.RegisterEnum("ethereum.messages.v1.Topic", Topic_name, Topic_value)
|
||||
}
|
||||
|
||||
func init() { proto.RegisterFile("messages.proto", fileDescriptor_messages_b2b448a5e8345e4f) }
|
||||
|
||||
var fileDescriptor_messages_b2b448a5e8345e4f = []byte{
|
||||
// 445 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x92, 0xcd, 0x6e, 0xd3, 0x4c,
|
||||
0x14, 0x86, 0xbf, 0x69, 0xf3, 0x7b, 0x62, 0x7d, 0x58, 0xa3, 0x50, 0x0c, 0xe5, 0x27, 0xca, 0x2a,
|
||||
0xb0, 0x88, 0xc4, 0xcf, 0x92, 0x4d, 0x1a, 0x22, 0x51, 0x11, 0xd9, 0xc5, 0x76, 0x85, 0x58, 0x59,
|
||||
0x53, 0xfb, 0xc8, 0x1e, 0x91, 0xcc, 0x98, 0x39, 0x76, 0xa4, 0x5e, 0x16, 0x17, 0xc5, 0x7d, 0xa0,
|
||||
0xb1, 0x9d, 0x52, 0x01, 0x3b, 0x3f, 0xef, 0x7b, 0x34, 0x3e, 0xcf, 0xd8, 0xf0, 0xff, 0x1e, 0x89,
|
||||
0x44, 0x8e, 0xb4, 0x2c, 0x8d, 0xae, 0x34, 0x9f, 0x62, 0x55, 0xa0, 0xc1, 0x7a, 0xbf, 0xbc, 0x2b,
|
||||
0x0e, 0xaf, 0xe7, 0x3f, 0x18, 0x4c, 0xd7, 0x7a, 0xb7, 0x13, 0x95, 0xd4, 0xea, 0x42, 0x67, 0xb7,
|
||||
0x21, 0x7e, 0xaf, 0x91, 0x2a, 0xfe, 0x18, 0x46, 0x54, 0x08, 0x93, 0x25, 0x32, 0xf3, 0xd8, 0x8c,
|
||||
0x2d, 0x7a, 0xe1, 0xb0, 0xe1, 0xcb, 0x8c, 0x9f, 0xc1, 0xa0, 0x44, 0x23, 0x75, 0xe6, 0x9d, 0x34,
|
||||
0x45, 0x47, 0xfc, 0x19, 0x40, 0x5a, 0xd4, 0xea, 0x5b, 0x62, 0xb4, 0xae, 0xbc, 0xd3, 0x19, 0x5b,
|
||||
0x38, 0xe1, 0xb8, 0x49, 0x42, 0xad, 0x2b, 0xfe, 0x12, 0xdc, 0xd2, 0xe8, 0x52, 0x13, 0x9a, 0x44,
|
||||
0x64, 0x99, 0x41, 0x22, 0xaf, 0xd7, 0x0c, 0x3d, 0x38, 0xe6, 0xab, 0x36, 0xe6, 0x4f, 0x61, 0x4c,
|
||||
0x32, 0x57, 0xa2, 0xaa, 0x0d, 0x7a, 0xfd, 0xf6, 0xa0, 0xbb, 0x60, 0xbe, 0x85, 0x87, 0x7f, 0xac,
|
||||
0x4c, 0xa5, 0x56, 0x84, 0xfc, 0x05, 0x4c, 0x0a, 0x14, 0x19, 0x9a, 0xa4, 0x10, 0x54, 0x34, 0x6b,
|
||||
0x3b, 0x21, 0xb4, 0xd1, 0x47, 0x41, 0x05, 0xe7, 0xd0, 0xbb, 0xd1, 0xd9, 0x6d, 0xb3, 0xb7, 0x13,
|
||||
0x36, 0xcf, 0xf3, 0x9f, 0x0c, 0x26, 0xb1, 0x11, 0x8a, 0x44, 0x6a, 0x0f, 0xe4, 0x53, 0xe8, 0x2b,
|
||||
0xad, 0x52, 0xec, 0xac, 0x5b, 0xe0, 0xe7, 0x30, 0xce, 0x05, 0x25, 0xa5, 0x91, 0x29, 0x76, 0xda,
|
||||
0xa3, 0x5c, 0xd0, 0x95, 0xe5, 0x63, 0xb9, 0x93, 0x7b, 0xd9, 0x7a, 0xb7, 0xe5, 0xd6, 0xb2, 0x75,
|
||||
0x31, 0x98, 0xca, 0x52, 0xa2, 0xaa, 0x3a, 0xdf, 0xdf, 0x81, 0x7d, 0xdb, 0x41, 0xec, 0xea, 0xd6,
|
||||
0xb2, 0x17, 0xb6, 0x60, 0x53, 0xa9, 0xca, 0xba, 0xf2, 0x06, 0xcd, 0x7c, 0x0b, 0xfc, 0xfd, 0xfd,
|
||||
0x5b, 0x19, 0xce, 0xd8, 0x62, 0xf2, 0xe6, 0xf9, 0xf2, 0x5f, 0x5f, 0x75, 0x19, 0xc9, 0x5c, 0xd9,
|
||||
0xa9, 0xfb, 0xb7, 0xf6, 0x0e, 0x46, 0xc7, 0x98, 0x3b, 0xc0, 0x0e, 0x9d, 0x1f, 0x3b, 0x58, 0x32,
|
||||
0x9d, 0x13, 0x33, 0x96, 0xa8, 0x93, 0x60, 0xf4, 0x2a, 0x81, 0x7e, 0xac, 0x4b, 0x99, 0xf2, 0x09,
|
||||
0x0c, 0xaf, 0xfd, 0x4f, 0x7e, 0xf0, 0xc5, 0x77, 0xff, 0xe3, 0x4f, 0xe0, 0x6c, 0x1d, 0x6c, 0xb7,
|
||||
0xab, 0xf8, 0x32, 0xf0, 0x93, 0x8b, 0xe0, 0xc3, 0xd7, 0x24, 0xdc, 0x7c, 0xbe, 0xde, 0x44, 0xb1,
|
||||
0xcb, 0xf8, 0x39, 0x3c, 0xfa, 0xab, 0x8b, 0xae, 0x02, 0x3f, 0xda, 0xb8, 0x27, 0xdc, 0x05, 0x27,
|
||||
0x0e, 0x57, 0x7e, 0xb4, 0x5a, 0xdb, 0x3a, 0x72, 0x4f, 0x6f, 0x06, 0xcd, 0xdf, 0xf9, 0xf6, 0x57,
|
||||
0x00, 0x00, 0x00, 0xff, 0xff, 0x27, 0xa7, 0xf1, 0x57, 0xaf, 0x02, 0x00, 0x00,
|
||||
}
|
39
proto/sharding/v1/messages.proto
Normal file
39
proto/sharding/v1/messages.proto
Normal file
@ -0,0 +1,39 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package ethereum.messages.v1;
|
||||
|
||||
enum Topic {
|
||||
UNKNOWN = 0;
|
||||
COLLATION_BODY_REQUEST = 1;
|
||||
COLLATION_BODY_RESPONSE = 2;
|
||||
TRANSACTIONS = 3;
|
||||
}
|
||||
|
||||
message CollationBodyRequest {
|
||||
uint64 shard_id = 1;
|
||||
uint64 period = 2;
|
||||
bytes chunk_root = 3;
|
||||
bytes proposer_address = 4;
|
||||
bytes signature = 5;
|
||||
}
|
||||
|
||||
message CollationBodyResponse {
|
||||
bytes header_hash = 1;
|
||||
bytes body = 2;
|
||||
}
|
||||
|
||||
message Transaction {
|
||||
uint64 nonce = 1;
|
||||
uint64 gas_price = 2;
|
||||
uint64 gas_limit = 3;
|
||||
bytes recipient = 4;
|
||||
uint64 value = 5;
|
||||
bytes input = 6;
|
||||
Signture signature = 7;
|
||||
}
|
||||
|
||||
message Signture {
|
||||
uint64 v = 1;
|
||||
uint64 r = 2;
|
||||
uint64 s = 3;
|
||||
}
|
@ -16,7 +16,7 @@ func startNode(ctx *cli.Context) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// starts a connection to a beacon node and kicks off every registered service.
|
||||
|
||||
shardingNode.Start()
|
||||
return nil
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ go_library(
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
size = "medium",
|
||||
srcs = ["service_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
|
@ -3,15 +3,28 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"discovery.go",
|
||||
"feed.go",
|
||||
"message.go",
|
||||
"options.go",
|
||||
"peer.go",
|
||||
"service.go",
|
||||
"topics.go",
|
||||
],
|
||||
importpath = "github.com/prysmaticlabs/geth-sharding/sharding/p2p",
|
||||
visibility = ["//sharding:__subpackages__"],
|
||||
deps = [
|
||||
"//proto/sharding/v1:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//event:go_default_library",
|
||||
"@com_github_golang_protobuf//proto:go_default_library",
|
||||
"@com_github_libp2p_go_floodsub//:go_default_library",
|
||||
"@com_github_libp2p_go_libp2p//:go_default_library",
|
||||
"@com_github_libp2p_go_libp2p//p2p/discovery:go_default_library",
|
||||
"@com_github_libp2p_go_libp2p_crypto//:go_default_library",
|
||||
"@com_github_libp2p_go_libp2p_host//:go_default_library",
|
||||
"@com_github_libp2p_go_libp2p_peer//:go_default_library",
|
||||
"@com_github_libp2p_go_libp2p_peerstore//:go_default_library",
|
||||
"@com_github_multiformats_go_multiaddr//:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
],
|
||||
)
|
||||
@ -19,10 +32,25 @@ go_library(
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"discovery_test.go",
|
||||
"feed_example_test.go",
|
||||
"feed_test.go",
|
||||
"options_test.go",
|
||||
"service_test.go",
|
||||
"topics_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
deps = ["//sharding/types:go_default_library"],
|
||||
deps = [
|
||||
"//proto/sharding/v1:go_default_library",
|
||||
"//sharding/types:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//event:go_default_library",
|
||||
"@com_github_golang_protobuf//proto:go_default_library",
|
||||
"@com_github_libp2p_go_floodsub//:go_default_library",
|
||||
"@com_github_libp2p_go_libp2p//p2p/discovery:go_default_library",
|
||||
"@com_github_libp2p_go_libp2p//p2p/host/basic:go_default_library",
|
||||
"@com_github_libp2p_go_libp2p_peer//:go_default_library",
|
||||
"@com_github_libp2p_go_libp2p_swarm//testing:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
"@com_github_sirupsen_logrus//hooks/test:go_default_library",
|
||||
],
|
||||
)
|
||||
|
71
sharding/p2p/discovery.go
Normal file
71
sharding/p2p/discovery.go
Normal file
@ -0,0 +1,71 @@
|
||||
package p2p
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
host "github.com/libp2p/go-libp2p-host"
|
||||
peer "github.com/libp2p/go-libp2p-peer"
|
||||
ps "github.com/libp2p/go-libp2p-peerstore"
|
||||
mdns "github.com/libp2p/go-libp2p/p2p/discovery"
|
||||
pb "github.com/prysmaticlabs/geth-sharding/proto/sharding/v1"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// Discovery interval for multicast DNS querying.
|
||||
var discoveryInterval = 1 * time.Minute
|
||||
|
||||
// mDNSTag is the name of the mDNS service.
|
||||
var mDNSTag = mdns.ServiceTag
|
||||
|
||||
// startDiscovery protocols. Currently, this supports discovery via multicast
|
||||
// DNS peer discovery.
|
||||
//
|
||||
// TODO: add other discovery protocols such as DHT, etc.
|
||||
func startDiscovery(ctx context.Context, host host.Host, gsub topicPeerLister) error {
|
||||
mdnsService, err := mdns.NewMdnsService(ctx, host, discoveryInterval, mDNSTag)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mdnsService.RegisterNotifee(&discovery{ctx, host, gsub})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// topicPeerLister has a method to return connected peers on a given topic.
|
||||
// This is implemented by floodsub.PubSub.
|
||||
type topicPeerLister interface {
|
||||
ListPeers(string) []peer.ID
|
||||
}
|
||||
|
||||
// Discovery implements mDNS notifee interface.
|
||||
type discovery struct {
|
||||
ctx context.Context
|
||||
host host.Host
|
||||
|
||||
// Required for helper method.
|
||||
gsub topicPeerLister
|
||||
}
|
||||
|
||||
// HandlePeerFound registers the peer with the host.
|
||||
func (d *discovery) HandlePeerFound(pi ps.PeerInfo) {
|
||||
d.host.Peerstore().AddAddrs(pi.ID, pi.Addrs, ps.PermanentAddrTTL)
|
||||
if err := d.host.Connect(d.ctx, pi); err != nil {
|
||||
log.Warnf("Failed to connect to peer: %v", err)
|
||||
}
|
||||
|
||||
log.Debugf("Peers now: %s", d.host.Peerstore().Peers())
|
||||
log.Debugf("gsub has peers: %v", d.topicPeerMap())
|
||||
}
|
||||
|
||||
// topicPeerMap helper function for inspecting which peers are available for
|
||||
// the p2p topics.
|
||||
func (d *discovery) topicPeerMap() map[pb.Topic][]peer.ID {
|
||||
m := make(map[pb.Topic][]peer.ID)
|
||||
for topic := range topicTypeMapping {
|
||||
peers := d.gsub.ListPeers(topic.String())
|
||||
m[topic] = peers
|
||||
}
|
||||
return m
|
||||
}
|
64
sharding/p2p/discovery_test.go
Normal file
64
sharding/p2p/discovery_test.go
Normal file
@ -0,0 +1,64 @@
|
||||
package p2p
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
floodsub "github.com/libp2p/go-floodsub"
|
||||
peer "github.com/libp2p/go-libp2p-peer"
|
||||
swarmt "github.com/libp2p/go-libp2p-swarm/testing"
|
||||
mdns "github.com/libp2p/go-libp2p/p2p/discovery"
|
||||
bhost "github.com/libp2p/go-libp2p/p2p/host/basic"
|
||||
)
|
||||
|
||||
var _ = mdns.Notifee(&discovery{})
|
||||
var _ = topicPeerLister(&floodsub.PubSub{})
|
||||
|
||||
var _ = topicPeerLister(&fakeTopicPeerLister{})
|
||||
|
||||
type fakeTopicPeerLister struct {
|
||||
}
|
||||
|
||||
func (f *fakeTopicPeerLister) ListPeers(topic string) []peer.ID {
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestStartDiscovery_HandlePeerFound(t *testing.T) {
|
||||
discoveryInterval = 50 * time.Millisecond // Short interval for testing.
|
||||
|
||||
ctx, cancel := context.WithCancel(context.TODO())
|
||||
defer cancel()
|
||||
|
||||
gsub := &fakeTopicPeerLister{}
|
||||
|
||||
a := bhost.New(swarmt.GenSwarm(t, ctx))
|
||||
err := startDiscovery(ctx, a, gsub)
|
||||
if err != nil {
|
||||
t.Errorf("Error when starting discovery: %v", err)
|
||||
}
|
||||
|
||||
b := bhost.New(swarmt.GenSwarm(t, ctx))
|
||||
err = startDiscovery(ctx, b, gsub)
|
||||
if err != nil {
|
||||
t.Errorf("Error when starting discovery: %v", err)
|
||||
}
|
||||
|
||||
// The two hosts should have found each other after 1+ intervals.
|
||||
time.Sleep(2 * discoveryInterval)
|
||||
|
||||
expectPeers(t, a, 2)
|
||||
expectPeers(t, b, 2)
|
||||
}
|
||||
|
||||
func expectPeers(t *testing.T, h *bhost.BasicHost, n int) {
|
||||
if len(h.Peerstore().Peers()) != n {
|
||||
t.Errorf(
|
||||
"Expected %d peer for host %v, but has %d peers. They are: %v.",
|
||||
n,
|
||||
h.ID(),
|
||||
len(h.Peerstore().Peers()),
|
||||
h.Peerstore().Peers(),
|
||||
)
|
||||
}
|
||||
}
|
@ -25,7 +25,16 @@ import (
|
||||
// msg := <- ch
|
||||
// fmt.Printf("Message received: %v", msg.Data)
|
||||
func (s *Server) Feed(msg interface{}) *event.Feed {
|
||||
t := reflect.TypeOf(msg)
|
||||
var t reflect.Type
|
||||
|
||||
// Support passing reflect.Type as the msg.
|
||||
switch msg.(type) {
|
||||
case reflect.Type:
|
||||
t = msg.(reflect.Type)
|
||||
default:
|
||||
t = reflect.TypeOf(msg)
|
||||
}
|
||||
|
||||
if s.feeds[t] == nil {
|
||||
s.feeds[t] = new(event.Feed)
|
||||
}
|
||||
|
@ -1,6 +1,9 @@
|
||||
package p2p
|
||||
|
||||
import "testing"
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestFeed_ReturnsSameFeed(t *testing.T) {
|
||||
tests := []struct {
|
||||
@ -13,6 +16,7 @@ func TestFeed_ReturnsSameFeed(t *testing.T) {
|
||||
{a: 'a', b: 'b', want: true},
|
||||
{a: struct{ c int }{c: 1}, b: struct{ c int }{c: 2}, want: true},
|
||||
{a: struct{ c string }{c: "a"}, b: struct{ c string }{c: "b"}, want: true},
|
||||
{a: reflect.TypeOf(struct{ c int }{c: 1}), b: struct{ c int }{c: 2}, want: true},
|
||||
// Inequality tests
|
||||
{a: 1, b: '2', want: false},
|
||||
{a: 'a', b: 1, want: false},
|
||||
|
@ -4,6 +4,6 @@ package p2p
|
||||
type Message struct {
|
||||
// Peer represents the sender of the message.
|
||||
Peer Peer
|
||||
// Data can be any type of message found in sharding/p2p/messages package.
|
||||
// Data can be any type of message found in sharding/p2p/proto package.
|
||||
Data interface{}
|
||||
}
|
||||
|
@ -1,31 +0,0 @@
|
||||
package messages
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
)
|
||||
|
||||
// CollationBodyRequest defines a p2p message being sent over subscription feeds
|
||||
// by notaries to other notaries or to proposers.
|
||||
type CollationBodyRequest struct {
|
||||
ChunkRoot *common.Hash
|
||||
ShardID *big.Int
|
||||
Period *big.Int
|
||||
Proposer *common.Address
|
||||
Signature [32]byte
|
||||
}
|
||||
|
||||
// CollationBodyResponse defines the p2p message response sent back
|
||||
// to the requesting peer.
|
||||
type CollationBodyResponse struct {
|
||||
HeaderHash *common.Hash
|
||||
Body []byte
|
||||
}
|
||||
|
||||
// TransactionBroadcast defines the p2p message broadcast from simulators
|
||||
// to the rest of the actors for transactions to be included in collation.
|
||||
type TransactionBroadcast struct {
|
||||
Transaction *types.Transaction
|
||||
}
|
29
sharding/p2p/options.go
Normal file
29
sharding/p2p/options.go
Normal file
@ -0,0 +1,29 @@
|
||||
package p2p
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
libp2p "github.com/libp2p/go-libp2p"
|
||||
crypto "github.com/libp2p/go-libp2p-crypto"
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
)
|
||||
|
||||
var port int32 = 9000
|
||||
var portRange int32 = 100
|
||||
|
||||
// buildOptions for the libp2p host.
|
||||
// TODO: Expand on these options and provide the option configuration via flags.
|
||||
// Currently, this is a random port and a (seemingly) consistent private key
|
||||
// identity.
|
||||
func buildOptions() []libp2p.Option {
|
||||
rand.Seed(int64(time.Now().Nanosecond()))
|
||||
priv, _, _ := crypto.GenerateKeyPair(crypto.Secp256k1, 512)
|
||||
listen, _ := ma.NewMultiaddr(fmt.Sprintf("/ip4/127.0.0.1/tcp/%d", port+(rand.Int31n(portRange))))
|
||||
|
||||
return []libp2p.Option{
|
||||
libp2p.ListenAddrs(listen),
|
||||
libp2p.Identity(priv),
|
||||
}
|
||||
}
|
9
sharding/p2p/options_test.go
Normal file
9
sharding/p2p/options_test.go
Normal file
@ -0,0 +1,9 @@
|
||||
package p2p
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestBuildOptions(t *testing.T) {
|
||||
opts := buildOptions()
|
||||
|
||||
_ = opts
|
||||
}
|
@ -1,10 +1,25 @@
|
||||
// Package p2p handles peer-to-peer networking for the sharding package.
|
||||
//
|
||||
// Notes:
|
||||
// Gossip sub topics can be identified by their proto message types.
|
||||
//
|
||||
// topic := proto.MessageName(myMsg)
|
||||
//
|
||||
// Then we can assume that only these message types are broadcast in that
|
||||
// gossip subscription.
|
||||
package p2p
|
||||
|
||||
import (
|
||||
"context"
|
||||
"reflect"
|
||||
|
||||
"github.com/ethereum/go-ethereum/event"
|
||||
"github.com/golang/protobuf/proto"
|
||||
|
||||
floodsub "github.com/libp2p/go-floodsub"
|
||||
libp2p "github.com/libp2p/go-libp2p"
|
||||
host "github.com/libp2p/go-libp2p-host"
|
||||
pb "github.com/prysmaticlabs/geth-sharding/proto/sharding/v1"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
@ -16,24 +31,58 @@ type Sender interface {
|
||||
|
||||
// Server is a placeholder for a p2p service. To be designed.
|
||||
type Server struct {
|
||||
feeds map[reflect.Type]*event.Feed
|
||||
ctx context.Context
|
||||
cancel context.CancelFunc
|
||||
feeds map[reflect.Type]*event.Feed
|
||||
host host.Host
|
||||
gsub *floodsub.PubSub
|
||||
}
|
||||
|
||||
// NewServer creates a new p2p server instance.
|
||||
func NewServer() (*Server, error) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
opts := buildOptions()
|
||||
host, err := libp2p.New(ctx, opts...)
|
||||
if err != nil {
|
||||
cancel()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
gsub, err := floodsub.NewGossipSub(ctx, host)
|
||||
if err != nil {
|
||||
cancel()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Server{
|
||||
feeds: make(map[reflect.Type]*event.Feed),
|
||||
ctx: ctx,
|
||||
cancel: cancel,
|
||||
feeds: make(map[reflect.Type]*event.Feed),
|
||||
host: host,
|
||||
gsub: gsub,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Start the main routine for an p2p server.
|
||||
func (s *Server) Start() {
|
||||
log.Info("Starting shardp2p server")
|
||||
if err := startDiscovery(s.ctx, s.host, s.gsub); err != nil {
|
||||
log.Errorf("Could not start p2p discovery! %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Subscribe to all topics.
|
||||
for topic, msgType := range topicTypeMapping {
|
||||
log.Debugf("Subscribing to topic: %s", topic)
|
||||
go s.subscribeToTopic(topic, msgType)
|
||||
}
|
||||
}
|
||||
|
||||
// Stop the main p2p loop.
|
||||
func (s *Server) Stop() error {
|
||||
log.Info("Stopping shardp2p server")
|
||||
|
||||
s.cancel()
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -41,10 +90,74 @@ func (s *Server) Stop() error {
|
||||
func (s *Server) Send(msg interface{}, peer Peer) {
|
||||
// TODO
|
||||
// https://github.com/prysmaticlabs/geth-sharding/issues/175
|
||||
|
||||
// TODO: Support passing value and pointer type messages.
|
||||
|
||||
// TODO: Remove debug log after send is implemented.
|
||||
_ = peer
|
||||
log.Debug("Broadcasting to everyone rather than sending a single peer.")
|
||||
s.Broadcast(msg)
|
||||
}
|
||||
|
||||
// Broadcast a message to the world.
|
||||
func (s *Server) Broadcast(msg interface{}) {
|
||||
// TODO
|
||||
// https://github.com/prysmaticlabs/geth-sharding/issues/176
|
||||
// TODO https://github.com/prysmaticlabs/geth-sharding/issues/176
|
||||
topic := topic(msg)
|
||||
log.Debugf("Broadcasting msg on topic %s for message type %T", topic, msg)
|
||||
|
||||
if topic == pb.Topic_UNKNOWN {
|
||||
log.Warnf("Topic is unknown for message type %T. %v", msg, msg)
|
||||
}
|
||||
|
||||
// TODO: Next assertion may fail if your msg is not a pointer to a msg.
|
||||
m, ok := msg.(proto.Message)
|
||||
if !ok {
|
||||
log.Errorf("Message to broadcast (type: %T) is not a protobuf message: %v", msg, msg)
|
||||
return
|
||||
}
|
||||
|
||||
b, err := proto.Marshal(m)
|
||||
if err != nil {
|
||||
log.Errorf("Failed to marshal data for broadcast: %v", err)
|
||||
return
|
||||
}
|
||||
s.gsub.Publish(topic.String(), b)
|
||||
}
|
||||
|
||||
func (s *Server) subscribeToTopic(topic pb.Topic, msgType reflect.Type) {
|
||||
sub, err := s.gsub.Subscribe(topic.String())
|
||||
if err != nil {
|
||||
log.Errorf("Failed to subscribe to topic: %v", err)
|
||||
return
|
||||
}
|
||||
defer sub.Cancel()
|
||||
feed := s.Feed(msgType)
|
||||
|
||||
for {
|
||||
msg, err := sub.Next(s.ctx)
|
||||
|
||||
if s.ctx.Err() != nil {
|
||||
return // Context closed or something.
|
||||
}
|
||||
if err != nil {
|
||||
log.Errorf("Failed to get next message: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// TODO: reflect.Value.Interface() can panic so we should capture that
|
||||
// panic so the server doesn't crash.
|
||||
d, ok := reflect.New(msgType).Interface().(proto.Message)
|
||||
if !ok {
|
||||
log.Error("Received message is not a protobuf message")
|
||||
continue
|
||||
}
|
||||
err = proto.Unmarshal(msg.Data, d)
|
||||
if err != nil {
|
||||
log.Errorf("Failed to decode data: %v", err)
|
||||
continue
|
||||
}
|
||||
|
||||
i := feed.Send(Message{Data: d})
|
||||
log.Debugf("Send a request to %d subs", i)
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,133 @@
|
||||
package p2p
|
||||
|
||||
import "github.com/prysmaticlabs/geth-sharding/sharding/types"
|
||||
import (
|
||||
"context"
|
||||
"io/ioutil"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/event"
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/prysmaticlabs/geth-sharding/sharding/types"
|
||||
|
||||
floodsub "github.com/libp2p/go-floodsub"
|
||||
swarmt "github.com/libp2p/go-libp2p-swarm/testing"
|
||||
bhost "github.com/libp2p/go-libp2p/p2p/host/basic"
|
||||
pb "github.com/prysmaticlabs/geth-sharding/proto/sharding/v1"
|
||||
log "github.com/sirupsen/logrus"
|
||||
logTest "github.com/sirupsen/logrus/hooks/test"
|
||||
)
|
||||
|
||||
// Ensure that server implements service.
|
||||
var _ = types.Service(&Server{})
|
||||
|
||||
func init() {
|
||||
log.SetLevel(log.DebugLevel)
|
||||
log.SetOutput(ioutil.Discard)
|
||||
}
|
||||
|
||||
func TestLifecycle(t *testing.T) {
|
||||
hook := logTest.NewGlobal()
|
||||
|
||||
s, err := NewServer()
|
||||
if err != nil {
|
||||
t.Fatalf("Could not start a new server: %v", err)
|
||||
}
|
||||
|
||||
s.Start()
|
||||
msg := hook.Entries[0]
|
||||
want := "Starting shardp2p server"
|
||||
if msg == nil || msg.Message != want {
|
||||
t.Errorf("incorrect log. wanted: %s. got: %v", want, msg)
|
||||
}
|
||||
|
||||
s.Stop()
|
||||
msg = hook.LastEntry()
|
||||
want = "Stopping shardp2p server"
|
||||
if msg == nil || msg.Message != want {
|
||||
t.Errorf("incorrect log. wanted: %s. got: %v", want, msg)
|
||||
}
|
||||
|
||||
// The context should have been cancelled.
|
||||
if s.ctx.Err() == nil {
|
||||
t.Error("Context was not cancelled")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBroadcast(t *testing.T) {
|
||||
s, err := NewServer()
|
||||
if err != nil {
|
||||
t.Fatalf("Could not start a new server: %v", err)
|
||||
}
|
||||
|
||||
msg := &pb.CollationBodyRequest{}
|
||||
s.Broadcast(msg)
|
||||
|
||||
// TODO: test that topic was published
|
||||
}
|
||||
|
||||
func TestSubscribeToTopic(t *testing.T) {
|
||||
ctx, cancel := context.WithTimeout(context.TODO(), 1*time.Second)
|
||||
defer cancel()
|
||||
h := bhost.New(swarmt.GenSwarm(t, ctx))
|
||||
|
||||
gsub, err := floodsub.NewFloodSub(ctx, h)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to create floodsub: %v", err)
|
||||
}
|
||||
|
||||
s := Server{
|
||||
ctx: ctx,
|
||||
gsub: gsub,
|
||||
host: h,
|
||||
feeds: make(map[reflect.Type]*event.Feed),
|
||||
}
|
||||
|
||||
feed := s.Feed(pb.CollationBodyRequest{})
|
||||
ch := make(chan Message)
|
||||
sub := feed.Subscribe(ch)
|
||||
defer sub.Unsubscribe()
|
||||
|
||||
topic := pb.Topic_COLLATION_BODY_REQUEST
|
||||
msgType := topicTypeMapping[topic]
|
||||
go s.subscribeToTopic(topic, msgType)
|
||||
|
||||
// Short delay to let goroutine add subscription.
|
||||
time.Sleep(time.Millisecond * 10)
|
||||
|
||||
// The topic should be subscribed with gsub.
|
||||
topics := gsub.GetTopics()
|
||||
if len(topics) < 1 || topics[0] != topic.String() {
|
||||
t.Errorf("Unexpected subscribed topics: %v. Wanted %s", topics, topic)
|
||||
}
|
||||
|
||||
pbMsg := &pb.CollationBodyRequest{ShardId: 5}
|
||||
|
||||
done := make(chan bool)
|
||||
go func() {
|
||||
// The message should be received from the feed.
|
||||
msg := <-ch
|
||||
if !proto.Equal(msg.Data.(proto.Message), pbMsg) {
|
||||
t.Errorf("Unexpected msg: %+v. Wanted %+v.", msg.Data, pbMsg)
|
||||
}
|
||||
|
||||
done <- true
|
||||
}()
|
||||
|
||||
b, err := proto.Marshal(pbMsg)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to marshal pbMsg: %v", err)
|
||||
}
|
||||
if err = gsub.Publish(topic.String(), b); err != nil {
|
||||
t.Errorf("Failed to publish message: %v", err)
|
||||
}
|
||||
|
||||
// Wait for our message assertion to complete.
|
||||
select {
|
||||
case <-done:
|
||||
case <-ctx.Done():
|
||||
t.Error("Context timed out before a message was received!")
|
||||
}
|
||||
|
||||
}
|
||||
|
37
sharding/p2p/topics.go
Normal file
37
sharding/p2p/topics.go
Normal file
@ -0,0 +1,37 @@
|
||||
package p2p
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
pb "github.com/prysmaticlabs/geth-sharding/proto/sharding/v1"
|
||||
)
|
||||
|
||||
// Mapping of message topic enums to protobuf types.
|
||||
var topicTypeMapping = map[pb.Topic]reflect.Type{
|
||||
pb.Topic_COLLATION_BODY_REQUEST: reflect.TypeOf(pb.CollationBodyRequest{}),
|
||||
pb.Topic_COLLATION_BODY_RESPONSE: reflect.TypeOf(pb.CollationBodyResponse{}),
|
||||
pb.Topic_TRANSACTIONS: reflect.TypeOf(pb.Transaction{}),
|
||||
}
|
||||
|
||||
// Mapping of message types to topic enums.
|
||||
var typeTopicMapping = reverseMapping(topicTypeMapping)
|
||||
|
||||
// ReverseMapping from K,V to V,K
|
||||
func reverseMapping(m map[pb.Topic]reflect.Type) map[reflect.Type]pb.Topic {
|
||||
n := make(map[reflect.Type]pb.Topic)
|
||||
for k, v := range m {
|
||||
n[v] = k
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
// Topic returns the given topic for a given interface. This is the preferred
|
||||
// way to resolve a topic from an value. The msg could be a pointer or value
|
||||
// argument to resolve to the correct topic.
|
||||
func topic(msg interface{}) pb.Topic {
|
||||
msgType := reflect.TypeOf(msg)
|
||||
if msgType.Kind() == reflect.Ptr {
|
||||
msgType = reflect.Indirect(reflect.ValueOf(msg)).Type()
|
||||
}
|
||||
return typeTopicMapping[msgType]
|
||||
}
|
62
sharding/p2p/topics_test.go
Normal file
62
sharding/p2p/topics_test.go
Normal file
@ -0,0 +1,62 @@
|
||||
package p2p
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
pb "github.com/prysmaticlabs/geth-sharding/proto/sharding/v1"
|
||||
)
|
||||
|
||||
type testStruct struct{}
|
||||
|
||||
func TestReverseMapping(t *testing.T) {
|
||||
tests := []struct {
|
||||
input map[pb.Topic]reflect.Type
|
||||
want map[reflect.Type]pb.Topic
|
||||
}{
|
||||
{
|
||||
input: map[pb.Topic]reflect.Type{
|
||||
pb.Topic_UNKNOWN: reflect.TypeOf(testStruct{}),
|
||||
},
|
||||
want: map[reflect.Type]pb.Topic{
|
||||
reflect.TypeOf(testStruct{}): pb.Topic_UNKNOWN,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
got := reverseMapping(tt.input)
|
||||
if !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("reverseMapping(%+v) = %+v. Wanted %+v", tt.input, got, tt.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestTopic(t *testing.T) {
|
||||
type CustomStruct struct{}
|
||||
|
||||
tests := []struct {
|
||||
input interface{}
|
||||
want pb.Topic
|
||||
}{
|
||||
{
|
||||
input: pb.CollationBodyRequest{},
|
||||
want: pb.Topic_COLLATION_BODY_REQUEST,
|
||||
},
|
||||
{
|
||||
input: &pb.CollationBodyRequest{},
|
||||
want: pb.Topic_COLLATION_BODY_REQUEST,
|
||||
},
|
||||
{
|
||||
input: CustomStruct{},
|
||||
want: pb.Topic_UNKNOWN,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
got := topic(tt.input)
|
||||
if got != tt.want {
|
||||
t.Errorf("topic(%T) = %v. wanted %v", tt.input, got, tt.want)
|
||||
}
|
||||
}
|
||||
}
|
@ -10,6 +10,7 @@ go_library(
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
size = "small",
|
||||
srcs = ["config_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
)
|
||||
|
@ -9,14 +9,15 @@ go_library(
|
||||
importpath = "github.com/prysmaticlabs/geth-sharding/sharding/proposer",
|
||||
visibility = ["//sharding:__subpackages__"],
|
||||
deps = [
|
||||
"//proto/sharding/v1:go_default_library",
|
||||
"//sharding/database:go_default_library",
|
||||
"//sharding/mainchain:go_default_library",
|
||||
"//sharding/p2p:go_default_library",
|
||||
"//sharding/p2p/messages:go_default_library",
|
||||
"//sharding/params:go_default_library",
|
||||
"//sharding/syncer:go_default_library",
|
||||
"//sharding/txpool:go_default_library",
|
||||
"//sharding/types:go_default_library",
|
||||
"//shared/legacyutil:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//accounts:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//accounts/abi/bind:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//core/types:go_default_library",
|
||||
@ -27,6 +28,7 @@ go_library(
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
size = "small",
|
||||
srcs = ["service_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
|
@ -8,14 +8,15 @@ import (
|
||||
|
||||
gethTypes "github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/event"
|
||||
pb "github.com/prysmaticlabs/geth-sharding/proto/sharding/v1"
|
||||
"github.com/prysmaticlabs/geth-sharding/sharding/database"
|
||||
"github.com/prysmaticlabs/geth-sharding/sharding/mainchain"
|
||||
"github.com/prysmaticlabs/geth-sharding/sharding/p2p"
|
||||
"github.com/prysmaticlabs/geth-sharding/sharding/p2p/messages"
|
||||
"github.com/prysmaticlabs/geth-sharding/sharding/params"
|
||||
"github.com/prysmaticlabs/geth-sharding/sharding/syncer"
|
||||
"github.com/prysmaticlabs/geth-sharding/sharding/txpool"
|
||||
"github.com/prysmaticlabs/geth-sharding/sharding/types"
|
||||
"github.com/prysmaticlabs/geth-sharding/shared/legacyutil"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
@ -47,14 +48,15 @@ func NewProposer(config *params.Config, client *mainchain.SMCClient, p2p *p2p.Se
|
||||
client,
|
||||
p2p,
|
||||
txpool,
|
||||
nil,
|
||||
nil, // txpoolSub
|
||||
dbService,
|
||||
shardID,
|
||||
nil,
|
||||
nil, // shard
|
||||
ctx,
|
||||
cancel,
|
||||
sync,
|
||||
nil}, nil
|
||||
nil, // msgChan
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Start the main loop for proposing collations.
|
||||
@ -62,7 +64,7 @@ func (p *Proposer) Start() {
|
||||
log.Info("Starting proposer service")
|
||||
p.shard = types.NewShard(big.NewInt(int64(p.shardID)), p.dbService.DB())
|
||||
p.msgChan = make(chan p2p.Message, 20)
|
||||
feed := p.p2p.Feed(messages.TransactionBroadcast{})
|
||||
feed := p.p2p.Feed(pb.Transaction{})
|
||||
p.txpoolSub = feed.Subscribe(p.msgChan)
|
||||
go p.proposeCollations()
|
||||
}
|
||||
@ -78,16 +80,21 @@ func (p *Proposer) Stop() error {
|
||||
|
||||
// proposeCollations listens to the transaction feed and submits collations over an interval.
|
||||
func (p *Proposer) proposeCollations() {
|
||||
feed := p.p2p.Feed(pb.Transaction{})
|
||||
ch := make(chan p2p.Message, 20)
|
||||
sub := feed.Subscribe(ch)
|
||||
defer sub.Unsubscribe()
|
||||
defer close(ch)
|
||||
for {
|
||||
select {
|
||||
case msg := <-p.msgChan:
|
||||
tx, ok := msg.Data.(messages.TransactionBroadcast)
|
||||
case msg := <-ch:
|
||||
tx, ok := msg.Data.(*pb.Transaction)
|
||||
if !ok {
|
||||
log.Error("Received incorrect p2p message. Wanted a transaction broadcast message")
|
||||
break
|
||||
}
|
||||
log.Infof("Received transaction: %x", tx.Transaction.Hash())
|
||||
if err := p.createCollation(p.ctx, []*gethTypes.Transaction{tx.Transaction}); err != nil {
|
||||
// log.Debugf("Received transaction: %x", tx)
|
||||
if err := p.createCollation(p.ctx, []*gethTypes.Transaction{legacyutil.TransformTransaction(tx)}); err != nil {
|
||||
log.Errorf("Create collation failed: %v", err)
|
||||
}
|
||||
case <-p.ctx.Done():
|
||||
|
@ -6,13 +6,11 @@ go_library(
|
||||
importpath = "github.com/prysmaticlabs/geth-sharding/sharding/simulator",
|
||||
visibility = ["//sharding:__subpackages__"],
|
||||
deps = [
|
||||
"//proto/sharding/v1:go_default_library",
|
||||
"//sharding/mainchain:go_default_library",
|
||||
"//sharding/p2p:go_default_library",
|
||||
"//sharding/p2p/messages:go_default_library",
|
||||
"//sharding/params:go_default_library",
|
||||
"//sharding/syncer:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//core/types:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//event:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
],
|
||||
@ -20,12 +18,12 @@ go_library(
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
size = "small",
|
||||
srcs = ["service_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//sharding/mainchain:go_default_library",
|
||||
"//sharding/p2p:go_default_library",
|
||||
"//sharding/p2p/messages:go_default_library",
|
||||
"//sharding/params:go_default_library",
|
||||
"//sharding/types:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//:go_default_library",
|
||||
|
@ -4,16 +4,16 @@ import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"math/big"
|
||||
mrand "math/rand"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/event"
|
||||
"github.com/prysmaticlabs/geth-sharding/sharding/mainchain"
|
||||
"github.com/prysmaticlabs/geth-sharding/sharding/p2p"
|
||||
"github.com/prysmaticlabs/geth-sharding/sharding/p2p/messages"
|
||||
"github.com/prysmaticlabs/geth-sharding/sharding/params"
|
||||
"github.com/prysmaticlabs/geth-sharding/sharding/syncer"
|
||||
|
||||
pb "github.com/prysmaticlabs/geth-sharding/proto/sharding/v1"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
@ -45,8 +45,7 @@ func NewSimulator(config *params.Config, client *mainchain.SMCClient, p2p *p2p.S
|
||||
// Start the main loop for simulating p2p requests.
|
||||
func (s *Simulator) Start() {
|
||||
log.Info("Starting simulator service")
|
||||
|
||||
s.requestFeed = s.p2p.Feed(messages.CollationBodyRequest{})
|
||||
s.requestFeed = s.p2p.Feed(pb.CollationBodyRequest{})
|
||||
|
||||
go s.broadcastTransactions(time.NewTicker(s.delay).C, s.ctx.Done())
|
||||
go s.simulateNotaryRequests(s.client.SMCCaller(), s.client.ChainReader(), time.NewTicker(s.delay).C, s.ctx.Done())
|
||||
@ -79,18 +78,20 @@ func (s *Simulator) simulateNotaryRequests(fetcher mainchain.RecordFetcher, read
|
||||
}
|
||||
|
||||
period := new(big.Int).Div(blockNumber.Number(), big.NewInt(s.config.PeriodLength))
|
||||
// Collation for current period may not exist yet, so let's ask for
|
||||
// the collation at period - 1.
|
||||
period = period.Sub(period, big.NewInt(1))
|
||||
req, err := syncer.RequestCollationBody(fetcher, big.NewInt(int64(s.shardID)), period)
|
||||
if err != nil {
|
||||
log.Errorf("Error constructing collation body request: %v", err)
|
||||
continue
|
||||
}
|
||||
|
||||
if req != nil {
|
||||
msg := p2p.Message{
|
||||
Peer: p2p.Peer{},
|
||||
Data: *req,
|
||||
}
|
||||
s.requestFeed.Send(msg)
|
||||
log.Info("Sent request for collation body via a shardp2p feed")
|
||||
s.p2p.Broadcast(req)
|
||||
log.Debug("Sent request for collation body via a shardp2p broadcast")
|
||||
} else {
|
||||
log.Warn("Syncer generated nil CollationBodyRequest")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -107,16 +108,20 @@ func (s *Simulator) broadcastTransactions(delayChan <-chan time.Time, done <-cha
|
||||
return
|
||||
case <-delayChan:
|
||||
tx := createTestTx()
|
||||
s.p2p.Broadcast(messages.TransactionBroadcast{Transaction: tx})
|
||||
log.Debugf("Transaction broadcast with hash: %v", tx.Hash().Hex())
|
||||
s.p2p.Broadcast(tx)
|
||||
log.Debug("Transaction broadcasted")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// createTestTx is a helper method to generate tx with random data bytes.
|
||||
// it is used for broadcastTransactions.
|
||||
func createTestTx() *types.Transaction {
|
||||
func createTestTx() *pb.Transaction {
|
||||
data := make([]byte, 1024)
|
||||
rand.Read(data)
|
||||
return types.NewTransaction(0, common.HexToAddress("0x0"), nil, 0, nil, data)
|
||||
// TODO: add more fields.
|
||||
return &pb.Transaction{
|
||||
Nonce: mrand.Uint64(),
|
||||
Input: data,
|
||||
}
|
||||
}
|
||||
|
@ -10,14 +10,11 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/prysmaticlabs/geth-sharding/sharding/mainchain"
|
||||
|
||||
"github.com/ethereum/go-ethereum"
|
||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
gethTypes "github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/prysmaticlabs/geth-sharding/sharding/p2p/messages"
|
||||
|
||||
"github.com/prysmaticlabs/geth-sharding/sharding/mainchain"
|
||||
"github.com/prysmaticlabs/geth-sharding/sharding/p2p"
|
||||
"github.com/prysmaticlabs/geth-sharding/sharding/params"
|
||||
"github.com/prysmaticlabs/geth-sharding/sharding/types"
|
||||
@ -141,8 +138,6 @@ func TestSimulateNotaryRequests_FaultyReader(t *testing.T) {
|
||||
t.Fatalf("Unable to setup simulator service: %v", err)
|
||||
}
|
||||
|
||||
simulator.requestFeed = server.Feed(messages.CollationBodyRequest{})
|
||||
|
||||
delayChan := make(chan time.Time)
|
||||
doneChan := make(chan struct{})
|
||||
exitRoutine := make(chan bool)
|
||||
@ -154,7 +149,7 @@ func TestSimulateNotaryRequests_FaultyReader(t *testing.T) {
|
||||
delayChan <- time.Time{}
|
||||
doneChan <- struct{}{}
|
||||
|
||||
msg := hook.AllEntries()[0].Message
|
||||
msg := hook.LastEntry().Message
|
||||
want := "Could not fetch current block number: cannot fetch block by number"
|
||||
if msg != want {
|
||||
t.Errorf("incorrect log, expected %s, got %s", want, msg)
|
||||
@ -181,8 +176,6 @@ func TestSimulateNotaryRequests_FaultyCaller(t *testing.T) {
|
||||
t.Fatalf("Unable to setup simulator service: %v", err)
|
||||
}
|
||||
|
||||
simulator.requestFeed = server.Feed(messages.CollationBodyRequest{})
|
||||
|
||||
delayChan := make(chan time.Time)
|
||||
doneChan := make(chan struct{})
|
||||
exitRoutine := make(chan bool)
|
||||
@ -221,7 +214,6 @@ func TestSimulateNotaryRequests(t *testing.T) {
|
||||
t.Fatalf("Unable to setup simulator service: %v", err)
|
||||
}
|
||||
|
||||
simulator.requestFeed = server.Feed(messages.CollationBodyRequest{})
|
||||
delayChan := make(chan time.Time)
|
||||
doneChan := make(chan struct{})
|
||||
exitRoutine := make(chan bool)
|
||||
@ -234,8 +226,8 @@ func TestSimulateNotaryRequests(t *testing.T) {
|
||||
delayChan <- time.Time{}
|
||||
doneChan <- struct{}{}
|
||||
|
||||
msg := hook.AllEntries()[0].Message
|
||||
want := "Sent request for collation body via a shardp2p feed"
|
||||
msg := hook.Entries[1].Message
|
||||
want := "Sent request for collation body via a shardp2p broadcast"
|
||||
if msg != want {
|
||||
t.Errorf("incorrect log, expected %s, got %s", want, msg)
|
||||
}
|
||||
@ -255,7 +247,7 @@ func TestBroadcastTransactions(t *testing.T) {
|
||||
t.Fatalf("Unable to setup p2p server: %v", err)
|
||||
}
|
||||
|
||||
simulator, err := NewSimulator(params.DefaultConfig, &mainchain.SMCClient{}, server, shardID, 1)
|
||||
simulator, err := NewSimulator(params.DefaultConfig, &mainchain.SMCClient{}, server, shardID, 1*time.Second)
|
||||
if err != nil {
|
||||
t.Fatalf("Unable to setup simulator service: %v", err)
|
||||
}
|
||||
@ -272,8 +264,8 @@ func TestBroadcastTransactions(t *testing.T) {
|
||||
delayChan <- time.Time{}
|
||||
doneChan <- struct{}{}
|
||||
|
||||
msg := hook.AllEntries()[0].Message
|
||||
want := "Transaction broadcast with hash"
|
||||
msg := hook.Entries[1].Message
|
||||
want := "Transaction broadcasted"
|
||||
if !strings.Contains(msg, want) {
|
||||
t.Errorf("incorrect log, expected %s, got %s", want, msg)
|
||||
}
|
||||
|
@ -9,10 +9,10 @@ go_library(
|
||||
importpath = "github.com/prysmaticlabs/geth-sharding/sharding/syncer",
|
||||
visibility = ["//sharding:__subpackages__"],
|
||||
deps = [
|
||||
"//proto/sharding/v1:go_default_library",
|
||||
"//sharding/database:go_default_library",
|
||||
"//sharding/mainchain:go_default_library",
|
||||
"//sharding/p2p:go_default_library",
|
||||
"//sharding/p2p/messages:go_default_library",
|
||||
"//sharding/params:go_default_library",
|
||||
"//sharding/types:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//accounts/abi/bind:go_default_library",
|
||||
@ -24,17 +24,18 @@ go_library(
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
size = "small",
|
||||
srcs = [
|
||||
"handlers_test.go",
|
||||
"service_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//proto/sharding/v1:go_default_library",
|
||||
"//sharding/contracts:go_default_library",
|
||||
"//sharding/database:go_default_library",
|
||||
"//sharding/mainchain:go_default_library",
|
||||
"//sharding/p2p:go_default_library",
|
||||
"//sharding/p2p/messages:go_default_library",
|
||||
"//sharding/params:go_default_library",
|
||||
"//sharding/types:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//accounts:go_default_library",
|
||||
@ -44,6 +45,7 @@ go_test(
|
||||
"@com_github_ethereum_go_ethereum//core:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//core/types:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//crypto:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
"@com_github_sirupsen_logrus//hooks/test:go_default_library",
|
||||
],
|
||||
)
|
||||
|
@ -6,24 +6,34 @@ import (
|
||||
|
||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
pb "github.com/prysmaticlabs/geth-sharding/proto/sharding/v1"
|
||||
"github.com/prysmaticlabs/geth-sharding/sharding/mainchain"
|
||||
"github.com/prysmaticlabs/geth-sharding/sharding/p2p"
|
||||
"github.com/prysmaticlabs/geth-sharding/sharding/p2p/messages"
|
||||
"github.com/prysmaticlabs/geth-sharding/sharding/types"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// RespondCollationBody is called by a node responding to another node's request
|
||||
// for a collation body given a (shardID, chunkRoot, period, proposerAddress) tuple.
|
||||
// The proposer will fetch the corresponding data from persistent storage (shardDB) by
|
||||
// constructing a collation header from the input and calculating its hash.
|
||||
func RespondCollationBody(req p2p.Message, collationFetcher types.CollationFetcher) (*messages.CollationBodyResponse, error) {
|
||||
func RespondCollationBody(req p2p.Message, collationFetcher types.CollationFetcher) (*pb.CollationBodyResponse, error) {
|
||||
// Type assertion helps us catch incorrect data requests.
|
||||
msg, ok := req.Data.(messages.CollationBodyRequest)
|
||||
msg, ok := req.Data.(*pb.CollationBodyRequest)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("received incorrect data request type: %v", msg)
|
||||
log.Debugf("Request data type: %T", req.Data)
|
||||
return nil, fmt.Errorf("received incorrect data request type. Data: %+v", msg)
|
||||
}
|
||||
|
||||
header := types.NewCollationHeader(msg.ShardID, msg.ChunkRoot, msg.Period, msg.Proposer, msg.Signature)
|
||||
shardID := new(big.Int).SetUint64(msg.ShardId)
|
||||
chunkRoot := common.BytesToHash(msg.ChunkRoot)
|
||||
period := new(big.Int).SetUint64(msg.Period)
|
||||
proposer := common.BytesToAddress(msg.ProposerAddress)
|
||||
var sig [32]byte
|
||||
if len(msg.Signature) >= 32 {
|
||||
copy(sig[:], msg.Signature[0:32])
|
||||
}
|
||||
header := types.NewCollationHeader(shardID, &chunkRoot, period, &proposer, sig)
|
||||
|
||||
// Fetch the collation by its header hash from the shardChainDB.
|
||||
headerHash := header.Hash()
|
||||
@ -31,15 +41,18 @@ func RespondCollationBody(req p2p.Message, collationFetcher types.CollationFetch
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not fetch collation: %v", err)
|
||||
}
|
||||
if collation == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return &messages.CollationBodyResponse{HeaderHash: &headerHash, Body: collation.Body()}, nil
|
||||
return &pb.CollationBodyResponse{HeaderHash: headerHash.Bytes(), Body: collation.Body()}, nil
|
||||
}
|
||||
|
||||
// RequestCollationBody fetches a collation header record submitted to the SMC for
|
||||
// a shardID, period pair and constructs a p2p collationBodyRequest that will
|
||||
// then be relayed to the appropriate proposer that submitted the collation header.
|
||||
// In production, this will be done within a notary service.
|
||||
func RequestCollationBody(fetcher mainchain.RecordFetcher, shardID *big.Int, period *big.Int) (*messages.CollationBodyRequest, error) {
|
||||
func RequestCollationBody(fetcher mainchain.RecordFetcher, shardID *big.Int, period *big.Int) (*pb.CollationBodyRequest, error) {
|
||||
|
||||
record, err := fetcher.CollationRecords(&bind.CallOpts{}, shardID, period)
|
||||
if err != nil {
|
||||
@ -52,16 +65,17 @@ func RequestCollationBody(fetcher mainchain.RecordFetcher, shardID *big.Int, per
|
||||
}
|
||||
|
||||
if sum == 0 {
|
||||
log.Debugf("No collation exists for shard %d and period %d", shardID, period)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Converts from fixed size [32]byte to []byte slice.
|
||||
chunkRoot := common.BytesToHash(record.ChunkRoot[:])
|
||||
|
||||
return &messages.CollationBodyRequest{
|
||||
ChunkRoot: &chunkRoot,
|
||||
ShardID: shardID,
|
||||
Period: period,
|
||||
Proposer: &record.Proposer,
|
||||
return &pb.CollationBodyRequest{
|
||||
ChunkRoot: chunkRoot.Bytes(),
|
||||
ShardId: shardID.Uint64(),
|
||||
Period: period.Uint64(),
|
||||
ProposerAddress: record.Proposer.Bytes(),
|
||||
}, nil
|
||||
}
|
||||
|
@ -15,9 +15,9 @@ import (
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
pb "github.com/prysmaticlabs/geth-sharding/proto/sharding/v1"
|
||||
"github.com/prysmaticlabs/geth-sharding/sharding/contracts"
|
||||
"github.com/prysmaticlabs/geth-sharding/sharding/p2p"
|
||||
"github.com/prysmaticlabs/geth-sharding/sharding/p2p/messages"
|
||||
shardparams "github.com/prysmaticlabs/geth-sharding/sharding/params"
|
||||
shardingTypes "github.com/prysmaticlabs/geth-sharding/sharding/types"
|
||||
)
|
||||
@ -147,11 +147,11 @@ func TestCollationBodyResponse(t *testing.T) {
|
||||
proposerAddress := common.BytesToAddress([]byte{})
|
||||
chunkRoot := common.BytesToHash([]byte{})
|
||||
|
||||
goodReq := messages.CollationBodyRequest{
|
||||
ChunkRoot: &chunkRoot,
|
||||
ShardID: big.NewInt(1),
|
||||
Period: big.NewInt(1),
|
||||
Proposer: &proposerAddress,
|
||||
goodReq := pb.CollationBodyRequest{
|
||||
ChunkRoot: chunkRoot.Bytes(),
|
||||
ShardId: 1,
|
||||
Period: 1,
|
||||
ProposerAddress: proposerAddress.Bytes(),
|
||||
}
|
||||
incorrectReq := faultyRequest{}
|
||||
|
||||
@ -160,31 +160,41 @@ func TestCollationBodyResponse(t *testing.T) {
|
||||
|
||||
badMsg := p2p.Message{
|
||||
Peer: p2p.Peer{},
|
||||
Data: incorrectReq,
|
||||
Data: &incorrectReq,
|
||||
}
|
||||
|
||||
goodMsg := p2p.Message{
|
||||
Peer: p2p.Peer{},
|
||||
Data: goodReq,
|
||||
Data: &goodReq,
|
||||
}
|
||||
|
||||
if _, err := RespondCollationBody(badMsg, fetcher); err == nil {
|
||||
t.Errorf("Incorrect request should throw error. Expecting messages.CollationBodyRequest{}, received: %v", incorrectReq)
|
||||
t.Errorf("Incorrect request should throw error. Expecting pb.CollationBodyRequest{}, received: %v", incorrectReq)
|
||||
}
|
||||
|
||||
if _, err := RespondCollationBody(goodMsg, faultyFetcher); err == nil {
|
||||
t.Error("Faulty collatiom fetcher should cause function to throw error. no error thrown.")
|
||||
}
|
||||
|
||||
header := shardingTypes.NewCollationHeader(goodReq.ShardID, goodReq.ChunkRoot, goodReq.Period, goodReq.Proposer, [32]byte{})
|
||||
shardID := new(big.Int).SetUint64(goodReq.ShardId)
|
||||
chunkRoot = common.BytesToHash(goodReq.ChunkRoot)
|
||||
period := new(big.Int).SetUint64(goodReq.Period)
|
||||
proposer := common.BytesToAddress(goodReq.ProposerAddress)
|
||||
|
||||
header := shardingTypes.NewCollationHeader(
|
||||
shardID,
|
||||
&chunkRoot,
|
||||
period,
|
||||
&proposer,
|
||||
[32]byte{})
|
||||
body := []byte{}
|
||||
response, err := RespondCollationBody(goodMsg, fetcher)
|
||||
if err != nil {
|
||||
t.Fatalf("Could not construct collation body response: %v", err)
|
||||
}
|
||||
|
||||
if response.HeaderHash.Hex() != header.Hash().Hex() {
|
||||
t.Errorf("Incorrect header hash received. want: %v, received: %v", header.Hash().Hex(), response.HeaderHash.Hex())
|
||||
if common.BytesToHash(response.HeaderHash).Hex() != header.Hash().Hex() {
|
||||
t.Errorf("Incorrect header hash received. want: %v, received: %v", header.Hash().Hex(), common.BytesToHash(response.HeaderHash).Hex())
|
||||
}
|
||||
|
||||
if !bytes.Equal(response.Body, body) {
|
||||
@ -237,19 +247,19 @@ func TestConstructNotaryRequest(t *testing.T) {
|
||||
t.Errorf("constructNotaryRequest should return nil for an inexistent collation header. got: %v", err)
|
||||
}
|
||||
|
||||
if request.ChunkRoot.Hex() != chunkRoot.Hex() {
|
||||
t.Errorf("Chunk root from notary request incorrect. want: %v, got: %v", chunkRoot.Hex(), request.ChunkRoot.Hex())
|
||||
if common.BytesToHash(request.ChunkRoot).Hex() != chunkRoot.Hex() {
|
||||
t.Errorf("Chunk root from notary request incorrect. want: %v, got: %v", chunkRoot.Hex(), common.BytesToHash(request.ChunkRoot).Hex())
|
||||
}
|
||||
|
||||
if request.Proposer.Hex() != proposerAddress.Hex() {
|
||||
t.Errorf("Proposer address from notary request incorrect. want: %v, got: %v", proposerAddress.Hex(), request.Proposer.Hex())
|
||||
if common.BytesToAddress(request.ProposerAddress).Hex() != proposerAddress.Hex() {
|
||||
t.Errorf("Proposer address from notary request incorrect. want: %v, got: %v", proposerAddress.Hex(), common.BytesToAddress(request.ProposerAddress).Hex())
|
||||
}
|
||||
|
||||
if request.ShardID.Cmp(shardID) != 0 {
|
||||
t.Errorf("ShardID from notary request incorrect. want: %s, got: %s", shardID, request.ShardID)
|
||||
if shardID.Uint64() != request.ShardId {
|
||||
t.Errorf("ShardID from notary request incorrect. want: %d, got: %d", shardID.Uint64(), request.ShardId)
|
||||
}
|
||||
|
||||
if request.Period.Cmp(period) != 0 {
|
||||
t.Errorf("Proposer address from notary request incorrect. want: %s, got: %s", period, request.Period)
|
||||
if request.Period != period.Uint64() {
|
||||
t.Errorf("Proposer address from notary request incorrect. want: %d, got: %d", period.Uint64(), request.Period)
|
||||
}
|
||||
}
|
||||
|
@ -4,11 +4,12 @@ import (
|
||||
"context"
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/event"
|
||||
pb "github.com/prysmaticlabs/geth-sharding/proto/sharding/v1"
|
||||
"github.com/prysmaticlabs/geth-sharding/sharding/database"
|
||||
"github.com/prysmaticlabs/geth-sharding/sharding/mainchain"
|
||||
"github.com/prysmaticlabs/geth-sharding/sharding/p2p"
|
||||
"github.com/prysmaticlabs/geth-sharding/sharding/p2p/messages"
|
||||
"github.com/prysmaticlabs/geth-sharding/sharding/params"
|
||||
"github.com/prysmaticlabs/geth-sharding/sharding/types"
|
||||
log "github.com/sirupsen/logrus"
|
||||
@ -45,7 +46,7 @@ func (s *Syncer) Start() {
|
||||
shard := types.NewShard(big.NewInt(int64(s.shardID)), s.shardChainDB.DB())
|
||||
|
||||
s.msgChan = make(chan p2p.Message, 100)
|
||||
s.bodyRequests = s.p2p.Feed(messages.CollationBodyRequest{}).Subscribe(s.msgChan)
|
||||
s.bodyRequests = s.p2p.Feed(pb.CollationBodyRequest{}).Subscribe(s.msgChan)
|
||||
go s.HandleCollationBodyRequests(shard, s.ctx.Done())
|
||||
}
|
||||
|
||||
@ -71,16 +72,22 @@ func (s *Syncer) HandleCollationBodyRequests(collationFetcher types.CollationFet
|
||||
return
|
||||
case req := <-s.msgChan:
|
||||
if req.Data != nil {
|
||||
log.Infof("Received p2p request of type: %T", req)
|
||||
log.Debugf("Received p2p request of type: %T", req.Data)
|
||||
res, err := RespondCollationBody(req, collationFetcher)
|
||||
if err != nil {
|
||||
log.Errorf("Could not construct response: %v", err)
|
||||
continue
|
||||
}
|
||||
|
||||
if res == nil {
|
||||
// TODO: Send that we don't have it?
|
||||
log.Debug("No response for this collation request. Not sending anything.")
|
||||
continue
|
||||
}
|
||||
|
||||
// Reply to that specific peer only.
|
||||
s.p2p.Send(*res, req.Peer)
|
||||
log.Infof("Responding to p2p request with collation with headerHash: %v", res.HeaderHash.Hex())
|
||||
s.p2p.Send(res, req.Peer)
|
||||
log.Infof("Responding to p2p request with collation with headerHash: 0x%v", common.Bytes2Hex(res.HeaderHash))
|
||||
}
|
||||
case <-s.bodyRequests.Err():
|
||||
log.Debugf("Subscriber failed")
|
||||
|
@ -2,26 +2,29 @@ package syncer
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"math/big"
|
||||
"testing"
|
||||
|
||||
"github.com/prysmaticlabs/geth-sharding/sharding/mainchain"
|
||||
"github.com/prysmaticlabs/geth-sharding/sharding/params"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
gethTypes "github.com/ethereum/go-ethereum/core/types"
|
||||
|
||||
"github.com/prysmaticlabs/geth-sharding/sharding/p2p/messages"
|
||||
|
||||
logTest "github.com/sirupsen/logrus/hooks/test"
|
||||
|
||||
pb "github.com/prysmaticlabs/geth-sharding/proto/sharding/v1"
|
||||
"github.com/prysmaticlabs/geth-sharding/sharding/database"
|
||||
"github.com/prysmaticlabs/geth-sharding/sharding/mainchain"
|
||||
"github.com/prysmaticlabs/geth-sharding/sharding/p2p"
|
||||
"github.com/prysmaticlabs/geth-sharding/sharding/params"
|
||||
"github.com/prysmaticlabs/geth-sharding/sharding/types"
|
||||
log "github.com/sirupsen/logrus"
|
||||
logTest "github.com/sirupsen/logrus/hooks/test"
|
||||
)
|
||||
|
||||
var _ = types.Service(&Syncer{})
|
||||
|
||||
func init() {
|
||||
log.SetLevel(log.DebugLevel)
|
||||
log.SetOutput(ioutil.Discard)
|
||||
}
|
||||
|
||||
func TestStop(t *testing.T) {
|
||||
hook := logTest.NewGlobal()
|
||||
|
||||
@ -40,7 +43,7 @@ func TestStop(t *testing.T) {
|
||||
t.Fatalf("Unable to setup sync service: %v", err)
|
||||
}
|
||||
|
||||
feed := server.Feed(messages.CollationBodyRequest{})
|
||||
feed := server.Feed(pb.CollationBodyRequest{})
|
||||
syncer.msgChan = make(chan p2p.Message)
|
||||
syncer.bodyRequests = feed.Subscribe(syncer.msgChan)
|
||||
|
||||
@ -98,7 +101,7 @@ func TestHandleCollationBodyRequests(t *testing.T) {
|
||||
t.Fatalf("Unable to setup syncer service: %v", err)
|
||||
}
|
||||
|
||||
feed := server.Feed(messages.CollationBodyRequest{})
|
||||
feed := server.Feed(pb.CollationBodyRequest{})
|
||||
|
||||
syncer.msgChan = make(chan p2p.Message)
|
||||
syncer.bodyRequests = feed.Subscribe(syncer.msgChan)
|
||||
@ -113,24 +116,24 @@ func TestHandleCollationBodyRequests(t *testing.T) {
|
||||
|
||||
msg := p2p.Message{
|
||||
Peer: p2p.Peer{},
|
||||
Data: messages.CollationBodyRequest{
|
||||
ChunkRoot: &chunkRoot,
|
||||
ShardID: shardID,
|
||||
Period: period,
|
||||
Proposer: &proposerAddress,
|
||||
Data: &pb.CollationBodyRequest{
|
||||
ChunkRoot: chunkRoot.Bytes(),
|
||||
ShardId: shardID.Uint64(),
|
||||
Period: period.Uint64(),
|
||||
ProposerAddress: proposerAddress.Bytes(),
|
||||
},
|
||||
}
|
||||
syncer.msgChan <- msg
|
||||
doneChan <- struct{}{}
|
||||
exitRoutine <- true
|
||||
|
||||
logMsg := hook.AllEntries()[0].Message
|
||||
want := fmt.Sprintf("Received p2p request of type: %T", p2p.Message{})
|
||||
logMsg := hook.Entries[0].Message
|
||||
want := fmt.Sprintf("Received p2p request of type: %T", &pb.CollationBodyRequest{})
|
||||
if logMsg != want {
|
||||
t.Errorf("incorrect log, expected %s, got %s", want, logMsg)
|
||||
}
|
||||
|
||||
logMsg = hook.AllEntries()[1].Message
|
||||
logMsg = hook.Entries[3].Message
|
||||
want = fmt.Sprintf("Responding to p2p request with collation with headerHash: %v", header.Hash().Hex())
|
||||
if logMsg != want {
|
||||
t.Errorf("incorrect log, expected %s, got %s", want, logMsg)
|
||||
|
@ -16,6 +16,8 @@ go_library(
|
||||
"@com_github_ethereum_go_ethereum//crypto/sha3:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//ethdb:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//rlp:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
"@com_github_syndtr_goleveldb//leveldb/errors:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
@ -10,6 +10,8 @@ import (
|
||||
gethTypes "github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/ethdb"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
log "github.com/sirupsen/logrus"
|
||||
leveldberrors "github.com/syndtr/goleveldb/leveldb/errors"
|
||||
)
|
||||
|
||||
// Shard defines a way for services attached to a sharding-enabled node to
|
||||
@ -45,6 +47,10 @@ func (s *Shard) ValidateShardID(h *CollationHeader) error {
|
||||
// HeaderByHash looks up a collation header from the shardDB using the header's hash.
|
||||
func (s *Shard) HeaderByHash(hash *common.Hash) (*CollationHeader, error) {
|
||||
encoded, err := s.shardDB.Get(hash.Bytes())
|
||||
if err != nil && err.Error() == leveldberrors.ErrNotFound.Error() {
|
||||
log.Debugf("No header found for hash %v", hash.Hex())
|
||||
return nil, nil
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get failed: %v", err)
|
||||
}
|
||||
@ -69,6 +75,10 @@ func (s *Shard) CollationByHeaderHash(headerHash *common.Hash) (*Collation, erro
|
||||
return nil, fmt.Errorf("cannot fetch header by hash: %v", err)
|
||||
}
|
||||
|
||||
if header == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
body, err := s.BodyByChunkRoot(header.ChunkRoot())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot fetch body by chunk root: %v", err)
|
||||
|
@ -314,6 +314,9 @@ func MigrateFlags(action func(ctx *cli.Context) error) func(*cli.Context) error
|
||||
// Setup initializes profiling based on the CLI flags.
|
||||
// It should be called as early as possible in the program.
|
||||
func Setup(ctx *cli.Context) error {
|
||||
// TODO: Set verbosity level from flag.
|
||||
log.SetLevel(log.DebugLevel)
|
||||
|
||||
// profiling, tracing
|
||||
runtime.MemProfileRate = ctx.GlobalInt(MemProfileRateFlag.Name)
|
||||
if traceFile := ctx.GlobalString(TraceFlag.Name); traceFile != "" {
|
||||
|
@ -2,10 +2,11 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["messages.go"],
|
||||
importpath = "github.com/prysmaticlabs/geth-sharding/sharding/p2p/messages",
|
||||
visibility = ["//sharding:__subpackages__"],
|
||||
srcs = ["convert_transaction.go"],
|
||||
importpath = "github.com/prysmaticlabs/geth-sharding/shared/legacyutil",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//proto/sharding/v1:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//core/types:go_default_library",
|
||||
],
|
23
shared/legacyutil/convert_transaction.go
Normal file
23
shared/legacyutil/convert_transaction.go
Normal file
@ -0,0 +1,23 @@
|
||||
// This package exists to convert Ethererum 2.0 types to go-ethereum or
|
||||
// Ethereum 1.0 types.
|
||||
package legacyutil
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
gethTypes "github.com/ethereum/go-ethereum/core/types"
|
||||
pb "github.com/prysmaticlabs/geth-sharding/proto/sharding/v1"
|
||||
)
|
||||
|
||||
// TransformTransaction of proto transaction to geth's transction.
|
||||
func TransformTransaction(t *pb.Transaction) *gethTypes.Transaction {
|
||||
return gethTypes.NewTransaction(
|
||||
t.Nonce,
|
||||
common.BytesToAddress(t.Recipient),
|
||||
big.NewInt(0).SetUint64(t.Value),
|
||||
t.GasLimit,
|
||||
big.NewInt(0).SetUint64(t.GasPrice),
|
||||
t.Input,
|
||||
)
|
||||
}
|
Loading…
Reference in New Issue
Block a user