From 7398b841fb65b2c109480f259eaa850faaed665f Mon Sep 17 00:00:00 2001 From: David Wolever Date: Sun, 5 Aug 2018 21:01:47 -0400 Subject: [PATCH] WIP: Proposal for withdraw function --- contracts/.LedgerChannel.sol.swp | Bin 0 -> 49152 bytes contracts/LedgerChannel.sol | 127 ++++++++++++++++++++++++++++--- 2 files changed, 115 insertions(+), 12 deletions(-) create mode 100644 contracts/.LedgerChannel.sol.swp diff --git a/contracts/.LedgerChannel.sol.swp b/contracts/.LedgerChannel.sol.swp new file mode 100644 index 0000000000000000000000000000000000000000..4a637fc025e866b20d18c6620c9641bdf2231fbc GIT binary patch literal 49152 zcmeI533#M+o#zX$5fJfMMn;_3mnfKYr<3#nL?6~H?rQd1Bx!=iZ1Sq>*E2!&giJ?%-}P!itDZ-Ue9{0&VGLX`#q|X z#$#Qq_j$gl)ce1G|Lb@C|1~u-F@9e3f}yn)o~KnRZ@*=B@2Wq)^9j#7qf$B4tS1MP zmV|VD#^&N?I#h2?$Mvr9E;ktt?_P)-2S`vFK+~&oG~-mJkh*A-+T_|!hgrSpE93U$g@GX=K_ks6=o4`TvVsIw-1Mn>HyPyKT zio)XK;632g;2Ll>xClHM+>gTLV(>ihZImCM2Ok1&0+)a@!Q;V$C{8{F-UZ$UZUHX` z3D^nNfM^4~d&^KoN$J8o3tR&`JFK+=fX z^7jlEW3kp~uRHDZz3cWxQ_V)TG$3hBuN&DC*W<=?LK%{=JVDZ=Jy#5mtJPMLrqM#& zYA=nS5e*MV+sC50#i@!)&Yw(-Eh@&un2KMUuHoI%j<%G?9W9GH>f%z8@qvlbcHB-} zfT?n{xKQQw#8|sFpEMWSDz`&(P)7$u)Ix&Nh(MRv)|Ra6^`wD6jY>D(sI_ZxyV;7G zGg7P$bE#~RX>!qG0s%e!rkc%qR7=MjyOVaip3EnWHeJ;&#u%$NQ}Z@$w-%?{x#199 zqDrIHIS(MydKLO821V3ZoZq>SG$zIhmA*g`aQm35I%BmELDDJmP~jv}w4G|U=XB>n z*tz&%61}upYb4bIsdOi7@7OzxqGIn@I&U9qQuH3vu`X{rmnOzq&1UzUX=G!>tcccb)H5!1HL=My?2ED!OC|`Zru0M` zC8_y$JX*K0s zz!4P}V*>KZ7)?0nq{zekT8xUG*30VOjLMv{`Mk zbdv0tg*ht2*oGB5F-$sI4EAYD0v!!H_MzDp8Ph6?8?)Q>nC;S}+@f44;o$W7EUd)} zhwT|J2K)Au1cqr#n(Nb+1lql8I_P>k@Eo1|n9L7$PbeKHpwtCw?^9cK3BAm&zDL+B zMBu)LNN6v7}O# zC}A(JaI&nNDCfdrbSXQ-Efl&dtXVL`EPYh4C!1|g>9DkEY)|VA(-_UTqHZ`m| zZMY~HiBmk)%|_lfwg)CXHDQ&7Ry;c&N5rgEYwe}zB_l%{hSse=qayPEL&%Y5A#;lS zZ|&nZBir8qUISKvW59QiE zU1atLz-PdR!F#~X;407tGvMEVbHEG1(?JFN6Egfq!5csuOn}qC3E+Fk?Dv5Wfa|~k zupfwA|0m%0z_H+GBBz6Y1owcuz%8o(3x5pODvY1J{84U;}tMco>@9 z3*G^iz@LB};2a?I+y;72j{-dk^eE7yz+;<1Dj*Re>lU@nn^qL!z#999v0vM!Dh{ zt+JR-9!tB%%kyj{SsA&tTfJ12fU_&fC8r?hS}6n-qmAqu&51nSs#c5t`;Tp3&o9?Yu_i1Kx05(zRBah)_(MDC&_slC_1s~17 zGtBjoyfE2xNm7U*lAn+7zs)Q*rrWhded3d0LEssz>j$KnTdf4(D zx~vN}8!y4-76cnX&ta<$_2uY(L;4cB$}^@<+}e?E(lg{uK=-j;QF-vk4<>n&{Z<%< zg%?J4^wliH==6fgR!FsX!!qy8Y;$SD@o$>F+`u;!93I}S?Hy+;rE!{{4u;&*i>(w9 za`WbBQk45ftQAW6nN$2GZ*0owKr%fYAHWdSA5YbWu+ucF$*y?%KvL~j`onG5X9i95 zf!w}yS;SfEBv`2=XL(kVyN)xcwUkmyK6muy{U)PLK`fDb&A8f6m-J5>MQCkcAfU?(gzGomAJrI`r*Ale&rQ%$#UBz&S9?z0t==51UneWF zE7&R}9ErT{-3B=tOwKu*iyIJ=Y#jQd{gY_2x6+&TG`z9Q4T@sc>!kgc@j-3F@nK4d zV7`ts97O*A7V`5hk+G5gt^fUpkoOls8>|IiN5+36xEzRme-Ahs+>1Pa6*vq0lsx_l z+zAc<$@A0T1K=&-bwFhNmw~gvQ^5n2Epq&4kj<|J+rU;3fyaUWh5Y>m@DXqexB_ek zCxRa%ga0GA8{7*19Egm5HCP4iNB+JKybHV&G{FG)@7UD84E`H<2Y5PILa;RuIkz`Co5ayW&V1{dmvuCg{WiTrZn z>(pYH)mllv9d?<0h{{E)-H6Nvt=$)$xjEYuY=^6}Z%*46tV)HVJcFAnCXsPDF3xG~bEzV=)#jjGKgZ9KmnrAaa`);&=s)~cBMocYoj_&O8DZt>BkY!gQ) zTMUm?tcLM?62&RjIf~MDb%>WtA8=igCqXS0<|d$#*@-ZbH__@PmiFP+tj2)hL_Ht6 z(5fA@J_Q4=Jfjw!Olz}VhaJ2OO;&EWXl^JNeP$uvd-}di(+8#5du>Yxon0Q=hF_&9 z!GBq1$?`0;tBYO}ReSvUY}r0FuKQWrBA#Uz)=6K}NwY}m+2_BlWiI+}a2dfjHO5p) zQd*$1UbCj-)^5Ao^lG|S_uY_MsE4=&rIF4gt^Ry)mXF(;trhhc?3=?EXGuvpCatmO zM>fxBCa%@lh58tr?y0!{_~(~XH(9+xiXCCyT#afo{b4rI$ru8nOD_%bUcXPhbQ`I( z#rL^&b+Zb4O>v;UgeneFIOS!`?1m1dw=4xd40ep-p3 zqz;AIpLKp>5rt{UcUqRCQC06AWxd&VWfWv86Sk&MOs*=bg@tkgo~OJbL4>dxmZG z#p%ijSem0fRIAra1YcxBsWA)mB{jNTe%XChn5|MH3e(a^Veua5jmW{oA z3g%GdPL0SyJsXCiJ<^1X!FcG9ac?j!nupnGR;lQ8OSw*Z2fOt{(QcA+k6JxlCKJgs zY*Ds7hcJVu!p7R7@mdrIHtg%wq>3LV{$Vq%CY&zCDVkJF3!-(p4r$V;raCArMhGYQ zjyGmoHQdW^k3@`>T(pA-z2vE}b|@Of*B2+sLUqnGc2Z(jjlcz zt;My}aFtSaE19V$xROe#n$4>^-dyO<=$cPpn~0!?l*=n!oYLbLK0nOVw_+hdAp?={ zy_i)6SOOxkE0VapcD0(gOvd$%+C`Mgv=W>IV@LA1&Y(=wMfiPN5go%f+l)Frj2g|h z8K`!llp%kp!9a=FgHbe?O7HMfX)2kH7t!FLB~U|A`KJ28tlGFa+QIag!jVx3=JF<2 zzAO3vZ;?MmRu%c*p0EEQGXD?22f=ONFM;?0JPC*oz~?|4>;vb3QLq-Q2H!spc^zB_ z9tReY^EZI+BIiE>J`3IlUJqUl#83ZRFbIBx%>N1SE^rN~f$iW-upX=fUqtr57%YJo zfnDGv@C9W4*MO_QpMss>Zsh%w!Lz{cf`38Q|2cRwcpZ2xxCtBtF9F{|?*AP4D0nxx z72E)>2N#0V!B>&{{~5dqtOuWlcAo<809Szqm;j2Vk7cvhZ)w}?QfWVXx*ByiC)?T< zbJU`zt1)B4uurVqJzb3`!F#%zw5O|)!&rNJx*D@Ybdt0R8itkWQ+m3Zf^1!& zd$;|}%elEUJzb4DLdmQRv;=nK_H;ERYNLP|`i;=l7|lh{eOP9Ue2O+BlCy_ml|p(R zQOXo?ND#HboO*S5L`|8%n556~s<#7vJ_UxOWvxlpW`s@9Df5)UNS{D7%%mJA^sJ?v zC{(5q7rH+4-4|+gZ(c9zYuVLyB&NTlkuGW%F|#me#~4VaZH8lFvJ(Ls?MDn6O+!F^ z+S%IVQta;t-P3hB8DlkAN=Tn>F3!%0NDjTH5_}oZ!yx2~+94)B$7bcoaj2!xY6EZ1 z@V)^TTK$q?ujbR)AyHN&EpK=kq!*P&mI0vpOcuUX!%F`DL*%$uq5}~5e}|Fj{ws3+ z{XpdZH-lGzD%cMGH8>F*4Ss~Y|2^`Uh{193G zufZJH2l~O)$nKW{IY0k2a6I@V^835Ntw7Gt?*b=-?;yY54sHXl0&BsKvEPe5|9-F& zJQ@5Py8R4%0tgMS2aocR9+4-%73EaJYxk|*?4}FMq&F%plW-)HaD;>vRUUu*sFFAN ze6lKVwB(^Op9x;qZYRSsB&;=_`E~{cwZX11i3Y&Mz&49(iYWkR^ z?MP*e5w>D$m#Mum4rc6tVYzyuOTqb8Z*@Ko27MRFkkpk zI9P;D%vEkEJ9{JsnT&+Xuy0>DsPg$_r_FK>0V}Bq^J=V>pj71FKJ_N`UcSXHR~{y{%F z?euM6GC8v_;xgXM0gY@bzuK-~*??@Po?0lPe4TI;fBTsDESak;vQytp^1|fyQ%(|F zUq@eAHU%|O@DOrKhFW7M)zk>ziaShxIOM6~dM6(-OZjlK^9xNrO(t`aNXM*>CIhE% zpLTdSpIYq^a}tLs^hArEJ@b(tK7K6{Apx{L6IArxPV8nT$?kB`PT2U`4$I+5dsHaeNFOd zZ1E(p2Y{v0+0`?jD8KqjX>NlKnJ3B0PLO;i*`;@79Lo`}tWtr}f~j)x&~LvU^g+jE zxQ1Vh=V8wOLOjnlY}3D7jwer;+?JtvQoTBK9zeN7u9cdF^6A(XM(fIppk3pxAEpDW zgmTi1utwLA(8MJ`-2r6kRgunujT zi*Pq;%aLQ@hs0CV7?7!kJ|SY}Vwi^b-f{?w6OTsyw~41flB=#Iz|?_WYq zc{v#MZ87#7ToM|>=FzZ5G8+q7LWb4lt9wB0|A!_0j;6U^NA_8LrBCeLz-Op>lH@t!|iUcfV#3N-kkD z5!~KuNvr+;&qQE-P~=wR|0yH9eg)b76W|S?4$cJw;CF!B`S)dTKe!Jpfm6WqfSd_< z0Ga;|a5>lxP6S^==KmPD8@v@<2jq;vd0-ek1N;yjz?XpN1a1L0fjxo{Y?sKdLy%1yNh~sl%vhQ_S3< z*CBFtH`S}I+f74{vlXRR3$R~y)&;7JPU!=!YOeHfFJD3GT-l-xS%y#n`{6mWWmBoi zyhRAC|5N7xI$jmnq2em(sLQ0o9fGa_ZaEGQDNV`_v0L~!;iKW!xLL|B1J>uQ%u#5p zJl0}QnnhwR>1Fod2aYZJGE6Q>vzfvQLT%@SRz2{1@ z>`K{%cW&yqx~gIBR-f!^@eYw4Y0xuWZdR0ejmWs17*kW;*=Ewk1#u;|OM+ex7{hWY zYBTEN{L_5W2Y;Q2b_R{$!XhH~tenV-^djM9$w@ncbqPlO7kYXz&+REFIU~U#Ci&PB zEH~4}sn}*^N4`}L*zkZI^pnvB7SF)5G|0+qqdGGB%11nQX4-u6l{iyoWH9*=A8pjK zBF%2VAziBkvlha9o~9b|l=L+Ar_Q0_0eMNCNxD9FY99L6CbODi_Ns2 zvdgZNAVsl^kU_R7+yxpmIFo(I58KEg3#$le21UsIGB$NS&i-7f2#Mv%uPK@@wUv?N zLz4@WrAyqx)RDM$6on) z`9A^t^f=^Ia0RG?1Y7`if)jw;`S(6B3gqtoJCWg2Fb6IK$AFI^ugl$irvQ=H{|r1A z$Ql2C0Cxa6<9{)D3D^qcod1uJ!#@rF0$dLc0FlpM2u=eV!1s{Nt-t>zMqd9HWb}K$ zXTTkx1vY>mAfMj}{sWi<&jTW}%l-Lp0&fH_0?!9>fBvh%0C)%*{tb8!5PBX0ogV2Y zdAjqVxvgID$XYcICobA~e|Bh0Z^rKYuv-}9?6E3}KTPhHoc|FeBdR=ohzSNsEAn%` zE1HW|?DuwmKaX7lI#gUw3ol|=#{UAf-Uvf(xgg8FC-ry%ENrPPf#HB$}bBNGz|O6Gxtj%r78htzphQqnTf)pzCNH zo6r~6C)PY>MOM8p${pFdUTAKWjOxG1bPtVbE9*d*5Y;4UR)-WNy-^sq9g^zW`O#uI z<9x?tIOOH(lijM7n#fZj+;uxtDw{sohJ~i#9^5H?u!-kN4>#o%q|TL{+osL-p~v^K zy;RuycPAJ5g`q=bD8gLPMvwZzUOykEbV&9ZymI2Kwbm0$lx9`?UFOkv0bL6W0h1f$R# zj0#y51%F$Pt~4XBELBeWmox$lX$0 z;)HxQd$P-?^P%X{oW!OkD!NUb)=iztEq=jZVra_U9O{=Rl$xWTi=))_G;%Z;jTk@n zk!H+@9eOWUg!Mp0T{WV#YWSPV{H)h5CR3~2(`Tub6;k`81QhtyYv>}LzHzQGYq64G zakLgl=@J>eR8$`|wzfP;AWsJpm=Q0lgr;?28T+a@&v1P%Q$YWpyEJ7iP`Hy~?V5U2rJ__n1`Ux}l{n zPogW`8+}uf`-;|8xu&=mglAuD@uF>BVe5ubHh?T#h&5R2{IkopTYz)RwtHWuwAEbs z#F*3AY6ZkbS$kwD(i^PuCz`3rEqP}8%bW47s$Q&(^UfM1QjC~;+$y1c@x@VLiM4_} z<(dLK?D@iN6($4i!jJi(HiN6E+BwvnNGyez8nm;h5i83wdbx{&k zRCZqLYPD1oW8*X>$Dmu2n>QVz3(*XW{YTlB`~g~C+h#ElSHOqsUUK^h9Gh%E#iJ=1 zW?JO`=LGWqE+eqsfxN#2`oZUs@9n*RV&j)P|61Vpf!y!+DbN5XfMdZi;6~*6SAy%o zbzn7k1iAihk?p~o!3@|8>~HP86+=Wd4VK4!{gY5n=xC6Ao3&8WiKO@6`5qts2 z`TgDCnc#8YKO)254sHWCgZ*F?5PSTGz+ZtI!8|w{oD3rHZRGhoKniML4v63XbHF{w z_ww6#mw*}YufX3U-+vT*0Nep?083yw*T25E3|8Ew%;si3pDgMh_U`VN_xRdDAXZw=s)cfj|L>B z?m>X7xqnwuZ(CSaI)+0~-k4GydCFrcIToKy6(x+7mz0-@WAkwt*$pa7^UWQq5lY`> zDaFI0Qv-bEZOV{ZLAp$nx~0mL7Np8a`D{Cw;yHb}r1u-4VRj7J3B`3ZX^mqOd))0? zThzg_;0mq6rC7nBD7_50oE&llsXQc9uSiYHW64RR@{mxy!YEy?Nt>9nxvR!92W3`3 zsBMtGluQH|%B`44K`&-V6uj?9pde0$Ji+^J#3?kxkS1t_Jx(M2Vh8bZ1P%svMlw)B zPk9%X&9Y1}g{lUH1g*^$5d=^`2zbQI;vaVuCV7ag?bWq zF0x}|vIPdM42y&3l|s)hMk!3u0@_9JhL*BzEAF+$4fnPdly>`A1boyfZ@NF17 zGDifbo-gH#vI_b@BQMmVF70NuxsjXec=J|Dt)T8qVR;0zhAJtG@+QboH)@z%Fb@i!qcoMVphEHb&whv+B&;Z zwg{O@#b3cNuBF+i;l8$f#xh}6n6WH470J;)g(?Trs(Xclh|5+t6SrGsgNWhUX!cvV zCBH)_DW(wL(PfWzap6{8A!nYL=SKqcsun*W!D3ngq?7U z)m`cHRO8jdUDD+_f$Uxp>)0cZRt?fhU z?`UV0^W}ym!lb}$r2g=4sU(!IuqxbB)Ki&ud(|DME&KM!MabD(*OO|#x|WVbR&{yO zXBO;$bRARX+w%XI_==RNr@w58_O_BxXvvLM+Y0kT7=7m@X)3>mpeZ2MXYmE$HWkAi zs_nEdYoxVgFX&%n9rt}2{ZX_w@^{jPb0wFOxsp#g5~Q?(gX<+khW<`7_tE+wkNY+X zDK$sG%l?!I2gYryt?4D?9u$YmfaQv2xnj79hpJMJ>#Gw`lFc!gne94Q_LoL-xa~_M zy}dJ6{9sVK6K4r`eoj&mX)cy668J8+quBO|RrqR$Ygs;8HS)1_5(21w z+}skx-35AhhYQM>8S#(OFn%?F{C2n(OaLfzMBxg&*xUR41)^SZQ z%1Ee~>_#~~v>?VHEKseR$@W|B zh_2L12Dte3Nlk0*Aw4?$Hg09X?PF$3w$h-p4*MM^yy!`qBTq&B<&V!&-ekYY8#8dc zuovv=T-b<2CTpU;3CHIuDdn+4*~O8iFxb3J-)J^rWmn-ywx!##1QcqU*$8!gZSh&I zMN-?^=5xtz?8_YX=L!|Go^>>*gqmrx>Yj_<=r|w%xK9E3pG9miW`W_LWW5`QEn_zC_kKYBq@&Y z_9*p>BX;k?!9Z-=(kF4vaXwb~BZ;txu(Lbyp6n1ffZ_KQ}&KP{J#ISHor-$pa4Hyg9?8k((< zJGcz>)#X>}G7B~@?MbHO|3&2CZ6YTl|F01NmFJtt_n!kF25$!=;91}(@Ga#1hrpM> z-+^1exj@bX{0y1@17H?B8~g(@|9e3UE(8on%{GR|s`vi(DA1!oj{-dk^eE7yz^{V>R#@-~SEXg` zDYVN};ys17R|nXJ7s;&5t zl1=57#7pl^Y^X;#fG>0 aT7#0+F8B~vb#)L!Rop39tR}p_@_zwH?>4Rg literal 0 HcmV?d00001 diff --git a/contracts/LedgerChannel.sol b/contracts/LedgerChannel.sol index 6850d17..9c4bff7 100644 --- a/contracts/LedgerChannel.sol +++ b/contracts/LedgerChannel.sol @@ -36,6 +36,13 @@ contract LedgerChannel { bool isToken ); + event DidLCWithdraw ( + bytes32 indexed channelId, + address indexed recipient, + uint256 amount, + bool isToken + ); + event DidLCUpdateState ( bytes32 indexed channelId, uint256 sequence, @@ -166,6 +173,9 @@ contract LedgerChannel { require(msg.sender == Channels[_lcID].partyAddresses[0] && Channels[_lcID].isOpen == false); require(now > Channels[_lcID].LCopenTimeout); + // DW: Even though `ethBalances[0]` *should* match `initialDeposit[0]`, + // could this be re-written so that only `ethBalances[0]` is used for + // added clarity? if(Channels[_lcID].initialDeposit[0] != 0) { Channels[_lcID].partyAddresses[0].transfer(Channels[_lcID].ethBalances[0]); } @@ -234,6 +244,83 @@ contract LedgerChannel { emit DidLCDeposit(_lcID, recipient, _balance, isToken); } + // Withdraw from a ledger channel without closing it. + // An optional signed state update can be included, which will update the + // channel's state before performing the withdrawal. The state update will + // only be applied if the update's sequence number is greater than the + // channel's current sequence number. + function withdraw( + bytes32 _lcID, + uint256 _balance, + bool isToken, + uint256[6] updateParams, // [sequence, numOpenVc, ethbalanceA, ethbalanceI, tokenbalanceA, tokenbalanceI] + bytes32 _VCroot, + string _sigA, + string _sigI + ) + public + { + Channel storage channel = Channels[_lcID]; + require(channel.isOpen == true, "Tried withdrawing from a closed channel"); + + // Only update the LC state if the provided state is later than the + // current state. This will allow a user to withdraw from a channel + // without providing a state update (for example, if they want to + // withdraw funds they have just deposited, or they want to withdraw + // tokens with one transaction, then eth with the next) + if (updateParams[0] > channel.sequence) { + // TODO: this broadcasts a DidLCUpdateState event, but I'm not + // certain that's either necessary or desierable. Possibly + // (probaby?) the `emit DidLCUpdateState(...)` should be moved to + // the `updateLCstate` function instead of being done here. + _updateLCstate(_lcID, updateParams, _VCroot, _sigA, _sigI) + } + + uint256 senderIdx = ( + channel.partyAddresses[0] == msg.sender ? 0 : + channel.partyAddresses[1] == msg.sender ? 1 : + require(false, "Message sender is not a channel party") + ); + + if (isToken) { + // DW: TODO: how should this handle deposited tokens? + require(channel.erc20Balances[senderIdx] >= _balance, "Insufficient token balance"); + channel.erc20Balances[senderIdx] -= _balance; + channel.initialDeposit[1] -= _balance; + require(channel.token.transfer(msg.senderIdx, _balance), "Token transfer failed"); + } else { + // DW: TODO: how should this handle deposited ETH? + require(channel.erc20Balances[senderIdx] >= _balance, "Insufficient token balance"); + channel.ethBalances[senderIdx] -= _balance; + channel.initialDeposit[0] -= _balance; + msg.sender.transfer(_balance); + } + + /* + DW: TODO: this means the channel will be in a bit of a weird state, + because it will have `channel.state = N`, but the balances in the + channel will not match balances shown in signed state N. + + Proposal: when there's a withdrawal, assume that there's a + subsequent state update where the person doing the withdrawal sends + a state update to reflect the updated balances. This means that the + workflow would be: + + 1. Alice wants to withdraw 1 ETH + 2. She sends state `lc-state(N+1)` to Ingrid, where the amount she + wants to withdraw has been deducted from the state + 3. She calls `LedgerChannel.withdraw(...)` with `lc-state(N)` + 4. The `LedgerChannel.withdraw(...)` method increments + `channel.sequence += 1` so its internal sequence number will be + `N + 1`, and its internal state will match `lc-state(N+1)` + + This would also imply that the `deposit(...)` funciton should be + similarly updated. + */ + + emit DidLCWithdraw(_lcID, msg.sender, _balance, isToken); + } + // TODO: Check there are no open virtual channels, the client should have cought this before signing a close LC state update function consensusCloseChannel( bytes32 _lcID, @@ -288,27 +375,24 @@ contract LedgerChannel { emit DidLCClose(_lcID, _sequence, _balances[0], _balances[1], _balances[2], _balances[3]); } - // Byzantine functions - function updateLCstate( + function _updateLCstate( bytes32 _lcID, uint256[6] updateParams, // [sequence, numOpenVc, ethbalanceA, ethbalanceI, tokenbalanceA, tokenbalanceI] bytes32 _VCroot, string _sigA, string _sigI - ) - public + ) + private { Channel storage channel = Channels[_lcID]; require(channel.isOpen); require(channel.sequence < updateParams[0]); // do same as vc sequence check + + // DW: TODO: this doesn't seem to consider deposited balances require(channel.ethBalances[0] + channel.ethBalances[1] >= updateParams[2] + updateParams[3]); require(channel.erc20Balances[0] + channel.erc20Balances[1] >= updateParams[4] + updateParams[5]); - if(channel.isUpdateLCSettling == true) { - require(channel.updateLCtimeout > now); - } - bytes32 _state = keccak256( abi.encodePacked( _lcID, @@ -336,10 +420,6 @@ contract LedgerChannel { channel.erc20Balances[0] = updateParams[4]; channel.erc20Balances[1] = updateParams[5]; channel.VCrootHash = _VCroot; - channel.isUpdateLCSettling = true; - channel.updateLCtimeout = now + channel.confirmTime; - - // make settlement flag emit DidLCUpdateState ( _lcID, @@ -354,6 +434,29 @@ contract LedgerChannel { ); } + // Byzantine functions + + function updateLCstate( + bytes32 _lcID, + uint256[6] updateParams, // [sequence, numOpenVc, ethbalanceA, ethbalanceI, tokenbalanceA, tokenbalanceI] + bytes32 _VCroot, + string _sigA, + string _sigI + ) + public + { + Channel storage channel = Channels[_lcID]; + + if(channel.isUpdateLCSettling == true) { + require(channel.updateLCtimeout > now); + } + + channel.isUpdateLCSettling = true; + channel.updateLCtimeout = now + channel.confirmTime; + + _updateLCstate(_lcID, updateParams, _VCroot, _sigA, _sigB) + } + // supply initial state of VC to "prime" the force push game function initVCstate( bytes32 _lcID,