Skip to content

Commit

Permalink
simplify spk.erl so that it is easier to verify that hard update 25 d…
Browse files Browse the repository at this point in the history
…oesn't break anything.
  • Loading branch information
zack-bitcoin committed Aug 2, 2019
1 parent 353f4cc commit d6884f9
Show file tree
Hide file tree
Showing 9 changed files with 139 additions and 239 deletions.
4 changes: 4 additions & 0 deletions apps/amoveo_core/priv/market.fs
Expand Up @@ -127,13 +127,17 @@ macro unmatched ( OracleProof -- delay nonce amount )
int 10000 MaxPrice @ -
then
;
macro no_oracle
print car drop car swap drop car swap drop car drop binary 5 ZW1wdHk= print == tuck drop drop or_die print
;
macro main
swap
int 0 == if drop drop no_publish else drop
int 1 == if drop drop swap match_order else drop
int 2 == if drop drop drop contradictory_prices else drop
int 3 == if drop drop drop evidence else drop
int 4 == if drop drop unmatched else drop
% int 5 == if drop drop no_oracle else drop then
then then then then then
% the "amount" was originally set up so that 10000= amount I bet + amount you bet.
% we also need a small refund, if the price a bet gets matched is different from the price they were willing to pay.
Expand Down
42 changes: 31 additions & 11 deletions apps/amoveo_core/src/channels/market.erl
Expand Up @@ -50,6 +50,10 @@ settle(SPD, OID, Price) ->
" " ++ PriceDeclare ++ " int 1",
SS = spk:new_ss(compiler_chalang:doit(list_to_binary(SS1a)), [{oracles, OID}]),
SS#ss{meta = Price}.
no_oracle(OID) ->
SS2a = " int 5 ",
spk:new_ss(compiler_chalang:doit(list_to_binary(SS2a)), [{oracles, OID}]).

no_publish(OID) ->
%If the market maker fails in his duty to publish a price, this is how you withdraw your funds from the market early.
SS2a = " int 0 ",
Expand Down Expand Up @@ -78,6 +82,7 @@ price_declaration_maker(Height, Price, PortionMatched, MarketID) ->

test() ->
Question = <<>>,
Question2 = <<" ">>,
%OID = <<3:256>>,
Fee = 20 + constants:initial_fee(),
headers:dump(),
Expand All @@ -86,7 +91,9 @@ test() ->
test_txs:mine_blocks(2),
timer:sleep(150),
Tx = oracle_new_tx:make_dict(constants:master_pub(), Fee, Question, 1 + block:height(), 0, 0),
TxUnused = oracle_new_tx:make_dict(constants:master_pub(), Fee, Question2, 1, 0, 0),
OID = oracle_new_tx:id(Tx),
OID2 = oracle_new_tx:id(TxUnused),
Stx = keys:sign(Tx),
test_txs:absorb(Stx),
timer:sleep(200),
Expand All @@ -105,21 +112,27 @@ test() ->
test_txs:absorb(Stx3),

CID = <<5:256>>,
CID2 = <<6:256>>,
Delay = 0,

Ctx4 = new_channel_tx:make_dict(CID, constants:master_pub(), NewPub, 10000, 20000, Delay, Fee),
Ctx42 = new_channel_tx:make_dict(CID2, constants:master_pub(), NewPub, 10000, 20000, Delay, Fee),
Stx42 = keys:sign(Ctx42),
Stx4 = keys:sign(Ctx4),
SStx42 = testnet_sign:sign_tx(Stx42, NewPub, NewPriv),
SStx4 = testnet_sign:sign_tx(Stx4, NewPub, NewPriv),
test_txs:absorb(SStx42),
test_txs:absorb(SStx4),
timer:sleep(400),
test2(NewPub, OID).
test2(NewPub, OID, OID2).

