sharding: Local networked P2P! (#222)

Former-commit-id: d22d05529bb0050b8a03053a28d876e3e458bbff [formerly 284a04699110aa285a42f5b0ad244ca9bd77d2df]
Former-commit-id: 83cd9c8a48fb5ce9c57ff8ef6c2b1741a4d05130
This commit is contained in:
Preston Van Loon 2018-07-17 14:39:04 -04:00 committed by Raul Jordan
parent 77267169ea
commit 9ac88d11da
40 changed files with 1786 additions and 150 deletions

View File

@ -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
View File

@ -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",

View 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"],
)

View 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
```

View 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)
}
}

View File

@ -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) {

View 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"],
)

View 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,
}

View 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;
}

View File

@ -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
}

View File

@ -24,6 +24,7 @@ go_library(
go_test(
name = "go_default_test",
size = "medium",
srcs = ["service_test.go"],
embed = [":go_default_library"],
deps = [

View File

@ -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
View 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
}

View 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(),
)
}
}

View File

@ -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)
}

View File

@ -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},

View File

@ -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{}
}

View File

@ -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
View 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),
}
}

View File

@ -0,0 +1,9 @@
package p2p
import "testing"
func TestBuildOptions(t *testing.T) {
opts := buildOptions()
_ = opts
}

View File

@ -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)
}
}

View File

@ -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
View 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]
}

View 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)
}
}
}

View File

@ -10,6 +10,7 @@ go_library(
go_test(
name = "go_default_test",
size = "small",
srcs = ["config_test.go"],
embed = [":go_default_library"],
)

View File

@ -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 = [

View File

@ -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():

View File

@ -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",

View File

@ -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,
}
}

View File

@ -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)
}

View File

@ -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",
],
)

View File

@ -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
}

View File

@ -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)
}
}

View File

@ -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")

View File

@ -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)

View File

@ -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",
],
)

View File

@ -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)

View File

@ -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 != "" {

View File

@ -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",
],

View 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,
)
}