From 94a3f463ad591d5021593d4371eb38cb03612548 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Mon, 20 Jan 2014 17:30:49 -0300 Subject: [PATCH 01/40] bugfix and sound added to streamed txs for address --- app/models/Transaction.js | 5 ++++- public/js/controllers/transactions.js | 6 ++++-- public/sound/beep.mp3 | Bin 0 -> 15932 bytes public/sound/transaction.mp3 | Bin 0 -> 27732 bytes public/views/transaction/list.html | 2 +- 5 files changed, 9 insertions(+), 4 deletions(-) create mode 100644 public/sound/beep.mp3 create mode 100644 public/sound/transaction.mp3 diff --git a/app/models/Transaction.js b/app/models/Transaction.js index 5e418adf..eaa0081b 100644 --- a/app/models/Transaction.js +++ b/app/models/Transaction.js @@ -171,10 +171,13 @@ TransactionSchema.statics.explodeTransactionItems = function(txid, time, cb) { TransactionItem.create({ txid : txid, value_sat : o.valueSat, - addr : o.scriptPubKey.addresses[0], + addr : o.scriptPubKey.addresses[0], // TODO: only address 0? index : o.n, ts : time, }, next_out); + if (addrs.indexOf(o.scriptPubKey.addresses[0]) === -1) { + addrs.push(o.scriptPubKey.addresses[0]); + } } else { console.log ('WARN in TX: %s could not parse OUTPUT %d', txid, o.n); diff --git a/public/js/controllers/transactions.js b/public/js/controllers/transactions.js index 52b12c90..3d9f92cb 100644 --- a/public/js/controllers/transactions.js +++ b/public/js/controllers/transactions.js @@ -22,7 +22,7 @@ angular.module('insight.transactions').controller('transactionsController', txId: txid }, function(tx) { $scope.tx = tx; - $scope.txs.push(tx); + $scope.txs.unshift(tx); }, function(e) { if (e.status === 400) { $rootScope.flashMessage = 'Invalid Transaction ID: ' + $routeParams.txId; @@ -54,7 +54,9 @@ angular.module('insight.transactions').controller('transactionsController', }; var socket = get_socket($scope); socket.on('atx', function(tx) { - console.log('Incoming transaction for address!', tx); + console.log('atx '+tx.txid); + var beep = new Audio('/sound/transaction.mp3'); + beep.play(); $scope.findTx(tx.txid); }); diff --git a/public/sound/beep.mp3 b/public/sound/beep.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..ed6a42ad1ec59000ca994839a8125edda282ddca GIT binary patch literal 15932 zcmeI2cTiJn+wNBqO6Vd4A7z-`9Pwg*V1RfW4t$ zZ)2jy`rOZY+no&y@iKRhRP{U?4F7WnZsOzP?HPIzVD4lxSl<9ZXcz#1zu)zHrfb6u z2Tb9H=K4%~MY-(4hgM7h#=BoG2TV^g6MRq7iYl^-s2piJ(YF{S*a%7FDIP^eZ=8VD zXY9)#yyQ5@VL_4`{`+TRZCKg46Rb1u?o^!vCB>248RvunDA`kBcYY{-OBfS$h4(No zkEPP}-H{HAUy^`8F|Q7rh~KFt=Gi}B;8?dW$4F2%)d+SFSf9^Pr+ZqH$^6Zv8gxDc zkZ=x8AaTDY&f9R51H*^oWn%-8fy(}aOeXU)4mXDb05&j~1i;~fyb!*Wi-vqe@es!j z^YRHw&o!U@B}LrDim!wcG&t|@byG!Rj_>R0+aE6zg<~*6kvJW7FbJ*z9k9q?xC_BW z50IXa)bJ!2B({Pr#!!dbOi;lrDKi$L^0jb( O0g8gD_Neij*iM+rep34e3Vhjw1 zq1&UN+oO}o2DicFYs4eaWjbI0)0d-!JI-(ekfTMEn~j#TM|%oFR_u7UbT_gdHLk{z z-qJa^(qU#$8IA;)te5QcQy$5T7_0qSdxU&Ra#{xrI-Ziit~!1@9XO!P4CB^5j>^+Q zf&_KWCwSa^7pH4*8)j<29fIni8~19$2@<9yaZgWSR2%Yo@@ZBxW~YVBxr(kc$F{SK zg)~wcm`tk|O{EGK65L||K)wt>aDOoxoAJE|@{nPq1E&}utPqERWLAT~4X_L_D+h@3 z3>@L^(;=l1lvG6biD$XvL3Rx37L_D+O#=mHLsh*_N_RG73h>JaHZT#TFqxEl+MEK1 zB+V%JlgwYU$DnA(OUIuvKOjzv6j3vyd{BYR>2gZAmht3$9%58)G;yvcLH>o$kg6M7seR-A_f zKg&b_&(jTq!M~&)|5lIq5Xv0`CJrDZ!kiB=-^JTJFlc&nG4bYh>-F6lq;GVD!^LI! z(@V@#IWVjQtz_D{fjN6m$j8=x6}#bbr*(I*ium3xtU0%yS@Xc(-hp7@<2BlpF!=xg zU?c#1u0hhv|E1;Zelm*9O-E>tkON6LY|dbGQl-mJZ$gvaBxPc2 zWtF0qNPV3<5Gss0*mVkUl0=5do%pt!blwbP19v&E;L)9VhwzX|n2snB@Zw6Z&Jxy~ zFkjkM_v8NIJ#(UO!s3-LGBRgtK(1&AdOOUh~_72 zz(ui7hRQf2JTf9eqoo;_3~rt;%djFc=W55}EGtAzfzD)aSYM>S{f*tqs@f}>z`i8g zammVq6y|Ts7|)6WU+*5&Xyy1cGamZ(oXazXfUwXZ#hjB3^_2%;h}Vir&ffCVZD%Iy z%W&h$Dj$e7OV?I==>_tE`VYtC)Z7^W7Xtukp6*q<;{3+d!sAyA4lc;Y-{1*N`&47qQ~uECTfpRJOFc^J2pBQ+(puR|MO{Q$H7C&c461;TCU!xh^AGm zn0@e9X!!LBBaj1$zhoHXe5B55ySlpP$~$PNL;bCt2C;=1m5lI?Ct6<5yw3rw@B+Bk zZw74~N*J6c=Zg!m~EVR)y6AugrVs95K@se)_u)Ej&d9;grnDCjj;05 z6qQs9(+_F{fD5cJ%wV@`|2h-ndKPlr&?B--yd&;7<5-6@!0}U1?@Ykrl$o=t4*u0$ zXPu&b>42~WKx-T*EGkggzPuBHAA+a*fs+t61E3PSIp(UfePZ0X7P%Ttsqf^5UAh^U z#5JG(eG*|>cUD)4v&Y#-?&fBBt9Uif-n%|$-=k;j=u%&tOK8|#>nTADIS{W#9ob%R zx;M;Sa{@0Gj)D)GqywNmLe+q1+T4*b$F!~_`W~Tn*4n);krf*KB7S$}sH`A{jmJ!M zA&yVx8%gIgpzdvWRm(NlBb4fLpj^cn?$dvZq`c0bXfUR#;P9y7x4(c1!Apt^c)pz+ zmwbQu`nLVKJ!!qnKsENMSP*h%p1JyGk=v5{4{93@dVf3p%K?5ofoK4x96H+U>~MWy zzER=lWK$-8Mpxaq&%I}L6GCq!DfjgPs&l?Q%sC%YtUR@#rPo{RSf*aomyrw zlexQl=4oIH1tX&rVOvXdoIUZIIIgV{-vT1$K(~5FV-;f7=#N_IJp5#rSD}qp=!JLo zg`Zia--7U-RgzHgNtVBf3h=$&JnhVPs=$ilY&dAlB-&>U+KM)ql)AZA3`8WZp0`Hs9cLr(_g|Wxm45LR1biz3a8& zx}kWQb?Rs6(dhC&ox%VhD)g6zdg$*v7Dw7+UMZxRCtg3J1F|9@;|!4_;sa9j zn$?q`vq?d*U@xF9FDbKeJamen?Rw_HFrywiNJJk*$z4=xYZ!OPJ;niXj;Jn($-u~0 z)$Fud;8gKtvuYzl9BbZp7aUKohnn(uxC$I`Rla<`&epU9LqN?^J(suF%NYQG0{{&& zuzyCjAsWY@&-0TjMo@n1P)AHr*-H=+;FM%jrp6yA{^?YVk=^2<$vVIpP)$%OiIO`e z`q5yUX*nIIjbbw)8w0jh9^bYDnj5U93JR;7UsigY8o#GefN(9jzGzO1-Q^q8LLNlX zbjMC^qY#`r8YTB320mqh27e1Z5m0K{6;G!?h=^fXrsky?7?$Cw*95%2?}yjWPASR_m@WOS^* z>gPf4>2cel18N8cpuyfEOEwu3m#n(}5to={>;&b&=|XiZ*2Jf)WLudVe)@(4@s;7m z5UlE+hF+7z zQfkz}g*hyCjMKD0BXUktp3hp(zjZgdHyff#b_*!v5Am_6C{o$}?000>Pf-XFX{Qa$>-BzVVHPB5S$S|(P(AhM3<%YP5 znghRdp*wGj2`+DF4JAqNe8x3G~a6 z-g?FvgzN!b@5B%5Bp(1kvfQuT#nQt0j#1^HGqwOgHzsk&85nVoYukDp&PP)RC~KiN z+-W**?iFx*WE{ql^JQh<gJTv)GK%LK9rRd{S9gw1d1HTF(m zpnM@lfCT3ctyE3(vJ!O_>S#>%#wo1S^5<`BvL=&X%)D_L(;SsRN@77?4Vn4TdGbp^ zsG1h=A!qZh2h6Es#oT!LE#HVwxa{8}#3YGlJkuX@ z4DO<{G_*R>e(iU#>rHeB=QdWJu6)?^pvzra$o+M96vuJ1{@P3`D+@2+kFCWTM5kw=&T z78jhtWAQxaJe&@z8sA#ne!Sk1YC$R%H8(4yDHv?mYz6uB%!`#9c6L0qK#PrEGH96d z_2|Dgn$bKuB4$Bc46LKs3fgAl_0Y)~#G1AB_oAYb-I~q;r#gpL{)@o>ZKF-Y1^}G{ z0B^3=(?$o7Kw0hsQaX-fG!7>j`}q7P8Cqy*{>-&Eb#Lmw%Hsu&HGT>h!gfXN$G~i^ zWir!khuTW@|CnQj?ac0Gd@R2uye}41UPVPE7S@@!UE8kkauuyYkt4NKc%qcN^}bEK zXhpdFMM%tfPeW;gy?YuOXqS=TnloCOx9F0lNaz6IZXj=y4veC<9PYC+FW?(qSQ&I->C%m%A_ywFVCfCm?v?opySMcf)RRPC z_}Jr8Rwc^ZjId80EH?z53yZBjZE3S=rJ=EOCTv_A5yJ*Z;JXT5xnG<)T3d{=iYoz~=^6Sl#s2?6+nb_{mXc#Z+EuuPp6}i%awN zl)z>#7aMU&y@St^>e=rhbYWRoXab$)7O%y@$04*FXK|_i262bHymcZP zfD03DaZE(qU8CG%63ue@(}`r!1*f!>0=7x~3Hrm5;!ZU!_8SWS($K)1{^&+pHy8bV zuxPPX)qgNn3 z$Q{9T;f-#HAtlp#m}w%K3$gV`R^WQd>YTGTZ11yoCY z&{P7e)cy~n-GL<_79j~h>?u!j)tYsnQmq>l@BtW7Yl;KW?WI6fP(FLSV7x3;@pzx{ z1O4H?OmkWJH^SWN48Ru>0I>Z!XYLHo3UHt2O&+Nr#!Idgq?wyG%=RaaC&m5L*DOkrzK|ip!0g;R zlu1F-#0m@?elc6;n3dN-5D$ilUE7h#!aQ8=$>Hke4Te zr>B2J=XCN9a_pQrD0a@Gi6tye3!araml6A@9Q7$zAHBX z+dxwp17w4~yS5U#+Y2*c&KfnLoDq{;3_c_Del4Lcp8@QpZ!|k2%wL2guI}X_tFCdq zKM6es@_FhVWLH%3e>K!Z&A#jB84qDgsmLg!rww|cisTGJY8+g0K~3Io;*C5xl`|{7 zWm})kroKU|yb=N9MYM3Q(J3-l?O%j@f)lx3%7Sw|J6rmPYYQ z04zdc6FA?F21e6FNHN@w=YQ?}S`AzkvOl7ki`B7??=Im$%?1FiM*>a52s$afvm85-az*RA;Z1JPZ z5MvQ)`IgvOpHSk)nBZVvH+j9UKI66X7^#;P=Jpa12O#2O#(^FevI}1wq4|V*<@jVFc^n=5%==B!JC5xYiY!DNa1{ z%ty^^B`Eb=96>{IHirjwiTYkmAQze(aG$cAZPwgu3I)h6t$)dY?OF`^ZBxGh1j0GeUkxWPi|VF2RXqKIVwq0ZcX0&_$Frs!bAGg=nN6# zM{Hmcvh_g1@t!5(T6thltGyY&Al{AL(5oV`N&0BT$tBu{I$z%YL}ibsW5U%gl$c)5}@Z|JAC2 zSA-T$`gkqpDfp28)Kt3|t9D=kGNK>F)h{|CO9G%rtT-DOy%Z9J$ z+zSJ*7htmG+g{Eh9*ys!NqC&-m{60f3&QsF<4;u&w8v%2WEv#^ekU}Nz^=;vbN`bNAj!od6q45UhFpc!VOi}CIXjy?9fM0-o7?8KlKIv2JaU9 z`{UL2^|AXhhNhDn0lhHPvG;MJbTfU~UF>y(w~s{~Y2&?PoB zz{uuJV@EtG@DKl;XB(}+{@Na^BAU@W_N*bQJ`*u6R#0Z`)21P3#oui1P5&@`M-9a( zR<5@Gq332Ucgvxj)*$i_@&IBsNAfMYq_p~pgRqI1MKWcenS=lM^#2*?+F>@pUSCTF z&=PL`u3CKa ze`!d(lI0XwUhex|lpE<_hbSg1CgnI5>@<9H7$s{PDPR=rld}WNa|p@PmFj~NRyr|JNE3l}!uR->O0Ttz7FUkoI!R0Efm_+_XqMJ7WaIyL`IabA~ z5qGlE91p#o!G5jcfI3)qzl90D)8w+hg&2E#_!>f>RqAL{}h%rl-R3Nxn7AOyt$!g#7MeqrJ2wM_m~hf*25 zddeBpIEvkeQo^S*6|woc0I0n3g8g`7_C06$WFGut$Q`2PJAOZIE+v?w*JRm#d@=FG z6+}4bB^|k!?QOFILNzVMc{~w z9!WMY%CWMdc*I%E}FT*1+Y`}KncKLfY*Mmeh(EBktdnHn|9?#z4TY5TJaQ=~NKnp-h!Zyx{IxaX`y0rj+Hu!=l& z3%!$H=YEkl{e_+HD$>wW}#}>+e%B zFS|aQsW`=}!&#doL=!QSQM>BzdNrW<0utJFBGD z^2AW^5=#LstH~g5*0?*!GJoIH@%@P)aI?*K)qaMuxX0RP}qa4^|Lu)EjG8Me#Dv z5%oIY5b8h5G1!MdW!}k-^zW$u9Wv;5dBaKXP8hi;yCO=K%l^+U7i^R#sWt+2y7jFq z;SGS{I1PUZ#^@apaV2R;foBna^jBskTcWTH)`DWr?1^n6;`io%^X;21_mnn0r^S#i z%pey3zP`K3+@o=&z8>goIYET8AVAX4=t=4|;(R zwTzstF)=rQ@hE`qM&IPf5IB?>U;s|3|3v4ZTV@*LB>ZAalwg9k1^W#ZTH#O8LmhEf zAQvW4!tV|#TAFtDOuEP~S{SdD@R(|2WGyso>0GrVX;~(dQ6>Im{A$?OFWf4NEniS3 zfS6<%mfUOr;C$Kg(?&s~K!T(^00G%RuUWixBb|6xk3$-RX|57&Ms{C^l!+PMmOI)D zVKsechqVOj-MjV(eJ4r!|3xU5{_f|;iH_9PYNG!^-Cy00A87ubjr#Z=tAq4;KbI5>_TP7=sm;KQ1vZp{uY z86YfZ$r3;`B`9EHx!ESyMCp5gU)?GyLCdl~3xmDzG~sKBzlwF6w^OGE_=&TfIFUTP7xEdjqTX4^v%5`FYs#M`*pp8Q0_o%tGod?Ih3~mOBU5zu^ zlmj1__!fE;3v+sq^T{N8i#Pwa$Y;&Z;Ff49oq(W#WFPVE@5F#Z2{=FoeKphQgUI_q zWX;3bBKSH%m1~`ktjN{%!31W-+39eLys;h9=8_MB7h=lu()fnr+`fj%rGy=^rh0rS z`+V_Mv6Aenm3p(O1>XPOU`5Mo-b~8;a?f-$jiyu}TRvqCouC60PW!(f*jz zWI+LwJwnSQsir@@+)(I!pPw66?M_Y6ZhTp$oj8sZN!y`!JSX#>L?JMt^g#>TE?E!` z9=>j$Tz@8X@+0w6bGn*sggJZ}1TFY-0j2lw*EaHl)@gAJDm7CTf$k}Rtq(oBtFprT z8R=GSr<~=7EogoAE8SBg&A^j$Os$9IK4jzlR=3WW>25g7509dRGnMO}exv33Q2C;Z zzt#{w91$;jwB1)Y%9lMI^P<1>5K1_e0f68Dh`XFraPe^9x{QDsPEz%@@qG*qh7-M) z1_H|YyHwwaeHjq_{D)clfZhPOn5s^4vrF8MW|RI255b{+JJe93BQ7;ra&wagNJ5N^ zFYLpMif3jXYFVD+O*FzBPA@`Bi_lRjnv-kOBca24<-59^8KG>;X_e>9$cn;UZdHVdB#+*l}>VO*kf-wpR2|5S7m0dH@h+`9%J^a3V@B4N z7aB%52_OeFk?oZ8PuF^ykj;%Z@AJ4vOrJ{<#M8kL!>s|YiW1ew-VDN(&t7_ z^}Y;Ddi>b!(CML*->?{kBn%D;d2oyE@aN)mE9=b6?Tz#~TDqnDmS*WyasFuh~&w(i1B#P|^@qyI89|iW2jt7gC)!?cklOxucKHi(?4Z zS=+>_Vwib`*ZxVLnBg?;i;R5vzhIpuVvTd2z=}>?80x1z2iigT;?jGBo&u6}e`yH$ zms5zY#7HCnF`p6+(zmg5%$??y*8Jpm8+>(|XyN{7@jGtFAy22l$RE2$nB8aU*S=#V zM$=VgC5ykOcX!$N66PEqM)5cGp>YX}KwS-^Q--vP0YrcEwTEVChIjN&rS>hO1KMgP zVoSmLF#cqQCb!pD1=Gxq{T3CO0bWA0tq+6vL2pfEyo=|lM-W%7lNYxgoo(}7Dn?oE z#l-a8>cut-lknGhwuuaNB07dEdrZin1Hq!D4gfqko1~{(ljWE8x3N`0=wLy%&M~te zz;IjagXDchZBmd*1*oMkrAN&1Pp- zjc&;#oZTJ7Ln^yIKjn^+v9gNWil$_Sp9~qMhC=Ek`B?3~jvP_4qeWx#+D;(z)Q`+|hkHYk1Zz`Km{&&5p2&Mt#eh zw=YqhE$ewZST=sI6h?wLr4JU@jxXKV&jz9ZkdQq>(S>}=RgKj-1W;BY~Ob;7y>AyQ*ZrW334OwT@icYK^g z^ddo$^@b=mY6kctjw>I?1wvwiX^csapjY|1vzZok;|?m--jW%D$2~f_P9@U{LK-Qmr#7VX<6DwJ+73vNZ8^45Gw-0#E$%AH#q}7vg(Hcf+ga>!(f=x091I~ z?7^%42aoyR{9sO*dtR$6&HAoZyqVx;`{b?gLz(-650262b|3H5T|ZZcy)gMe;ni8w zj`kQIKFswGnqh*VE>;`kWc1V1I8$zwsy7bRkJbX*+c|z%XD7+(DwiDI3Dvvs)gzw` z$QxJ|&kTKwn)9iyaoo;lA8!1^XNBTrnVx`D;c!tVOkqu;-Ka^0b-6+JXgBQ)PG3vz zMfQ25dUzC(KZprr1Th9!UFSVmQecS`()T?=Q-I_Gi_nGOAz4;E#BvJ1-bC(mBZKn6 zz$6;y7ffeCC~F8 zQ{d_OKpMi(QG_x@$k=!&M$>?HsB*CZ)fLhAq1MUV1YY{pg7?loZ24m55&ie<)abtT zTbHKqp(!SeX4$eQda3in@g~|Q9Jjyo)L*GMiPhJ_>gMdvky+RW?xuK#R!&-~7GzNl)~HaVa8q4QR3&yCK;?D3;_ zLVlxPPsnz?W>bd@n5h}hTPI0X57*Be4a@G#BH0eS0iP-+OeZY|RHq5ft8X-xz&+S#LL+Y$N^l_wJhbO;*7IYL zzU?#U7FF1R`c0uk=ojoDQQXS4%~M?}y`+<1bY=Vpt!WF{JR4s+`e4`x@V5=hmLGVN z?5lEQe04g7nqLM8a$T8!KHx8vi;vQ$?K}=PD!c?h04og}>kez@IfSllu>m#!cY_STp3i+p zCNEzu4;3+G9=v(<+T%7PJSF6ka$j3^SuaKxiU_Zv+?{k?8alu{cAfPMWtTyT0o03^ z9z7xe{o~8q)a%o2M2VEGWRkMP~*K&d0*Xs z-(9sQp|rbdDdg^GlUE7lH#6vagoXi0*FW=6w<-O-?uJ!|rLFV%b2mg;7M_LC;p9vy zwxiV*Wle@dSSpU1B%%i}_z$=dnpW2~8ws!;SPKtGJ+1)-fifY+7t@Sh zYiLknRS@fyWLj%O+6RSS>TsKf9I2;bYn|Xab4?I{A`>5lM7K&dvAE)3K{j z)BR*|Sd}LJ%^h2njP9V-slaX8xbg7IGug?;2L5#xD&r-@6Z9GDCblWLo?xWHaI8db zf8mIHDy#3ts>fKXkPGBL`@PpD=^HTtAcNhIAlx{g7;s+dgj9NLL39Ksa7% z5ZAlW{d4sGxr1s~+B!^RVirrCx&(TZ`!3h7J+9Tyja>V1+2L!eu%Kw+ONgdqE0n`l zWfCv_P|=f9mH*rp6bh>6&=FSRY+l|o;_Xza>`%%xd$1bFGm;F@_-QW`1)S*tA->XXxCAsap^)68%DF(v( zQC^EmxYdO8GwN)V>+3DA^Q1ZGtlUM!aN~XL_jwq-4M(?6^U240ghLawSPe!ufDPlu zCBZ%mwc#Kx?_$ivF@U@%gjayeh?K<*VC~n99z1=+(H%PBQezvU9Z554F#UEI1E|tr@#N#}nu`zm{|@A#|8cQ9@=SN+_{muTA~oL1cJSN_or@8lc)xod-h5d4 zD$FgNm|4`?G*~F-Gpl*Gqxwf6&*ON0SmQL^NBP%~)Y&1aXYbE#{H(i#cAH^OUZ|

3hDx0@T~+V#y|9SzctmhiQJZqC`exMq@fE01<>R zUVFa&^F----_YqH6_HZ?*5#wN4LQwoit2A`IQ9oP;}0#{y23g&Ca~8>ej}48MHA+D ze|$A7*!(m8e`a8h5Saw9o~-}tEb^@Ff5zWw2KERsN&gV~J2Cn9Yx#%Jzt6|tZ|@&M ze?KPwentNf`uF+x`|bTh=>K&LjOJ=f4{wd2>rh?fdl{3um4EsfBGW+`Mv*s H27vzs6aE^6 literal 0 HcmV?d00001 diff --git a/public/sound/transaction.mp3 b/public/sound/transaction.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..4841543a64a6ed8e5723f3c9a181753edebde3c7 GIT binary patch literal 27732 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 HVQ51D{u$rP literal 0 HcmV?d00001 diff --git a/public/views/transaction/list.html b/public/views/transaction/list.html index f8501c95..eb3a45cb 100644 --- a/public/views/transaction/list.html +++ b/public/views/transaction/list.html @@ -1,6 +1,6 @@

Loading...
There are not transactions
-
+
{{tx.txid}} {{tx.time * 1000 | date:'medium'}} From f7fce1af7d7ca8e6e5d7b1f0982b951893415fc7 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Mon, 20 Jan 2014 17:31:14 -0300 Subject: [PATCH 02/40] remove old sound --- public/sound/beep.mp3 | Bin 15932 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 public/sound/beep.mp3 diff --git a/public/sound/beep.mp3 b/public/sound/beep.mp3 deleted file mode 100644 index ed6a42ad1ec59000ca994839a8125edda282ddca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15932 zcmeI2cTiJn+wNBqO6Vd4A7z-`9Pwg*V1RfW4t$ zZ)2jy`rOZY+no&y@iKRhRP{U?4F7WnZsOzP?HPIzVD4lxSl<9ZXcz#1zu)zHrfb6u z2Tb9H=K4%~MY-(4hgM7h#=BoG2TV^g6MRq7iYl^-s2piJ(YF{S*a%7FDIP^eZ=8VD zXY9)#yyQ5@VL_4`{`+TRZCKg46Rb1u?o^!vCB>248RvunDA`kBcYY{-OBfS$h4(No zkEPP}-H{HAUy^`8F|Q7rh~KFt=Gi}B;8?dW$4F2%)d+SFSf9^Pr+ZqH$^6Zv8gxDc zkZ=x8AaTDY&f9R51H*^oWn%-8fy(}aOeXU)4mXDb05&j~1i;~fyb!*Wi-vqe@es!j z^YRHw&o!U@B}LrDim!wcG&t|@byG!Rj_>R0+aE6zg<~*6kvJW7FbJ*z9k9q?xC_BW z50IXa)bJ!2B({Pr#!!dbOi;lrDKi$L^0jb( O0g8gD_Neij*iM+rep34e3Vhjw1 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

3hDx0@T~+V#y|9SzctmhiQJZqC`exMq@fE01<>R zUVFa&^F----_YqH6_HZ?*5#wN4LQwoit2A`IQ9oP;}0#{y23g&Ca~8>ej}48MHA+D ze|$A7*!(m8e`a8h5Saw9o~-}tEb^@Ff5zWw2KERsN&gV~J2Cn9Yx#%Jzt6|tZ|@&M ze?KPwentNf`uF+x`|bTh=>K&LjOJ=f4{wd2>rh?fdl{3um4EsfBGW+`Mv*s H27vzs6aE^6 From 8e7887fa4005dc54cc4474d627044b14b48684c8 Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Mon, 20 Jan 2014 17:39:27 -0300 Subject: [PATCH 03/40] isolate TX view --- public/views/transaction.html | 70 +++--------------------------- public/views/transaction/list.html | 68 +---------------------------- public/views/transaction/tx.html | 68 +++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+), 130 deletions(-) create mode 100644 public/views/transaction/tx.html diff --git a/public/views/transaction.html b/public/views/transaction.html index fe4afeb1..ddc6007c 100644 --- a/public/views/transaction.html +++ b/public/views/transaction.html @@ -5,66 +5,7 @@

- - -
- -
-
    -
  • - - - Address could not be parsed - {{vin.addr}} - {{vin.value}} BTC -
  • - -
-
-
    -
  • - No Inputs (Newly Generated isCoinBasens) - {{vinn.reward}} BTC -
  • -
-
-
- -
- -
- -
-
-
- {{vout.scriptPubKey.type}} -
-
- -
-
-
-
- -
- Feeds: {{tx.feeds}} -
- - - -
-
+
@@ -81,9 +22,12 @@ {{tx.time * 1000|date:'medium'}} - Block - Block - + Block + + +
diff --git a/public/views/transaction/list.html b/public/views/transaction/list.html index f8501c95..a8d35eb1 100644 --- a/public/views/transaction/list.html +++ b/public/views/transaction/list.html @@ -1,71 +1,5 @@
Loading...
There are not transactions
-
- {{tx.txid}} - {{tx.time * 1000 | date:'medium'}} -
- -
-
-
-
-

No Inputs (Newly Generated isCoinBasens)

-
-

{{vin.reward}} BTC

-
-
    -
  • - - -
    -
    - Address could not be parsed - {{vin.addr}} -
    -
    -

    {{vin.value}} BTC

    -
  • -
-
- -
-   -
- -
-
-
-
- {{vout.scriptPubKey.type}} -
-
-
-
- -
-
-

{{vout.value}} BTC

-
-
-
-
-
- -
-
-
- - - -
- Feeds: {{tx.feeds}} -
-
+
diff --git a/public/views/transaction/tx.html b/public/views/transaction/tx.html new file mode 100644 index 00000000..a48c67b8 --- /dev/null +++ b/public/views/transaction/tx.html @@ -0,0 +1,68 @@ +
+ {{tx.txid}} + {{tx.time * 1000 | date:'medium'}} +
+ +
+
+
+
+

No Inputs (Newly Generated isCoinBasens)

+
+

{{vin.reward}} BTC

+
+
    +
  • + + +
    +
    + Address could not be parsed + {{vin.addr}} +
    +
    +

    {{vin.value}} BTC

    +
  • +
+
+ +
+   +
+ +
+
+
+
+ {{vout.scriptPubKey.type}} +
+
+
+
+ +
+
+

{{vout.value}} BTC

+
+
+
+
+
+ +
+
+
+ + + +
+ Feeds: {{tx.feeds}} +
+
+ From 0c10fd35ea8ed78e743df837b4d5ffa06957396a Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Mon, 20 Jan 2014 17:51:13 -0300 Subject: [PATCH 04/40] fix layouts problems in tx --- public/views/transaction.html | 6 ++---- public/views/transaction/tx.html | 6 +++--- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/public/views/transaction.html b/public/views/transaction.html index ddc6007c..aef2bfab 100644 --- a/public/views/transaction.html +++ b/public/views/transaction.html @@ -11,7 +11,7 @@

Summary

- +
@@ -25,9 +25,7 @@
Size Block - + {{tx.blockhash}}
diff --git a/public/views/transaction/tx.html b/public/views/transaction/tx.html index a48c67b8..84261d09 100644 --- a/public/views/transaction/tx.html +++ b/public/views/transaction/tx.html @@ -7,13 +7,13 @@
-

No Inputs (Newly Generated isCoinBasens)

+

No Inputs (Newly Generated Coins)

{{vin.reward}} BTC

  • - +
    @@ -40,7 +40,7 @@
    From e45c1ef2bdec63754021d1b0061ab216a192417b Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Mon, 20 Jan 2014 18:09:18 -0300 Subject: [PATCH 05/40] remove old style angular module def --- public/js/controllers/address.js | 9 +-------- public/js/controllers/blocks.js | 5 +++-- public/js/controllers/footer.js | 7 ++----- public/js/controllers/header.js | 5 +++-- public/js/controllers/index.js | 10 ++-------- public/js/controllers/search.js | 5 +++-- public/js/controllers/status.js | 5 +++-- public/js/controllers/transactions.js | 13 ++----------- public/js/services/address.js | 5 +++-- public/js/services/blocks.js | 10 ++++++---- public/js/services/global.js | 4 +++- public/js/services/socket.js | 5 +++-- public/js/services/status.js | 10 ++++++---- public/js/services/transactions.js | 20 ++++++++++++-------- 14 files changed, 52 insertions(+), 61 deletions(-) diff --git a/public/js/controllers/address.js b/public/js/controllers/address.js index 664c2ba6..fde4660f 100644 --- a/public/js/controllers/address.js +++ b/public/js/controllers/address.js @@ -1,13 +1,6 @@ 'use strict'; angular.module('insight.address').controller('AddressController', - ['$scope', - '$rootScope', - '$routeParams', - '$location', - 'Global', - 'Address', - 'get_socket', function ($scope, $rootScope, $routeParams, $location, Global, Address, get_socket) { $scope.global = Global; @@ -33,4 +26,4 @@ angular.module('insight.address').controller('AddressController', socket.emit('subscribe', $routeParams.addrStr); $scope.params = $routeParams; -}]); +}); diff --git a/public/js/controllers/blocks.js b/public/js/controllers/blocks.js index e3002999..a934718c 100644 --- a/public/js/controllers/blocks.js +++ b/public/js/controllers/blocks.js @@ -1,6 +1,7 @@ 'use strict'; -angular.module('insight.blocks').controller('BlocksController', ['$scope', '$rootScope', '$routeParams', '$location', 'Global', 'Block', 'Blocks', function ($scope, $rootScope, $routeParams, $location, Global, Block, Blocks) { +angular.module('insight.blocks').controller('BlocksController', + function ($scope, $rootScope, $routeParams, $location, Global, Block, Blocks) { $scope.global = Global; $scope.list = function() { @@ -32,4 +33,4 @@ angular.module('insight.blocks').controller('BlocksController', ['$scope', '$roo }; $scope.params = $routeParams; -}]); +}); diff --git a/public/js/controllers/footer.js b/public/js/controllers/footer.js index 611cfc82..e9d5c423 100644 --- a/public/js/controllers/footer.js +++ b/public/js/controllers/footer.js @@ -1,10 +1,7 @@ 'use strict'; angular.module('insight.system').controller('FooterController', - ['$scope', - 'Global', - 'Status', - function ($scope, Global, Status) { + function ($scope, Global, Status) { $scope.global = Global; $scope.getFooter = function() { @@ -15,5 +12,5 @@ angular.module('insight.system').controller('FooterController', }); }; -}]); +}); diff --git a/public/js/controllers/header.js b/public/js/controllers/header.js index fc9eed3a..8b3b4f7e 100755 --- a/public/js/controllers/header.js +++ b/public/js/controllers/header.js @@ -1,6 +1,7 @@ 'use strict'; -angular.module('insight.system').controller('HeaderController', ['$scope', 'Global', function ($scope, Global) { +angular.module('insight.system').controller('HeaderController', + function ($scope, Global) { $scope.global = Global; $scope.menu = [ @@ -15,4 +16,4 @@ angular.module('insight.system').controller('HeaderController', ['$scope', 'Glob ]; $scope.isCollapsed = false; -}]); +}); diff --git a/public/js/controllers/index.js b/public/js/controllers/index.js index e733d751..cbda7cc0 100755 --- a/public/js/controllers/index.js +++ b/public/js/controllers/index.js @@ -3,13 +3,7 @@ var TRANSACTION_DISPLAYED = 5; var BLOCKS_DISPLAYED = 5; angular.module('insight.system').controller('IndexController', - ['$scope', - '$rootScope', - 'Global', - 'get_socket', - 'Blocks', - 'Transactions', - function($scope, $rootScope, Global, get_socket, Blocks, Transactions) { + function($scope, $rootScope, Global, get_socket, Blocks, Transactions) { $scope.global = Global; var socket = get_socket($scope); @@ -55,4 +49,4 @@ angular.module('insight.system').controller('IndexController', $scope.txs = []; $scope.blocks = []; -}]); +}); diff --git a/public/js/controllers/search.js b/public/js/controllers/search.js index a41b9feb..e1299dce 100644 --- a/public/js/controllers/search.js +++ b/public/js/controllers/search.js @@ -1,6 +1,7 @@ 'use strict'; -angular.module('insight.search').controller('SearchController', ['$scope', '$routeParams', '$location', 'Global', 'Block', 'Transaction', 'Address', function ($scope, $routeParams, $location, Global, Block, Transaction, Address) { +angular.module('insight.search').controller('SearchController', + function ($scope, $routeParams, $location, Global, Block, Transaction, Address) { $scope.global = Global; $scope.search = function() { @@ -31,4 +32,4 @@ angular.module('insight.search').controller('SearchController', ['$scope', '$rou }); }; -}]); +}); diff --git a/public/js/controllers/status.js b/public/js/controllers/status.js index 8fa2f24b..019c04d0 100644 --- a/public/js/controllers/status.js +++ b/public/js/controllers/status.js @@ -1,6 +1,7 @@ 'use strict'; -angular.module('insight.status').controller('StatusController', ['$scope', '$routeParams', '$location', '$rootScope', 'Global', 'Status', 'Sync', function ($scope, $routeParams, $location, $rootScope, Global, Status, Sync) { +angular.module('insight.status').controller('StatusController', + function ($scope, $routeParams, $location, $rootScope, Global, Status, Sync) { $scope.global = Global; $scope.getStatus = function(q) { @@ -27,5 +28,5 @@ angular.module('insight.status').controller('StatusController', ['$scope', '$rou $rootScope.syncError = 'Could not get sync information' + e; }); }; -}]); +}); diff --git a/public/js/controllers/transactions.js b/public/js/controllers/transactions.js index 3d9f92cb..496e0ddc 100644 --- a/public/js/controllers/transactions.js +++ b/public/js/controllers/transactions.js @@ -1,16 +1,7 @@ 'use strict'; angular.module('insight.transactions').controller('transactionsController', - ['$scope', - '$rootScope', - '$routeParams', - '$location', - 'Global', - 'Transaction', - 'TransactionsByBlock', - 'TransactionsByAddress', - 'get_socket', - function ($scope, $rootScope, $routeParams, $location, Global, Transaction, TransactionsByBlock, TransactionsByAddress, get_socket) { + function ($scope, $rootScope, $routeParams, $location, Global, Transaction, TransactionsByBlock, TransactionsByAddress, get_socket) { $scope.global = Global; $scope.findThis = function() { @@ -62,4 +53,4 @@ angular.module('insight.transactions').controller('transactionsController', $scope.txs = []; -}]); +}); diff --git a/public/js/services/address.js b/public/js/services/address.js index 6773267b..17d05ce0 100644 --- a/public/js/services/address.js +++ b/public/js/services/address.js @@ -1,6 +1,7 @@ 'use strict'; -angular.module('insight.address').factory('Address', ['$resource', function($resource) { +angular.module('insight.address').factory('Address', + function($resource) { return $resource('/api/addr/:addrStr', { addrStr: '@addStr' }, { @@ -18,5 +19,5 @@ angular.module('insight.address').factory('Address', ['$resource', function($res } } }); -}]); +}); diff --git a/public/js/services/blocks.js b/public/js/services/blocks.js index 346b6508..e713f1f6 100644 --- a/public/js/services/blocks.js +++ b/public/js/services/blocks.js @@ -1,6 +1,7 @@ 'use strict'; -angular.module('insight.blocks').factory('Block', ['$resource', function($resource) { +angular.module('insight.blocks').factory('Block', + function($resource) { return $resource('/api/block/:blockHash', { blockHash: '@blockHash' }, { @@ -18,8 +19,9 @@ angular.module('insight.blocks').factory('Block', ['$resource', function($resour } } }); -}]); +}); -angular.module('insight.blocks').factory('Blocks', ['$resource', function($resource) { +angular.module('insight.blocks').factory('Blocks', + function($resource) { return $resource('/api/blocks'); -}]); +}); diff --git a/public/js/services/global.js b/public/js/services/global.js index 73637022..1b1f375f 100755 --- a/public/js/services/global.js +++ b/public/js/services/global.js @@ -1,5 +1,7 @@ 'use strict'; //Global service for global variables -angular.module('insight.system').factory('Global', [function() {}]); +angular.module('insight.system').factory('Global', + function() { +}); diff --git a/public/js/services/socket.js b/public/js/services/socket.js index 98af5e1e..6dc07491 100644 --- a/public/js/services/socket.js +++ b/public/js/services/socket.js @@ -46,7 +46,8 @@ ScopedSocket.prototype.emit = function(event, data, callback) { }); }; -angular.module('insight.socket').factory('get_socket', ['$rootScope', function($rootScope) { +angular.module('insight.socket').factory('get_socket', + function($rootScope) { var socket = io.connect(); return function(scope) { var scopedSocket = new ScopedSocket(socket, $rootScope); @@ -55,5 +56,5 @@ angular.module('insight.socket').factory('get_socket', ['$rootScope', function($ }); return scopedSocket; }; -}]); +}); diff --git a/public/js/services/status.js b/public/js/services/status.js index 67d7004a..eb807620 100644 --- a/public/js/services/status.js +++ b/public/js/services/status.js @@ -1,12 +1,14 @@ 'use strict'; -angular.module('insight.status').factory('Status', ['$resource', function($resource) { +angular.module('insight.status').factory('Status', + function($resource) { return $resource('/api/status', { q: '@q' }); -}]); +}); -angular.module('insight.status').factory('Sync', ['$resource', function($resource) { +angular.module('insight.status').factory('Sync', + function($resource) { return $resource('/api/sync'); -}]); +}); diff --git a/public/js/services/transactions.js b/public/js/services/transactions.js index d1b0b355..25202463 100644 --- a/public/js/services/transactions.js +++ b/public/js/services/transactions.js @@ -1,6 +1,7 @@ 'use strict'; -angular.module('insight.transactions').factory('Transaction', ['$resource', function($resource) { +angular.module('insight.transactions').factory('Transaction', + function($resource) { return $resource('/api/tx/:txId', { txId: '@txId' }, { @@ -18,20 +19,23 @@ angular.module('insight.transactions').factory('Transaction', ['$resource', func } } }); -}]); +}); -angular.module('insight.transactions').factory('TransactionsByBlock', ['$resource', function($resource) { +angular.module('insight.transactions').factory('TransactionsByBlock', + function($resource) { return $resource('/api/txs', { block: '@block' }); -}]); +}); -angular.module('insight.transactions').factory('TransactionsByAddress', ['$resource', function($resource) { +angular.module('insight.transactions').factory('TransactionsByAddress', + function($resource) { return $resource('/api/txs', { address: '@address' }); -}]); +}); -angular.module('insight.transactions').factory('Transactions', ['$resource', function($resource) { +angular.module('insight.transactions').factory('Transactions', + function($resource) { return $resource('/api/txs'); -}]); +}); From aab8ac2e29f9f33c85dfd836b2a29a026afb25e7 Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Mon, 20 Jan 2014 18:11:50 -0300 Subject: [PATCH 06/40] add scripts to tx --- public/views/transaction.html | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/public/views/transaction.html b/public/views/transaction.html index aef2bfab..8e4ee015 100644 --- a/public/views/transaction.html +++ b/public/views/transaction.html @@ -48,6 +48,20 @@
    +
    +

    ScriptSig

    +
      +
    • + {{vin.scriptSig.asm}} +
    +
    +
    +

    ScriptPubKey

    +
      +
    • {{vout.scriptPubKey.asm}} +
    +
    +
    From ef0b558ed970ee8801b7e050da9f19001a55f18f Mon Sep 17 00:00:00 2001 From: Gustavo Cortez Date: Mon, 20 Jan 2014 18:52:28 -0300 Subject: [PATCH 07/40] fix conflicts --- app/controllers/blocks.js | 14 ++++++++++++++ app/models/Block.js | 9 +++++++++ config/routes.js | 3 +++ public/js/config.js | 4 ++++ public/js/services/blocks.js | 8 +++++++- 5 files changed, 37 insertions(+), 1 deletion(-) diff --git a/app/controllers/blocks.js b/app/controllers/blocks.js index 37324a09..b41b67f3 100644 --- a/app/controllers/blocks.js +++ b/app/controllers/blocks.js @@ -32,6 +32,20 @@ exports.show = function(req, res) { } }; +/** + * Show block by Height + */ +exports.blockindex = function(req, res, next, height) { + Block.fromHeight(height, function(err, hash) { + if (err) { + console.log(err); + res.status(400).send('Bad Request'); // TODO + } + else { + res.jsonp(hash); + } + }); +}; /** * List of blocks by date diff --git a/app/models/Block.js b/app/models/Block.js index 3f4bcbcf..33bf34bd 100644 --- a/app/models/Block.js +++ b/app/models/Block.js @@ -72,6 +72,15 @@ BlockSchema.statics.load = function(id, cb) { }).exec(cb); }; +BlockSchema.statics.fromHeight = function(height, cb) { + var rpc = new RpcClient(config.bitcoind); + var hash = {}; + rpc.getBlockHash(height, function(err, bh){ + if (err) return cb(err); + hash.blockHash = bh.result; + cb(null, hash); + }); +}; BlockSchema.statics.fromHash = function(hash, cb) { this.findOne({ diff --git a/config/routes.js b/config/routes.js index fc27b789..8125f561 100644 --- a/config/routes.js +++ b/config/routes.js @@ -14,6 +14,9 @@ module.exports = function(app, historicSync) { app.get('/api/block/:blockHash', blocks.show); app.param('blockHash', blocks.block); + app.get('/api/block-index/:height', blocks.blockindex); + app.param('height', blocks.blockindex); + // Transaction routes var transactions = require('../app/controllers/transactions'); app.get('/api/tx/:txid', transactions.show); diff --git a/public/js/config.js b/public/js/config.js index 65028fd9..9791eb07 100755 --- a/public/js/config.js +++ b/public/js/config.js @@ -7,6 +7,10 @@ angular.module('insight').config(['$routeProvider', when('/block/:blockHash', { templateUrl: 'views/block.html' }). + when('/block-index/:blockHeight', { + controller: 'BlocksController', + template: 'Redirecting...' + }). when('/tx/:txId', { templateUrl: 'views/transaction.html' }). diff --git a/public/js/services/blocks.js b/public/js/services/blocks.js index e713f1f6..12d1da16 100644 --- a/public/js/services/blocks.js +++ b/public/js/services/blocks.js @@ -23,5 +23,11 @@ angular.module('insight.blocks').factory('Block', angular.module('insight.blocks').factory('Blocks', function($resource) { - return $resource('/api/blocks'); + return $resource('/api/blocks'); }); + +angular.module('insight.blocks').factory('BlockByHeight', + function($resource) { + return $resource('/api/block-index/:blockHeight'); +}); + From 4291af0cc3ba74cbc8eb527504f96e8153c80627 Mon Sep 17 00:00:00 2001 From: Gustavo Cortez Date: Mon, 20 Jan 2014 18:53:24 -0300 Subject: [PATCH 08/40] go to block using height value. url is: /block-index/ --- app/controllers/status.js | 2 +- public/js/controllers/blocks.js | 13 ++++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/app/controllers/status.js b/app/controllers/status.js index 1874605e..7fb6f72a 100644 --- a/app/controllers/status.js +++ b/app/controllers/status.js @@ -10,7 +10,7 @@ var Status = require('../models/Status'), /** * Status */ -exports.show = function(req, res, next) { +exports.show = function(req, res) { if (! req.query.q) { res.status(400).send('Bad Request'); diff --git a/public/js/controllers/blocks.js b/public/js/controllers/blocks.js index a934718c..2013db3b 100644 --- a/public/js/controllers/blocks.js +++ b/public/js/controllers/blocks.js @@ -1,9 +1,20 @@ 'use strict'; angular.module('insight.blocks').controller('BlocksController', - function ($scope, $rootScope, $routeParams, $location, Global, Block, Blocks) { + function ($scope, $rootScope, $routeParams, $location, Global, Block, Blocks, BlockByHeight) { $scope.global = Global; + if ($routeParams.blockHeight) { + BlockByHeight.get({ + blockHeight: $routeParams.blockHeight + }, function(hash) { + $location.path('/block/' + hash.blockHash); + }, function() { + $rootScope.flashMessage = 'Bad Request'; + $location.path('/'); + }); + } + $scope.list = function() { Blocks.get({ blockDate: $routeParams.blockDate From 0dfaec73db9512f8df9b78ba55a6ff0c58791c4d Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Mon, 20 Jan 2014 18:57:50 -0300 Subject: [PATCH 09/40] simple versions of vin vout for displaying --- public/js/controllers/transactions.js | 44 +++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/public/js/controllers/transactions.js b/public/js/controllers/transactions.js index 52b12c90..c82b6599 100644 --- a/public/js/controllers/transactions.js +++ b/public/js/controllers/transactions.js @@ -17,11 +17,55 @@ angular.module('insight.transactions').controller('transactionsController', $scope.findTx($routeParams.txId); }; + + $scope.aggregateItems = function(items) { + var l = items.length; + + var ret = []; + var tmp = {}; + // TODO multiple output address + // + for(var i=0; i < l; i++) { + + // non standard output + if (items[i].scriptPubKey && items[i].scriptPubKey.addresses.length > 1) { + ret.push(items[i]); + continue; + } + + var addr = items[i].addr || items[i].scriptPubKey.addresses[0]; + if (!tmp[addr]) { + tmp[addr] = {}; + tmp[addr].valueSat = 0; + tmp[addr].count = 0; + tmp[addr].addr = addr; + tmp[addr].items = []; + } + tmp[addr].valueSat += items[i].valueSat; + tmp[addr].value = tmp[addr].valueSat / 100000000; + tmp[addr].items.push(items[i]); + tmp[addr].count++; + } + + angular.forEach(tmp, function(v) { + ret.push(v); + }); + return (ret); + }; + + + $scope.processTX = function(tx) { + tx.vinSimple = $scope.aggregateItems(tx.vin); + tx.voutSimple = $scope.aggregateItems(tx.vout); +console.log('[transactions.js.33:insSimple:]',tx); //TODO + }; + $scope.findTx = function(txid) { Transaction.get({ txId: txid }, function(tx) { $scope.tx = tx; +$scope.processTX(tx); $scope.txs.push(tx); }, function(e) { if (e.status === 400) { From 8b15df0e2a393c40ba2f63ead82e0b3459ffee05 Mon Sep 17 00:00:00 2001 From: Gustavo Cortez Date: Mon, 20 Jan 2014 21:02:47 -0300 Subject: [PATCH 10/40] link and fix lookandfell statusPage. fix footer, placeholder, block box. Little fix pager of block list. --- app/models/Transaction.js | 9 +++++-- public/css/common.css | 41 +++++++++++++++++----------- public/views/blocks/list.html | 43 +++++++++++++++++------------- public/views/footer.html | 8 ++---- public/views/header.html | 4 +-- public/views/status.html | 42 ++++++++++++----------------- public/views/transaction/list.html | 8 ++++-- 7 files changed, 84 insertions(+), 71 deletions(-) diff --git a/app/models/Transaction.js b/app/models/Transaction.js index eaa0081b..e9834a6d 100644 --- a/app/models/Transaction.js +++ b/app/models/Transaction.js @@ -346,8 +346,13 @@ TransactionSchema.methods.fillInfo = function(next) { if (err) return next(err); that.info = info; - that.info.time = that.time; - return next(); + if (! that.info) { + return next(); + } + else { + that.info.time = that.time; + return next(); + } }); }; diff --git a/public/css/common.css b/public/css/common.css index 9c9e546d..a5587d84 100644 --- a/public/css/common.css +++ b/public/css/common.css @@ -29,7 +29,7 @@ h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 { min-height: 100%; height: auto; /* Negative indent footer by its height */ - margin: 0 auto -60px; + margin: 0 auto -44px; /* Pad bottom by footer height */ padding: 0 0 60px; } @@ -87,22 +87,22 @@ h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 { font-weight: 100; } -#search::-webkit-input-placeholder { +#search::-webkit-input-placeholder { font-family: Ubuntu, sans-serif; font-weight: 100; font-style: italic; - font-size: 13px; + font-size: 15px; color: #BCDF7E; - line-height: 18px; + line-height: 20px; } -#search::-moz-placeholder { +#search::-moz-placeholder { font-family: Ubuntu, sans-serif; font-weight: 100; - font-size: 13px; + font-size: 15px; color: #BCDF7E; - line-height: 18px; + line-height: 20px; } .status { @@ -122,8 +122,6 @@ h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 { background-color: #F4F4F4; padding: 15px; margin-top: 21px; - width: 265px; - height: 87%; border-radius: 5px; } @@ -223,8 +221,10 @@ h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 { /* Set the fixed height of the footer here */ #footer { - height: 60px; - background-color: #f5f5f5; + height: 44px; + background-color: #8DC429; + border-top: 4px solid #64920F; + color: #fff; } .line-bot { @@ -246,9 +246,14 @@ h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 { #wrap > .container { padding: 60px 15px 0; } -/*.container .text-muted { - margin: 20px 0; -}*/ + +.container .text-muted { + margin: 10px 0; +} + +.container .text-muted a { + color: #eee; +} #footer > .container { padding-left: 15px; @@ -265,7 +270,13 @@ h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 { #search { width: 400px; } - +.no_matching { + background-color: #FFFFFF; + border: 2px solid #64920F; + padding: 10px 20px; + position: absolute; + top: 46px; +} /*Animations*/ .fader.ng-enter { diff --git a/public/views/blocks/list.html b/public/views/blocks/list.html index e7e0f60b..494255ff 100644 --- a/public/views/blocks/list.html +++ b/public/views/blocks/list.html @@ -1,27 +1,32 @@
    - - - - - - - - - - - -
    HashSolved at
    {{block.hash}}{{block.time * 1000 | date:'medium'}}
    -

    No blocks yet.

    +
    +
    + + + + + + + + + + + + + + +
    HashSolved at
    {{block.hash}}{{block.time * 1000 | date:'medium'}}
    +
    +
    +

    No blocks yet.

    diff --git a/public/views/footer.html b/public/views/footer.html index 4e08b207..7401eaee 100644 --- a/public/views/footer.html +++ b/public/views/footer.html @@ -1,10 +1,6 @@ -
    +
    -

    - Blocks: {{info.blocks}} | - Connections: {{info.connections}} | - Difficulty: {{info.difficulty}} -

    +

    Insight

    diff --git a/public/views/header.html b/public/views/header.html index e831eb56..6d12e447 100755 --- a/public/views/header.html +++ b/public/views/header.html @@ -20,7 +20,7 @@
    - No matching records found! +
    No matching records found!
    @@ -36,4 +36,4 @@
    -
    \ No newline at end of file +
diff --git a/public/views/status.html b/public/views/status.html index 71951199..da408791 100644 --- a/public/views/status.html +++ b/public/views/status.html @@ -5,8 +5,8 @@
-
-

getInfo

+
+

getInfo()

@@ -31,7 +31,7 @@ - + @@ -71,9 +71,8 @@
blocks{{info.blocks}}{{info.blocks}}
timeoffset
-
-
-

sync status

+ +

Sync Status

@@ -95,14 +94,16 @@ - - @@ -116,14 +117,10 @@ - - - -
start{{sync.start}} - (genesisBlock) + + {{sync.start}} + (genesisBlock)
end{{sync.end}} - (genesisBlock) + + {{sync.end}} + (genesisBlock)
-

getTxOutSetInfo

+

getTxOutSetInfo()

@@ -134,11 +131,11 @@ - + - + @@ -162,12 +159,8 @@
Height{{txoutsetinfo.height}}{{txoutsetinfo.height}}
bestblock{{txoutsetinfo.bestblock}}{{txoutsetinfo.bestblock}}
transactions
-
-
-
-
-

getDifficulty

+

getDifficulty()

@@ -183,9 +176,8 @@
-
-
-

getLastBlockHash

+ +

getLastBlockHash()

diff --git a/public/views/transaction/list.html b/public/views/transaction/list.html index eb3a45cb..78746347 100644 --- a/public/views/transaction/list.html +++ b/public/views/transaction/list.html @@ -1,5 +1,9 @@ -
Loading...
-
There are not transactions
+
+
+ Loading... +
+
+
There are not transactions
{{tx.txid}} From c41d2f1b95c7273fe744f7e70199a8daecf0b34b Mon Sep 17 00:00:00 2001 From: Eric Martindale Date: Tue, 21 Jan 2014 00:26:28 +0000 Subject: [PATCH 11/40] Move external dependencies into package.json. --- README.md | 30 ------------------------------ package.json | 5 +++-- 2 files changed, 3 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index 8c1ed487..efc9ae00 100644 --- a/README.md +++ b/README.md @@ -57,36 +57,6 @@ $ npm install -g bower If you get an error, please check the next section "Post-install" -### Post-install (post-dependecies) - - Get bufferput package from Github repository: - - $ git clone git@github.com:gasteve/node-bufferput.git - - Create symbolic link of node-bufferput in your insight folder: - - $ cd /insight/node_modules - $ ln -s /node-bufferput bufferput - - Get bitcore from github repository: - - Get bitcore from github repository: - - $ git clone https://github.com/bitpay/bitcore.git - - $ cd bitcore - - $ npm install - - Then create a symbolic link from this to your insight repository. We need to - use bitcore from github, not with npm for now: - - $ cd insight/node_modules - - $ rm -R bitcore - - $ ln -s /bitcore - ## Syncing old blockchain data Run sync from insight repository (to save old blocks and transactions in MongoDB): diff --git a/package.json b/package.json index 3078ba40..c0fa2e7b 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,6 @@ "mongoose": "~3.8.3", "lodash": "~2.4.1", "bower": "~1.2.8", - "bitcore": "*", "buffertools": "*", "grunt": "~0.4.2", "grunt-cli": "~0.1.11", @@ -75,7 +74,9 @@ "socket.io": "~0.9.16", "moment": "~2.5.0", "sinon": "~1.7.3", - "chai": "~1.8.1" + "chai": "~1.8.1", + "bitcore": "git://github.com/bitpay/bitcore.git", + "bufferput": "git://github.com/bitpay/node-bufferput.git" }, "devDependencies": { "grunt-contrib-watch": "latest", From 8df8b9e35082afcf12a6dc7853dc96ad0756be86 Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Mon, 20 Jan 2014 23:01:07 -0300 Subject: [PATCH 12/40] expand input / outputs --- app/models/Transaction.js | 2 +- public/css/common.css | 9 +++ public/js/controllers/transactions.js | 13 +++- public/views/transaction.html | 13 ---- public/views/transaction/tx.html | 86 ++++++++++++++++++++------- 5 files changed, 86 insertions(+), 37 deletions(-) diff --git a/app/models/Transaction.js b/app/models/Transaction.js index 5e418adf..e7f08826 100644 --- a/app/models/Transaction.js +++ b/app/models/Transaction.js @@ -279,7 +279,7 @@ TransactionSchema.statics.queryInfo = function(txid, cb) { else { tx.ins.forEach(function(i) { if (i.value) { - info.vin[c].value = util.formatValue(i.value); + info.vin[c].value = parseFloat(util.formatValue(i.value)); var n = util.valueToBigInt(i.value).toNumber(); info.vin[c].valueSat = n; valueIn = valueIn.add( n ); diff --git a/public/css/common.css b/public/css/common.css index 5747588c..525bd9aa 100644 --- a/public/css/common.css +++ b/public/css/common.css @@ -314,4 +314,13 @@ h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 { background-color: #1a1a1a; } +.expanded-tx { + border-bottom: 1px dashed #444; +} + + +.expanded-tx small { + font-size: 80%; +} + diff --git a/public/js/controllers/transactions.js b/public/js/controllers/transactions.js index c82b6599..7488ed3a 100644 --- a/public/js/controllers/transactions.js +++ b/public/js/controllers/transactions.js @@ -29,11 +29,13 @@ angular.module('insight.transactions').controller('transactionsController', // non standard output if (items[i].scriptPubKey && items[i].scriptPubKey.addresses.length > 1) { + item[i].addr = items[i].scriptPubKey.addresses.join(','); ret.push(items[i]); continue; } - var addr = items[i].addr || items[i].scriptPubKey.addresses[0]; + var addr = items[i].addr || + (items[i].scriptPubKey && items[i].scriptPubKey.addresses[0] ); if (!tmp[addr]) { tmp[addr] = {}; tmp[addr].valueSat = 0; @@ -57,7 +59,6 @@ angular.module('insight.transactions').controller('transactionsController', $scope.processTX = function(tx) { tx.vinSimple = $scope.aggregateItems(tx.vin); tx.voutSimple = $scope.aggregateItems(tx.vout); -console.log('[transactions.js.33:insSimple:]',tx); //TODO }; $scope.findTx = function(txid) { @@ -65,7 +66,7 @@ console.log('[transactions.js.33:insSimple:]',tx); //TODO txId: txid }, function(tx) { $scope.tx = tx; -$scope.processTX(tx); + $scope.processTX(tx); $scope.txs.push(tx); }, function(e) { if (e.status === 400) { @@ -85,6 +86,9 @@ $scope.processTX(tx); TransactionsByBlock.query({ block: bId }, function(txs) { + angular.forEach(txs, function(tx) { + $scope.processTX(tx); + }); $scope.txs = txs; }); }; @@ -93,6 +97,9 @@ $scope.processTX(tx); TransactionsByAddress.query({ address: aId }, function(txs) { + angular.forEach(txs, function(tx) { + $scope.processTX(tx); + }); $scope.txs = txs; }); }; diff --git a/public/views/transaction.html b/public/views/transaction.html index 8e4ee015..4e325be5 100644 --- a/public/views/transaction.html +++ b/public/views/transaction.html @@ -48,19 +48,6 @@
-
-

ScriptSig

-
    -
  • - {{vin.scriptSig.asm}} -
-
-
-

ScriptPubKey

-
    -
  • {{vout.scriptPubKey.asm}} -
-
diff --git a/public/views/transaction/tx.html b/public/views/transaction/tx.html index 84261d09..c33a0f6a 100644 --- a/public/views/transaction/tx.html +++ b/public/views/transaction/tx.html @@ -11,19 +11,45 @@

{{vin.reward}} BTC

- +

{{vin.value}} BTC

+ + +
    +
  • + + +
    +
    + Address could not be parsed + {{vin.addr}} +
    +
    + scriptSig{{vin.scriptSig.asm}} +
    +
    +

    {{vin.value}} BTC

    +
+ + +
@@ -32,21 +58,41 @@
-
-
- {{vout.scriptPubKey.type}} -
-
-
-
+
+

{{vout.value}} BTC

+
+
+ + type {{vout.scriptPubKey.type}} +
+ scriptPubKey {{vout.scriptPubKey.asm}} +
+
+
+

{{vout.value}} BTC

+
+
+ +
+
From 11adc88651e0fbd49fdc924801a3b39348beec80 Mon Sep 17 00:00:00 2001 From: Gustavo Cortez Date: Tue, 21 Jan 2014 10:09:51 -0300 Subject: [PATCH 13/40] check if mongod is running. show a message. --- server.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/server.js b/server.js index 1f495031..33f62484 100644 --- a/server.js +++ b/server.js @@ -24,6 +24,16 @@ var express = require('express'), var config = require('./config/config'); //Bootstrap db connection +// If mongod is running +mongoose.connection.on('open', function (ref) { + console.log('Connected to mongo server.'); +}); +// If mongod is not running +mongoose.connection.on('error', function (err) { + console.log('Could not connect to mongo server!'); + console.log(err); +}); + mongoose.connect(config.db); //Bootstrap models From 56dc130b4fc9a1c48a99889e922fe030c62657be Mon Sep 17 00:00:00 2001 From: Gustavo Cortez Date: Tue, 21 Jan 2014 10:46:19 -0300 Subject: [PATCH 14/40] show for 2 sec a box message if not found block --- public/js/controllers/search.js | 5 ++++- public/views/header.html | 14 +++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/public/js/controllers/search.js b/public/js/controllers/search.js index e1299dce..1dd2c58a 100644 --- a/public/js/controllers/search.js +++ b/public/js/controllers/search.js @@ -1,7 +1,7 @@ 'use strict'; angular.module('insight.search').controller('SearchController', - function ($scope, $routeParams, $location, Global, Block, Transaction, Address) { + function ($scope, $routeParams, $location, $timeout, Global, Block, Transaction, Address) { $scope.global = Global; $scope.search = function() { @@ -26,6 +26,9 @@ angular.module('insight.search').controller('SearchController', $location.path('address/' + q); }, function () { //address not found, fail :( $scope.badQuery = true; + $timeout(function() { + $scope.badQuery = false; + }, 2000); $scope.q = q; }); }); diff --git a/public/views/header.html b/public/views/header.html index 6d12e447..bcc2d551 100755 --- a/public/views/header.html +++ b/public/views/header.html @@ -11,17 +11,18 @@
From ef109e32516a573fce405993ea5ff4525c96f04e Mon Sep 17 00:00:00 2001 From: Gustavo Cortez Date: Tue, 21 Jan 2014 10:55:35 -0300 Subject: [PATCH 15/40] search by height of block --- public/js/controllers/search.js | 48 ++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/public/js/controllers/search.js b/public/js/controllers/search.js index 1dd2c58a..07af17be 100644 --- a/public/js/controllers/search.js +++ b/public/js/controllers/search.js @@ -1,7 +1,7 @@ 'use strict'; angular.module('insight.search').controller('SearchController', - function ($scope, $routeParams, $location, $timeout, Global, Block, Transaction, Address) { + function ($scope, $routeParams, $location, $timeout, Global, Block, Transaction, Address, BlockByHeight) { $scope.global = Global; $scope.search = function() { @@ -10,28 +10,34 @@ angular.module('insight.search').controller('SearchController', $scope.badQuery = false; $scope.q = ''; - Block.get({ - blockHash: q - }, function() { - $location.path('block/' + q); - }, function () { //block not found, search on TX - Transaction.get({ - txId: q + BlockByHeight.get({ + blockHeight: q + }, function(hash) { + $location.path('/block/' + hash.blockHash); + }, function() { // block by height not found + Block.get({ + blockHash: q }, function() { - $location.path('tx/' + q); - }, function () { //tx not found, search on Address - Address.get({ - addrStr: q + $location.path('block/' + q); + }, function () { //block not found, search on TX + Transaction.get({ + txId: q }, function() { - $location.path('address/' + q); - }, function () { //address not found, fail :( - $scope.badQuery = true; - $timeout(function() { - $scope.badQuery = false; - }, 2000); - $scope.q = q; - }); - }); + $location.path('tx/' + q); + }, function () { //tx not found, search on Address + Address.get({ + addrStr: q + }, function() { + $location.path('address/' + q); + }, function () { //address not found, fail :( + $scope.badQuery = true; + $timeout(function() { + $scope.badQuery = false; + }, 2000); + $scope.q = q; + }); + }); + }); }); }; From 9337196233824175e7b91048ccb7911f3b97a317 Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Tue, 21 Jan 2014 10:56:09 -0300 Subject: [PATCH 16/40] fix conflics --- app/views/includes/foot.jade | 1 - public/js/controllers/footer.js | 16 --------- public/js/controllers/status.js | 11 ++++++ public/js/controllers/transactions.js | 17 ++++++++-- public/views/header.html | 24 +++++++------ public/views/transaction.html | 2 +- public/views/transaction/tx.html | 49 +++++++++++---------------- 7 files changed, 59 insertions(+), 61 deletions(-) delete mode 100644 public/js/controllers/footer.js diff --git a/app/views/includes/foot.jade b/app/views/includes/foot.jade index 735e8c0b..4a14f1ae 100755 --- a/app/views/includes/foot.jade +++ b/app/views/includes/foot.jade @@ -36,7 +36,6 @@ script(type='text/javascript', src='/js/services/socket.js') //Application Controllers script(type='text/javascript', src='/js/controllers/index.js') script(type='text/javascript', src='/js/controllers/header.js') -script(type='text/javascript', src='/js/controllers/footer.js') script(type='text/javascript', src='/js/controllers/blocks.js') script(type='text/javascript', src='/js/controllers/transactions.js') script(type='text/javascript', src='/js/controllers/address.js') diff --git a/public/js/controllers/footer.js b/public/js/controllers/footer.js deleted file mode 100644 index e9d5c423..00000000 --- a/public/js/controllers/footer.js +++ /dev/null @@ -1,16 +0,0 @@ -'use strict'; - -angular.module('insight.system').controller('FooterController', - function ($scope, Global, Status) { - $scope.global = Global; - - $scope.getFooter = function() { - Status.get({ - q: 'getInfo' - }, function(d) { - $scope.info = d.info; - }); - }; - -}); - diff --git a/public/js/controllers/status.js b/public/js/controllers/status.js index 019c04d0..f1fddedd 100644 --- a/public/js/controllers/status.js +++ b/public/js/controllers/status.js @@ -23,6 +23,17 @@ angular.module('insight.status').controller('StatusController', $scope.getSync = function() { Sync.get({}, function(sync) { $rootScope.syncError = null; + + if (sync.blocksToSync > sync.syncedBlocks ) { + sync.message = 'Blocks to sync: ' + (sync.blocksToSync - sync.syncedBlocks); + sync.tooltip = 'Skipped blocks:' + sync.skipped_blocks; + } + else { + sync.message = 'On sync'; + sync.tooltip = ''; + } + + $scope.sync = sync; }, function(e) { $rootScope.syncError = 'Could not get sync information' + e; diff --git a/public/js/controllers/transactions.js b/public/js/controllers/transactions.js index d33e2503..28efee2a 100644 --- a/public/js/controllers/transactions.js +++ b/public/js/controllers/transactions.js @@ -14,19 +14,29 @@ angular.module('insight.transactions').controller('transactionsController', var ret = []; var tmp = {}; + var u=0; // TODO multiple output address // for(var i=0; i < l; i++) { + var notAddr = false; + + // non standard input + if (items[i].scriptSig && !items[i].addr) { + items[i].addr = 'Unparsed address [' + u++ + ']'; + items[i].notAddr = true; + notAddr = true; + } + // non standard output if (items[i].scriptPubKey && items[i].scriptPubKey.addresses.length > 1) { - item[i].addr = items[i].scriptPubKey.addresses.join(','); + items[i].addr = items[i].scriptPubKey.addresses.join(','); ret.push(items[i]); continue; } - var addr = items[i].addr || - (items[i].scriptPubKey && items[i].scriptPubKey.addresses[0] ); + var addr = items[i].addr || (items[i].scriptPubKey && items[i].scriptPubKey.addresses[0] ); + if (!tmp[addr]) { tmp[addr] = {}; tmp[addr].valueSat = 0; @@ -37,6 +47,7 @@ angular.module('insight.transactions').controller('transactionsController', tmp[addr].valueSat += items[i].valueSat; tmp[addr].value = tmp[addr].valueSat / 100000000; tmp[addr].items.push(items[i]); + tmp[addr].notAddr = notAddr; tmp[addr].count++; } diff --git a/public/views/header.html b/public/views/header.html index bcc2d551..38f0c847 100755 --- a/public/views/header.html +++ b/public/views/header.html @@ -23,16 +23,20 @@
No matching records found!
-
- - Status: On Sync - - - Connections: {{info.connections}} - - - Height: {{info.blocks}} - +
+ + + {{sync.message}} + + + + + Connections: {{info.connections}} + + + Height: {{info.blocks}} + +
diff --git a/public/views/transaction.html b/public/views/transaction.html index 4e325be5..3970353f 100644 --- a/public/views/transaction.html +++ b/public/views/transaction.html @@ -23,7 +23,7 @@ Block - + {{tx.blockhash}} diff --git a/public/views/transaction/tx.html b/public/views/transaction/tx.html index c33a0f6a..76be7869 100644 --- a/public/views/transaction/tx.html +++ b/public/views/transaction/tx.html @@ -1,6 +1,14 @@
{{tx.txid}} + + + + + + {{tx.time * 1000 | date:'medium'}} + +
@@ -13,42 +21,32 @@
-
@@ -58,17 +56,18 @@
-
+
- {{address}} + {{vout.addr}} + {{address}}

{{vout.value}} BTC

- From 0e92ef0100910cedc9681335bf5540c455447eda Mon Sep 17 00:00:00 2001 From: Gustavo Cortez Date: Tue, 21 Jan 2014 11:28:30 -0300 Subject: [PATCH 17/40] a warning --- server.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server.js b/server.js index 33f62484..365ff28e 100644 --- a/server.js +++ b/server.js @@ -25,7 +25,7 @@ var config = require('./config/config'); //Bootstrap db connection // If mongod is running -mongoose.connection.on('open', function (ref) { +mongoose.connection.on('open', function () { console.log('Connected to mongo server.'); }); // If mongod is not running From ae9dd66b7aada3d1221335b60f36944cc3fdd5b2 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Tue, 21 Jan 2014 11:51:34 -0300 Subject: [PATCH 18/40] starting to show sync status via socket --- app/controllers/socket.js | 3 ++- public/js/controllers/footer.js | 10 +--------- public/js/controllers/status.js | 9 ++++++++- public/views/header.html | 4 ++-- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/app/controllers/socket.js b/app/controllers/socket.js index acfa2c9c..0ff3b4a0 100644 --- a/app/controllers/socket.js +++ b/app/controllers/socket.js @@ -27,5 +27,6 @@ module.exports.broadcast_address_tx = function(address, tx) { }; module.exports.broadcastSyncInfo = function(syncInfo) { - ios.sockets.emit('sync', syncInfo); + console.log('broadcastSyncInfo'); + ios.sockets.in('sync').emit('status', syncInfo); }; diff --git a/public/js/controllers/footer.js b/public/js/controllers/footer.js index e9d5c423..7cdfb57c 100644 --- a/public/js/controllers/footer.js +++ b/public/js/controllers/footer.js @@ -1,16 +1,8 @@ 'use strict'; angular.module('insight.system').controller('FooterController', - function ($scope, Global, Status) { + function ($scope, Global) { $scope.global = Global; - $scope.getFooter = function() { - Status.get({ - q: 'getInfo' - }, function(d) { - $scope.info = d.info; - }); - }; - }); diff --git a/public/js/controllers/status.js b/public/js/controllers/status.js index 019c04d0..267dac25 100644 --- a/public/js/controllers/status.js +++ b/public/js/controllers/status.js @@ -1,7 +1,7 @@ 'use strict'; angular.module('insight.status').controller('StatusController', - function ($scope, $routeParams, $location, $rootScope, Global, Status, Sync) { + function ($scope, $routeParams, $location, $rootScope, Global, Status, Sync, get_socket) { $scope.global = Global; $scope.getStatus = function(q) { @@ -28,5 +28,12 @@ angular.module('insight.status').controller('StatusController', $rootScope.syncError = 'Could not get sync information' + e; }); }; + + var socket = get_socket($scope); + socket.emit('subscribe', 'sync'); + socket.on('status', function(info) { + console.log('info '+JSON.stringify(info)); + }); + }); diff --git a/public/views/header.html b/public/views/header.html index 6d12e447..aae47530 100755 --- a/public/views/header.html +++ b/public/views/header.html @@ -22,9 +22,9 @@
No matching records found!
-
+
- Status: On Sync + Status: {{statusMessage}} Connections: {{info.connections}} From 758f9fc068d391b5e68747049e9f654b98ff362f Mon Sep 17 00:00:00 2001 From: Bechi Date: Tue, 21 Jan 2014 12:25:36 -0300 Subject: [PATCH 19/40] address page --- public/css/common.css | 2 + public/views/address.html | 81 +++++++++++++++++++-------------------- public/views/block.html | 11 +++--- 3 files changed, 47 insertions(+), 47 deletions(-) diff --git a/public/css/common.css b/public/css/common.css index 685758a9..f51137db 100644 --- a/public/css/common.css +++ b/public/css/common.css @@ -38,6 +38,7 @@ h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 { .m20h {margin: 0 20px;} .m5v {margin: 5px 0;} .m20v {margin: 20px 0;} +.m10v {margin: 10px 0;} .m50v {margin: 50px 0;} .m10b {margin-bottom: 10px;} @@ -119,6 +120,7 @@ h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 { } .col-gray { + width: 267px; background-color: #F4F4F4; padding: 15px; margin-top: 21px; diff --git a/public/views/address.html b/public/views/address.html index 1e21aec7..71ec54e8 100644 --- a/public/views/address.html +++ b/public/views/address.html @@ -1,45 +1,44 @@
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
Address{{address.addrStr}}
Total Received{{address.totalReceived}} BTC
Total Sent{{address.totalSent}} BTC
Final Balance{{address.balance}} BTC
No. Transactions{{address.txApperances}}
+
+
+
+ +

Address

+ {{address.addrStr}} +
+ +
+

Summary

+ + + + + + + + + + + + + + + + + + + +
Total Received{{address.totalReceived}} BTC
Total Sent{{address.totalSent}} BTC
Final Balance{{address.balance}} BTC
No. Transactions{{address.txApperances}}
+
+
+
+ +
+
+

Transactions Transactions contained within this block

+
+
-
- -
-
- -
-

Transactions Transactions contained within this block

-
-
+
diff --git a/public/views/block.html b/public/views/block.html index d3db9010..16447eb4 100644 --- a/public/views/block.html +++ b/public/views/block.html @@ -8,30 +8,29 @@

Block #{{ block.height }}

-

Hashes

- + - + - + - +
Hash Hash {{block.hash}}
Previous Block Previous Block {{block.previousblockhash}}
Next Block Next Block {{block.nextblockhash}}
Merkle RootMerkle Root

{{block.merkleroot}}

-
+
From c112b1c7e59cf4d746b917a030e1ae8b9ba1b92d Mon Sep 17 00:00:00 2001 From: Mario Colque Date: Tue, 21 Jan 2014 12:55:38 -0300 Subject: [PATCH 20/40] lazy load for transactions list --- app/controllers/transactions.js | 62 ++++++++++++++++-------- public/js/controllers/transactions.js | 70 +++++++++++++++++++-------- public/js/directives.js | 26 +++++++++- public/views/footer.html | 7 +-- public/views/transaction/list.html | 10 ++-- 5 files changed, 123 insertions(+), 52 deletions(-) diff --git a/app/controllers/transactions.js b/app/controllers/transactions.js index 5676790e..10128159 100644 --- a/app/controllers/transactions.js +++ b/app/controllers/transactions.js @@ -52,8 +52,12 @@ var getTransaction = function(txid, cb) { */ exports.list = function(req, res, next) { var bId = req.query.block; - var aId = req.query.address; - var limit = req.query.limit || 1000; + var addrStr = req.query.address; + var page = req.query.pageNum; + var pageLength = 20; + var pagesTotal = 1; + var txLength; + var txs; if (bId) { Block.fromHashWithInfo(bId, function(err, block) { @@ -63,14 +67,28 @@ exports.list = function(req, res, next) { return next(); } - async.mapSeries(block.info.tx, getTransaction, + txLength = block.info.tx.length; + + if (page) { + var spliceInit = page * pageLength; + txs = block.info.tx.splice(spliceInit, pageLength); + pagesTotal = Math.ceil(txLength / pageLength); + } + else { + txs = block.info.tx; + } + + async.mapSeries(txs, getTransaction, function(err, results) { - res.jsonp(results); + res.jsonp({ + pagesTotal: pagesTotal, + txs: results + }); }); }); } - else if (aId) { - var a = Address.new(aId); + else if (addrStr) { + var a = Address.new(addrStr); a.update(function(err) { if (err && !a.totalReceivedSat) { @@ -79,23 +97,25 @@ exports.list = function(req, res, next) { return next(); } - async.mapSeries(a.transactions, getTransaction, + txLength = a.transactions.length; + + if (page) { + var spliceInit = page * pageLength; + txs = a.transactions.splice(spliceInit, pageLength); + pagesTotal = Math.ceil(txLength / pageLength); + } + else { + txs = a.transactions; + } + + async.mapSeries(txs, getTransaction, function(err, results) { - res.jsonp(results); + res.jsonp({ + pagesTotal: pagesTotal, + txs: results + }); }); }); } - else { - Transaction - .find() - .limit(limit) - .sort('-time') - .exec(function(err, txs) { - if (err) { - res.status(500).send(err); - } else { - res.jsonp(txs); - } - }); - } + }; diff --git a/public/js/controllers/transactions.js b/public/js/controllers/transactions.js index 28efee2a..f657dea6 100644 --- a/public/js/controllers/transactions.js +++ b/public/js/controllers/transactions.js @@ -3,12 +3,16 @@ angular.module('insight.transactions').controller('transactionsController', function ($scope, $rootScope, $routeParams, $location, Global, Transaction, TransactionsByBlock, TransactionsByAddress, get_socket) { $scope.global = Global; + $scope.loading = false; + $scope.loadedBy = null; + + var pageNum = 0; + var pagesTotal = 1; $scope.findThis = function() { $scope.findTx($routeParams.txId); }; - $scope.aggregateItems = function(items) { var l = items.length; @@ -16,12 +20,12 @@ angular.module('insight.transactions').controller('transactionsController', var tmp = {}; var u=0; // TODO multiple output address - // + // for(var i=0; i < l; i++) { var notAddr = false; - // non standard input + // non standard input if (items[i].scriptSig && !items[i].addr) { items[i].addr = 'Unparsed address [' + u++ + ']'; items[i].notAddr = true; @@ -57,7 +61,6 @@ angular.module('insight.transactions').controller('transactionsController', return (ret); }; - $scope.processTX = function(tx) { tx.vinSimple = $scope.aggregateItems(tx.vin); tx.voutSimple = $scope.aggregateItems(tx.vout); @@ -84,27 +87,54 @@ angular.module('insight.transactions').controller('transactionsController', }); }; - $scope.byBlock = function(bId) { - TransactionsByBlock.query({ - block: bId - }, function(txs) { - angular.forEach(txs, function(tx) { - $scope.processTX(tx); - }); - $scope.txs = txs; + $scope.byBlock = function() { + TransactionsByBlock.get({ + block: $routeParams.blockHash, + pageNum: pageNum + }, function(data) { + $scope.paginate(data); }); }; - $scope.byAddress = function(aId) { - TransactionsByAddress.query({ - address: aId - }, function(txs) { - angular.forEach(txs, function(tx) { - $scope.processTX(tx); - }); - $scope.txs = txs; + $scope.byAddress = function () { + TransactionsByAddress.get({ + address: $routeParams.addrStr, + pageNum: pageNum + }, function(data) { + $scope.paginate(data); }); }; + + $scope.paginate = function (data) { + $scope.loading = false; + + pagesTotal = data.pagesTotal; + pageNum += 1; + + data.txs.forEach(function(tx) { + $scope.processTX(tx); + $scope.txs.push(tx); + }); + }; + + $scope.load = function(from) { + $scope.loadedBy = from; + $scope.loadMore(); + }; + + $scope.loadMore = function() { + if (pageNum < pagesTotal && !$scope.loading) { + $scope.loading = true; + + if ($scope.loadedBy === 'address') { + $scope.byAddress(); + } + else { + $scope.byBlock(); + } + } + }; + var socket = get_socket($scope); socket.on('atx', function(tx) { console.log('atx '+tx.txid); diff --git a/public/js/directives.js b/public/js/directives.js index a726efc4..d0fe4877 100755 --- a/public/js/directives.js +++ b/public/js/directives.js @@ -1 +1,25 @@ -'use strict'; \ No newline at end of file +'use strict'; + +angular.module('insight.address').directive('whenScrolled', ['$window', function($window) { + return { + link: function(scope, elm, attr) { + var pageHeight, clientHeight, scrollPos; + $window = angular.element($window); + + var handler = function() { + pageHeight = window.document.documentElement.scrollHeight; + clientHeight = window.document.documentElement.clientHeight; + scrollPos = window.pageYOffset; + + if (pageHeight - (scrollPos + clientHeight) === 0) { + scope.$apply(attr.whenScrolled); + } + }; + + $window.on('scroll', handler); + scope.$on('$destroy', function() { + return $window.off('scroll', handler); + }); + } + }; +}]); diff --git a/public/views/footer.html b/public/views/footer.html index 7401eaee..24a739e8 100644 --- a/public/views/footer.html +++ b/public/views/footer.html @@ -1,6 +1,3 @@ -
-
-

Insight

-
+ - diff --git a/public/views/transaction/list.html b/public/views/transaction/list.html index bd9b7555..c1262f2d 100644 --- a/public/views/transaction/list.html +++ b/public/views/transaction/list.html @@ -1,9 +1,9 @@ -
-
- Loading... -
-
There are not transactions
+
+
+ Loading... +
+
From 038ab3c12a3ae2f94894ed337cc863e897cc59ee Mon Sep 17 00:00:00 2001 From: Mario Colque Date: Tue, 21 Jan 2014 13:01:35 -0300 Subject: [PATCH 21/40] added the directive for loadMore --- public/views/address.html | 8 ++++---- public/views/block.html | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/public/views/address.html b/public/views/address.html index 71ec54e8..2736b03e 100644 --- a/public/views/address.html +++ b/public/views/address.html @@ -7,7 +7,7 @@

Address

{{address.addrStr}}
- +

Summary

@@ -33,11 +33,11 @@ - +
-
+

Transactions Transactions contained within this block

-
+
diff --git a/public/views/block.html b/public/views/block.html index 16447eb4..88cc2313 100644 --- a/public/views/block.html +++ b/public/views/block.html @@ -33,7 +33,7 @@ - +

Summary

@@ -84,9 +84,9 @@
-
+

Transactions Transactions contained within this block

-
+
From 132569ed3ef138eff0ac1aab98cef45c50c49351 Mon Sep 17 00:00:00 2001 From: Gustavo Cortez Date: Tue, 21 Jan 2014 13:22:08 -0300 Subject: [PATCH 22/40] fix navbar --- public/views/header.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/views/header.html b/public/views/header.html index 38f0c847..71449124 100755 --- a/public/views/header.html +++ b/public/views/header.html @@ -31,7 +31,7 @@ - Connections: {{info.connections}} + Conn: {{info.connections}} Height: {{info.blocks}} From 9c1906641a6a1eac3d56389c37148f69532ed613 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Tue, 21 Jan 2014 13:28:01 -0300 Subject: [PATCH 23/40] stream sync status --- app/controllers/socket.js | 1 - lib/HistoricSync.js | 379 ++++++++++++++++---------------- public/js/controllers/status.js | 47 ++-- public/views/footer.html | 2 +- public/views/header.html | 4 +- server.js | 1 + 6 files changed, 223 insertions(+), 211 deletions(-) diff --git a/app/controllers/socket.js b/app/controllers/socket.js index 0ff3b4a0..ace6315d 100644 --- a/app/controllers/socket.js +++ b/app/controllers/socket.js @@ -27,6 +27,5 @@ module.exports.broadcast_address_tx = function(address, tx) { }; module.exports.broadcastSyncInfo = function(syncInfo) { - console.log('broadcastSyncInfo'); ios.sockets.in('sync').emit('status', syncInfo); }; diff --git a/lib/HistoricSync.js b/lib/HistoricSync.js index b33b4bd8..f6a29e29 100644 --- a/lib/HistoricSync.js +++ b/lib/HistoricSync.js @@ -2,43 +2,39 @@ require('classtool'); - function spec() { - var util = require('util'); - var RpcClient = require('bitcore/RpcClient').class(); - var networks = require('bitcore/networks'); - var async = require('async'); - var config = require('../config/config'); - var Block = require('../app/models/Block'); - var Sync = require('./Sync').class(); - var sockets = require('../app/controllers/socket.js'); + var util = require('util'); + var RpcClient = require('bitcore/RpcClient').class(); + var networks = require('bitcore/networks'); + var async = require('async'); + var config = require('../config/config'); + var Block = require('../app/models/Block'); + var Sync = require('./Sync').class(); + var sockets = require('../app/controllers/socket.js'); function HistoricSync(opts) { - this.network = config.network === 'testnet' ? networks.testnet: networks.livenet; + this.network = config.network === 'testnet' ? networks.testnet: networks.livenet; var genesisHashReversed = new Buffer(32); this.network.genesisBlock.hash.copy(genesisHashReversed); this.genesis = genesisHashReversed.reverse().toString('hex'); - this.sync = new Sync(opts); - + this.sync = new Sync(opts); //available status: new / syncing / finished / aborted - this.status = 'new'; + this.status = 'new'; this.syncInfo = {}; } function p() { var args = []; - Array.prototype.push.apply( args, arguments ); + Array.prototype.push.apply(args, arguments); - - args.unshift('[historic_sync]'); /*jshint validthis:true */ console.log.apply(this, args); } - HistoricSync.prototype.init = function(opts,cb) { + HistoricSync.prototype.init = function(opts, cb) { this.rpc = new RpcClient(config.bitcoind); this.opts = opts; this.sync.init(opts, cb); @@ -48,76 +44,84 @@ function spec() { this.sync.close(); }; - HistoricSync.prototype.showProgress = function() { var self = this; var i = self.syncInfo; var per = parseInt(100 * i.syncedBlocks / i.blocksToSync); p(util.format('status: %d/%d [%d%%]', i.syncedBlocks, i.blocksToSync, per)); - if (self.opts.broadcast) { + if (self.opts.shouldBroadcast) { sockets.broadcastSyncInfo(self.syncInfo); } }; - HistoricSync.prototype.getPrevNextBlock = function(blockHash, blockEnd, opts, cb) { var self = this; // recursion end. - if (!blockHash ) return cb(); + if (!blockHash) return cb(); - var existed = 0; + var existed = false; var blockInfo; var blockObj; async.series([ - // Already got it? - function(c) { - Block.findOne({hash:blockHash}, function(err,block){ - if (err) { p(err); return c(err); } - if (block) { - existed =1; - blockObj =block; - } - return c(); - }); + // Already got it? + function(c) { + Block.findOne({ + hash: blockHash }, - //show some (inacurate) status - function(c) { - var step = parseInt(self.syncInfo.blocksToSync / 100); - if (step < 10) step = 10; - - if (self.syncInfo.syncedBlocks % step === 1) { - self.showProgress(); + function(err, block) { + if (err) { + p(err); + return c(err); + } + if (block) { + existed = true; + blockObj = block; } return c(); - }, - //get Info from RPC - function(c) { + }); + }, + //show some (inacurate) status + function(c) { + if (!self.step) { + var step = parseInt(self.syncInfo.blocksToSync / 100); + if (self.opts.progressStep) { + step = self.opts.progressStep; + } + if (step < 2) step = 2; + self.step = step; + } + if (self.syncInfo.syncedBlocks % self.step === 1) { + self.showProgress(); + } + return c(); + }, + //get Info from RPC + function(c) { - // TODO: if we store prev/next, no need to go to RPC - // if (blockObj && blockObj.nextBlockHash) return c(); + // TODO: if we store prev/next, no need to go to RPC + // if (blockObj && blockObj.nextBlockHash) return c(); + self.rpc.getBlock(blockHash, function(err, ret) { + if (err) return c(err); - self.rpc.getBlock(blockHash, function(err, ret) { - if (err) return c(err); + blockInfo = ret; + return c(); + }); + }, + //store it + function(c) { + if (existed) return c(); + self.sync.storeBlock(blockInfo.result, function(err) { - blockInfo = ret; - return c(); - }); - }, - //store it - function(c) { - if (existed) return c(); - self.sync.storeBlock(blockInfo.result, function(err) { + existed = err && err.toString().match(/E11000/); - existed = err && err.toString().match(/E11000/); - - if (err && ! existed) return c(err); - return c(); - }); - }, - /* TODO: Should Start to sync backwards? (this is for partial syncs) + if (err && ! existed) return c(err); + return c(); + }); + }, + /* TODO: Should Start to sync backwards? (this is for partial syncs) function(c) { if (blockInfo.result.prevblockhash != current.blockHash) { @@ -127,164 +131,164 @@ function spec() { return c(); } */ - ], - function (err){ + ], function(err) { - if (err) { - self.err = util.format('ERROR: @%s: %s [count: syncedBlocks: %d]', blockHash, err, self.syncInfo.syncedBlocks); - self.status = 'aborted'; - p(self.err); - } + if (err) { + self.err = util.format('ERROR: @%s: %s [count: syncedBlocks: %d]', blockHash, err, self.syncInfo.syncedBlocks); + self.status = 'aborted'; + p(self.err); + } - else { - self.err = null; - self.status = 'syncing'; - } + else { + self.err = null; + self.status = 'syncing'; + } - if (opts.upToExisting && existed ) { - var diff = self.syncInfo.blocksToSync - self.syncInfo.syncedBlocks; - if (diff <= 0) { - self.status = 'finished'; - p('DONE. Found existing block: ', blockHash); - return cb(err); - } - else { - self.syncInfo.skipped_blocks = self.syncInfo.skipped_blocks || 1; - if ((self.syncInfo.skipped_blocks++ % 1000) === 1 ) { - p('WARN found target block\n\tbut blockChain Height is still higher that ours. Previous light sync must be interrupted.\n\tWill keep syncing.', self.syncInfo.syncedBlocks, self.syncInfo.blocksToSync, self.syncInfo.skipped_blocks); - } - } - } - - if (blockEnd && blockEnd === blockHash) { + if (opts.upToExisting && existed) { + var diff = self.syncInfo.blocksToSync - self.syncInfo.syncedBlocks; + if (diff <= 0) { self.status = 'finished'; - p('DONE. Found END block: ', blockHash); + p('DONE. Found existing block: ', blockHash); return cb(err); } - - - // Continue - if (blockInfo && blockInfo.result) { - if (! existed) self.syncInfo.syncedBlocks++; - if (opts.prev && blockInfo.result.previousblockhash) { - return self.getPrevNextBlock(blockInfo.result.previousblockhash, blockEnd, opts, cb); + else { + self.syncInfo.skipped_blocks = self.syncInfo.skipped_blocks || 1; + if ((self.syncInfo.skipped_blocks++ % 1000) === 1) { + p('WARN found target block\n\tbut blockChain Height is still higher that ours. Previous light sync must be interrupted.\n\tWill keep syncing.', self.syncInfo.syncedBlocks, self.syncInfo.blocksToSync, self.syncInfo.skipped_blocks); } - - if (opts.next && blockInfo.result.nextblockhash) - return self.getPrevNextBlock(blockInfo.result.nextblockhash, blockEnd, opts, cb); } + } + + if (blockEnd && blockEnd === blockHash) { + self.status = 'finished'; + p('DONE. Found END block: ', blockHash); return cb(err); + } + + // Continue + if (blockInfo && blockInfo.result) { + if (!existed) self.syncInfo.syncedBlocks++; + if (opts.prev && blockInfo.result.previousblockhash) { + return self.getPrevNextBlock(blockInfo.result.previousblockhash, blockEnd, opts, cb); + } + + if (opts.next && blockInfo.result.nextblockhash) return self.getPrevNextBlock(blockInfo.result.nextblockhash, blockEnd, opts, cb); + } + return cb(err); }); }; HistoricSync.prototype.import_history = function(opts, next) { var self = this; - var retry_secs = 2; + var retry_secs = 2; var bestBlock; var blockChainHeight; async.series([ - function(cb) { - if (opts.destroy) { - p('Deleting DB...'); - return self.sync.destroy(cb); - } + function(cb) { + if (opts.destroy) { + p('Deleting DB...'); + return self.sync.destroy(cb); + } + return cb(); + }, + // We are not using getBestBlockHash, because is not available in all clients + function(cb) { + if (!opts.reverse) return cb(); + + self.rpc.getBlockCount(function(err, res) { + if (err) return cb(err); + blockChainHeight = res.result; return cb(); - }, - // We are not using getBestBlockHash, because is not available in all clients - function(cb) { - if (!opts.reverse) return cb(); + }); + }, + function(cb) { + if (!opts.reverse) return cb(); - self.rpc.getBlockCount(function(err, res) { + self.rpc.getBlockHash(blockChainHeight, function(err, res) { + if (err) return cb(err); + + bestBlock = res.result; + + return cb(); + }); + }, + function(cb) { + // This is only to inform progress. + if (!opts.upToExisting) { + self.rpc.getInfo(function(err, res) { if (err) return cb(err); - blockChainHeight = res.result; + self.syncInfo.blocksToSync = res.result.blocks; return cb(); }); - }, - function(cb) { - if (!opts.reverse) return cb(); - - self.rpc.getBlockHash(blockChainHeight, function(err, res) { + } + else { + // should be isOrphan = true or null to be more accurate. + Block.count({ + isOrphan: null + }, + function(err, count) { if (err) return cb(err); - bestBlock = res.result; - + self.syncInfo.blocksToSync = blockChainHeight - count; + if (self.syncInfo.blocksToSync < 1) self.syncInfo.blocksToSync = 1; return cb(); }); - }, - function(cb) { - // This is only to inform progress. - if (!opts.upToExisting) { - self.rpc.getInfo(function(err, res) { - if (err) return cb(err); - self.syncInfo.blocksToSync = res.result.blocks; - return cb(); - }); + } + }, + ], function(err) { + + var start, end; + function sync() { + if (opts.reverse) { + start = bestBlock; + end = self.genesis; + opts.prev = true; } else { - // should be isOrphan = true or null to be more accurate. - Block.count({ isOrphan: null}, function(err, count) { - if (err) return cb(err); + start = self.genesis; + end = null; + opts.next = true; + } - self.syncInfo.blocksToSync = blockChainHeight - count; - if (self.syncInfo.blocksToSync < 1) self.syncInfo.blocksToSync = 1; - return cb(); - }); - } - }, - ], - function(err) { + self.syncInfo = util._extend(self.syncInfo, { + start: start, + isStartGenesis: start === self.genesis, + end: end, + isEndGenesis: end === self.genesis, + scanningForward: opts.next, + scanningBackward: opts.prev, + upToExisting: opts.upToExisting, + syncedBlocks: 0, + }); + p('Starting from: ', start); + p(' to : ', end); + p(' opts: ', JSON.stringify(opts)); - var start, end; - function sync() { - if (opts.reverse) { - start = bestBlock; - end = self.genesis; - opts.prev = true; - } - else { - start = self.genesis; - end = null; - opts.next = true; + self.getPrevNextBlock(start, end, opts, function(err) { + if (err && err.message.match(/ECONNREFUSED/)) { + setTimeout(function() { + p('Retrying in %d secs', retry_secs); + sync(); + }, + retry_secs * 1000); } + else return next(err); + }); + } - self.syncInfo = util._extend(self.syncInfo, { - start: start, - isStartGenesis: start === self.genesis, - end: end, - isEndGenesis: end === self.genesis, - scanningForward: opts.next, - scanningBackward: opts.prev, - upToExisting: opts.upToExisting, - syncedBlocks: 0, - }); - - p('Starting from: ', start); - p(' to : ', end); - p(' opts: ', JSON.stringify(opts)); - - self.getPrevNextBlock( start, end, opts , function(err) { - if (err && err.message.match(/ECONNREFUSED/)){ - setTimeout(function() { - p('Retrying in %d secs', retry_secs); - sync(); - }, retry_secs * 1000); - } - else - return next(err); - }); - } - - if (err) { - self.syncInfo = util._extend(self.syncInfo, { error: err.message }); - return next(err, 0); - } - else { - sync(); - } + if (err) { + self.syncInfo = util._extend(self.syncInfo, { + error: err.message + }); + return next(err, 0); + } + else { + sync(); + } }); }; @@ -292,11 +296,13 @@ function spec() { HistoricSync.prototype.smart_import = function(next) { var self = this; - Block.findOne({hash:self.genesis}, function(err, b){ + Block.findOne({ + hash: self.genesis + }, + function(err, b) { if (err) return next(err); - if (!b) { p('Could not find Genesis block. Running FULL SYNC'); } @@ -305,7 +311,7 @@ function spec() { } var opts = { - reverse: 1, + reverse: true, upToExisting: b ? true: false, }; @@ -313,7 +319,6 @@ function spec() { }); }; - return HistoricSync; } module.defineClass(spec); diff --git a/public/js/controllers/status.js b/public/js/controllers/status.js index 4d60b59e..d4d41112 100644 --- a/public/js/controllers/status.js +++ b/public/js/controllers/status.js @@ -1,16 +1,18 @@ 'use strict'; angular.module('insight.status').controller('StatusController', - function ($scope, $routeParams, $location, $rootScope, Global, Status, Sync, get_socket) { +function($scope, $routeParams, $location, $rootScope, Global, Status, Sync, get_socket) { $scope.global = Global; $scope.getStatus = function(q) { Status.get({ - q: 'get' + q - }, function(d) { + q: 'get' + q + }, + function(d) { $rootScope.infoError = null; angular.extend($scope, d); - }, function(e) { + }, + function(e) { if (e.status === 503) { $rootScope.infoError = 'Backend Error. ' + e.data; } @@ -20,30 +22,35 @@ angular.module('insight.status').controller('StatusController', }); }; + var on_sync_update = function(sync) { + if (sync.blocksToSync > sync.syncedBlocks) { + var p = parseInt(100*(sync.syncedBlocks) / sync.blocksToSync); + var delta = sync.blocksToSync - sync.syncedBlocks; + sync.message = 'Sync ' + p + '% ['+delta+' blocks remaining]'; + sync.style = 'warn'; + } else { + sync.message = 'On sync'; + sync.style = 'success'; + } + sync.tooltip = 'Synced blocks: '+sync.syncedBlocks; + $scope.sync = sync; + }; + $scope.getSync = function() { - Sync.get({}, function(sync) { + Sync.get({}, + function(sync) { $rootScope.syncError = null; - - if (sync.blocksToSync > sync.syncedBlocks ) { - sync.message = 'Blocks to sync: ' + (sync.blocksToSync - sync.syncedBlocks); - sync.tooltip = 'Skipped blocks:' + sync.skipped_blocks; - } - else { - sync.message = 'On sync'; - sync.tooltip = ''; - } - - - $scope.sync = sync; - }, function(e) { + on_sync_update(sync); + }, + function(e) { $rootScope.syncError = 'Could not get sync information' + e; }); }; var socket = get_socket($scope); socket.emit('subscribe', 'sync'); - socket.on('status', function(info) { - console.log('info '+JSON.stringify(info)); + socket.on('status', function(sync) { + on_sync_update(sync); }); }); diff --git a/public/views/footer.html b/public/views/footer.html index 7401eaee..05404553 100644 --- a/public/views/footer.html +++ b/public/views/footer.html @@ -1,4 +1,4 @@ -
+
diff --git a/public/views/header.html b/public/views/header.html index 38f0c847..47917e14 100755 --- a/public/views/header.html +++ b/public/views/header.html @@ -26,12 +26,12 @@
- {{sync.message}} + {{sync.message}} - Connections: {{info.connections}} + Conn: {{info.connections}} Height: {{info.blocks}} diff --git a/server.js b/server.js index 365ff28e..c2fde5f5 100644 --- a/server.js +++ b/server.js @@ -60,6 +60,7 @@ if (!config.disableHistoricSync) { historicSync.init({ skipDbConnection: true, shouldBroadcast: true, + progressStep: 2, networkName: config.network }, function() { historicSync.smart_import(function(err){ From f96d0e0033e9d172d48fef22b6b1db376a3ca6d2 Mon Sep 17 00:00:00 2001 From: Bechi Date: Tue, 21 Jan 2014 14:58:04 -0300 Subject: [PATCH 24/40] footer --- public/css/common.css | 15 ++++++++++++--- public/views/footer.html | 2 +- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/public/css/common.css b/public/css/common.css index f51137db..ccbc4278 100644 --- a/public/css/common.css +++ b/public/css/common.css @@ -223,12 +223,21 @@ h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 { /* Set the fixed height of the footer here */ #footer { - height: 44px; - background-color: #8DC429; - border-top: 4px solid #64920F; + height: 51px; + background-color: #373D42; + border-top: 4px solid #656E76; color: #fff; } +#footer .insight { + font-size: 20px; + text-decoration: none; +} + +.line-footer { + border-top: 2px dashed #ccc; +} + .line-bot { padding: 0 0 10px 0; margin-bottom: 10px; diff --git a/public/views/footer.html b/public/views/footer.html index 24a739e8..aac69ff5 100644 --- a/public/views/footer.html +++ b/public/views/footer.html @@ -1,3 +1,3 @@ From 24694939ea31f87d5d86042ccf9e6656f56c7102 Mon Sep 17 00:00:00 2001 From: Gustavo Cortez Date: Tue, 21 Jan 2014 15:10:34 -0300 Subject: [PATCH 25/40] fix height of footer --- public/css/common.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/css/common.css b/public/css/common.css index ccbc4278..300daeb7 100644 --- a/public/css/common.css +++ b/public/css/common.css @@ -29,7 +29,7 @@ h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 { min-height: 100%; height: auto; /* Negative indent footer by its height */ - margin: 0 auto -44px; + margin: 0 auto -51px; /* Pad bottom by footer height */ padding: 0 0 60px; } From 3cdfe47d14633b0776483592b8b52416c5b0d0df Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Tue, 21 Jan 2014 15:35:05 -0300 Subject: [PATCH 26/40] status wording --- public/views/status.html | 68 ++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/public/views/status.html b/public/views/status.html index da408791..ba1740db 100644 --- a/public/views/status.html +++ b/public/views/status.html @@ -1,12 +1,12 @@
-

getInfo()

+

Bitcoin node information

@@ -18,55 +18,55 @@ - + - + - + - + - + - + - + - + - + - - + + - + - + - + @@ -85,42 +85,42 @@ - + - + - + - + - +
{{info.version}}
protocolversionProtocol version {{info.protocolversion}}
walletversionWallet version {{info.walletversion}}
balanceBalance (BTC) {{info.balance}}
blocksBlocks {{info.blocks}}
timeoffsetTime Offset {{info.timeoffset}}
connectionsConnections to other nodes {{info.connections}}
proxyProxy setting {{info.proxy}}
difficultyMining Difficulty {{info.difficulty}}
testnetTestnet {{info.testnet}}
keypoololdest{{info.keypoololdest}}Keypool Oldest Date{{info.keypoololdest*1000 | date:'medium' }}
keypoolsizeKeypool Size {{info.keypoolsize}}
paytxfeeDefault Transaction Fee (BTC) {{info.paytxfee}}
infoErrorsInfo Errors {{info.infoErrors}}
{{(100 * sync.syncedBlocks/sync.blocksToSync)| number:2}}%
blocksToSyncBlocks to Sync {{sync.blocksToSync}}
syncedBlocksSynced Blocks {{sync.syncedBlocks}}
startStart {{sync.start}} (genesisBlock)
endEnd {{sync.end}} (genesisBlock)
Sync TypeSync properties
  • Stops at existing block
  • - scanningBackward - scanningForward + Backward Scan + Forward Scan
-

getTxOutSetInfo()

+

Transaction Output Set Information

@@ -134,33 +134,33 @@ - + - + - + - + - + - +
{{txoutsetinfo.height}}
bestblockBest Block {{txoutsetinfo.bestblock}}
transactionsTransactions {{txoutsetinfo.transactions}}
txoutsTransaction Outputs {{txoutsetinfo.txouts}}
bytes_serializedBytes Serialized {{txoutsetinfo.bytes_serialized}}
hash_serializedHash Serialized {{txoutsetinfo.hash_serialized}}
total_amountTotal Amount {{txoutsetinfo.total_amount}}
-

getDifficulty()

+

Difficulty

@@ -171,13 +171,13 @@ - +
DifficultyMining Difficulty {{difficulty}}
-

getLastBlockHash()

+

Last Block

@@ -188,7 +188,7 @@ - +
Last block hash{{lastblockhash}}{{lastblockhash}}
From ee275dde12b514349c0702cc629f49bfb83c7a7f Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Tue, 21 Jan 2014 15:49:25 -0300 Subject: [PATCH 27/40] show tx by reverse order in addr --- app/models/Address.js | 2 +- public/views/address.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/Address.js b/app/models/Address.js index e054ff19..12a4a284 100644 --- a/app/models/Address.js +++ b/app/models/Address.js @@ -60,7 +60,7 @@ function spec() { // TODO TXout! //T function (cb) { - TransactionItem.find({addr:that.addrStr}).sort({ts:1}).exec(function(err,txItems){ + TransactionItem.find({addr:that.addrStr}).sort({ts:-1}).exec(function(err,txItems){ if (err) return cb(err); txItems.forEach(function(txItem){ diff --git a/public/views/address.html b/public/views/address.html index 2736b03e..3063a0fa 100644 --- a/public/views/address.html +++ b/public/views/address.html @@ -36,7 +36,7 @@
-

Transactions Transactions contained within this block

+

Transactions Transactions for this address

From 21a994457c68635df3c8e2eb1ba284cf7a336f41 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Tue, 21 Jan 2014 15:53:38 -0300 Subject: [PATCH 28/40] progress bar for sync status --- public/views/status.html | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/public/views/status.html b/public/views/status.html index ba1740db..8ca3f614 100644 --- a/public/views/status.html +++ b/public/views/status.html @@ -82,7 +82,12 @@ Sync Progress - {{(100 * sync.syncedBlocks/sync.blocksToSync)| number:2}}% + +
+
+ {{(100 * sync.syncedBlocks/sync.blocksToSync)| number:2}}% Complete +
+
Blocks to Sync From 30bdbf051e353c43af6694ffadb7cffcb34f48e2 Mon Sep 17 00:00:00 2001 From: Bechi Date: Tue, 21 Jan 2014 16:06:21 -0300 Subject: [PATCH 29/40] status page --- public/css/common.css | 4 + public/views/status.html | 226 ++++++++++++++++++++------------------- 2 files changed, 118 insertions(+), 112 deletions(-) diff --git a/public/css/common.css b/public/css/common.css index ccbc4278..b2b5e2ee 100644 --- a/public/css/common.css +++ b/public/css/common.css @@ -221,6 +221,10 @@ h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 { border: 2px solid #6C0000; } +#status .table { + margin-bottom: 45px; +} + /* Set the fixed height of the footer here */ #footer { height: 51px; diff --git a/public/views/status.html b/public/views/status.html index da408791..94cfaf79 100644 --- a/public/views/status.html +++ b/public/views/status.html @@ -1,79 +1,11 @@
- -
-
-

getInfo()

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Loading... -
{{infoError}} -
Version{{info.version}}
protocolversion{{info.protocolversion}}
walletversion{{info.walletversion}}
balance{{info.balance}}
blocks{{info.blocks}}
timeoffset{{info.timeoffset}}
connections{{info.connections}}
proxy{{info.proxy}}
difficulty{{info.difficulty}}
testnet{{info.testnet}}
keypoololdest{{info.keypoololdest}}
keypoolsize{{info.keypoolsize}}
paytxfee{{info.paytxfee}}
infoErrors{{info.infoErrors}}
- -

Sync Status

- +
+ +
+

Sync Status

+
{{ syncError }} @@ -119,9 +51,9 @@
- -

getTxOutSetInfo()

- + +

getTxOutSetInfo()

+
@@ -160,39 +92,109 @@
Loading...
-

getDifficulty()

- - - - - - - - - - - - - - -
Loading...
{{infoError}}
Difficulty{{difficulty}}
- -

getLastBlockHash()

- - - - - - - - - - - - - -
Loading...
{{infoError}}
Last block hash{{lastblockhash}}
-
-
+

getLastBlockHash()

+ + + + + + + + + + + + + +
Loading...
{{infoError}}
Last block hash{{lastblockhash}}
+
+ +
+
+

getInfo()

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Loading... +
{{infoError}} +
Version{{info.version}}
protocolversion{{info.protocolversion}}
walletversion{{info.walletversion}}
balance{{info.balance}}
blocks{{info.blocks}}
timeoffset{{info.timeoffset}}
connections{{info.connections}}
proxy{{info.proxy}}
difficulty{{info.difficulty}}
testnet{{info.testnet}}
keypoololdest{{info.keypoololdest}}
keypoolsize{{info.keypoolsize}}
paytxfee{{info.paytxfee}}
infoErrors{{info.infoErrors}}
+ +

getDifficulty()

+ + + + + + + + + + + + + + +
Loading...
{{infoError}}
Difficulty{{difficulty}}
+
+
+ From b53fbc3fd2cfc908eaaaf444f2d9276cecf16f47 Mon Sep 17 00:00:00 2001 From: Mario Colque Date: Tue, 21 Jan 2014 16:12:58 -0300 Subject: [PATCH 30/40] Several UI improvements --- public/views/transaction/list.html | 6 +++--- public/views/transaction/tx.html | 21 ++++++++------------- 2 files changed, 11 insertions(+), 16 deletions(-) diff --git a/public/views/transaction/list.html b/public/views/transaction/list.html index c1262f2d..8b68db0f 100644 --- a/public/views/transaction/list.html +++ b/public/views/transaction/list.html @@ -2,8 +2,8 @@
-
-
- Loading... +
+
+ Loading...
diff --git a/public/views/transaction/tx.html b/public/views/transaction/tx.html index 76be7869..3c53d76e 100644 --- a/public/views/transaction/tx.html +++ b/public/views/transaction/tx.html @@ -1,14 +1,9 @@
{{tx.txid}} - - - + - {{tx.time * 1000 | date:'medium'}} - -
@@ -25,8 +20,8 @@
  • - {{vin.addr}} - {{vin.addr}} + {{vin.addr}} + {{vin.addr}}

    {{vin.value}} BTC

    @@ -38,8 +33,8 @@
    - {{vin.addr}} - {{vin.addr}} + {{vin.addr}} + {{vin.addr}}
    scriptSig {{vin.scriptSig.asm}} @@ -59,7 +54,7 @@
    - {{vout.addr}} + {{vout.addr}} {{address}}
    @@ -72,7 +67,7 @@ - type {{vout.scriptPubKey.type}} + type {{vout.scriptPubKey.type}}
    scriptPubKey {{vout.scriptPubKey.asm}}
    @@ -81,7 +76,7 @@

    {{vout.value}} BTC

    - +
  • From bc35e2731fba9d79bf8e656c5fa017df0cfba926 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Tue, 21 Jan 2014 16:19:48 -0300 Subject: [PATCH 31/40] block wording changes --- public/views/block.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/views/block.html b/public/views/block.html index 88cc2313..f8fb216c 100644 --- a/public/views/block.html +++ b/public/views/block.html @@ -68,7 +68,7 @@ {{block.bits}} - Size + Size (bytes) {{block.size}} From b1082a05e98345ee11b07bb58198310a1a66767f Mon Sep 17 00:00:00 2001 From: Mario Colque Date: Tue, 21 Jan 2014 16:30:08 -0300 Subject: [PATCH 32/40] no address in vout --- public/js/controllers/transactions.js | 9 +++++++++ public/views/transaction/tx.html | 4 ++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/public/js/controllers/transactions.js b/public/js/controllers/transactions.js index f657dea6..6190c43a 100644 --- a/public/js/controllers/transactions.js +++ b/public/js/controllers/transactions.js @@ -14,6 +14,8 @@ angular.module('insight.transactions').controller('transactionsController', }; $scope.aggregateItems = function(items) { + if (!items) return []; + var l = items.length; var ret = []; @@ -33,6 +35,13 @@ angular.module('insight.transactions').controller('transactionsController', } // non standard output + if (items[i].scriptPubKey && !items[i].scriptPubKey.addresses) { + items[i].scriptPubKey.addresses = ['Unparsed address [' + u++ + ']']; + items[i].notAddr = true; + notAddr = true; + } + + // multiple addr at output if (items[i].scriptPubKey && items[i].scriptPubKey.addresses.length > 1) { items[i].addr = items[i].scriptPubKey.addresses.join(','); ret.push(items[i]); diff --git a/public/views/transaction/tx.html b/public/views/transaction/tx.html index 3c53d76e..cdd90d82 100644 --- a/public/views/transaction/tx.html +++ b/public/views/transaction/tx.html @@ -54,8 +54,8 @@
    - {{vout.addr}} - {{address}} + {{vout.addr}} + {{address}}
    From abefb1a879e692734889d8140ef3ebd53e0c9bc2 Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Tue, 21 Jan 2014 16:43:05 -0300 Subject: [PATCH 33/40] check network config --- lib/HistoricSync.js | 26 +++++++++++++++++++++++--- public/js/controllers/status.js | 6 ++++++ server.js | 18 ++++++++++++------ 3 files changed, 41 insertions(+), 9 deletions(-) diff --git a/lib/HistoricSync.js b/lib/HistoricSync.js index f6a29e29..25936901 100644 --- a/lib/HistoricSync.js +++ b/lib/HistoricSync.js @@ -35,9 +35,29 @@ function spec() { } HistoricSync.prototype.init = function(opts, cb) { - this.rpc = new RpcClient(config.bitcoind); - this.opts = opts; - this.sync.init(opts, cb); + + var self = this; + self.rpc = new RpcClient(config.bitcoind); + self.opts = opts; + self.sync.init(opts, function(err) { + if (err) { + self.err = err.message; + self.syncInfo = util._extend(self.syncInfo, { error: err.message }); + return cb(err); + } + else { + // check testnet? + self.rpc.getBlockHash(0, function(err, res){ + if (!err && ( res && res.result !== self.genesis)) { + self.err = 'Bad genesis block. Network mismatch between Insight and bitcoind? Insight is configured for:' + config.network; + err = new Error(self.err); + self.syncInfo = util._extend(self.syncInfo, { error: err.message }); + } + return cb(err); + }); + } + }); + }; HistoricSync.prototype.close = function() { diff --git a/public/js/controllers/status.js b/public/js/controllers/status.js index d4d41112..a3500025 100644 --- a/public/js/controllers/status.js +++ b/public/js/controllers/status.js @@ -23,6 +23,12 @@ function($scope, $routeParams, $location, $rootScope, Global, Status, Sync, get_ }; var on_sync_update = function(sync) { + + if (sync.error) { + $rootScope.syncError = sync.error; + return; + } + if (sync.blocksToSync > sync.syncedBlocks) { var p = parseInt(100*(sync.syncedBlocks) / sync.blocksToSync); var delta = sync.blocksToSync - sync.syncedBlocks; diff --git a/server.js b/server.js index c2fde5f5..a44d1ef3 100644 --- a/server.js +++ b/server.js @@ -62,13 +62,19 @@ if (!config.disableHistoricSync) { shouldBroadcast: true, progressStep: 2, networkName: config.network - }, function() { - historicSync.smart_import(function(err){ - var txt= 'ended.'; - if (err) txt = 'ABORTED with error: ' + err.message; + }, function(err) { + if (err) { + var txt = 'ABORTED with error: ' + err.message; + console.log('[historic_sync] ' + txt); + } + else { + historicSync.smart_import(function(err){ + var txt= 'ended.'; + if (err) txt = 'ABORTED with error: ' + err.message; - console.log('[historic_sync] ' + txt, historicSync.syncInfo); - }); + console.log('[historic_sync] ' + txt, historicSync.syncInfo); + }); + } }); } From 52cb28c586fe438c55c4676f4ae97b3cbd1fafc1 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Tue, 21 Jan 2014 16:49:09 -0300 Subject: [PATCH 34/40] feeds->fees --- app/models/Transaction.js | 2 +- public/views/transaction.html | 2 +- public/views/transaction/tx.html | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/models/Transaction.js b/app/models/Transaction.js index 7b2c4f9e..12b46986 100644 --- a/app/models/Transaction.js +++ b/app/models/Transaction.js @@ -322,7 +322,7 @@ TransactionSchema.statics.queryInfo = function(txid, cb) { if ( !tx.isCoinBase() ) { info.valueIn = valueIn / util.COIN; - info.feeds = (valueIn - valueOut) / util.COIN; + info.fees = (valueIn - valueOut) / util.COIN; } else { var reward = BitcoreBlock.getBlockValue(info.height) / util.COIN; diff --git a/public/views/transaction.html b/public/views/transaction.html index 3970353f..2a688e1e 100644 --- a/public/views/transaction.html +++ b/public/views/transaction.html @@ -43,7 +43,7 @@ Fees - {{tx.feeds}} BTC + {{tx.fees}} BTC diff --git a/public/views/transaction/tx.html b/public/views/transaction/tx.html index cdd90d82..fd505df3 100644 --- a/public/views/transaction/tx.html +++ b/public/views/transaction/tx.html @@ -92,7 +92,7 @@
    - Feeds: {{tx.feeds}} + Fees: {{tx.fees}}
    From 34d92dda32896d24108ae4ec56b010cfae279a7c Mon Sep 17 00:00:00 2001 From: Bechi Date: Tue, 21 Jan 2014 17:03:57 -0300 Subject: [PATCH 35/40] blocks by date --- public/css/common.css | 3 +-- public/views/block.html | 4 ++-- public/views/blocks/list.html | 38 +++++++++++++++++++++++------------ 3 files changed, 28 insertions(+), 17 deletions(-) diff --git a/public/css/common.css b/public/css/common.css index ccbc4278..c3f6f048 100644 --- a/public/css/common.css +++ b/public/css/common.css @@ -159,9 +159,8 @@ h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 { border-radius: :;px; } -.block-id h1 { +.block-id h3 { font-weight: bold; - font-size: 24px; color: #FFFFFF; line-height: 30px; text-align: center; diff --git a/public/views/block.html b/public/views/block.html index 88cc2313..274c7db6 100644 --- a/public/views/block.html +++ b/public/views/block.html @@ -1,12 +1,12 @@
    -
    +
    -

    Block #{{ block.height }}

    +

    Block #{{ block.height }}

    Hashes

    diff --git a/public/views/blocks/list.html b/public/views/blocks/list.html index 494255ff..abdcf856 100644 --- a/public/views/blocks/list.html +++ b/public/views/blocks/list.html @@ -1,18 +1,30 @@
    -
    -
    - - +
    +
    +
    +
    + +

    Blocks
    mined on:

    +
    +
    +

    {{pagination.current}}

    + + +
    +
    + +
    + +
    From 56a49785932b910b10107c7d1ee1969c8b3a59fb Mon Sep 17 00:00:00 2001 From: Bechi Date: Tue, 21 Jan 2014 17:20:05 -0300 Subject: [PATCH 36/40] 02 status page --- public/css/common.css | 4 + public/views/status.html | 213 ++++++++++++++++++++------------------- 2 files changed, 113 insertions(+), 104 deletions(-) diff --git a/public/css/common.css b/public/css/common.css index 7e4da555..b7543c75 100644 --- a/public/css/common.css +++ b/public/css/common.css @@ -224,6 +224,10 @@ h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 { margin-bottom: 45px; } +.progress-bar-info { + background-color: #8DC429; +} + /* Set the fixed height of the footer here */ #footer { height: 51px; diff --git a/public/views/status.html b/public/views/status.html index 8ca3f614..6ff6abfc 100644 --- a/public/views/status.html +++ b/public/views/status.html @@ -4,76 +4,11 @@ Application Status -
    -
    -

    Bitcoin node information

    -
    Hash
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Loading... -
    {{infoError}} -
    Version{{info.version}}
    Protocol version{{info.protocolversion}}
    Wallet version{{info.walletversion}}
    Balance (BTC){{info.balance}}
    Blocks{{info.blocks}}
    Time Offset{{info.timeoffset}}
    Connections to other nodes{{info.connections}}
    Proxy setting{{info.proxy}}
    Mining Difficulty{{info.difficulty}}
    Testnet{{info.testnet}}
    Keypool Oldest Date{{info.keypoololdest*1000 | date:'medium' }}
    Keypool Size{{info.keypoolsize}}
    Default Transaction Fee (BTC){{info.paytxfee}}
    Info Errors{{info.infoErrors}}
    +
    +
    -

    Sync Status

    - +

    Sync Status

    +
    - + - + - - -
    {{ syncError }} @@ -91,29 +26,29 @@
    Blocks to Sync{{sync.blocksToSync}}{{sync.blocksToSync}}
    Synced Blocks{{sync.syncedBlocks}}{{sync.syncedBlocks}}
    Start + {{sync.start}} (genesisBlock)
    End + {{sync.end}} (genesisBlock)
    Sync properties +
    • Stops at existing block
    • @@ -125,8 +60,8 @@
    -

    Transaction Output Set Information

    - +

    Transaction Output Set Information

    +
    @@ -136,54 +71,37 @@ - + - + - + - + - + - + - - - -
    Loading...
    Height{{txoutsetinfo.height}}{{txoutsetinfo.height}}
    Best Block{{txoutsetinfo.bestblock}}{{txoutsetinfo.bestblock}}
    Transactions{{txoutsetinfo.transactions}} {{txoutsetinfo.transactions}}
    Transaction Outputs{{txoutsetinfo.txouts}}{{txoutsetinfo.txouts}}
    Bytes Serialized{{txoutsetinfo.bytes_serialized}}{{txoutsetinfo.bytes_serialized}}
    Hash Serialized{{txoutsetinfo.hash_serialized}}{{txoutsetinfo.hash_serialized}}
    Total Amount{{txoutsetinfo.total_amount}}
    - -

    Difficulty

    - - - - - - - - - - - - +
    Loading...
    {{infoError}}
    Mining Difficulty{{difficulty}}{{txoutsetinfo.total_amount}}
    -

    Last Block

    - +

    Last Block

    +
    @@ -193,11 +111,98 @@ - +
    Loading...
    Last block hash{{lastblockhash}}{{lastblockhash}}
    -
    +
    + +
    +
    +

    Bitcoin node information

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Loading... +
    {{infoError}} +
    Version{{info.version}}
    Protocol version{{info.protocolversion}}
    Wallet version{{info.walletversion}}
    Balance (BTC){{info.balance}}
    Blocks{{info.blocks}}
    Time Offset{{info.timeoffset}}
    Connections to other nodes{{info.connections}}
    Proxy setting{{info.proxy}}
    Mining Difficulty{{info.difficulty}}
    Testnet{{info.testnet}}
    Keypool Oldest Date{{info.keypoololdest*1000 | date:'medium' }}
    Keypool Size{{info.keypoolsize}}
    Default Transaction Fee (BTC){{info.paytxfee}}
    Info Errors{{info.infoErrors}}
    + +

    Difficulty

    + + + + + + + + + + + + + + +
    Loading...
    {{infoError}}
    Mining Difficulty{{difficulty}}
    +
    +
    From 92dc356b0b73ab155d2182c0bd64138549096ce7 Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Tue, 21 Jan 2014 17:46:42 -0300 Subject: [PATCH 37/40] errors in sync header --- public/css/common.css | 6 ++++++ public/js/controllers/status.js | 30 ++++++++++++++++-------------- public/views/header.html | 2 ++ server.js | 3 +++ 4 files changed, 27 insertions(+), 14 deletions(-) diff --git a/public/css/common.css b/public/css/common.css index 7e4da555..9cc2c091 100644 --- a/public/css/common.css +++ b/public/css/common.css @@ -368,4 +368,10 @@ h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 { font-size: 80%; } +.status .text-danger { + color: white; + background: red; + display: inline-block; + padding:0px 5px; +} diff --git a/public/js/controllers/status.js b/public/js/controllers/status.js index a3500025..59f34b08 100644 --- a/public/js/controllers/status.js +++ b/public/js/controllers/status.js @@ -25,31 +25,33 @@ function($scope, $routeParams, $location, $rootScope, Global, Status, Sync, get_ var on_sync_update = function(sync) { if (sync.error) { - $rootScope.syncError = sync.error; - return; + $scope.syncError = sync.error; } - - if (sync.blocksToSync > sync.syncedBlocks) { - var p = parseInt(100*(sync.syncedBlocks) / sync.blocksToSync); - var delta = sync.blocksToSync - sync.syncedBlocks; - sync.message = 'Sync ' + p + '% ['+delta+' blocks remaining]'; - sync.style = 'warn'; - } else { - sync.message = 'On sync'; - sync.style = 'success'; + else { + if (sync.blocksToSync > sync.syncedBlocks) { + var p = parseInt(100*(sync.syncedBlocks) / sync.blocksToSync); + var delta = sync.blocksToSync - sync.syncedBlocks; + sync.message = 'Sync ' + p + '% ['+delta+' blocks remaining]'; + sync.style = 'warn'; + } else { + sync.message = 'On sync'; + sync.style = 'success'; + } + sync.tooltip = 'Synced blocks: '+sync.syncedBlocks; } - sync.tooltip = 'Synced blocks: '+sync.syncedBlocks; $scope.sync = sync; + $scope.hola = 'hola'; +console.log('[status.js.43:hola:]'); //TODO }; $scope.getSync = function() { Sync.get({}, function(sync) { - $rootScope.syncError = null; + $scope.syncError = null; on_sync_update(sync); }, function(e) { - $rootScope.syncError = 'Could not get sync information' + e; + $scope.syncError = 'Could not get sync information' + e; }); }; diff --git a/public/views/header.html b/public/views/header.html index 47917e14..a465aa92 100755 --- a/public/views/header.html +++ b/public/views/header.html @@ -25,6 +25,8 @@
    +
    ERROR
    + {{sync.message}} diff --git a/server.js b/server.js index a44d1ef3..b2cdaf0b 100644 --- a/server.js +++ b/server.js @@ -55,8 +55,11 @@ walk(models_path); // historic_sync process var historicSync = {}; + + if (!config.disableHistoricSync) { historicSync = new HistoricSync(); + historicSync.init({ skipDbConnection: true, shouldBroadcast: true, From 18bbe828cdef3ada98bf03561a3fe8ba57a6bf34 Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Tue, 21 Jan 2014 19:13:21 -0300 Subject: [PATCH 38/40] errors in sync header --- app/controllers/socket.js | 4 +- app/controllers/status.js | 4 +- config/express.js | 2 +- lib/HistoricSync.js | 154 ++++++++++++++++---------------- public/js/controllers/status.js | 12 +-- public/views/header.html | 2 +- server.js | 4 +- util/sync.js | 6 +- 8 files changed, 94 insertions(+), 94 deletions(-) diff --git a/app/controllers/socket.js b/app/controllers/socket.js index ace6315d..25a846ed 100644 --- a/app/controllers/socket.js +++ b/app/controllers/socket.js @@ -26,6 +26,6 @@ module.exports.broadcast_address_tx = function(address, tx) { ios.sockets.in(address).emit('atx', tx); }; -module.exports.broadcastSyncInfo = function(syncInfo) { - ios.sockets.in('sync').emit('status', syncInfo); +module.exports.broadcastSyncInfo = function(historicSync) { + ios.sockets.in('sync').emit('status', historicSync); }; diff --git a/app/controllers/status.js b/app/controllers/status.js index 7fb6f72a..c978722f 100644 --- a/app/controllers/status.js +++ b/app/controllers/status.js @@ -50,6 +50,6 @@ exports.show = function(req, res) { }; exports.sync = function(req, res) { - if (req.syncInfo) - res.jsonp(req.syncInfo); + if (req.historicSync) + res.jsonp(req.historicSync.info()); }; diff --git a/config/express.js b/config/express.js index 0e5c58d4..0b9c284d 100644 --- a/config/express.js +++ b/config/express.js @@ -31,7 +31,7 @@ module.exports = function(app, historicSync) { //custom middleware function setHistoric(req, res, next) { - req.syncInfo = historicSync.syncInfo; + req.historicSync = historicSync; next(); } app.use('/api/sync', setHistoric); diff --git a/lib/HistoricSync.js b/lib/HistoricSync.js index 25936901..5a2b2859 100644 --- a/lib/HistoricSync.js +++ b/lib/HistoricSync.js @@ -2,6 +2,8 @@ require('classtool'); + + function spec() { var util = require('util'); var RpcClient = require('bitcore/RpcClient').class(); @@ -12,6 +14,9 @@ function spec() { var Sync = require('./Sync').class(); var sockets = require('../app/controllers/socket.js'); + + var BAD_GEN_ERROR = 'Bad genesis block. Network mismatch between Insight and bitcoind? Insight is configured for:'; + function HistoricSync(opts) { this.network = config.network === 'testnet' ? networks.testnet: networks.livenet; @@ -22,7 +27,12 @@ function spec() { //available status: new / syncing / finished / aborted this.status = 'new'; - this.syncInfo = {}; + this.error = null; + + this.syncPercentage = 0; + this.syncedBlocks = 0; + this.skippedBlocks = 0; + } function p() { @@ -34,6 +44,13 @@ function spec() { console.log.apply(this, args); } + HistoricSync.prototype.setError = function(err) { + var self = this; + self.error = err.toString(); + self.status='error'; + self.showProgress(); + }; + HistoricSync.prototype.init = function(opts, cb) { var self = this; @@ -41,17 +58,15 @@ function spec() { self.opts = opts; self.sync.init(opts, function(err) { if (err) { - self.err = err.message; - self.syncInfo = util._extend(self.syncInfo, { error: err.message }); + self.setError(err); return cb(err); } else { // check testnet? self.rpc.getBlockHash(0, function(err, res){ if (!err && ( res && res.result !== self.genesis)) { - self.err = 'Bad genesis block. Network mismatch between Insight and bitcoind? Insight is configured for:' + config.network; - err = new Error(self.err); - self.syncInfo = util._extend(self.syncInfo, { error: err.message }); + err = new Error(BAD_GEN_ERROR + config.network); + self.setError(err); } return cb(err); }); @@ -64,14 +79,29 @@ function spec() { this.sync.close(); }; + + HistoricSync.prototype.info = function() { + return { + status: this.status, + blockChainHeight: this.blockChainHeight, + syncPercentage: this.syncPercentage, + skippedBlocks: this.skippedBlocks, + syncedBlocks: this.syncedBlocks, + }; + }; + HistoricSync.prototype.showProgress = function() { var self = this; - var i = self.syncInfo; - var per = parseInt(100 * i.syncedBlocks / i.blocksToSync); - p(util.format('status: %d/%d [%d%%]', i.syncedBlocks, i.blocksToSync, per)); + if (self.error) { + p('ERROR:' + self.error); + } + else { + self.syncPercentage = parseFloat(100 * self.syncedBlocks / self.blockChainHeight).toFixed(3); + p(util.format('status: [%d%%] skipped: %d', self.syncPercentage, self.skippedBlocks)); + } if (self.opts.shouldBroadcast) { - sockets.broadcastSyncInfo(self.syncInfo); + sockets.broadcastSyncInfo(self.info()); } }; @@ -105,17 +135,10 @@ function spec() { }, //show some (inacurate) status function(c) { - if (!self.step) { - var step = parseInt(self.syncInfo.blocksToSync / 100); - if (self.opts.progressStep) { - step = self.opts.progressStep; - } - if (step < 2) step = 2; - self.step = step; - } - if (self.syncInfo.syncedBlocks % self.step === 1) { + if ( ( self.syncedBlocks + self.skippedBlocks) % self.step === 1) { self.showProgress(); } + return c(); }, //get Info from RPC @@ -154,57 +177,49 @@ function spec() { ], function(err) { if (err) { - self.err = util.format('ERROR: @%s: %s [count: syncedBlocks: %d]', blockHash, err, self.syncInfo.syncedBlocks); + self.err = util.format('ERROR: @%s: %s [count: syncedBlocks: %d]', blockHash, err, self.syncedBlocks); self.status = 'aborted'; + self.showProgress(); p(self.err); } - else { self.err = null; self.status = 'syncing'; } - if (opts.upToExisting && existed) { - var diff = self.syncInfo.blocksToSync - self.syncInfo.syncedBlocks; - if (diff <= 0) { + if ( (opts.upToExisting && existed && self.syncedBlocks >= self.blockChainHeight) || + (blockEnd && blockEnd === blockHash)) { self.status = 'finished'; p('DONE. Found existing block: ', blockHash); + self.showProgress(); return cb(err); - } - else { - self.syncInfo.skipped_blocks = self.syncInfo.skipped_blocks || 1; - if ((self.syncInfo.skipped_blocks++ % 1000) === 1) { - p('WARN found target block\n\tbut blockChain Height is still higher that ours. Previous light sync must be interrupted.\n\tWill keep syncing.', self.syncInfo.syncedBlocks, self.syncInfo.blocksToSync, self.syncInfo.skipped_blocks); - } - } - } - - if (blockEnd && blockEnd === blockHash) { - self.status = 'finished'; - p('DONE. Found END block: ', blockHash); - return cb(err); } // Continue if (blockInfo && blockInfo.result) { - if (!existed) self.syncInfo.syncedBlocks++; - if (opts.prev && blockInfo.result.previousblockhash) { - return self.getPrevNextBlock(blockInfo.result.previousblockhash, blockEnd, opts, cb); - } - if (opts.next && blockInfo.result.nextblockhash) return self.getPrevNextBlock(blockInfo.result.nextblockhash, blockEnd, opts, cb); + if (existed) + self.skippedBlocks++; + else + self.syncedBlocks++; + + // recursion + if (opts.prev && blockInfo.result.previousblockhash) + return self.getPrevNextBlock(blockInfo.result.previousblockhash, blockEnd, opts, cb); + + if (opts.next && blockInfo.result.nextblockhash) + return self.getPrevNextBlock(blockInfo.result.nextblockhash, blockEnd, opts, cb); } return cb(err); }); }; - HistoricSync.prototype.import_history = function(opts, next) { + HistoricSync.prototype.importHistory = function(opts, next) { var self = this; var retry_secs = 2; var bestBlock; - var blockChainHeight; async.series([ function(cb) { @@ -220,14 +235,14 @@ function spec() { self.rpc.getBlockCount(function(err, res) { if (err) return cb(err); - blockChainHeight = res.result; + self.blockChainHeight = res.result; return cb(); }); }, function(cb) { if (!opts.reverse) return cb(); - self.rpc.getBlockHash(blockChainHeight, function(err, res) { + self.rpc.getBlockHash(self.blockChainHeight, function(err, res) { if (err) return cb(err); bestBlock = res.result; @@ -236,15 +251,8 @@ function spec() { }); }, function(cb) { - // This is only to inform progress. - if (!opts.upToExisting) { - self.rpc.getInfo(function(err, res) { - if (err) return cb(err); - self.syncInfo.blocksToSync = res.result.blocks; - return cb(); - }); - } - else { + if (opts.upToExisting) { + // should be isOrphan = true or null to be more accurate. Block.count({ isOrphan: null @@ -252,14 +260,12 @@ function spec() { function(err, count) { if (err) return cb(err); - self.syncInfo.blocksToSync = blockChainHeight - count; - if (self.syncInfo.blocksToSync < 1) self.syncInfo.blocksToSync = 1; + self.syncedBlocks = count || 0; return cb(); }); } }, ], function(err) { - var start, end; function sync() { if (opts.reverse) { @@ -272,18 +278,6 @@ function spec() { end = null; opts.next = true; } - - self.syncInfo = util._extend(self.syncInfo, { - start: start, - isStartGenesis: start === self.genesis, - end: end, - isEndGenesis: end === self.genesis, - scanningForward: opts.next, - scanningBackward: opts.prev, - upToExisting: opts.upToExisting, - syncedBlocks: 0, - }); - p('Starting from: ', start); p(' to : ', end); p(' opts: ', JSON.stringify(opts)); @@ -300,10 +294,20 @@ function spec() { }); } + + if (!self.step) { + var step = parseInt( (self.blockChainHeight - self.syncedBlocks) / 100); + + if (self.opts.progressStep) { + step = self.opts.progressStep; + } + + if (step < 100) step = 100; + self.step = step; + } + if (err) { - self.syncInfo = util._extend(self.syncInfo, { - error: err.message - }); + self.setError(err); return next(err, 0); } else { @@ -313,7 +317,7 @@ function spec() { }; // upto if we have genesis block? - HistoricSync.prototype.smart_import = function(next) { + HistoricSync.prototype.smartImport = function(next) { var self = this; Block.findOne({ @@ -335,7 +339,7 @@ function spec() { upToExisting: b ? true: false, }; - return self.import_history(opts, next); + return self.importHistory(opts, next); }); }; diff --git a/public/js/controllers/status.js b/public/js/controllers/status.js index 59f34b08..6009f0d4 100644 --- a/public/js/controllers/status.js +++ b/public/js/controllers/status.js @@ -24,10 +24,7 @@ function($scope, $routeParams, $location, $rootScope, Global, Status, Sync, get_ var on_sync_update = function(sync) { - if (sync.error) { - $scope.syncError = sync.error; - } - else { + if (!sync.error) { if (sync.blocksToSync > sync.syncedBlocks) { var p = parseInt(100*(sync.syncedBlocks) / sync.blocksToSync); var delta = sync.blocksToSync - sync.syncedBlocks; @@ -40,24 +37,23 @@ function($scope, $routeParams, $location, $rootScope, Global, Status, Sync, get_ sync.tooltip = 'Synced blocks: '+sync.syncedBlocks; } $scope.sync = sync; - $scope.hola = 'hola'; -console.log('[status.js.43:hola:]'); //TODO }; $scope.getSync = function() { Sync.get({}, function(sync) { - $scope.syncError = null; on_sync_update(sync); }, function(e) { - $scope.syncError = 'Could not get sync information' + e; + $scope.sync = { error: 'Could not get sync information' + e }; }); }; var socket = get_socket($scope); socket.emit('subscribe', 'sync'); socket.on('status', function(sync) { + +console.log('[status.js.55::] sync status update received!'); on_sync_update(sync); }); diff --git a/public/views/header.html b/public/views/header.html index a465aa92..2ee0e1c2 100755 --- a/public/views/header.html +++ b/public/views/header.html @@ -25,7 +25,7 @@
    -
    ERROR
    +
    ERROR
    {{sync.message}} diff --git a/server.js b/server.js index b2cdaf0b..64027d03 100644 --- a/server.js +++ b/server.js @@ -71,11 +71,11 @@ if (!config.disableHistoricSync) { console.log('[historic_sync] ' + txt); } else { - historicSync.smart_import(function(err){ + historicSync.smartImport(function(err){ var txt= 'ended.'; if (err) txt = 'ABORTED with error: ' + err.message; - console.log('[historic_sync] ' + txt, historicSync.syncInfo); + console.log('[historic_sync] ' + txt, historicSync.info()); }); } }); diff --git a/util/sync.js b/util/sync.js index b7f6e03c..2dd4f15f 100755 --- a/util/sync.js +++ b/util/sync.js @@ -33,10 +33,10 @@ async.series([ }, function(cb) { if (program.smart) { - historicSync.smart_import(cb); + historicSync.smartImport(cb); } else { - historicSync.import_history({ + historicSync.importHistory({ destroy: program.destroy, reverse: program.reverse, upToExisting: program.uptoexisting, @@ -50,7 +50,7 @@ async.series([ console.log('CRITICAL ERROR: ', err); } else { - console.log('Finished.\n Status:\n', historicSync.syncInfo); + console.log('Finished.\n Status:\n', historicSync.info()); } }); From 7ac3b5b1aa5afdedec49900bbd0e1004b8d06ee6 Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Tue, 21 Jan 2014 19:40:41 -0300 Subject: [PATCH 39/40] better header for sync --- lib/HistoricSync.js | 4 ++-- public/css/common.css | 15 +++++++++++++-- public/js/controllers/status.js | 14 -------------- public/views/header.html | 7 +++---- 4 files changed, 18 insertions(+), 22 deletions(-) diff --git a/lib/HistoricSync.js b/lib/HistoricSync.js index 5a2b2859..4f8c8258 100644 --- a/lib/HistoricSync.js +++ b/lib/HistoricSync.js @@ -296,13 +296,13 @@ function spec() { if (!self.step) { - var step = parseInt( (self.blockChainHeight - self.syncedBlocks) / 100); + var step = parseInt( (self.blockChainHeight - self.syncedBlocks) / 1000); if (self.opts.progressStep) { step = self.opts.progressStep; } - if (step < 100) step = 100; + if (step < 10) step = 10; self.step = step; } diff --git a/public/css/common.css b/public/css/common.css index 9cc2c091..7222a96c 100644 --- a/public/css/common.css +++ b/public/css/common.css @@ -368,10 +368,21 @@ h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 { font-size: 80%; } -.status .text-danger { +.status .t { color: white; - background: red; display: inline-block; padding:0px 5px; } +.status .text-danger { + background: red; +} + +.status .text-warning { + background: yellow; + color: black; +} + +.status .text-default { +} + diff --git a/public/js/controllers/status.js b/public/js/controllers/status.js index 6009f0d4..56c823a3 100644 --- a/public/js/controllers/status.js +++ b/public/js/controllers/status.js @@ -23,19 +23,6 @@ function($scope, $routeParams, $location, $rootScope, Global, Status, Sync, get_ }; var on_sync_update = function(sync) { - - if (!sync.error) { - if (sync.blocksToSync > sync.syncedBlocks) { - var p = parseInt(100*(sync.syncedBlocks) / sync.blocksToSync); - var delta = sync.blocksToSync - sync.syncedBlocks; - sync.message = 'Sync ' + p + '% ['+delta+' blocks remaining]'; - sync.style = 'warn'; - } else { - sync.message = 'On sync'; - sync.style = 'success'; - } - sync.tooltip = 'Synced blocks: '+sync.syncedBlocks; - } $scope.sync = sync; }; @@ -52,7 +39,6 @@ function($scope, $routeParams, $location, $rootScope, Global, Status, Sync, get_ var socket = get_socket($scope); socket.emit('subscribe', 'sync'); socket.on('status', function(sync) { - console.log('[status.js.55::] sync status update received!'); on_sync_update(sync); }); diff --git a/public/views/header.html b/public/views/header.html index 2ee0e1c2..726b8384 100755 --- a/public/views/header.html +++ b/public/views/header.html @@ -25,10 +25,9 @@
    -
    ERROR
    - - - {{sync.message}} +
    ERROR
    +
    {{sync.status}} {{sync.syncPercentage}}%
    +
    On sync
    From 163eda58409d03b8ceba3db853199b4a9d0f1845 Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Tue, 21 Jan 2014 19:53:00 -0300 Subject: [PATCH 40/40] update status page --- lib/HistoricSync.js | 2 ++ public/views/header.html | 2 +- public/views/status.html | 39 +++++++-------------------------------- 3 files changed, 10 insertions(+), 33 deletions(-) diff --git a/lib/HistoricSync.js b/lib/HistoricSync.js index 4f8c8258..7fd0a567 100644 --- a/lib/HistoricSync.js +++ b/lib/HistoricSync.js @@ -98,6 +98,8 @@ function spec() { } else { self.syncPercentage = parseFloat(100 * self.syncedBlocks / self.blockChainHeight).toFixed(3); + if (self.syncPercentage > 100) self.syncPercentage = 100; + p(util.format('status: [%d%%] skipped: %d', self.syncPercentage, self.skippedBlocks)); } if (self.opts.shouldBroadcast) { diff --git a/public/views/header.html b/public/views/header.html index 726b8384..baf6f772 100755 --- a/public/views/header.html +++ b/public/views/header.html @@ -27,7 +27,7 @@
    ERROR
    {{sync.status}} {{sync.syncPercentage}}%
    -
    On sync
    +
    On sync
    diff --git a/public/views/status.html b/public/views/status.html index 6ff6abfc..ab26f957 100644 --- a/public/views/status.html +++ b/public/views/status.html @@ -10,53 +10,28 @@

    Sync Status

    - - - - - + + - - - - - - - - - - - - + +
    {{ syncError }}
    {{ sync.err }} + {{sync.error}}
    Sync Progress
    -
    - {{(100 * sync.syncedBlocks/sync.blocksToSync)| number:2}}% Complete +
    + {{sync.syncPercentage}}% Complete
    Blocks to Sync{{sync.blocksToSync}}Initial Block Chain Height{{sync.blockChainHeight}}
    Synced Blocks {{sync.syncedBlocks}}
    Start - {{sync.start}} - (genesisBlock) -
    End - {{sync.end}} - (genesisBlock) -
    Sync properties -
      -
    • Stops at existing block -
    • - Backward Scan - Forward Scan -
    -
    Skipped Blocks (previously synced){{sync.skippedBlocks}}