test2(NewPub, OID) ->
test2(NewPub, OID, OID2) ->
test_txs:mine_blocks(1),
test_txs:mine_blocks(1),
%OID = <<3:256>>,
Fee = 20 + constants:initial_fee(),
Trees5 = (tx_pool:get())#tx_pool.block_trees,
%Trees5 = (tx_pool:get())#tx_pool.dict,
%Dict5 = (tx_pool:get())#tx_pool.dict,
%MarketID = <<405:256>>,
MarketID = OID,
Expand All @@ -128,7 +141,9 @@ test2(NewPub, OID) ->
Period = 3,
%market_smart_contract(BetLocation, MarketID, Direction, Expires, MaxPrice, Pubkey,Period,Amount, OID) ->
Bet = market_smart_contract(Location, MarketID,1, 1000, 4000, keys:pubkey(),Period,100,OID, 0),
Bet2_ = market_smart_contract(Location, OID2,1, 1000, 4000, keys:pubkey(),Period,100,OID2, 0),
SPK = spk:new(constants:master_pub(), NewPub, <<1:256>>, [Bet], 10000, 10000, 1, 0),
SPK2_ = spk:new(constants:master_pub(), NewPub, <<1:256>>, [Bet2_], 10000, 10000, 1, 0),
%ScriptPubKey = testnet_sign:sign_tx(keys:sign(SPK), NewPub, NewPriv, ID2, Accounts5),
%we need to try running it in all 4 ways of market, and all 4 ways of oracle_bet.
Price = 3500,
Expand All @@ -139,21 +154,24 @@ test2(NewPub, OID) ->
%First we check that if we try closing the bet early, it has a delay that lasts at least till Expires, which we can set far enough in the future that we can be confident that the oracle will be settled.
%amount, newnonce, delay
%{55,1000001,999} = %the bet amount was 100, so if the oracle is canceled the money is split 50-50.
%spk:run(fast, [SS1], SPK, 1, 0, Trees5),
%spk:dict_run(fast, [SS1], SPK, 1, 0, Trees5),

%SS0 = no_oracle(OID2),
%{} = spk:dict_run(fast, [SS0], SPK2_, 5, 0, Trees5),

%Next we try closing the bet as if the market maker has disappeared and stopped publishing prices
SS2 = no_publish(OID),
%amount, newnonce, delay
{0, 2, Period} =
spk:run(fast, [SS2], SPK, 5, 0, Trees5),
spk:dict_run(fast, [SS2], SPK, 5, 0, Trees5),
%spk:dict_run(fast, [SS2], SPK, 1, 0, Dict5),

%Next try closing it as if the market maker tries to stop us from closing the bet early, because he is still publishing data.
SS3 = evidence(SPD, OID),
%amount, newnonce, delay
{59, 3, 995} = %the nonce is bigger than no_publish, by half a period. So the market maker can always stop a no_publish by publishing a new price declaration and using it in a channel_slash transaction.
%The delay is until the contract expires. Once the oracle tells us a result we can do a channel slash to update to the outcome of our bet. So "amount" doesn't matter. It will eventually be replaced by the outcome of the bet.
spk:run(fast, [SS3], SPK, 5, 0, Trees5),
spk:dict_run(fast, [SS3], SPK, 5, 0, Trees5),


%Next we try closing the bet as if the market maker cheated by publishing 2 different prices too near to each other in time.
Expand All @@ -164,12 +182,13 @@ test2(NewPub, OID) ->
{0,2000001,0} =
%The nonce is super high, and the delay is zero, because if the market maker is publishing contradictory prices, he should be punished immediately.
%Amount is 0 because none of the money goes to the market maker.
spk:run(fast, [SS4], SPK, 5, 0, Trees5),
spk:dict_run(fast, [SS4], SPK, 5, 0, Trees5),


test_txs:mine_blocks(1),
timer:sleep(1000),
Trees60 = (tx_pool:get())#tx_pool.block_trees,
%Trees60 = (tx_pool:get())#tx_pool.dict,
%Dict60 = (tx_pool:get())#tx_pool.dict,
%close the oracle with oracle_close
Tx6 = oracle_close_tx:make_dict(constants:master_pub(),Fee, OID),
Expand All @@ -183,8 +202,9 @@ test2(NewPub, OID) ->
%The server won the bet, and gets all 100.
%amount, newnonce, delay
Trees61 = (tx_pool:get())#tx_pool.block_trees,
{105,999,0} = spk:run(fast, [SS1], SPK, 5, 0, Trees61),%ss1 is a settle-type ss
%{95,1000001,0} = spk:run(fast, [SS1], SPK, 1, 0, Trees61),%ss1 is a settle-type ss
%Trees61 = (tx_pool:get())#tx_pool.dict,
{105,999,0} = spk:dict_run(fast, [SS1], SPK, 5, 0, Trees61),%ss1 is a settle-type ss
%{95,1000001,0} = spk:dict_run(fast, [SS1], SPK, 1, 0, Trees61),%ss1 is a settle-type ss
%{95,1000001,0} = spk:dict_run(fast, [SS1], SPK, 1, 0, Dict60),

