-
Notifications
You must be signed in to change notification settings - Fork 6
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
Initial implementation #7
base: master
Are you sure you want to change the base?
Conversation
type annotations in tests |
"onlyFilesWithFlowAnnotation": true | ||
} | ||
} | ||
} |
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.
nit
.travis.yml
Outdated
script: | ||
- npm run lint | ||
- npm run typecheck | ||
- npm test |
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.
npm run check
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.
Done.
@@ -25,11 +27,19 @@ | |||
}, |
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.
MIT
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.
Done.
test/helpers.js
Outdated
return node.getBlock(node.chain.tip.hash); | ||
}, | ||
|
||
time: async (milliseconds) => { |
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.
rename to delay
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.
Done.
test/helpers.js
Outdated
"0503054CF7EBB4E62191AF1D8DE97945178D3F465EE88EF1FB4E80A70CB4A49A", | ||
"878DFE5B43AC858EA37B3A9EEBA9E244F1848A30F78B2E5AC5B3EBDE81AC7D45", | ||
"1349A1318B1426E6F724CBFE7ECD2C46008A364A96C4BD20C83FC1C4EBB2EB4A" | ||
].map((key) => KeyRing.fromPrivate(new Buffer(key, "hex"))), |
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.
Move to fixture file
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.
Done
var trustIncrease = this.parseTXAsTrustIncrease(tx); | ||
if (trustIncrease !== null) { | ||
return [trustIncrease]; | ||
} else { |
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.
avoid else-after-return
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 also wonder why programmers do this
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.
Same as above. Throughout the code I omit the else only when it doesn't help convey the meaning of the code, for example when guarding against error cases. Here there's two equally valid cases: either it's a trust increase or it's not.
@gubatron your comment is not very constructive.
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
] | ||
}); | ||
|
||
var changeAmount = coin.value - trustAmount - fee; |
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.
assert(changeAmount >= 0)
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? It's okay to have no change.
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.
Assert that change is not negative
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.
Done
var mtx = new MTX({ | ||
outputs: [ | ||
new Output({ | ||
script: bcoin.script.fromMultisig(1, 2, [originPubKey, dest]), |
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.
check that origin != dest
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.
Done.
var directTrusts = this.db.getSpendableDirectTrusts(originAddress, destAddress); | ||
return directTrusts.map((directTrust) => { | ||
var decrease = Math.min(trustDecreaseAmount, directTrust.amount); | ||
if (decrease === 0) return null; |
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.
Perhaps a for
loop with a break
here would be more readable, also avoiding the filter(Boolean)
part – and as a side effect it will also avoid unnecessary iterations.
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'm having trouble making flow type the resulting array correctly when I do that. Will investigate further.
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.
Apparently flow isn't that smart, can't get anything other than filter(Boolean) to work.
src/trust_is_risk.js
Outdated
], | ||
outputs: [new Output({ | ||
script: bcoin.script.fromPubkeyhash(Address.fromBase58(payee).hash), | ||
value: decreaseAmount - fee |
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.
Check that this is positive. If not, make this zero? Throwing an exception may not be appropriate: If multiple txs are spent to achieve the decrease, the last one may be borderline below the fee.
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.
Done.
src/trust_db.js
Outdated
} | ||
|
||
getDirectTrustByOutpoint(outpoint : bcoin$Outpoint) : (DirectTrust | null) { | ||
var trust = this.txToDirectTrust.get(outpoint.hash.toString("hex")); |
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.
Use getDirectTrustByTx
return trusts; | ||
} | ||
|
||
getGraphWeightMatrix() : number[][] { |
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.
If more readable, then move graphWeightMatrix to class variable and updated it when add
is called.
if (tx.inputs.length !== 1) return null; | ||
var input = tx.inputs[0]; | ||
if (input.getType() !== "pubkeyhash") return null; // TODO: This is unreliable | ||
if (this.db.isTrustOutput(input.prevout.hash.toString("hex"), input.prevout.index)) return null; |
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 condition is unnecessary, because if null
is returned here, then also null
is returned in line 191.
var input = tx.inputs[0]; | ||
if (input.getType() !== "pubkeyhash") return null; // TODO: This is unreliable | ||
if (this.db.isTrustOutput(input.prevout.hash.toString("hex"), input.prevout.index)) return null; | ||
var origin = tx.inputs[0].getAddress().toBase58(); |
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.
Explain the cases this getAddress
can return (p2pkh or something else) in a comment
if (this.db.isTrustOutput(input.prevout.hash.toString("hex"), input.prevout.index)) return null; | ||
var origin = tx.inputs[0].getAddress().toBase58(); | ||
|
||
if (tx.outputs.length === 0 || tx.outputs.length > 2) return null; |
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.
unnecessary
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 breaks the following test if I remove it, which makes sense:
.addTX() with a trust increasing transaction which has two change outputs does not change trust
Are you saying that we could relax this condition and allow trust increasing transactions with more than one change outputs?
src/trust_is_risk.js
Outdated
).filter(Boolean); | ||
|
||
if (recipient) { | ||
directTrusts.filter((trust) => trust.dest === recipient); |
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.
filter
doesn't modify underlying array – please add more regression tests
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 catch, this was a major bug. I've added a test to protect against it and fixed the problem.
src/trust_is_risk.js
Outdated
|
||
getInputTrusts(inputs : bcoin$Input[]) : DirectTrust[] { | ||
return inputs.map((input) => { | ||
var trust = this.db.getDirectTrustByOutpoint(input.prevout); |
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.
Think about & create github issue about malleability
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.
Done
src/trust_is_risk.js
Outdated
getInputTrusts(inputs : bcoin$Input[]) : DirectTrust[] { | ||
return inputs.map((input) => { | ||
var trust = this.db.getDirectTrustByOutpoint(input.prevout); | ||
if (trust && trust.outputIndex === input.prevout.index) return trust; |
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.
trust.outputIndex === input.prevout.index
unnecessary
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.
Done
src/trust_is_risk.js
Outdated
return inputs.map((input) => { | ||
var trust = this.db.getDirectTrustByOutpoint(input.prevout); | ||
if (trust && trust.outputIndex === input.prevout.index) return trust; | ||
else return null; |
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.
You can just return trust;
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.
Nice, done.
src/trust_is_risk.js
Outdated
|
||
nextTrust.prev = prevTrust; | ||
|
||
assert(nextTrust.amount - prevTrust.amount <= 0); |
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.
more readable as nextTrust.amount <= prevTrust.amount
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.
Done
259958b
to
ba908f5
Compare
Some minor change requests left. Opened issue #14.
Most CR comments have been addressed, let's merge this ASAP so that Orfeas can continue. The remaining comments are mostly readability related and I've opened #14 for them. |
} | ||
|
||
getTrustDecreasingMTX(directTrust : DirectTrust, decreaseAmount : number, payee : ?Entity, | ||
signingKeyRing : bcoin$KeyRing, fee : ?number) { |
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.
Add return type
: bcoin$MTX
"extends": [ | ||
"eslint:recommended", | ||
"plugin:flowtype/recommended" | ||
], |
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.
nit: indentation issues
@@ -0,0 +1,40 @@ | |||
{ |
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.
Replace tabs with spaces in file
This PR implements the following:
Unit and E2E tests for the above are included.