Better command line options for Ethereum (#181)

* [contracts] ContractInteractions.new() now requires account parameter

* [cli] Only perform Ethereum interactions when --eth-account is specified

* [cli] Add --persistence option that is disabled by default

* [cli] Use Option for ethDeployment parameter

* [node] Better error reporting when Ethereum node cannot be reached
This commit is contained in:
markspanbroek 2022-08-09 06:29:06 +02:00 committed by GitHub
parent eebcf7e7b2
commit 097a4cfd67
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 47 additions and 30 deletions

View File

@ -52,6 +52,21 @@ proc stop*(s: CodexServer) {.async.} =
s.runHandle.complete()
proc new(_: type ContractInteractions, config: CodexConf): ?ContractInteractions =
if not config.persistence:
if config.ethAccount.isSome:
warn "Ethereum account was set, but persistence is not enabled"
return
without account =? config.ethAccount:
error "Persistence enabled, but no Ethereum account was set"
quit QuitFailure
if deployment =? config.ethDeployment:
ContractInteractions.new(config.ethProvider, account, deployment)
else:
ContractInteractions.new(config.ethProvider, account)
proc new*(T: type CodexServer, config: CodexConf): T =
const SafePermissions = {UserRead, UserWrite}
@ -125,11 +140,7 @@ proc new*(T: type CodexServer, config: CodexConf): T =
engine = BlockExcEngine.new(localStore, wallet, network, discovery, peerStore, pendingBlocks)
store = NetworkStore.new(engine, localStore)
erasure = Erasure.new(store, leoEncoderProvider, leoDecoderProvider)
contracts = ContractInteractions.new(
config.ethProvider,
config.ethDeployment,
config.ethAccount
)
contracts = ContractInteractions.new(config)
codexNode = CodexNodeRef.new(switch, store, engine, erasure, blockDiscovery, contracts)
restServer = RestServerRef.new(
codexNode.initRestApi(config),

View File

@ -142,6 +142,12 @@ type
name: "cache-size"
abbr: "c" }: Natural
persistence* {.
desc: "Enables persistence mechanism, requires an Ethereum node"
defaultValue: false
name: "persistence"
.}: bool
ethProvider* {.
desc: "The URL of the JSON-RPC API of the Ethereum node"
defaultValue: "ws://localhost:8545"
@ -150,15 +156,15 @@ type
ethAccount* {.
desc: "The Ethereum account that is used for storage contracts"
defaultValue: EthAddress.default
defaultValue: EthAddress.none
name: "eth-account"
.}: EthAddress
.}: Option[EthAddress]
ethDeployment* {.
desc: "The json file describing the contract deployment"
defaultValue: string.default
defaultValue: string.none
name: "eth-deployment"
.}: string
.}: Option[string]
of initNode:
discard

View File

@ -42,16 +42,11 @@ proc new*(_: type ContractInteractions,
proc new*(_: type ContractInteractions,
providerUrl: string,
deploymentFile: string = string.default,
account = Address.default): ?ContractInteractions =
account: Address,
deploymentFile: string = string.default): ?ContractInteractions =
let provider = JsonRpcProvider.new(providerUrl)
var signer: Signer
if account == Address.default:
signer = provider.getSigner()
else:
signer = provider.getSigner(account)
let signer = provider.getSigner(account)
var deploy: Deployment
try:
@ -65,8 +60,9 @@ proc new*(_: type ContractInteractions,
ContractInteractions.new(signer, deploy)
proc new*(_: type ContractInteractions): ?ContractInteractions =
ContractInteractions.new("ws://localhost:8545")
proc new*(_: type ContractInteractions,
account: Address): ?ContractInteractions =
ContractInteractions.new("ws://localhost:8545", account)
proc start*(interactions: ContractInteractions) {.async.} =
await interactions.clock.start()

View File

@ -289,7 +289,7 @@ proc new*(
engine: BlockExcEngine,
erasure: Erasure,
discovery: Discovery,
contracts: ?ContractInteractions): T =
contracts = ContractInteractions.none): T =
T(
switch: switch,
blockStore: store,
@ -344,7 +344,11 @@ proc start*(node: CodexNodeRef) {.async.} =
# TODO: generate proof
return @[42'u8]
await contracts.start()
try:
await contracts.start()
except CatchableError as error:
error "Unable to start contract interactions: ", error=error.msg
node.contracts = ContractInteractions.none
node.networkId = node.switch.peerInfo.peerId
notice "Started codex node", id = $node.networkId, addrs = node.switch.peerInfo.addrs

View File

@ -17,7 +17,6 @@ import pkg/codex/node
import pkg/codex/manifest
import pkg/codex/discovery
import pkg/codex/blocktype as bt
import pkg/codex/contracts
import ./helpers
@ -39,7 +38,6 @@ suite "Test Node":
peerStore: PeerCtxStore
pendingBlocks: PendingBlocksManager
discovery: DiscoveryEngine
contracts: ?ContractInteractions
setup:
file = open(path.splitFile().dir /../ "fixtures" / "test.jpg")
@ -54,8 +52,7 @@ suite "Test Node":
discovery = DiscoveryEngine.new(localStore, peerStore, network, blockDiscovery, pendingBlocks)
engine = BlockExcEngine.new(localStore, wallet, network, discovery, peerStore, pendingBlocks)
store = NetworkStore.new(engine, localStore)
contracts = ContractInteractions.new()
node = CodexNodeRef.new(switch, store, engine, nil, blockDiscovery, contracts) # TODO: pass `Erasure`
node = CodexNodeRef.new(switch, store, engine, nil, blockDiscovery) # TODO: pass `Erasure`
await node.start()

View File

@ -5,23 +5,24 @@ import ./examples
ethersuite "Storage Contract Interactions":
let account = Address.example
var contracts: ContractInteractions
setup:
contracts = !ContractInteractions.new()
contracts = !ContractInteractions.new(account)
test "can be instantiated with a signer and deployment info":
let signer = provider.getSigner()
let deployment = deployment()
check ContractInteractions.new(signer, deployment).isSome
test "can be instantiated with a provider url and account":
test "can be instantiated with a provider url":
let url = "http://localhost:8545"
let account = Address.example
let deployment = "vendor" / "dagger-contracts" / "deployment-localhost.json"
check ContractInteractions.new(url).isSome
check ContractInteractions.new(url, account = account).isSome
check ContractInteractions.new(url, deploymentFile = deployment).isSome
check ContractInteractions.new(url, account).isSome
check ContractInteractions.new(url, account, deployment).isSome
test "provides purchasing":
check contracts.purchasing != nil

View File

@ -20,11 +20,13 @@ ethersuite "Integration tests":
node1 = startNode [
"--api-port=8080",
"--udp-port=8090",
"--persistence",
"--eth-account=" & $accounts[0]
]
node2 = startNode [
"--api-port=8081",
"--udp-port=8091",
"--persistence",
"--eth-account=" & $accounts[1]
]
baseurl1 = "http://localhost:8080/api/codex/v1"