%Now we will try betting in the opposite direction.
Expand All @@ -194,22 +214,22 @@ test2(NewPub, OID) ->
%Again, the delay is zero, so we can get our money out as fast as possible once they oracle is settled.
%This time we won the bet.
%amount, newnonce, shares, delay
{14,999,0} = spk:run(fast, [SS1], SPK2, 5, 0, Trees61),
{14,999,0} = spk:dict_run(fast, [SS1], SPK2, 5, 0, Trees61),

%test a trade that gets only partly matched.
%SPD3 = price_declaration_maker(Height+5, 3000, 5000, MarketID),%5000 means it gets 50% matched.
SPD3 = price_declaration_maker(5, 3000, 5000, MarketID),%5000 means it gets 50% matched.
SS5 = settle(SPD3, OID, 3000),
%amount, newnonce, shares, delay
{109, 999, 0} = spk:run(fast, [SS5], SPK, 5, 0, Trees61),
{109, 999, 0} = spk:dict_run(fast, [SS5], SPK, 5, 0, Trees61),
%The first 50 tokens were won by betting, the next 20 tokens were a refund from a bet at 2-3 odds.

%test a trade that goes unmatched.
%since it is unmatched, they each get their money back.
%the nonce is medium, and delay is non-zero because if a price declaration is found, it could be used.
SS6 = unmatched(OID),
%amount, newnonce, delay
{59, 2, Period} = spk:run(fast, [SS6], SPK, 5, 0, Trees61),
{59, 2, Period} = spk:dict_run(fast, [SS6], SPK, 5, 0, Trees61),
success.
test3() ->
%This makes the compiled smart contract in market.js
Expand Down
24 changes: 12 additions & 12 deletions apps/amoveo_core/src/channels/scalar_market.erl
Expand Up @@ -224,21 +224,21 @@ test2(NewPub, Many) ->
%First we check that if we try closing the bet early, it has a delay that lasts at least till Expires, which we can set far enough in the future that we can be confident that the oracle will be settled.
%amount, newnonce, delay
%{55,1000001,999} = %the bet amount was 100, so if the oracle is canceled the money is split 50-50.
%spk:run(fast, [SS1], SPK, 1, 0, Trees5),
%spk:dict_run(fast, [SS1], SPK, 1, 0, Trees5),

%Next we try closing the bet as if the market maker has disappeared and stopped publishing prices
SS2 = no_publish(OID),
%amount, newnonce, delay
{0, 2, Period} =
spk:run(fast, [SS2], SPK, 5, 0, Trees5),
spk:dict_run(fast, [SS2], SPK, 5, 0, Trees5),
%spk:dict_run(fast, [SS2], SPK, 1, 0, Dict5),

%Next try closing it as if the market maker tries to stop us from closing the bet early, because he is still publishing data.
SS3 = evidence(SPD, OID),
%amount, newnonce, delay
{59, 3, 995} = %the nonce is bigger than no_publish, by half a period. So the market maker can always stop a no_publish by publishing a new price declaration and using it in a channel_slash transaction.
%The delay is until the contract expires. Once the oracle tells us a result we can do a channel slash to update to the outcome of our bet. So "amount" doesn't matter. It will eventually be replaced by the outcome of the bet.
spk:run(fast, [SS3], SPK, 5, 0, Trees5),
spk:dict_run(fast, [SS3], SPK, 5, 0, Trees5),


%Next we try closing the bet as if the market maker cheated by publishing 2 different prices too near to each other in time.
Expand All @@ -249,7 +249,7 @@ test2(NewPub, Many) ->
{0,2000001,0} =
%The nonce is super high, and the delay is zero, because if the market maker is publishing contradictory prices, he should be punished immediately.
%Amount is 0 because none of the money goes to the market maker.
spk:run(fast, [SS4], SPK, 5, 0, Trees5),
spk:dict_run(fast, [SS4], SPK, 5, 0, Trees5),


