Skip to content
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

[WIP] Adding Inflight tx exits #132

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open

Conversation

nanspro
Copy link
Member

@nanspro nanspro commented Jan 28, 2019

Implementing Limbo(Inflight tx) Exits
Fixes #86

@nanspro nanspro changed the title Adding some basic fucntions Adding some basic functions Jan 28, 2019
@nanspro nanspro changed the title Adding some basic functions Adding Inflight tx exits Jan 28, 2019
@nanspro nanspro changed the title Adding Inflight tx exits [WIP] Adding Inflight tx exits Jan 28, 2019
// transaction hash + constant signed by alice
const signature = (transferTx + c).sign(alicePriv);

const inTxData = Tx.parseToParams(transferTx);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can't calculate transferProof because period is not getting submitted(transferTx is inflight) so i am parsing it to data and then passing it to function and in our contract we can parse this data to obtain the transaction.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

possible, even simpler would be transferTx.hex().

const inTxData = Tx.parseToParams(transferTx);

// Bob will start the exit for Alice
await exitHandler.startLimboExit(inTxData, signature, outputIndex,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Who will start the limbo exit for tx A->B? A or B?
(Current) B starts a limbo exit by submitting all data A would submit if A were exiting from the coin, as well as the signature received and the in-flight transaction.. All data A would submit will be the depositTx and depositProof.

(b, tx) => b.addTx(tx),
new Block(33)
);
prevRoot = period.merkleRoot();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need spendProof (Proof that bob sent the money to charlie) so that i can pass it to challengeLimbo and validate it there. Can i create a block simply and not publish it to Bridge so that i can get period.

const depositProof = period.proof(depositTx);
const outputIndex = 1;
const exitStake = exitHandler.exitStake();
const signature = (transferTx + c).sign(alicePriv);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A sends B a signature on the hash of the in-flight transaction plus some special constant.
Need to fix it

bytes32 depositTxHash;
(txPos, depositTxHash,) = TxLib.validateProof(96, depositProof);
require(
depositTxHash == transferTx.ins[*].outpoint.hash,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was supposed to pass _inputIndex in the function and put it here but i was looking for some other way to verify this.

@@ -181,6 +181,64 @@ contract ExitHandler is DepositHandler {
exitDuration = _exitDuration;
}

function startLimboExit(
bytes memory limboTxData, bytes32 signature, uint8 _outputIndex,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nanspro i think you have been looking at the wrong specification. there should not be any signatures for more viable plasma. can you make sure that you tried to implement this: https://ethresear.ch/t/more-viable-plasma/2160

@nanspro nanspro force-pushed the master branch 3 times, most recently from 0ffcbbf to d495814 Compare February 5, 2019 01:54
@nanspro
Copy link
Member Author

nanspro commented Feb 5, 2019

@johannbarbie i've updated the PR(still need to update test cases though), could you check it out once and give me a feedback upon it.
I still need to do some more things in core contract (labeled as TODO in comments).

@johannbarbie
Copy link
Member

could you check it out once and give me a feedback upon it.

👀


bytes32 inTxHash = keccak256(inTxData);

// for now assume outputIndex 0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what should this be later? youngest input?

Copy link
Member Author

@nanspro nanspro Feb 10, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If a tx has multiple inputs and multiple outputs then there will be multiple utxo's so right now i am handling one but a tx might have more so i how should i handle that scenario?
One possible soln: if a tx has multiple utxo's then i can write a combine function which will get me combined priority for the tx (i can use getERC20ExitPriority to get individual utxo priority)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can i use youngest input in any way for this?

output: outputs,
input: inputs,
finalized: false,
exitor: msg.sender,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does there need to be any special relation between msg.sender and the transaction? signer of inputs?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no there's actually no need for storing it with tx, i thought we might need it to check if same address is initiating large amount of exits but i think keeping exitStake handles this problem
Will remove it

function challengeLimboExitByOutputSpend(
bytes32 exitId,
bytes inTxData, uint8 inOutputNo,
bytes competingTxData, bytes proof, uint8 competingInputNo, uint32 blockNumber)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think here you should borrow from our existing proof structure (bytes32[]), which will allow you to read the blockHeight from the bridge

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah i am comparing blockHeight of inTx and spendTx to see who comes first.

TxLib.Tx memory transferTx = Tx.parseTx(inTxData);

// [TODO]check if this tx is included or not
// TxLib.Tx memory includedTx = checkForValidityAndInclusion(blockNumber, includedTxData, includedProof);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wouldn't you need to pass an inclusion proof here? i think you can copy from the other exit functions: https://github.com/leapdao/leap-contracts/blob/master/test/exitHandler.js#L134-L136


function respondInputSpendChallenge(
bytes32 exitId, bytes inTxData, uint8 inInputNo,
bytes includedTxData, bytes includedProof, uint8 includedOutputNo, uint32 blockNumber
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here also use bytes32[] for inclusion proof and make use of leap-core and txLib.sol.

Copy link
Member

@johannbarbie johannbarbie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nanspro you are on the right way. i think figuring out the inclusion proofs is the biggest gap left. awesome work 👍

@nanspro nanspro requested review from eezcjkr and removed request for eezcjkr February 10, 2019 02:26
@nanspro nanspro force-pushed the master branch 2 times, most recently from f5f89cb to ec05c37 Compare February 12, 2019 00:43
uint32 timestamp;

// priority based on youngestInput
if (_youngestInputProof.length > 0) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unnecessary check? We always need youngestInputProof, no? Otherwise, I guess it will fail on line 171 (validateProof)


function challengeLimboExitByInclusionProof(
bytes32 exitId, bytes memory inTxData,
uint8 InputNo, bytes32[] memory _youngestInputProof, bytes32[] memory _inclusionProof)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_youngestInputProof is not used in any of these

Copy link
Member

@troggy troggy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't done a complete review. This looks like a nice effort, however couple of my findings make me think that the whole implementation is not working correct yet. Having a working set of unit tests will definitely help here.

I will continue review once the tests are done, so I can make sure I do my best work here.

for(uint8 i=0; i < currentExit.output.length; i++){
LimboOut memory out = currentExit.output[i];
if (out.exitable){
amount = piggybackStake + out.amount;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

piggybackStake is in wei and out.amount is in tokens. Separate transfers needed here

for(uint8 i=0; i < currentExit.input.length; i++){
LimboIn memory input = currentExit.input[i];
if (input.exitable){
amount = piggybackStake + input.amount;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

piggybackStake is in wei and input.amount is in tokens. Separate transfers needed here

uint32 prevHeight = bridge.periods[_prevProof[0]].height;

require(blockHeight < prevHeight);
tokens[transferTx.outs[0].color].addr.transferFrom(address(this), msg.sender, challengeStake);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

challengeStake is in ether, so it should transfer ether here. Also the destination is not correct: we are returning stake of the previous challenger, so it should transfer to prevChallenge.owner


require(inTxHash == txHash, "Invalid inclusion proof");

limboExit.isValid = false;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should not we check that provided tx has any connection to challenged exit?

@johannbarbie
Copy link
Member

@nanspro how are things here? :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants