Skip to content

Commit

Permalink
Merge pull request #55 from obsidiansystems/jg-fix-locked-funds
Browse files Browse the repository at this point in the history
Fix locked funds on RC
  • Loading branch information
alexfmpe authored Mar 16, 2021
2 parents 42b6e9f + 83eb679 commit 218805b
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 110 deletions.
70 changes: 21 additions & 49 deletions src/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -320,11 +320,6 @@ enum parse_rv parse_SECP256K1OutputOwners(struct SECP256K1OutputOwners_state *co
return sub_rv;
}

// Forward declarations because StakeableLockOutput is recursive
void init_Locked_TransferableOutput(struct Locked_TransferableOutput_state *const state);

enum parse_rv parse_Locked_TransferableOutput(struct Locked_TransferableOutput_state *const state, parser_meta_state_t *const meta);

static void lockedFundsPrompt(char *const out, size_t const out_size, locked_prompt_t const *const in) {
check_null(out);
check_null(in);
Expand Down Expand Up @@ -352,26 +347,30 @@ enum parse_rv parse_StakeableLockOutput(struct StakeableLockOutput_state *const
state->locktime=state->uint64State.val;
PRINTF("StakeableLockOutput locktime: %.*h\n", 8, state->uint64State.buf);
state->state++;
INIT_SUBPARSER(outputState, Locked_TransferableOutput);
case 1: // nested TransferrableOutput
CALL_SUBPARSER(outputState, Locked_TransferableOutput); // Expanded call, we need to cast here.
INIT_SUBPARSER(uint32State, uint32_t);
case 1: // Parse the type field of the nested output here, rather than dispatching through Output.
CALL_SUBPARSER(uint32State, uint32_t);
if(state->uint32State.val != 0x00000007) REJECT("Can only parse SECP256K1TransferableOutput nested in StakeableLockoutput");
state->state++;
INIT_SUBPARSER(secp256k1TransferOutput, SECP256K1TransferOutput);
case 2: // nested TransferrableOutput
CALL_SUBPARSER(secp256k1TransferOutput, SECP256K1TransferOutput);
locked_prompt_t promptData;
promptData.amount=meta->last_output_amount;
promptData.until=state->locktime;
state->state++;
if( ADD_PROMPT("Funds locked", &promptData, sizeof(locked_prompt_t), lockedFundsPrompt) ) {
break;
}
case 2:
case 3:
sub_rv=PARSE_RV_DONE;
break;
}
return sub_rv;
}

void init_Output(struct Output_state *const state, bool noStakeableLock) {
void init_Output(struct Output_state *const state) {
state->state = 0;
state->noStakeableLock = noStakeableLock;
INIT_SUBPARSER(uint32State, uint32_t);
}

Expand All @@ -389,7 +388,6 @@ enum parse_rv parse_Output(struct Output_state *const state, parser_meta_state_t
INIT_SUBPARSER(secp256k1TransferOutput, SECP256K1TransferOutput);
break;
case 0x00000016:
if(state->noStakeableLock) REJECT("Can't parse nested StakeableLockOutput");
INIT_SUBPARSER(stakeableLockOutput, StakeableLockOutput);
break;
}
Expand All @@ -401,7 +399,6 @@ enum parse_rv parse_Output(struct Output_state *const state, parser_meta_state_t
CALL_SUBPARSER(secp256k1TransferOutput, SECP256K1TransferOutput);
break;
case 0x00000016:
if(state->noStakeableLock) REJECT("Can't parse nested StakeableLockOutput");
CALL_SUBPARSER(stakeableLockOutput, StakeableLockOutput);
break;
}
Expand All @@ -411,17 +408,9 @@ enum parse_rv parse_Output(struct Output_state *const state, parser_meta_state_t

void init_TransferableOutput(struct TransferableOutput_state *const state) {
state->state = 0;
state->noStakeableLock = false;
INIT_SUBPARSER(id32State, Id32);
}

void init_Locked_TransferableOutput(struct Locked_TransferableOutput_state *const state) {
state->state = 0;
state->noStakeableLock = true;
INIT_SUBPARSER(id32State, Id32);
}


enum parse_rv parse_TransferableOutput(struct TransferableOutput_state *const state, parser_meta_state_t *const meta) {
PRINTF("***Parse Transferable Output***\n");
enum parse_rv sub_rv = PARSE_RV_INVALID;
Expand All @@ -432,17 +421,13 @@ enum parse_rv parse_TransferableOutput(struct TransferableOutput_state *const st
PRINTF("Asset ID: %.*h\n", 32, state->id32State.buf);
check_asset_id(&state->id32State.val, meta);
state->state++;
INIT_SUBPARSER_WITH(outputState, Output, state->noStakeableLock);
INIT_SUBPARSER(outputState, Output);
case 1:
CALL_SUBPARSER(outputState, Output);
}
return sub_rv;
}

enum parse_rv parse_Locked_TransferableOutput(struct Locked_TransferableOutput_state *const state, parser_meta_state_t *const meta) {
return parse_TransferableOutput((struct TransferableOutput_state*) state, meta);
}

void init_SECP256K1TransferInput(struct SECP256K1TransferInput_state *const state) {
state->state = 0;
state->address_index_i = 0;
Expand Down Expand Up @@ -482,10 +467,6 @@ enum parse_rv parse_SECP256K1TransferInput(struct SECP256K1TransferInput_state *
return sub_rv;
}


void init_Locked_TransferableInput(struct Locked_TransferableInput_state *const state);
enum parse_rv parse_Locked_TransferableInput(struct Locked_TransferableInput_state *const state, parser_meta_state_t *const meta);

void init_StakeableLockInput(struct StakeableLockInput_state *const state){
state->state=0;
INIT_SUBPARSER(uint64State, uint64_t);
Expand All @@ -498,16 +479,20 @@ enum parse_rv parse_StakeableLockInput(struct StakeableLockInput_state *const st
CALL_SUBPARSER(uint64State, uint64_t);
PRINTF("StakeableLockInput locktime: %.*h\n", 8, state->uint64State.buf);
state->state++;
INIT_SUBPARSER(inputState, Locked_TransferableInput);
case 1: // nested TransferrableInput
CALL_SUBPARSER(inputState, Locked_TransferableInput); // Expanded call, we need to cast here.
INIT_SUBPARSER(uint32State, uint32_t);
case 1: // Parse the type field of the nested input here, rather than dispatching through Output.
CALL_SUBPARSER(uint32State, uint32_t);
if(state->uint32State.val != 0x00000005) REJECT("Can only parse SECP256K1TransferableInput nested in StakeableLockInput");
state->state++;
INIT_SUBPARSER(secp256k1TransferInput, SECP256K1TransferInput);
case 2: // nested Input
CALL_SUBPARSER(secp256k1TransferInput, SECP256K1TransferInput);
}
return sub_rv;
}

void init_Input(struct Input_state *const state, bool noStakeableInput) {
void init_Input(struct Input_state *const state) {
state->state = 0;
state->noStakeableInput = noStakeableInput;
INIT_SUBPARSER(uint32State, uint32_t);
}

Expand All @@ -526,7 +511,6 @@ enum parse_rv parse_Input(struct Input_state *const state, parser_meta_state_t *
INIT_SUBPARSER(secp256k1TransferInput, SECP256K1TransferInput);
break;
case 0x00000015: // SECP256K1 transfer input
if(state->noStakeableInput) REJECT("Nested StakeableLock not allowed");
INIT_SUBPARSER(stakeableLockInput, StakeableLockInput);
break;
}
Expand All @@ -538,7 +522,6 @@ enum parse_rv parse_Input(struct Input_state *const state, parser_meta_state_t *
CALL_SUBPARSER(secp256k1TransferInput, SECP256K1TransferInput);
break;
case 0x00000015: // SECP256K1 transfer input
if(state->noStakeableInput) REJECT("Nested StakeableLock not allowed");
CALL_SUBPARSER(stakeableLockInput, StakeableLockInput);
break;
}
Expand All @@ -549,13 +532,6 @@ enum parse_rv parse_Input(struct Input_state *const state, parser_meta_state_t *

void init_TransferableInput(struct TransferableInput_state *const state) {
state->state = 0;
state->noStakeableInput = false;
INIT_SUBPARSER(id32State, Id32);
}

void init_Locked_TransferableInput(struct Locked_TransferableInput_state *const state) {
state->state = 0;
state->noStakeableInput = true;
INIT_SUBPARSER(id32State, Id32);
}

Expand All @@ -577,17 +553,13 @@ enum parse_rv parse_TransferableInput(struct TransferableInput_state *const stat
PRINTF("ASSET ID: %.*h\n", 32, state->id32State.buf);
check_asset_id(&state->id32State.val, meta);
state->state++;
INIT_SUBPARSER_WITH(inputState, Input, state->noStakeableInput);
INIT_SUBPARSER(inputState, Input);
case 3: // Input
CALL_SUBPARSER(inputState, Input);
}
return sub_rv;
}

enum parse_rv parse_Locked_TransferableInput(struct Locked_TransferableInput_state *const state, parser_meta_state_t *const meta) {
return parse_TransferableInput((struct TransferableInput_state *) state, meta);
}

#define IMPL_ARRAY(name) \
void init_ ## name ## s (struct name ## s_state *const state) { \
state->state = 0; \
Expand Down
51 changes: 2 additions & 49 deletions src/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,42 +87,18 @@ struct SECP256K1OutputOwners_state {
};
};

// Nested Output_state and TransferableOutput_state for the TransferableOuptut
// in a StakeableLockOutput.
// Needed so that we don't build a loop in the sub-state unions.
// MUST match the layout of Output_state and TransferableOutputState in all
// other respects.
struct Locked_Output_state {
int state;
uint32_t type;
bool noStakeableLock;
union {
NUMBER_STATES;
struct SECP256K1TransferOutput_state secp256k1TransferOutput;
};
};
struct Locked_TransferableOutput_state {
int state;
bool noStakeableLock;
union {
struct Id32_state id32State;
struct Locked_Output_state outputState;
};
};

struct StakeableLockOutput_state {
int state;
uint64_t locktime;
union {
NUMBER_STATES;
struct Locked_TransferableOutput_state outputState;
struct SECP256K1TransferOutput_state secp256k1TransferOutput;
};
};

struct Output_state {
int state;
uint32_t type;
bool noStakeableLock;
union {
NUMBER_STATES;
struct SECP256K1TransferOutput_state secp256k1TransferOutput;
Expand All @@ -132,7 +108,6 @@ struct Output_state {

struct TransferableOutput_state {
int state;
bool noStakeableLock;
union {
struct Id32_state id32State;
struct Output_state outputState;
Expand All @@ -151,38 +126,17 @@ struct SECP256K1TransferInput_state {
};
};

struct Locked_Input_state {
int state;
uint32_t type;
bool noStakeableInput;
union {
NUMBER_STATES;
struct SECP256K1TransferInput_state secp256k1TransferInput;
};
};

struct Locked_TransferableInput_state {
int state;
bool noStakeableInput;
union {
NUMBER_STATES;
struct Id32_state id32State;
struct Locked_Input_state inputState;
};
};

struct StakeableLockInput_state {
int state;
union {
NUMBER_STATES;
struct Locked_TransferableInput_state inputState;
struct SECP256K1TransferInput_state secp256k1TransferInput;
};
};

struct Input_state {
int state;
uint32_t type;
bool noStakeableInput;
union {
NUMBER_STATES;
struct SECP256K1TransferInput_state secp256k1TransferInput;
Expand All @@ -192,7 +146,6 @@ struct Input_state {

struct TransferableInput_state {
int state;
bool noStakeableInput;
union {
NUMBER_STATES;
struct Id32_state id32State;
Expand Down
Loading

0 comments on commit 218805b

Please sign in to comment.