test_txs:mine_blocks(1),
Expand All @@ -271,8 +271,8 @@ test2(NewPub, Many) ->
%amount, newnonce, shares, delay
Trees61 = (tx_pool:get())#tx_pool.block_trees,
%{amount, nonce, delay}
% if oracle amount is 0 {5,999,0} = spk:run(fast, [SS1], SPK, 5, 0, Trees61),%ss1 is a settle-type ss
%{45,999,0} = spk:run(fast, [SS1], SPK, 5, 0, Trees61),%ss1 is a settle-type ss
% if oracle amount is 0 {5,999,0} = spk:dict_run(fast, [SS1], SPK, 5, 0, Trees61),%ss1 is a settle-type ss
%{45,999,0} = spk:dict_run(fast, [SS1], SPK, 5, 0, Trees61),%ss1 is a settle-type ss
io:fwrite("scalar market ss 1: "),
io:fwrite(packer:pack(SS1)),
%found a blockfound a blockscalar market ss 1: ["ss",
Expand All @@ -298,9 +298,9 @@ test2(NewPub, Many) ->
% 119,69,121,80,109,67,120,55,103,61,0,0,0,0,1>>

io:fwrite("\n"),
{105,999,0} = spk:run(fast, [SS1], SPK, 5, 0, Trees61),%ss1 is a settle-type ss
{105,999,0} = spk:dict_run(fast, [SS1], SPK, 5, 0, Trees61),%ss1 is a settle-type ss
% 5 is height.
%{95,1000001,0} = spk:run(fast, [SS1], SPK, 1, 0, Trees61),%ss1 is a settle-type ss
%{95,1000001,0} = spk:dict_run(fast, [SS1], SPK, 1, 0, Trees61),%ss1 is a settle-type ss
%{95,1000001,0} = spk:dict_run(fast, [SS1], SPK, 1, 0, Dict60),

%Now we will try betting in the opposite direction.
Expand All @@ -311,16 +311,16 @@ test2(NewPub, Many) ->
%Again, the delay is zero, so we can get our money out as fast as possible once the oracle is settled.
%This time we won the bet.
%amount, newnonce, shares, delay
% if oracle amount is 0 {15,999,0} = spk:run(fast, [SS1], SPK2, 5, 0, Trees60),
{14,999,0} = spk:run(fast, [SS1], SPK2, 5, 0, Trees61),
% if oracle amount is 0 {15,999,0} = spk:dict_run(fast, [SS1], SPK2, 5, 0, Trees60),
{14,999,0} = spk:dict_run(fast, [SS1], SPK2, 5, 0, Trees61),

%test a trade that gets only partly matched.
%SPD3 = price_declaration_maker(Height+5, 3000, 5000, MarketID),%5000 means it gets 50% matched.
SPD3 = price_declaration_maker(5, 3000, 5000, MarketID),%5000 means it gets 50% matched.
%SS5 = settle(SPD3, OID, 3000),
SS5 = settle_scalar(SPD3, OIDN, 3000, Many),
%amount, newnonce, shares, delay
{109, 999, 0} = spk:run(fast, [SS5], SPK, 5, 0, Trees61),
{109, 999, 0} = spk:dict_run(fast, [SS5], SPK, 5, 0, Trees61),
%The first 50 tokens were won by betting, the next 20 tokens were a refund from a bet at 2-3 odds.

%test a trade that goes unmatched.
Expand All @@ -329,7 +329,7 @@ test2(NewPub, Many) ->
%SS6 = unmatched_scalar(OIDN, Many),
SS6 = unmatched(OID),
%amount, newnonce, delay
{59, 2, Period} = spk:run(fast, [SS6], SPK, 5, 0, Trees61),
{59, 2, Period} = spk:dict_run(fast, [SS6], SPK, 5, 0, Trees61),
success.
test3() ->
%This makes the compiled smart contract in market.js
Expand Down
2 changes: 1 addition & 1 deletion apps/amoveo_core/src/channels/secrets.erl
Expand Up @@ -69,6 +69,6 @@ test() ->
Amount = 200,
Bet = spk:new_bet(Code, Code, Amount),
SPK = spk:new(1, 2, <<3:256>>, [Bet], 9000, 9000, 1, 1),
{Amount, _, _} = spk:run(fast, [SS], SPK, Height, 0, Trees),%for sanity check
{Amount, _, _} = spk:dict_run(fast, [SS], SPK, Height, 0, Trees),%for sanity check
success.

3 changes: 2 additions & 1 deletion apps/amoveo_core/src/consensus/forks.erl
Expand Up @@ -32,4 +32,5 @@ get(20) -> common(68696, test_height());
get(21) -> common(72700, test_height());
get(22) -> common(73300, test_height());
get(23) -> common(76200, test_height());
get(24) -> common(706200, 700000).
get(24) -> common(706200, 700000);%require that new oracle ids conform to the standard.
get(25) -> common(706200, test_height()).%so that we can prove the non-existence of oracles and channels and accounts.

0 comments on commit d6884f9

Please sign in to comment.