-
Notifications
You must be signed in to change notification settings - Fork 75
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[CGKIELE-107] mallet #436
[CGKIELE-107] mallet #436
Conversation
build.sbt
Outdated
"org.jline" % "jline" sha1 "dfb4e9e15e981634155ce063fa697b2b8964d507", | ||
"org.scala-lang.modules" % "scala-parser-combinators" sha1 "3c1c5475ece77c41e18dd971f8f818c091e4961c", | ||
// FIXME: WTF? | ||
"com.google.j2objc" % "j2objc-annotations" sha1 "976d8d30bebc251db406f2bdb3eb01962b5685b3" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did a bit of searching. This is a dependency pulled in via guava v22
(check image below) and is discussed here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What uses guava?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using sbt
with addSbtPlugin("net.virtual-void" % "sbt-dependency-graph" % "0.9.0")
:
$ sbt whatDependsOn com.google.guava guava 22.0
[info] com.google.guava:guava:22.0
[info] +-io.atomix:atomix-utils:2.1.0-beta1
[info] | +-io.atomix:atomix-cluster:2.1.0-beta1
[info] | [...]
[info] +-org.consensusresearch:scrypto_2.12:1.2.0-RC3 [S]
[info] | [...]
[info] +-org.scorexfoundation:iodb_2.12:0.3.0 [S]
[info]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@loverdos I removed the j2objc-annotations
artifact from my local cache. After rebuilding, the checksum changed and it passed the verification. See also the updated PR description
@@ -93,7 +93,7 @@ class EthashMiner( | |||
val startTime = System.currentTimeMillis() | |||
val mineResult = mine(headerHash, block.header.difficulty.toLong, dagSize, dag, miningConfig.mineRounds) | |||
val time = System.currentTimeMillis() - startTime | |||
val hashRate = (mineResult.triedHashes * 1000) / time | |||
val hashRate = if (time > 0) (mineResult.triedHashes * 1000) / time else Long.MaxValue |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was wondering if we could use a "better" (=monotonic) clock, e.g. System.nanoTime()
whose purpose is to measure elapsed time. There is no strong guarantee that this is indeed going to be monotonic because it ultimately depends on the OS facilities but this is generally not a problem in Linux nowadays.
Another possible route is to not update the hash rate if we cannot reliably compute it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: guava has a com.google.common.base.StopWatch
class for this purpose.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd rather not spend too much time on this, this is not really a big problem anyway. I can add a FIXME though
} | ||
|
||
implicit class OptionOps[T](opt: Option[T]) { | ||
def toEither[U](left: U): Either[U, T] = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is scala.Option.toRight
, so we can avoid introducing a new construct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lol, how did I miss that? :)
da3349b
to
792e0af
Compare
src/universal/bin/mantis
Outdated
@@ -0,0 +1,3 @@ | |||
#!/bin/bash | |||
|
|||
./bin/mantis-app -Dconfig.file=./conf/mantis.conf -Dlogback.configurationFile=./conf/logback.xml -J-Xss10M |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should also fix mantis-vm script to use mantis-app (currently it won't run vm but start mantis node)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, I was actually going to explore another way with those scripts, thanks for reminding me.
warnOnUnverifiedFiles = true, | ||
warnOnUnusedVerifications = true | ||
warnOnUnverifiedFiles = false, | ||
warnOnUnusedVerifications = false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why this change? it seems keeping it true is more secure
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
false
means error instead of warning. I actually didn't plan on changing this, but it happened during some fixes I applied wrt sbt-verify
.
I'm not having any problems with sbt-verify
now, so I wouldn't mind staying with false
. WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense, I didn't know it means an error :)
} | ||
|
||
case class Quoted(input: String) extends Literal { | ||
def unqoute: String = unquote(input) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo: unqoute -> unquote
|
||
protected val convert = { | ||
case h: Hex if h.bytes.nonEmpty && h.bytes.length <= 20 => | ||
Address(h.bytes) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we also support quoted addresses?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My first intuition was to try with quotes. Also geth console uses quoted addresses (it doesn't even accept unquoted ones)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess it would be easy to do, but for now I wouldn't go further than adding a TODO
comment to consider this.
Firstly, I'd rather have the syntax be strict, and secondly there's supporting account aliases (which would be quoted) on the list missing features.
"jsonrpc" -> "2.0".asJson, | ||
"method" -> method.asJson, | ||
"params" -> args.asJson, | ||
"id" -> "mallet".asJson |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't really matter for Mantis, but the semantics of this field is that it's a unique request id. Maybe it would be better to just use a random value here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess the idea was for it to be easily recognisable that the reqest came from mallet. How about "id" -> ("mallet_" + randomUuid()).asJson
?
"com.github.scopt" % "scopt" sha1 "e078455e1a65597146f8608dab3247bf1eb92e6e" | ||
) | ||
|
||
verifyOptions in verify := VerifyOptions( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this needed here? how does it relate to the options in build.sbt?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file is auto-generated, see the PR description
One thing I noticed: we probably don't want to store the |
That's a really good point! |
Another one:
full |
8c84cf8
to
dbb8155
Compare
@LukasGasior1 Also on the subject, note there are no longer separate In other news:
|
dbb8155
to
0494ee4
Compare
} | ||
|
||
def apply(args: Seq[String]): Option[ClOptions] = { | ||
val parser = new scopt.OptionParser[ClOptions]("scopt") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
super minor: the string argument here is a programName
, guess it should be Constants.AppName
rather than "scopt"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not that minor, good catch
// TODO: CL option to enable akka logging | ||
private val akkaConfig = ConfigFactory.load("mallet") | ||
|
||
implicit val actorSystem = ActorSystem("mallet_rpc", akkaConfig) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not instantiate it in Mallet app and pass to RpcClient as a parameter?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I meant to avoid ActorSystem
leaking out of RpcClient
cause it's an internal detail. Obviously this is not the case now, because I forgot to add shutdown()
method to RpcClient
- then the actor system could be private to RpcClient
. What do you think about such approach?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To me, actor system is not really internal to rpc client. Even though for mallet it's only used here, it has an impact on the whole app (for example, keeps it alive until it's shutdown), that's why I'd opt for putting in on app-level and pass (perhaps implicitly) to rpc client. It would also make RpcClient's dependencies more clear as well as make it reusable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also, is there any reason why we're using the actorSystem.dispatcher
instead of global EC or, even better, implicit ec passed as a constructor param?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's wrong with using dispatcher
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since you're using blocking operation (await), doesn't that mean that one of the threads that akka uses internally will be blocked? I know, in this case it doesn't matter since RpcClient is the only component using actors, but for the reasons mentioned above (reusability) I think it would be better to let the user of this class choose which EC he prefers (or, alternatively use global ec that won't block system dispatcher's thread).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
one small comment, besides that LGMT
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What I do not see is a small document that introduces mallet and its use-case, presents the design without being elaborate on this, comments on configuration options and also presents a couple of examples. In other words: a tech doc.
Any explanations, comments, etc we do on this PR description and elsewhere are great during the review process but are lost, no-one looks back on PRs and we actually do not own them and cannot reproduce them (they are not in git). What remains is the code and (hopefully) an accompanying, lightweight tech doc for the new functionality. We can just call it the mallet README, if we like.
import io.iohk.ethereum.mallet.service.PasswordReader | ||
|
||
/** | ||
* This implementation of [[PasswordReader]] is in non-interactive mode when the password is |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have a small warning in scaladoc generation:
[warn] mantis/src/main/scala/io/iohk/ethereum/mallet/main/ConstPasswordReader.scala:5: Could not find any member to link for "PasswordReader".
[warn] /**
[warn] ^
[warn] one warning found
The fix is to use the fully qualified name:
[[io.iohk.ethereum.mallet.service.PasswordReader PasswordReader]]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't it a bug? The PasswordReader
is imported. See this scaladoc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@loverdos wdyt?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It works only if the referenced thing is in the same package, not if it is imported. I do not know if this is intended behaviour or a bug though. So I just use the FQN on these occasions.
build.sbt
Outdated
@@ -186,7 +96,6 @@ scalacOptions := Seq( | |||
"-unchecked", | |||
"-deprecation", | |||
"-feature", | |||
"-Xfatal-warnings", | |||
"-Xlint:unsound-match", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After fixing the scaladoc warning, I re-enabled -Xfatal-warnings
and the build went fine from an sbt clean
state.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can re-enable it. I always disable it when working on something complicated, because of unused imports. I'm adding and removing code back and forth, and going to imports for each such change kills my concentration and infuriates me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a keystroke in IntelliJ that takes care of unused imports :)
ssl-config { | ||
trustManager = { | ||
stores = [ | ||
# TODO: move to Wiki maybe? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we have to make some documentation elsewhere ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As discussed, it will be done in #445
|
||
/** | ||
* Talks to a node over HTTP(S) JSON-RPC | ||
* Note: the URI schema determins whether HTTP or HTTPS is used |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo: determines
} | ||
} | ||
|
||
val helpHeader = "fetch the receipt for a know transaction hash" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo: known
* This factory method is defining an ActorSystem, ActorMaterializer and ExecutionContext for | ||
* the [[RpcClient]]. To customize these dependencies use [[RpcClient]]'s constructor | ||
*/ | ||
def apply(node: Uri): RpcClient = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@LukasGasior1 hopefully this should address your remarks about reusability, while limiting the scope of dependencies in mallet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, let's leave it that way
The minimalist CLI wallet for KEVM/IELE testnet.
See the list of missing features
Additional improvements:
sbt-verify
: to regenerate checksums simply typeverifyGenerate
. This will create a fileverify.sbt
in the root dir - no need for manual copying of the output